LCOV - code coverage report
Current view: top level - zephyr/drivers/pcie - pcie.h Hit Total Coverage
Test: new.info Lines: 30 115 26.1 %
Date: 2024-12-22 00:14:23

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

Generated by: LCOV version 1.14