LCOV - code coverage report
Current view: top level - zephyr/drivers/pcie - pcie.h Coverage Total Hit
Test: new.info Lines: 25.9 % 116 30
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            0 : /*
       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              : /**
      11              :  * @brief Interfaces for PCIe devices.
      12              :  * @defgroup pcie_interface PCIe
      13              :  * @ingroup io_interfaces
      14              :  * @{
      15              :  * @}
      16              :  *
      17              :  * @brief Interfaces for PCIe Host.
      18              :  * @defgroup pcie_host_interface PCIe Host
      19              :  * @ingroup pcie_interface
      20              :  * @{
      21              :  */
      22              : 
      23              : #include <stddef.h>
      24              : #include <zephyr/devicetree.h>
      25              : #include <zephyr/dt-bindings/pcie/pcie.h>
      26              : #include <zephyr/types.h>
      27              : #include <zephyr/kernel.h>
      28              : #include <zephyr/sys/iterable_sections.h>
      29              : 
      30              : #ifdef __cplusplus
      31              : extern "C" {
      32              : #endif
      33              : 
      34              : /**
      35              :  * @typedef pcie_bdf_t
      36              :  * @brief A unique PCI(e) endpoint (bus, device, function).
      37              :  *
      38              :  * A PCI(e) endpoint is uniquely identified topologically using a
      39              :  * (bus, device, function) tuple. The internal structure is documented
      40              :  * in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since
      41              :  * these tuples are referenced from devicetree.
      42              :  */
      43            1 : typedef uint32_t pcie_bdf_t;
      44              : 
      45              : /**
      46              :  * @typedef pcie_id_t
      47              :  * @brief A unique PCI(e) identifier (vendor ID, device ID).
      48              :  *
      49              :  * The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID)
      50              :  * pair, which is meant to tell the system what the PCI(e) endpoint is. Again,
      51              :  * look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more.
      52              :  */
      53            1 : typedef uint32_t pcie_id_t;
      54              : 
      55              : /* Helper macro to exclude invalid PCIe identifiers. We should really only
      56              :  * need to look for PCIE_ID_NONE, but because of some broken PCI host controllers
      57              :  * we have try cases where both VID & DID are zero or just one of them is
      58              :  * zero (0x0000) and the other is all ones (0xFFFF).
      59              :  */
      60            0 : #define PCIE_ID_IS_VALID(id) ((id != PCIE_ID_NONE) && \
      61              :                               (id != PCIE_ID(0x0000, 0x0000)) && \
      62              :                               (id != PCIE_ID(0xFFFF, 0x0000)) && \
      63              :                               (id != PCIE_ID(0x0000, 0xFFFF)))
      64              : 
      65            0 : struct pcie_dev {
      66            0 :         pcie_bdf_t bdf;
      67            0 :         pcie_id_t  id;
      68            0 :         uint32_t   class_rev;
      69            0 :         uint32_t   class_rev_mask;
      70              : };
      71              : 
      72              : #define Z_DEVICE_PCIE_NAME(node_id) _CONCAT(pcie_dev_, DT_DEP_ORD(node_id))
      73              : 
      74              : /**
      75              :  * @brief Get the PCIe Vendor and Device ID for a node
      76              :  *
      77              :  * @param node_id DTS node identifier
      78              :  * @return The VID/DID combination as pcie_id_t
      79              :  */
      80            1 : #define PCIE_DT_ID(node_id) PCIE_ID(DT_PROP_OR(node_id, vendor_id, 0xffff), \
      81              :                                     DT_PROP_OR(node_id, device_id, 0xffff))
      82              : 
      83              : /**
      84              :  * @brief Get the PCIe Vendor and Device ID for a node
      85              :  *
      86              :  * This is equivalent to
      87              :  * <tt>PCIE_DT_ID(DT_DRV_INST(inst))</tt>
      88              :  *
      89              :  * @param inst Devicetree instance number
      90              :  * @return The VID/DID combination as pcie_id_t
      91              :  */
      92            1 : #define PCIE_DT_INST_ID(inst) PCIE_DT_ID(DT_DRV_INST(inst))
      93              : 
      94              : /**
      95              :  * @brief Declare a PCIe context variable for a DTS node
      96              :  *
      97              :  * Declares a PCIe context for a DTS node. This must be done before
      98              :  * using the DEVICE_PCIE_INIT() macro for the same node.
      99              :  *
     100              :  * @param node_id DTS node identifier
     101              :  */
     102            1 : #define DEVICE_PCIE_DECLARE(node_id)                                        \
     103              :         STRUCT_SECTION_ITERABLE(pcie_dev, Z_DEVICE_PCIE_NAME(node_id)) = {  \
     104              :                 .bdf = PCIE_BDF_NONE,                                       \
     105              :                 .id = PCIE_DT_ID(node_id),                                  \
     106              :                 .class_rev = DT_PROP_OR(node_id, class_rev, 0),             \
     107              :                 .class_rev_mask = DT_PROP_OR(node_id, class_rev_mask, 0),   \
     108              :         }
     109              : 
     110              : /**
     111              :  * @brief Declare a PCIe context variable for a DTS node
     112              :  *
     113              :  * This is equivalent to
     114              :  * <tt>DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))</tt>
     115              :  *
     116              :  * @param inst Devicetree instance number
     117              :  */
     118            1 : #define DEVICE_PCIE_INST_DECLARE(inst) DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))
     119              : 
     120              : /**
     121              :  * @brief Initialize a named struct member to point at a PCIe context
     122              :  *
     123              :  * Initialize PCIe-related information within a specific instance of
     124              :  * a device config struct, using information from DTS. Using the macro
     125              :  * requires having first created PCIe context struct using the
     126              :  * DEVICE_PCIE_DECLARE() macro.
     127              :  *
     128              :  * Example for an instance of a driver belonging to the "foo" subsystem
     129              :  *
     130              :  * struct foo_config {
     131              :  *      struct pcie_dev *pcie;
     132              :  *      ...
     133              :  *};
     134              :  *
     135              :  * DEVICE_PCIE_ID_DECLARE(DT_DRV_INST(...));
     136              :  * struct foo_config my_config = {
     137              :         DEVICE_PCIE_INIT(pcie, DT_DRV_INST(...)),
     138              :  *      ...
     139              :  * };
     140              :  *
     141              :  * @param node_id DTS node identifier
     142              :  * @param name Member name within config for the MMIO region
     143              :  */
     144            1 : #define DEVICE_PCIE_INIT(node_id, name) .name = &Z_DEVICE_PCIE_NAME(node_id)
     145              : 
     146              : /**
     147              :  * @brief Initialize a named struct member to point at a PCIe context
     148              :  *
     149              :  * This is equivalent to
     150              :  * <tt>DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)</tt>
     151              :  *
     152              :  * @param inst Devicetree instance number
     153              :  * @param name Name of the struct member (of type struct pcie_dev *)
     154              :  */
     155            1 : #define DEVICE_PCIE_INST_INIT(inst, name) \
     156              :         DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)
     157              : 
     158            0 : struct pcie_bar {
     159            0 :         uintptr_t phys_addr;
     160            0 :         size_t size;
     161              : };
     162              : 
     163              : /*
     164              :  * These functions are arch-, board-, or SoC-specific.
     165              :  */
     166              : 
     167              : /**
     168              :  * @brief Read a 32-bit word from an endpoint's configuration space.
     169              :  *
     170              :  * This function is exported by the arch/SoC/board code.
     171              :  *
     172              :  * @param bdf PCI(e) endpoint
     173              :  * @param reg the configuration word index (not address)
     174              :  * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
     175              :  */
     176            1 : extern uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg);
     177              : 
     178              : /**
     179              :  * @brief Write a 32-bit word to an endpoint's configuration space.
     180              :  *
     181              :  * This function is exported by the arch/SoC/board code.
     182              :  *
     183              :  * @param bdf PCI(e) endpoint
     184              :  * @param reg the configuration word index (not address)
     185              :  * @param data the value to write
     186              :  */
     187            1 : extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data);
     188              : 
     189              : /** Callback type used for scanning for PCI endpoints
     190              :  *
     191              :  * @param bdf      BDF value for a found endpoint.
     192              :  * @param id       Vendor & Device ID for the found endpoint.
     193              :  * @param cb_data  Custom, use case specific data.
     194              :  *
     195              :  * @return true to continue scanning, false to stop scanning.
     196              :  */
     197            1 : typedef bool (*pcie_scan_cb_t)(pcie_bdf_t bdf, pcie_id_t id, void *cb_data);
     198              : 
     199            0 : enum {
     200              :         /** Scan all available PCI host controllers and sub-buses */
     201              :         PCIE_SCAN_RECURSIVE = BIT(0),
     202              :         /** Do the callback for all endpoint types, including bridges */
     203              :         PCIE_SCAN_CB_ALL = BIT(1),
     204              : };
     205              : 
     206              : /** Options for performing a scan for PCI devices */
     207            1 : struct pcie_scan_opt {
     208              :         /** Initial bus number to scan */
     209            1 :         uint8_t bus;
     210              : 
     211              :         /** Function to call for each found endpoint */
     212            1 :         pcie_scan_cb_t cb;
     213              : 
     214              :         /** Custom data to pass to the scan callback */
     215            1 :         void *cb_data;
     216              : 
     217              :         /** Scan flags */
     218            1 :         uint32_t flags;
     219              : };
     220              : 
     221              : /** Scan for PCIe devices.
     222              :  *
     223              :  * Scan the PCI bus (or buses) for available endpoints.
     224              :  *
     225              :  * @param opt Options determining how to perform the scan.
     226              :  * @return 0 on success, negative POSIX error number on failure.
     227              :  */
     228            1 : int pcie_scan(const struct pcie_scan_opt *opt);
     229              : 
     230              : /**
     231              :  * @brief Get the MBAR at a specific BAR index
     232              :  * @param bdf the PCI(e) endpoint
     233              :  * @param bar_index 0-based BAR index
     234              :  * @param mbar Pointer to struct pcie_bar
     235              :  * @return true if the mbar was found and is valid, false otherwise
     236              :  */
     237            1 : extern bool pcie_get_mbar(pcie_bdf_t bdf,
     238              :                           unsigned int bar_index,
     239              :                           struct pcie_bar *mbar);
     240              : 
     241              : /**
     242              :  * @brief Probe the nth MMIO address assigned to an endpoint.
     243              :  * @param bdf the PCI(e) endpoint
     244              :  * @param index (0-based) index
     245              :  * @param mbar Pointer to struct pcie_bar
     246              :  * @return true if the mbar was found and is valid, false otherwise
     247              :  *
     248              :  * A PCI(e) endpoint has 0 or more memory-mapped regions. This function
     249              :  * allows the caller to enumerate them by calling with index=0..n.
     250              :  * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
     251              :  * are order-preserving with respect to the endpoint BARs: e.g., index 0
     252              :  * will return the lowest-numbered memory BAR on the endpoint.
     253              :  */
     254            1 : extern bool pcie_probe_mbar(pcie_bdf_t bdf,
     255              :                             unsigned int index,
     256              :                             struct pcie_bar *mbar);
     257              : 
     258              : /**
     259              :  * @brief Get the I/O BAR at a specific BAR index
     260              :  * @param bdf the PCI(e) endpoint
     261              :  * @param bar_index 0-based BAR index
     262              :  * @param iobar Pointer to struct pcie_bar
     263              :  * @return true if the I/O BAR was found and is valid, false otherwise
     264              :  */
     265            1 : extern bool pcie_get_iobar(pcie_bdf_t bdf,
     266              :                            unsigned int bar_index,
     267              :                            struct pcie_bar *iobar);
     268              : 
     269              : /**
     270              :  * @brief Probe the nth I/O BAR address assigned to an endpoint.
     271              :  * @param bdf the PCI(e) endpoint
     272              :  * @param index (0-based) index
     273              :  * @param iobar Pointer to struct pcie_bar
     274              :  * @return true if the I/O BAR was found and is valid, false otherwise
     275              :  *
     276              :  * A PCI(e) endpoint has 0 or more I/O regions. This function
     277              :  * allows the caller to enumerate them by calling with index=0..n.
     278              :  * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
     279              :  * are order-preserving with respect to the endpoint BARs: e.g., index 0
     280              :  * will return the lowest-numbered I/O BAR on the endpoint.
     281              :  */
     282            1 : extern bool pcie_probe_iobar(pcie_bdf_t bdf,
     283              :                              unsigned int index,
     284              :                              struct pcie_bar *iobar);
     285              : 
     286              : /**
     287              :  * @brief Set or reset bits in the endpoint command/status register.
     288              :  *
     289              :  * @param bdf the PCI(e) endpoint
     290              :  * @param bits the powerset of bits of interest
     291              :  * @param on use true to set bits, false to reset them
     292              :  */
     293            1 : extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on);
     294              : 
     295              : #ifndef CONFIG_PCIE_CONTROLLER
     296              : /**
     297              :  * @brief Allocate an IRQ for an endpoint.
     298              :  *
     299              :  * This function first checks the IRQ register and if it contains a valid
     300              :  * value this is returned. If the register does not contain a valid value
     301              :  * allocation of a new one is attempted.
     302              :  * Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset.
     303              :  * It is thus available where architecture tied dynamic IRQ allocation for
     304              :  * PCIe device makes sense.
     305              :  *
     306              :  * @param bdf the PCI(e) endpoint
     307              :  * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed.
     308              :  */
     309            1 : extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf);
     310              : #endif /* CONFIG_PCIE_CONTROLLER */
     311              : 
     312              : /**
     313              :  * @brief Return the IRQ assigned by the firmware/board to an endpoint.
     314              :  *
     315              :  * @param bdf the PCI(e) endpoint
     316              :  * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown.
     317              :  */
     318            1 : extern unsigned int pcie_get_irq(pcie_bdf_t bdf);
     319              : 
     320              : /**
     321              :  * @brief Enable the PCI(e) endpoint to generate the specified IRQ.
     322              :  *
     323              :  * @param bdf the PCI(e) endpoint
     324              :  * @param irq the IRQ to generate
     325              :  *
     326              :  * If MSI is enabled and the endpoint supports it, the endpoint will
     327              :  * be configured to generate the specified IRQ via MSI. Otherwise, it
     328              :  * is assumed that the IRQ has been routed by the boot firmware
     329              :  * to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or
     330              :  * wherever appropriate).
     331              :  */
     332            1 : extern void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq);
     333              : 
     334              : /**
     335              :  * @brief Find a PCI(e) capability in an endpoint's configuration space.
     336              :  *
     337              :  * @param bdf the PCI endpoint to examine
     338              :  * @param cap_id the capability ID of interest
     339              :  * @return the index of the configuration word, or 0 if no capability.
     340              :  */
     341            1 : extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id);
     342              : 
     343              : /**
     344              :  * @brief Find an Extended PCI(e) capability in an endpoint's configuration space.
     345              :  *
     346              :  * @param bdf the PCI endpoint to examine
     347              :  * @param cap_id the capability ID of interest
     348              :  * @return the index of the configuration word, or 0 if no capability.
     349              :  */
     350            1 : extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id);
     351              : 
     352              : /**
     353              :  * @brief Dynamically connect a PCIe endpoint IRQ to an ISR handler
     354              :  *
     355              :  * @param bdf the PCI endpoint to examine
     356              :  * @param irq the IRQ to connect (see pcie_alloc_irq())
     357              :  * @param priority priority of the IRQ
     358              :  * @param routine the ISR handler to connect to the IRQ
     359              :  * @param parameter the parameter to provide to the handler
     360              :  * @param flags IRQ connection flags
     361              :  * @return true if connected, false otherwise
     362              :  */
     363            1 : extern bool pcie_connect_dynamic_irq(pcie_bdf_t bdf,
     364              :                                      unsigned int irq,
     365              :                                      unsigned int priority,
     366              :                                      void (*routine)(const void *parameter),
     367              :                                      const void *parameter,
     368              :                                      uint32_t flags);
     369              : 
     370              : /**
     371              :  * @brief Get the BDF for a given PCI host controller
     372              :  *
     373              :  * This macro is useful when the PCI host controller behind PCIE_BDF(0, 0, 0)
     374              :  * indicates a multifunction device. In such a case each function of this
     375              :  * endpoint is a potential host controller itself.
     376              :  *
     377              :  * @param n Bus number
     378              :  * @return BDF value of the given host controller
     379              :  */
     380            1 : #define PCIE_HOST_CONTROLLER(n) PCIE_BDF(0, 0, n)
     381              : 
     382              : /*
     383              :  * Configuration word 13 contains the head of the capabilities list.
     384              :  */
     385              : 
     386            0 : #define PCIE_CONF_CAPPTR        13U     /* capabilities pointer */
     387            0 : #define PCIE_CONF_CAPPTR_FIRST(w)       (((w) >> 2) & 0x3FU)
     388              : 
     389              : /*
     390              :  * The first word of every capability contains a capability identifier,
     391              :  * and a link to the next capability (or 0) in configuration space.
     392              :  */
     393              : 
     394            0 : #define PCIE_CONF_CAP_ID(w)             ((w) & 0xFFU)
     395            0 : #define PCIE_CONF_CAP_NEXT(w)           (((w) >> 10) & 0x3FU)
     396              : 
     397              : /*
     398              :  * The extended PCI Express capabilities lie at the end of the PCI configuration space
     399              :  */
     400              : 
     401            0 : #define PCIE_CONF_EXT_CAPPTR    64U
     402              : 
     403              : /*
     404              :  * The first word of every capability contains an extended capability identifier,
     405              :  * and a link to the next capability (or 0) in the extended configuration space.
     406              :  */
     407              : 
     408            0 : #define PCIE_CONF_EXT_CAP_ID(w)         ((w) & 0xFFFFU)
     409            0 : #define PCIE_CONF_EXT_CAP_VER(w)        (((w) >> 16) & 0xFU)
     410            0 : #define PCIE_CONF_EXT_CAP_NEXT(w)       (((w) >> 20) & 0xFFFU)
     411              : 
     412              : /*
     413              :  * Configuration word 0 aligns directly with pcie_id_t.
     414              :  */
     415              : 
     416            0 : #define PCIE_CONF_ID            0U
     417              : 
     418              : /*
     419              :  * Configuration word 1 contains command and status bits.
     420              :  */
     421              : 
     422            0 : #define PCIE_CONF_CMDSTAT       1U      /* command/status register */
     423              : 
     424            0 : #define PCIE_CONF_CMDSTAT_IO            0x00000001U  /* I/O access enable */
     425            0 : #define PCIE_CONF_CMDSTAT_MEM           0x00000002U  /* mem access enable */
     426            0 : #define PCIE_CONF_CMDSTAT_MASTER        0x00000004U  /* bus master enable */
     427            0 : #define PCIE_CONF_CMDSTAT_SERR          0x00000010U  /* SERR# enable */
     428            0 : #define PCIE_CONF_CMDSTAT_INTERRUPT     0x00080000U  /* interrupt status */
     429            0 : #define PCIE_CONF_CMDSTAT_CAPS          0x00100000U  /* capabilities list */
     430              : 
     431              : /*
     432              :  * Configuration word 2 has additional function identification that
     433              :  * we only care about for debug output (PCIe shell commands).
     434              :  */
     435              : 
     436            0 : #define PCIE_CONF_CLASSREV      2U      /* class/revision register */
     437              : 
     438            0 : #define PCIE_CONF_CLASSREV_CLASS(w)     (((w) >> 24) & 0xFFU)
     439            0 : #define PCIE_CONF_CLASSREV_SUBCLASS(w)  (((w) >> 16) & 0xFFU)
     440            0 : #define PCIE_CONF_CLASSREV_PROGIF(w)    (((w) >> 8) & 0xFFU)
     441            0 : #define PCIE_CONF_CLASSREV_REV(w)       ((w) & 0xFFU)
     442              : 
     443              : /*
     444              :  * The only part of configuration word 3 that is of interest to us is
     445              :  * the header type, as we use it to distinguish functional endpoints
     446              :  * from bridges (which are, for our purposes, transparent).
     447              :  */
     448              : 
     449            0 : #define PCIE_CONF_TYPE          3U
     450              : 
     451            0 : #define PCIE_CONF_MULTIFUNCTION(w)      (((w) & 0x00800000U) != 0U)
     452            0 : #define PCIE_CONF_TYPE_BRIDGE(w)        (((w) & 0x007F0000U) != 0U)
     453            0 : #define PCIE_CONF_TYPE_GET(w)           (((w) >> 16) & 0x7F)
     454              : 
     455            0 : #define PCIE_CONF_TYPE_STANDARD         0x0U
     456            0 : #define PCIE_CONF_TYPE_PCI_BRIDGE       0x1U
     457            0 : #define PCIE_CONF_TYPE_CARDBUS_BRIDGE   0x2U
     458              : 
     459              : /*
     460              :  * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may
     461              :  * be 64-bit decoders, in which case the next configuration word holds
     462              :  * the high-order bits (and is, thus, not a BAR itself).
     463              :  */
     464              : 
     465            0 : #define PCIE_CONF_BAR0          4U
     466            0 : #define PCIE_CONF_BAR1          5U
     467            0 : #define PCIE_CONF_BAR2          6U
     468            0 : #define PCIE_CONF_BAR3          7U
     469            0 : #define PCIE_CONF_BAR4          8U
     470            0 : #define PCIE_CONF_BAR5          9U
     471              : 
     472            0 : #define PCIE_CONF_BAR_IO(w)             (((w) & 0x00000001U) == 0x00000001U)
     473            0 : #define PCIE_CONF_BAR_MEM(w)            (((w) & 0x00000001U) != 0x00000001U)
     474            0 : #define PCIE_CONF_BAR_64(w)             (((w) & 0x00000006U) == 0x00000004U)
     475            0 : #define PCIE_CONF_BAR_ADDR(w)           ((w) & ~0xfUL)
     476            0 : #define PCIE_CONF_BAR_IO_ADDR(w)        ((w) & ~0x3UL)
     477            0 : #define PCIE_CONF_BAR_FLAGS(w)          ((w) & 0xfUL)
     478            0 : #define PCIE_CONF_BAR_NONE              0U
     479              : 
     480            0 : #define PCIE_CONF_BAR_INVAL             0xFFFFFFF0U
     481            0 : #define PCIE_CONF_BAR_INVAL64           0xFFFFFFFFFFFFFFF0UL
     482              : 
     483            0 : #define PCIE_CONF_BAR_INVAL_FLAGS(w)                    \
     484              :         ((((w) & 0x00000006U) == 0x00000006U) ||    \
     485              :          (((w) & 0x00000006U) == 0x00000002U))
     486              : 
     487              : /*
     488              :  * Type 1 Header has files related to bus management
     489              :  */
     490            0 : #define PCIE_BUS_NUMBER         6U
     491              : 
     492            0 : #define PCIE_BUS_PRIMARY_NUMBER(w)      ((w) & 0xffUL)
     493            0 : #define PCIE_BUS_SECONDARY_NUMBER(w)    (((w) >> 8) & 0xffUL)
     494            0 : #define PCIE_BUS_SUBORDINATE_NUMBER(w)  (((w) >> 16) & 0xffUL)
     495            0 : #define PCIE_SECONDARY_LATENCY_TIMER(w) (((w) >> 24) & 0xffUL)
     496              : 
     497            0 : #define PCIE_BUS_NUMBER_VAL(prim, sec, sub, lat) \
     498              :         (((prim) & 0xffUL) |                         \
     499              :          (((sec) & 0xffUL) << 8) |             \
     500              :          (((sub) & 0xffUL) << 16) |            \
     501              :          (((lat) & 0xffUL) << 24))
     502              : 
     503              : /*
     504              :  * Type 1 words 7 to 12 setups Bridge Memory base and limits
     505              :  */
     506            0 : #define PCIE_IO_SEC_STATUS      7U
     507              : 
     508            0 : #define PCIE_IO_BASE(w)         ((w) & 0xffUL)
     509            0 : #define PCIE_IO_LIMIT(w)        (((w) >> 8) & 0xffUL)
     510            0 : #define PCIE_SEC_STATUS(w)      (((w) >> 16) & 0xffffUL)
     511              : 
     512            0 : #define PCIE_IO_SEC_STATUS_VAL(iob, iol, sec_status) \
     513              :         (((iob) & 0xffUL) |                      \
     514              :          (((iol) & 0xffUL) << 8) |                 \
     515              :          (((sec_status) & 0xffffUL) << 16))
     516              : 
     517            0 : #define PCIE_MEM_BASE_LIMIT     8U
     518              : 
     519            0 : #define PCIE_MEM_BASE(w)        ((w) & 0xffffUL)
     520            0 : #define PCIE_MEM_LIMIT(w)       (((w) >> 16) & 0xffffUL)
     521              : 
     522            0 : #define PCIE_MEM_BASE_LIMIT_VAL(memb, meml) \
     523              :         (((memb) & 0xffffUL) |                  \
     524              :          (((meml) & 0xffffUL) << 16))
     525              : 
     526            0 : #define PCIE_PREFETCH_BASE_LIMIT        9U
     527              : 
     528            0 : #define PCIE_PREFETCH_BASE(w)   ((w) & 0xffffUL)
     529            0 : #define PCIE_PREFETCH_LIMIT(w)  (((w) >> 16) & 0xffffUL)
     530              : 
     531            0 : #define PCIE_PREFETCH_BASE_LIMIT_VAL(pmemb, pmeml) \
     532              :         (((pmemb) & 0xffffUL) |                        \
     533              :          (((pmeml) & 0xffffUL) << 16))
     534              : 
     535            0 : #define PCIE_PREFETCH_BASE_UPPER        10U
     536              : 
     537            0 : #define PCIE_PREFETCH_LIMIT_UPPER       11U
     538              : 
     539            0 : #define PCIE_IO_BASE_LIMIT_UPPER        12U
     540              : 
     541            0 : #define PCIE_IO_BASE_UPPER(w)   ((w) & 0xffffUL)
     542            0 : #define PCIE_IO_LIMIT_UPPER(w)  (((w) >> 16) & 0xffffUL)
     543              : 
     544            0 : #define PCIE_IO_BASE_LIMIT_UPPER_VAL(iobu, iolu) \
     545              :         (((iobu) & 0xffffUL) |                       \
     546              :          (((iolu) & 0xffffUL) << 16))
     547              : 
     548              : /*
     549              :  * Word 15 contains information related to interrupts.
     550              :  *
     551              :  * We're only interested in the low byte, which is [supposed to be] set by
     552              :  * the firmware to indicate which wire IRQ the device interrupt is routed to.
     553              :  */
     554              : 
     555            0 : #define PCIE_CONF_INTR          15U
     556              : 
     557            0 : #define PCIE_CONF_INTR_IRQ(w)   ((w) & 0xFFU)
     558            0 : #define PCIE_CONF_INTR_IRQ_NONE 0xFFU  /* no interrupt routed */
     559              : 
     560            0 : #define PCIE_MAX_BUS  (0xFFFFFFFFU & PCIE_BDF_BUS_MASK)
     561            0 : #define PCIE_MAX_DEV  (0xFFFFFFFFU & PCIE_BDF_DEV_MASK)
     562            0 : #define PCIE_MAX_FUNC (0xFFFFFFFFU & PCIE_BDF_FUNC_MASK)
     563              : 
     564              : /**
     565              :  * @brief Initialize an interrupt handler for a PCIe endpoint IRQ
     566              :  *
     567              :  * This routine is only meant to be used by drivers using PCIe bus and having
     568              :  * fixed or MSI based IRQ (so no runtime detection of the IRQ). In case
     569              :  * of runtime detection see pcie_connect_dynamic_irq()
     570              :  *
     571              :  * @param bdf_p PCIe endpoint BDF
     572              :  * @param irq_p IRQ line number.
     573              :  * @param priority_p Interrupt priority.
     574              :  * @param isr_p Address of interrupt service routine.
     575              :  * @param isr_param_p Parameter passed to interrupt service routine.
     576              :  * @param flags_p Architecture-specific IRQ configuration flags..
     577              :  */
     578              : #define PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p,                      \
     579            1 :                          isr_p, isr_param_p, flags_p)                   \
     580              :         ARCH_PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p,                 \
     581              :                               isr_p, isr_param_p, flags_p)
     582              : 
     583              : #ifdef __cplusplus
     584              : }
     585              : #endif
     586              : 
     587              : /**
     588              :  * @}
     589              :  */
     590              : 
     591              : #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */
        

Generated by: LCOV version 2.0-1