1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2019 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef VMD_H 7 #define VMD_H 8 9 #include "spdk/stdinc.h" 10 #include "spdk/vmd.h" 11 #include "spdk/env.h" 12 #include "spdk/util.h" 13 #include "spdk/log.h" 14 #include "vmd_spec.h" 15 16 struct vmd_hot_plug; 17 struct vmd_adapter; 18 struct vmd_pci_device; 19 20 struct pci_bars { 21 uint64_t vaddr; 22 uint64_t start; 23 uint32_t size; 24 }; 25 26 struct vmd_pci_bus { 27 struct vmd_adapter *vmd; 28 struct vmd_pci_bus *parent; /* parent bus that this bus is attached to(primary bus. */ 29 struct vmd_pci_device *self; /* Pci device that describes this bus(bar, bus numbers, etc */ 30 31 uint32_t domain : 8; 32 uint32_t hotplug_buses : 10; 33 uint32_t is_added : 1; 34 uint32_t hp_event_queued : 1; 35 uint32_t rsv : 12; 36 37 uint32_t bus_number : 8; 38 uint32_t primary_bus : 8; 39 uint32_t secondary_bus : 8; 40 uint32_t subordinate_bus : 8; 41 uint32_t bus_start : 8; 42 uint32_t config_bus_number : 8; 43 44 TAILQ_HEAD(, vmd_pci_device) dev_list; /* list of pci end device attached to this bus */ 45 TAILQ_ENTRY(vmd_pci_bus) tailq; /* link for all buses found during scan */ 46 }; 47 48 /* 49 * memory element for base address assignment and reuse 50 */ 51 struct pci_mem_mgr { 52 uint32_t size : 30; /* size of memory element */ 53 uint32_t in_use : 1; 54 uint32_t rsv : 1; 55 uint64_t addr; 56 TAILQ_ENTRY(pci_mem_mgr) tailq; 57 }; 58 59 struct vmd_hot_plug { 60 uint32_t count : 12; 61 uint32_t reserved_bus_count : 4; 62 uint32_t max_hotplug_bus_number : 8; 63 uint32_t next_bus_number : 8; 64 struct pci_bars bar; 65 union express_slot_status_register slot_status; 66 struct pci_mem_mgr mem[ADDR_ELEM_COUNT]; 67 uint8_t bus_numbers[RESERVED_HOTPLUG_BUSES]; 68 struct vmd_pci_bus *bus; 69 TAILQ_HEAD(, pci_mem_mgr) free_mem_queue; 70 TAILQ_HEAD(, pci_mem_mgr) alloc_mem_queue; 71 TAILQ_HEAD(, pci_mem_mgr) unused_mem_queue; 72 }; 73 74 struct vmd_pci_device { 75 struct spdk_pci_device pci; 76 struct pci_bars bar[6]; 77 78 struct vmd_pci_device *parent_bridge; 79 struct vmd_pci_bus *bus, *parent; 80 struct vmd_pci_bus *bus_object; /* bus tracks pci bus associated with this dev if type 1 dev. */ 81 struct vmd_pci_bus *subordinate; 82 volatile struct pci_header *header; 83 volatile struct pci_express_cap *pcie_cap; 84 volatile struct pci_msix_capability *msix_cap; 85 volatile struct pci_msi_cap *msi_cap; 86 volatile struct serial_number_capability *sn_cap; 87 volatile struct pci_msix_table_entry *msix_table; 88 89 TAILQ_ENTRY(vmd_pci_device) tailq; 90 91 uint32_t class; 92 uint16_t vid; 93 uint16_t did; 94 uint16_t pcie_flags, msix_table_size; 95 uint32_t devfn; 96 bool hotplug_capable; 97 98 uint32_t header_type : 1; 99 uint32_t multifunction : 1; 100 uint32_t hotplug_bridge : 1; 101 uint32_t is_added : 1; 102 uint32_t is_hooked : 1; 103 uint32_t rsv1 : 12; 104 uint32_t target : 16; 105 106 struct vmd_hot_plug hp; 107 /* Cached version of the slot_control register */ 108 union express_slot_control_register cached_slot_control; 109 }; 110 111 /* 112 * The VMD adapter 113 */ 114 struct vmd_adapter { 115 struct spdk_pci_device *pci; 116 uint32_t domain; 117 /* physical and virtual VMD bars */ 118 uint64_t cfgbar, cfgbar_size; 119 uint64_t membar, membar_size; 120 uint64_t msixbar, msixbar_size; 121 volatile uint8_t *cfg_vaddr; 122 volatile uint8_t *mem_vaddr; 123 volatile uint8_t *msix_vaddr; 124 volatile struct pci_msix_table_entry *msix_table; 125 uint32_t bar_sizes[6]; 126 127 uint64_t physical_addr; 128 uint32_t current_addr_size; 129 130 uint32_t next_bus_number : 10; 131 uint32_t max_pci_bus : 10; 132 uint32_t root_port_updated : 1; 133 uint32_t scan_completed : 1; 134 uint32_t rsv : 10; 135 136 /* end devices attached to vmd adapters */ 137 struct vmd_pci_device *target[MAX_VMD_TARGET]; 138 uint32_t dev_count : 16; 139 uint32_t nvme_count : 8; 140 uint32_t vmd_index : 8; 141 142 struct vmd_pci_bus vmd_bus; 143 144 TAILQ_HEAD(, vmd_pci_bus) bus_list; 145 146 struct event_fifo *hp_queue; 147 }; 148 149 struct vmd_pci_device *vmd_find_device(const struct spdk_pci_addr *addr); 150 151 #endif /* VMD_H */ 152