1 /* 2 * Copyright (c) 2019 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ 8 #define ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ 9 10 #include <stddef.h> 11 #include <dt-bindings/pcie/pcie.h> 12 #include <zephyr/types.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** 19 * @typedef pcie_bdf_t 20 * @brief A unique PCI(e) endpoint (bus, device, function). 21 * 22 * A PCI(e) endpoint is uniquely identified topologically using a 23 * (bus, device, function) tuple. The internal structure is documented 24 * in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since 25 * these tuples are referenced from devicetree. 26 */ 27 typedef uint32_t pcie_bdf_t; 28 29 /** 30 * @typedef pcie_id_t 31 * @brief A unique PCI(e) identifier (vendor ID, device ID). 32 * 33 * The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID) 34 * pair, which is meant to tell the system what the PCI(e) endpoint is. Again, 35 * look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more. 36 */ 37 typedef uint32_t pcie_id_t; 38 39 struct pcie_mbar { 40 uintptr_t phys_addr; 41 size_t size; 42 }; 43 44 /* 45 * These functions are arch-, board-, or SoC-specific. 46 */ 47 48 /** 49 * @brief Look up the BDF based on PCI(e) vendor & device ID 50 * 51 * This function is used to look up the BDF for a device given its 52 * vendor and device ID. 53 * 54 * @param id PCI(e) vendor & device ID encoded using PCIE_ID() 55 * @return The BDF for the device, or PCIE_BDF_NONE if it was not found 56 */ 57 extern pcie_bdf_t pcie_bdf_lookup(pcie_id_t id); 58 59 /** 60 * @brief Read a 32-bit word from an endpoint's configuration space. 61 * 62 * This function is exported by the arch/SoC/board code. 63 * 64 * @param bdf PCI(e) endpoint 65 * @param reg the configuration word index (not address) 66 * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word) 67 */ 68 extern uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg); 69 70 /** 71 * @brief Write a 32-bit word to an endpoint's configuration space. 72 * 73 * This function is exported by the arch/SoC/board code. 74 * 75 * @param bdf PCI(e) endpoint 76 * @param reg the configuration word index (not address) 77 * @param data the value to write 78 */ 79 extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data); 80 81 /** 82 * @brief Probe for the presence of a PCI(e) endpoint. 83 * 84 * @param bdf the endpoint to probe 85 * @param id the endpoint ID to expect, or PCIE_ID_NONE for "any device" 86 * @return true if the device is present, false otherwise 87 */ 88 extern bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id); 89 90 /** 91 * @brief Get the MBAR at a specific BAR index 92 * @param bdf the PCI(e) endpoint 93 * @param bar_index 0-based BAR index 94 * @param mbar Pointer to struct pcie_mbar 95 * @return true if the mbar was found and is valid, false otherwise 96 */ 97 extern bool pcie_get_mbar(pcie_bdf_t bdf, 98 unsigned int bar_index, 99 struct pcie_mbar *mbar); 100 101 /** 102 * @brief Probe the nth MMIO address assigned to an endpoint. 103 * @param bdf the PCI(e) endpoint 104 * @param index (0-based) index 105 * @param mbar Pointer to struct pcie_mbar 106 * @return true if the mbar was found and is valid, false otherwise 107 * 108 * A PCI(e) endpoint has 0 or more memory-mapped regions. This function 109 * allows the caller to enumerate them by calling with index=0..n. 110 * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices 111 * are order-preserving with respect to the endpoint BARs: e.g., index 0 112 * will return the lowest-numbered memory BAR on the endpoint. 113 */ 114 extern bool pcie_probe_mbar(pcie_bdf_t bdf, 115 unsigned int index, 116 struct pcie_mbar *mbar); 117 118 /** 119 * @brief Set or reset bits in the endpoint command/status register. 120 * 121 * @param bdf the PCI(e) endpoint 122 * @param bits the powerset of bits of interest 123 * @param on use true to set bits, false to reset them 124 */ 125 extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on); 126 127 /** 128 * @brief Allocate an IRQ for an endpoint. 129 * 130 * This function first checks the IRQ register and if it contains a valid 131 * value this is returned. If the register does not contain a valid value 132 * allocation of a new one is attempted. 133 * 134 * @param bdf the PCI(e) endpoint 135 * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed. 136 */ 137 extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf); 138 139 /** 140 * @brief Return the IRQ assigned by the firmware/board to an endpoint. 141 * 142 * @param bdf the PCI(e) endpoint 143 * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown. 144 */ 145 extern unsigned int pcie_get_irq(pcie_bdf_t bdf); 146 147 /** 148 * @brief Enable the PCI(e) endpoint to generate the specified IRQ. 149 * 150 * @param bdf the PCI(e) endpoint 151 * @param irq the IRQ to generate 152 * 153 * If MSI is enabled and the endpoint supports it, the endpoint will 154 * be configured to generate the specified IRQ via MSI. Otherwise, it 155 * is assumed that the IRQ has been routed by the boot firmware 156 * to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or 157 * wherever appropriate). 158 */ 159 extern void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq); 160 161 /** 162 * @brief Find a PCI(e) capability in an endpoint's configuration space. 163 * 164 * @param bdf the PCI endpoint to examine 165 * @param cap_id the capability ID of interest 166 * @return the index of the configuration word, or 0 if no capability. 167 */ 168 extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id); 169 170 /** 171 * @brief Find an Extended PCI(e) capability in an endpoint's configuration space. 172 * 173 * @param bdf the PCI endpoint to examine 174 * @param cap_id the capability ID of interest 175 * @return the index of the configuration word, or 0 if no capability. 176 */ 177 extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id); 178 179 /* 180 * Configuration word 13 contains the head of the capabilities list. 181 */ 182 183 #define PCIE_CONF_CAPPTR 13U /* capabilities pointer */ 184 #define PCIE_CONF_CAPPTR_FIRST(w) (((w) >> 2) & 0x3FU) 185 186 /* 187 * The first word of every capability contains a capability identifier, 188 * and a link to the next capability (or 0) in configuration space. 189 */ 190 191 #define PCIE_CONF_CAP_ID(w) ((w) & 0xFFU) 192 #define PCIE_CONF_CAP_NEXT(w) (((w) >> 10) & 0x3FU) 193 194 /* 195 * The extended PCI Express capabilies lies at the end of the PCI configuration space 196 */ 197 198 #define PCIE_CONF_EXT_CAPPTR 64U 199 200 /* 201 * The first word of every capability contains an extended capability identifier, 202 * and a link to the next capability (or 0) in the extended configuration space. 203 */ 204 205 #define PCIE_CONF_EXT_CAP_ID(w) ((w) & 0xFFFFU) 206 #define PCIE_CONF_EXT_CAP_VER(w) (((w) >> 16) & 0xFU) 207 #define PCIE_CONF_EXT_CAP_NEXT(w) (((w) >> 20) & 0xFFFU) 208 209 /* 210 * Configuration word 0 aligns directly with pcie_id_t. 211 */ 212 213 #define PCIE_CONF_ID 0U 214 215 /* 216 * Configuration word 1 contains command and status bits. 217 */ 218 219 #define PCIE_CONF_CMDSTAT 1U /* command/status register */ 220 221 #define PCIE_CONF_CMDSTAT_IO 0x00000001U /* I/O access enable */ 222 #define PCIE_CONF_CMDSTAT_MEM 0x00000002U /* mem access enable */ 223 #define PCIE_CONF_CMDSTAT_MASTER 0x00000004U /* bus master enable */ 224 #define PCIE_CONF_CMDSTAT_CAPS 0x00100000U /* capabilities list */ 225 226 /* 227 * Configuration word 2 has additional function identification that 228 * we only care about for debug output (PCIe shell commands). 229 */ 230 231 #define PCIE_CONF_CLASSREV 2U /* class/revision register */ 232 233 #define PCIE_CONF_CLASSREV_CLASS(w) (((w) >> 24) & 0xFFU) 234 #define PCIE_CONF_CLASSREV_SUBCLASS(w) (((w) >> 16) & 0xFFU) 235 #define PCIE_CONF_CLASSREV_PROGIF(w) (((w) >> 8) & 0xFFU) 236 #define PCIE_CONF_CLASSREV_REV(w) ((w) & 0xFFU) 237 238 /* 239 * The only part of configuration word 3 that is of interest to us is 240 * the header type, as we use it to distinguish functional endpoints 241 * from bridges (which are, for our purposes, transparent). 242 */ 243 244 #define PCIE_CONF_TYPE 3U 245 246 #define PCIE_CONF_TYPE_BRIDGE(w) (((w) & 0x007F0000U) != 0U) 247 248 /* 249 * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may 250 * be 64-bit decoders, in which case the next configuration word holds 251 * the high-order bits (and is, thus, not a BAR itself). 252 */ 253 254 #define PCIE_CONF_BAR0 4U 255 #define PCIE_CONF_BAR1 5U 256 #define PCIE_CONF_BAR2 6U 257 #define PCIE_CONF_BAR3 7U 258 #define PCIE_CONF_BAR4 8U 259 #define PCIE_CONF_BAR5 9U 260 261 #define PCIE_CONF_BAR_IO(w) (((w) & 0x00000001U) == 0x00000001U) 262 #define PCIE_CONF_BAR_MEM(w) (((w) & 0x00000001U) != 0x00000001U) 263 #define PCIE_CONF_BAR_64(w) (((w) & 0x00000006U) == 0x00000004U) 264 #define PCIE_CONF_BAR_ADDR(w) ((w) & ~0xfUL) 265 #define PCIE_CONF_BAR_FLAGS(w) ((w) & 0xfUL) 266 #define PCIE_CONF_BAR_NONE 0U 267 268 #define PCIE_CONF_BAR_INVAL 0xFFFFFFF0U 269 #define PCIE_CONF_BAR_INVAL64 0xFFFFFFFFFFFFFFF0UL 270 271 #define PCIE_CONF_BAR_INVAL_FLAGS(w) \ 272 ((((w) & 0x00000006U) == 0x00000006U) || \ 273 (((w) & 0x00000006U) == 0x00000002U)) 274 275 /* 276 * Word 15 contains information related to interrupts. 277 * 278 * We're only interested in the low byte, which is [supposed to be] set by 279 * the firmware to indicate which wire IRQ the device interrupt is routed to. 280 */ 281 282 #define PCIE_CONF_INTR 15U 283 284 #define PCIE_CONF_INTR_IRQ(w) ((w) & 0xFFU) 285 #define PCIE_CONF_INTR_IRQ_NONE 0xFFU /* no interrupt routed */ 286 287 #define PCIE_MAX_BUS (0xFFFFFFFF & PCIE_BDF_BUS_MASK) 288 #define PCIE_MAX_DEV (0xFFFFFFFF & PCIE_BDF_DEV_MASK) 289 #define PCIE_MAX_FUNC (0xFFFFFFFF & PCIE_BDF_FUNC_MASK) 290 291 #ifdef __cplusplus 292 } 293 #endif 294 295 #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */ 296