[a31845f7] | 1 | /* PCI Configuration Library, two versions of the library exists: |
---|
| 2 | * - auto configuration (default) |
---|
| 3 | * - static configuration (user defined config) |
---|
| 4 | * both versions are defined here. |
---|
| 5 | * |
---|
[71e8a5c] | 6 | * COPYRIGHT (c) 2010 Cobham Gaisler AB. |
---|
[a31845f7] | 7 | * |
---|
| 8 | * The license and distribution terms for this file may be |
---|
| 9 | * found in the file LICENSE in this distribution or at |
---|
| 10 | * http://www.rtems.com/license/LICENSE. |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | |
---|
| 14 | #ifndef __PCI_CFG_H__ |
---|
| 15 | #define __PCI_CFG_H__ |
---|
| 16 | |
---|
| 17 | #include <pci.h> |
---|
| 18 | |
---|
| 19 | /* PCI Configuration library */ |
---|
| 20 | |
---|
| 21 | /* Return the number of PCI buses in system */ |
---|
| 22 | extern int pci_bus_count(void); |
---|
| 23 | |
---|
| 24 | /* PCI Address assigned to BARs which failed to fit into the PCI Window or |
---|
| 25 | * is disabled by any other cause. |
---|
| 26 | */ |
---|
| 27 | extern uint32_t pci_invalid_address; |
---|
| 28 | |
---|
| 29 | /* PCI Configuration Library of the system */ |
---|
| 30 | enum { |
---|
| 31 | PCI_CONFIG_LIB_NONE = 0, |
---|
| 32 | PCI_CONFIG_LIB_AUTO = 1, |
---|
| 33 | PCI_CONFIG_LIB_STATIC = 2, |
---|
| 34 | PCI_CONFIG_LIB_READ = 3, |
---|
| 35 | PCI_CONFIG_LIB_PERIPHERAL = 4, |
---|
| 36 | }; |
---|
| 37 | extern const int pci_config_lib_type; |
---|
| 38 | |
---|
| 39 | /* Configuration library function pointers, these are set in <rtems/confdefs.h> |
---|
| 40 | * by project configuration or by the BSP. The configuration will pull in the |
---|
| 41 | * PCI Library needed and the PCI initialization functions will call these |
---|
| 42 | * functions on initialization from the host driver. |
---|
| 43 | */ |
---|
| 44 | extern int (*pci_config_lib_init)(void); |
---|
| 45 | extern void (*pci_config_lib_register)(void *config); |
---|
| 46 | |
---|
| 47 | /* Configure PCI devices and bridges, and setup the RAM data structures |
---|
| 48 | * describing the PCI devices currently present in the system. |
---|
| 49 | * |
---|
| 50 | * Returns 0 on success, -1 on failure. |
---|
| 51 | */ |
---|
| 52 | extern int pci_config_init(void); |
---|
| 53 | |
---|
| 54 | /* Register a config-library specific configuration used by the libarary in |
---|
| 55 | * pci_config_init(). |
---|
| 56 | */ |
---|
| 57 | extern void pci_config_register(void *config); |
---|
| 58 | |
---|
| 59 | /* Print current PCI configuration (C-code) to terminal, can be used in |
---|
| 60 | * static and peripheral PCI configuration library. The configuration is |
---|
| 61 | * taken from the current configuration library setup. |
---|
| 62 | */ |
---|
| 63 | extern void pci_cfg_print(void); |
---|
| 64 | |
---|
| 65 | struct pci_bus; /* Bridge Device and secondary bus information */ |
---|
| 66 | struct pci_dev; /* Device/function */ |
---|
| 67 | struct pci_res; /* Resource: BAR, ROM or Bridge Window */ |
---|
| 68 | |
---|
| 69 | /* The Host Bridge and all subdevices (the PCI RAM data structure) */ |
---|
| 70 | extern struct pci_bus pci_hb; |
---|
| 71 | |
---|
[07e5a0e] | 72 | /* Arguments for pci_for_each_child() search option */ |
---|
| 73 | #define SEARCH_CHILDREN 0 /* direct children of bus only */ |
---|
| 74 | #define SEARCH_DEPTH 1 /* all children of bus */ |
---|
| 75 | |
---|
[a31845f7] | 76 | /* Iterate over all PCI devices on a bus (see search options) and call func(), |
---|
| 77 | * iteration is stopped if a non-zero value is returned by func(). |
---|
| 78 | * |
---|
| 79 | * The function iterates over the PCI RAM data structure, it is not |
---|
| 80 | * available until after all devices have been found and pci_hb is populated, |
---|
| 81 | * typically after pci_config_init() is called. |
---|
| 82 | * |
---|
| 83 | * search options: 0 (no child buses), 1 (depth first, recursive) |
---|
| 84 | * |
---|
| 85 | * Return Values |
---|
| 86 | * 0 All PCI devices were processed, func() returned 0 on every call |
---|
| 87 | * X func() returned non-zero X value, the search was stopped |
---|
| 88 | */ |
---|
| 89 | extern int pci_for_each_child( |
---|
| 90 | struct pci_bus *bus, |
---|
| 91 | int (*func)(struct pci_dev *, void *arg), |
---|
| 92 | void *arg, |
---|
| 93 | int search); |
---|
| 94 | |
---|
| 95 | /* Depth first search of all PCI devices in PCI RAM data structure and call |
---|
| 96 | * func(dev, arg), iteration is stopped if a non-zero value is returned by |
---|
| 97 | * func(). |
---|
| 98 | * |
---|
| 99 | * The function iterates over the PCI RAM data structure, it is not |
---|
| 100 | * available until after all devices have been found and pci_hb is populated, |
---|
| 101 | * typically after pci_config_init() is called. |
---|
| 102 | * |
---|
| 103 | * Return Values |
---|
| 104 | * 0 All PCI devices were processed, func() returned 0 on every call |
---|
| 105 | * X func() returned non-zero X value, the search was stopped |
---|
| 106 | */ |
---|
| 107 | extern int pci_for_each_dev( |
---|
| 108 | int (*func)(struct pci_dev *, void *arg), |
---|
| 109 | void *arg); |
---|
| 110 | |
---|
| 111 | /* Get PCI device from RAM device tree for a device matching PCI Vendor, Device |
---|
| 112 | * and instance number 'index'. |
---|
| 113 | * |
---|
| 114 | * Return Values |
---|
| 115 | * -1 pci_find_dev did not find a device matching the criterion. |
---|
| 116 | * 0 device was found, *ppdev was updated with the PCI device address |
---|
| 117 | */ |
---|
| 118 | extern int pci_find_dev(uint16_t ven, uint16_t dev, int index, |
---|
| 119 | struct pci_dev **ppdev); |
---|
| 120 | |
---|
| 121 | /* Get PCI device from RAM device tree by BUS|SLOT|FUNC. |
---|
| 122 | * |
---|
| 123 | * Return Values |
---|
| 124 | * -1 pci_get_dev did not find a device matching the criterion |
---|
| 125 | * 0 device was found, *ppdev was updated with the PCI device address |
---|
| 126 | */ |
---|
| 127 | extern int pci_get_dev(pci_dev_t pcidev, struct pci_dev **ppdev); |
---|
| 128 | |
---|
| 129 | /* Resource flags */ |
---|
| 130 | #define PCI_RES_IO 1 |
---|
| 131 | #define PCI_RES_MEMIO 2 |
---|
| 132 | #define PCI_RES_MEM_PREFETCH 1 |
---|
| 133 | #define PCI_RES_MEM (PCI_RES_MEMIO | PCI_RES_MEM_PREFETCH) |
---|
| 134 | #define PCI_RES_TYPE_MASK 0x3 |
---|
| 135 | #define PCI_RES_IO32 0x08 |
---|
| 136 | #define PCI_RES_FAIL 0x10 /* Alloc Failed */ |
---|
| 137 | |
---|
| 138 | /* BAR Resouces entry */ |
---|
| 139 | struct pci_res { |
---|
| 140 | struct pci_res *next; |
---|
| 141 | uint32_t size; |
---|
| 142 | uint32_t boundary; |
---|
| 143 | unsigned char flags; /* I/O, MEM or MEMIO */ |
---|
| 144 | unsigned char bar; |
---|
| 145 | |
---|
| 146 | /* Assigned Resource (PCI address), zero if not assigned */ |
---|
| 147 | uint32_t start; |
---|
| 148 | uint32_t end; |
---|
| 149 | }; |
---|
| 150 | |
---|
[a2e0e6e] | 151 | /* Get Device from resource pointer. bar is the index of the pci_dev.resources |
---|
| 152 | * array and used to get the device base address of which the resource is |
---|
| 153 | * associated with. |
---|
| 154 | */ |
---|
[a31845f7] | 155 | #define RES2DEV(res) ((struct pci_dev *) \ |
---|
[a2e0e6e] | 156 | ((uintptr_t)res - (uintptr_t)(res->bar * (sizeof(struct pci_res))))) |
---|
[a31845f7] | 157 | |
---|
| 158 | /* Device flags */ |
---|
| 159 | #define PCI_DEV_BRIDGE 0x01 /* Device is a Bridge (struct pci_bus) */ |
---|
| 160 | #define PCI_DEV_RES_FAIL 0x02 /* Resource alloction for device BARs failed */ |
---|
| 161 | |
---|
| 162 | /* Bus Flags */ |
---|
| 163 | #define PCI_BUS_IO 0x01 /* 16-bit I/O address decoding */ |
---|
| 164 | #define PCI_BUS_MEMIO 0x02 /* Bus support non-prefetchable mem (always) */ |
---|
| 165 | #define PCI_BUS_MEM 0x04 /* Bus support prefetchable memory space */ |
---|
| 166 | #define PCI_BUS_IO32 0x08 /* 32-bit I/O address decoding */ |
---|
| 167 | |
---|
| 168 | #define BRIDGE_RES_COUNT 2 /* Number of BAR resources a bridge can have */ |
---|
| 169 | #define BUS_RES_START BRIDGE_RES_COUNT |
---|
| 170 | |
---|
| 171 | /* Bus Resources Array */ |
---|
| 172 | enum { |
---|
| 173 | BUS_RES_IO = 0, |
---|
| 174 | BUS_RES_MEMIO = 1, |
---|
| 175 | BUS_RES_MEM = 2, |
---|
| 176 | }; |
---|
| 177 | |
---|
| 178 | /* Device Resource array index meaning */ |
---|
| 179 | enum { |
---|
| 180 | /* A Device has up to 6 BARs and an optional ROM BAR */ |
---|
| 181 | DEV_RES_BAR1 = 0, |
---|
| 182 | DEV_RES_BAR2 = 1, |
---|
| 183 | DEV_RES_BAR3 = 2, |
---|
| 184 | DEV_RES_BAR4 = 3, |
---|
| 185 | DEV_RES_BAR5 = 4, |
---|
| 186 | DEV_RES_BAR6 = 5, |
---|
| 187 | DEV_RES_ROM = 6, |
---|
| 188 | |
---|
| 189 | /* Bridges have 2 BARs (BAR1 and BAR2) and 3 Windows to secondary bus |
---|
| 190 | * and an optional ROM BAR |
---|
| 191 | */ |
---|
| 192 | BRIDGE_RES_BAR1 = 0, |
---|
| 193 | BRIDGE_RES_BAR2 = 1, |
---|
| 194 | BRIDGE_RES_IO = 2, |
---|
| 195 | BRIDGE_RES_MEMIO = 3, |
---|
| 196 | BRIDGE_RES_MEM = 4, |
---|
| 197 | BRIDGE_RES_UNUSED1 = 5, |
---|
| 198 | BRIDGE_RES_ROM = 6, |
---|
| 199 | }; |
---|
| 200 | |
---|
| 201 | /* Maximum Number of Resources of a device */ |
---|
| 202 | #define DEV_RES_CNT (DEV_RES_ROM + 1) |
---|
| 203 | |
---|
| 204 | /* PCI Device (Bus|Slot|Function) description */ |
---|
| 205 | struct pci_dev { |
---|
| 206 | struct pci_res resources[DEV_RES_CNT]; /* must be topmost field */ |
---|
| 207 | struct pci_dev *next; |
---|
| 208 | struct pci_bus *bus; |
---|
| 209 | pci_dev_t busdevfun; |
---|
| 210 | uint8_t flags; |
---|
| 211 | uint8_t sysirq; |
---|
| 212 | uint16_t vendor; |
---|
| 213 | uint16_t device; |
---|
| 214 | uint16_t subvendor; |
---|
| 215 | uint16_t subdevice; |
---|
| 216 | uint32_t classrev; |
---|
| 217 | |
---|
| 218 | /* static configuration settings */ |
---|
| 219 | uint16_t command; |
---|
| 220 | }; |
---|
| 221 | |
---|
| 222 | /* PCI Bus description */ |
---|
| 223 | struct pci_bus { |
---|
| 224 | struct pci_dev dev; /* PCI Bridge */ |
---|
| 225 | struct pci_dev *devs; /* Devices on child (secondary) Bus */ |
---|
| 226 | unsigned int flags; |
---|
| 227 | |
---|
| 228 | /* Bridge Information */ |
---|
| 229 | int num; /* Bus number (0=Root-PCI-bus) */ |
---|
| 230 | int pri; /* Primary Bus Number */ |
---|
| 231 | int sord; /* Subordinate Buses (Child bus count) */ |
---|
| 232 | |
---|
| 233 | #if defined(PCI_CFG_AUTO_LIB) |
---|
| 234 | /* Resources of devices on bus. USED INTERNALLY IN AUTO-CFG LIBRARY. |
---|
| 235 | * |
---|
| 236 | * BUS_RES_IO = 0: I/O resources |
---|
| 237 | * BUS_RES_MEMIO = 1: Prefetchable memory resources |
---|
| 238 | * BUS_RES_MEM = 2: Non-Prefetchable memory resources |
---|
| 239 | */ |
---|
| 240 | struct pci_res *busres[3]; |
---|
| 241 | #endif |
---|
| 242 | }; |
---|
| 243 | |
---|
| 244 | #include <pci/cfg_auto.h> |
---|
| 245 | #include <pci/cfg_static.h> |
---|
| 246 | #include <pci/cfg_read.h> |
---|
| 247 | #include <pci/cfg_peripheral.h> |
---|
| 248 | |
---|
| 249 | #endif |
---|