LCOV - code coverage report
Current view: top level - zephyr/drivers/pcie - controller.h Coverage Total Hit
Test: new.info Lines: 53.3 % 30 16
Test Date: 2025-03-11 06:50:38

            Line data    Source code
       1            1 : /**
       2              :  * @file
       3              :  *
       4              :  * @brief Public APIs for the PCIe Controllers drivers.
       5              :  */
       6              : 
       7              : /*
       8              :  * Copyright (c) 2021 BayLibre, SAS
       9              :  *
      10              :  * SPDX-License-Identifier: Apache-2.0
      11              :  */
      12              : #ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_CONTROLLERS_H_
      13              : #define ZEPHYR_INCLUDE_DRIVERS_PCIE_CONTROLLERS_H_
      14              : 
      15              : #include <zephyr/types.h>
      16              : #include <zephyr/device.h>
      17              : 
      18              : #ifdef CONFIG_PCIE_MSI
      19              : #include <zephyr/drivers/pcie/msi.h>
      20              : #endif
      21              : 
      22              : /**
      23              :  * @brief PCI Express Controller Interface
      24              :  * @defgroup pcie_controller_interface PCI Express Controller Interface
      25              :  * @ingroup io_interfaces
      26              :  * @{
      27              :  */
      28              : 
      29              : #ifdef __cplusplus
      30              : extern "C" {
      31              : #endif
      32              : 
      33              : /**
      34              :  * @brief Function called to read a 32-bit word from an endpoint's configuration space.
      35              :  *
      36              :  * Read a 32-bit word from an endpoint's configuration space with the PCI Express Controller
      37              :  * configuration space access method (I/O port, memory mapped or custom method)
      38              :  *
      39              :  * @param dev PCI Express Controller device pointer
      40              :  * @param bdf PCI(e) endpoint
      41              :  * @param reg the configuration word index (not address)
      42              :  * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
      43              :  */
      44            1 : typedef uint32_t (*pcie_ctrl_conf_read_t)(const struct device *dev, pcie_bdf_t bdf,
      45              :                                           unsigned int reg);
      46              : 
      47              : /**
      48              :  * @brief Function called to write a 32-bit word to an endpoint's configuration space.
      49              :  *
      50              :  * Write a 32-bit word to an endpoint's configuration space with the PCI Express Controller
      51              :  * configuration space access method (I/O port, memory mapped or custom method)
      52              :  *
      53              :  * @param dev PCI Express Controller device pointer
      54              :  * @param bdf PCI(e) endpoint
      55              :  * @param reg the configuration word index (not address)
      56              :  * @param data the value to write
      57              :  */
      58            1 : typedef void (*pcie_ctrl_conf_write_t)(const struct device *dev, pcie_bdf_t bdf,
      59              :                                           unsigned int reg, uint32_t data);
      60              : 
      61              : /**
      62              :  * @brief Function called to allocate a memory region subset for an endpoint Base Address Register.
      63              :  *
      64              :  * When enumerating PCIe Endpoints, Type0 endpoints can require up to 6 memory zones
      65              :  * via the Base Address Registers from I/O or Memory types.
      66              :  *
      67              :  * This call allocates such zone in the PCI Express Controller memory regions if
      68              :  * such region is available and space is still available.
      69              :  *
      70              :  * @param dev PCI Express Controller device pointer
      71              :  * @param bdf PCI(e) endpoint
      72              :  * @param mem True if the BAR is of memory type
      73              :  * @param mem64 True if the BAR is of 64bit memory type
      74              :  * @param bar_size Size in bytes of the Base Address Register as returned by HW
      75              :  * @param bar_bus_addr bus-centric address allocated to be written in the BAR register
      76              :  * @return True if allocation was possible, False if allocation failed
      77              :  */
      78            1 : typedef bool (*pcie_ctrl_region_allocate_t)(const struct device *dev, pcie_bdf_t bdf,
      79              :                                             bool mem, bool mem64, size_t bar_size,
      80              :                                             uintptr_t *bar_bus_addr);
      81              : 
      82              : /**
      83              :  * @brief Function called to get the current allocation base of a memory region subset
      84              :  * for an endpoint Base Address Register.
      85              :  *
      86              :  * When enumerating PCIe Endpoints, Type1 bridge endpoints requires a range of memory
      87              :  * allocated by all endpoints in the bridged bus.
      88              :  *
      89              :  * @param dev PCI Express Controller device pointer
      90              :  * @param bdf PCI(e) endpoint
      91              :  * @param mem True if the BAR is of memory type
      92              :  * @param mem64 True if the BAR is of 64bit memory type
      93              :  * @param align size to take in account for alignment
      94              :  * @param bar_base_addr bus-centric address allocation base
      95              :  * @return True if allocation was possible, False if allocation failed
      96              :  */
      97            1 : typedef bool (*pcie_ctrl_region_get_allocate_base_t)(const struct device *dev, pcie_bdf_t bdf,
      98              :                                                      bool mem, bool mem64, size_t align,
      99              :                                                      uintptr_t *bar_base_addr);
     100              : 
     101              : /**
     102              :  * @brief Function called to translate an endpoint Base Address Register bus-centric address
     103              :  * into Physical address.
     104              :  *
     105              :  * When enumerating PCIe Endpoints, Type0 endpoints can require up to 6 memory zones
     106              :  * via the Base Address Registers from I/O or Memory types.
     107              :  *
     108              :  * The bus-centric address set in this BAR register is not necessarily accessible from the CPU,
     109              :  * thus must be translated by using the PCI Express Controller memory regions translation
     110              :  * ranges to permit mapping from the CPU.
     111              :  *
     112              :  * @param dev PCI Express Controller device pointer
     113              :  * @param bdf PCI(e) endpoint
     114              :  * @param mem True if the BAR is of memory type
     115              :  * @param mem64 True if the BAR is of 64bit memory type
     116              :  * @param bar_bus_addr bus-centric address written in the BAR register
     117              :  * @param bar_addr CPU-centric address translated from the bus-centric address
     118              :  * @return True if translation was possible, False if translation failed
     119              :  */
     120            1 : typedef bool (*pcie_ctrl_region_translate_t)(const struct device *dev, pcie_bdf_t bdf,
     121              :                                              bool mem, bool mem64, uintptr_t bar_bus_addr,
     122              :                                              uintptr_t *bar_addr);
     123              : 
     124              : #ifdef CONFIG_PCIE_MSI
     125              : typedef uint8_t (*pcie_ctrl_msi_device_setup_t)(const struct device *dev, unsigned int priority,
     126              :                                                 msi_vector_t *vectors, uint8_t n_vector);
     127              : #endif
     128              : 
     129              : /**
     130              :  * @brief Read a 32-bit word from a Memory-Mapped endpoint's configuration space.
     131              :  *
     132              :  * Read a 32-bit word from an endpoint's configuration space from a Memory-Mapped
     133              :  * configuration space access method, known as PCI Control Access Method (CAM) or
     134              :  * PCIe Extended Control Access Method (ECAM).
     135              :  *
     136              :  * @param cfg_addr Logical address of Memory-Mapped configuration space
     137              :  * @param bdf PCI(e) endpoint
     138              :  * @param reg the configuration word index (not address)
     139              :  * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
     140              :  */
     141            1 : uint32_t pcie_generic_ctrl_conf_read(mm_reg_t cfg_addr, pcie_bdf_t bdf, unsigned int reg);
     142              : 
     143              : 
     144              : /**
     145              :  * @brief Write a 32-bit word to a Memory-Mapped endpoint's configuration space.
     146              :  *
     147              :  * Write a 32-bit word to an endpoint's configuration space from a Memory-Mapped
     148              :  * configuration space access method, known as PCI Control Access Method (CAM) or
     149              :  * PCIe Extended Control Access Method (ECAM).
     150              :  *
     151              :  * @param cfg_addr Logical address of Memory-Mapped configuration space
     152              :  * @param bdf PCI(e) endpoint
     153              :  * @param reg the configuration word index (not address)
     154              :  * @param data the value to write
     155              :  */
     156            1 : void pcie_generic_ctrl_conf_write(mm_reg_t cfg_addr, pcie_bdf_t bdf,
     157              :                                   unsigned int reg, uint32_t data);
     158              : 
     159              : /**
     160              :  * @brief Start PCIe Endpoints enumeration.
     161              :  *
     162              :  * Start a PCIe Endpoints enumeration from a Bus number.
     163              :  * When on non-x86 architecture or when firmware didn't setup the PCIe Bus hierarchy,
     164              :  * the PCIe bus complex must be enumerated to setup the Endpoints Base Address Registers.
     165              :  *
     166              :  * @param dev PCI Express Controller device pointer
     167              :  * @param bdf_start PCI(e) start endpoint (only bus & dev are used to start enumeration)
     168              :  */
     169            1 : void pcie_generic_ctrl_enumerate(const struct device *dev, pcie_bdf_t bdf_start);
     170              : 
     171              : /** @brief Structure providing callbacks to be implemented for devices
     172              :  * that supports the PCI Express Controller API
     173              :  */
     174            1 : __subsystem struct pcie_ctrl_driver_api {
     175            0 :         pcie_ctrl_conf_read_t conf_read;
     176            0 :         pcie_ctrl_conf_write_t conf_write;
     177            0 :         pcie_ctrl_region_allocate_t region_allocate;
     178            0 :         pcie_ctrl_region_get_allocate_base_t region_get_allocate_base;
     179            0 :         pcie_ctrl_region_translate_t region_translate;
     180              : #ifdef CONFIG_PCIE_MSI
     181              :         pcie_ctrl_msi_device_setup_t msi_device_setup;
     182              : #endif
     183              : };
     184              : 
     185              : /**
     186              :  * @brief Read a 32-bit word from an endpoint's configuration space.
     187              :  *
     188              :  * Read a 32-bit word from an endpoint's configuration space with the PCI Express Controller
     189              :  * configuration space access method (I/O port, memory mapped or custom method)
     190              :  *
     191              :  * @param dev PCI Express Controller device pointer
     192              :  * @param bdf PCI(e) endpoint
     193              :  * @param reg the configuration word index (not address)
     194              :  * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
     195              :  */
     196            1 : static inline uint32_t pcie_ctrl_conf_read(const struct device *dev, pcie_bdf_t bdf,
     197              :                                            unsigned int reg)
     198              : {
     199              :         const struct pcie_ctrl_driver_api *api =
     200              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     201              : 
     202              :         return api->conf_read(dev, bdf, reg);
     203              : }
     204              : 
     205              : /**
     206              :  * @brief Write a 32-bit word to an endpoint's configuration space.
     207              :  *
     208              :  * Write a 32-bit word to an endpoint's configuration space with the PCI Express Controller
     209              :  * configuration space access method (I/O port, memory mapped or custom method)
     210              :  *
     211              :  * @param dev PCI Express Controller device pointer
     212              :  * @param bdf PCI(e) endpoint
     213              :  * @param reg the configuration word index (not address)
     214              :  * @param data the value to write
     215              :  */
     216            1 : static inline void pcie_ctrl_conf_write(const struct device *dev, pcie_bdf_t bdf,
     217              :                                         unsigned int reg, uint32_t data)
     218              : {
     219              :         const struct pcie_ctrl_driver_api *api =
     220              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     221              : 
     222              :         api->conf_write(dev, bdf, reg, data);
     223              : }
     224              : 
     225              : /**
     226              :  * @brief Allocate a memory region subset for an endpoint Base Address Register.
     227              :  *
     228              :  * When enumerating PCIe Endpoints, Type0 endpoints can require up to 6 memory zones
     229              :  * via the Base Address Registers from I/O or Memory types.
     230              :  *
     231              :  * This call allocates such zone in the PCI Express Controller memory regions if
     232              :  * such region is available and space is still available.
     233              :  *
     234              :  * @param dev PCI Express Controller device pointer
     235              :  * @param bdf PCI(e) endpoint
     236              :  * @param mem True if the BAR is of memory type
     237              :  * @param mem64 True if the BAR is of 64bit memory type
     238              :  * @param bar_size Size in bytes of the Base Address Register as returned by HW
     239              :  * @param bar_bus_addr bus-centric address allocated to be written in the BAR register
     240              :  * @return True if allocation was possible, False if allocation failed
     241              :  */
     242            1 : static inline bool pcie_ctrl_region_allocate(const struct device *dev, pcie_bdf_t bdf,
     243              :                                              bool mem, bool mem64, size_t bar_size,
     244              :                                              uintptr_t *bar_bus_addr)
     245              : {
     246              :         const struct pcie_ctrl_driver_api *api =
     247              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     248              : 
     249              :         return api->region_allocate(dev, bdf, mem, mem64, bar_size, bar_bus_addr);
     250              : }
     251              : 
     252              : /**
     253              :  * @brief Function called to get the current allocation base of a memory region subset
     254              :  * for an endpoint Base Address Register.
     255              :  *
     256              :  * When enumerating PCIe Endpoints, Type1 bridge endpoints requires a range of memory
     257              :  * allocated by all endpoints in the bridged bus.
     258              :  *
     259              :  * @param dev PCI Express Controller device pointer
     260              :  * @param bdf PCI(e) endpoint
     261              :  * @param mem True if the BAR is of memory type
     262              :  * @param mem64 True if the BAR is of 64bit memory type
     263              :  * @param align size to take in account for alignment
     264              :  * @param bar_base_addr bus-centric address allocation base
     265              :  * @return True if allocation was possible, False if allocation failed
     266              :  */
     267            1 : static inline bool pcie_ctrl_region_get_allocate_base(const struct device *dev, pcie_bdf_t bdf,
     268              :                                                       bool mem, bool mem64, size_t align,
     269              :                                                       uintptr_t *bar_base_addr)
     270              : {
     271              :         const struct pcie_ctrl_driver_api *api =
     272              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     273              : 
     274              :         return api->region_get_allocate_base(dev, bdf, mem, mem64, align, bar_base_addr);
     275              : }
     276              : 
     277              : /**
     278              :  * @brief Translate an endpoint Base Address Register bus-centric address into Physical address.
     279              :  *
     280              :  * When enumerating PCIe Endpoints, Type0 endpoints can require up to 6 memory zones
     281              :  * via the Base Address Registers from I/O or Memory types.
     282              :  *
     283              :  * The bus-centric address set in this BAR register is not necessarily accessible from the CPU,
     284              :  * thus must be translated by using the PCI Express Controller memory regions translation
     285              :  * ranges to permit mapping from the CPU.
     286              :  *
     287              :  * @param dev PCI Express Controller device pointer
     288              :  * @param bdf PCI(e) endpoint
     289              :  * @param mem True if the BAR is of memory type
     290              :  * @param mem64 True if the BAR is of 64bit memory type
     291              :  * @param bar_bus_addr bus-centric address written in the BAR register
     292              :  * @param bar_addr CPU-centric address translated from the bus-centric address
     293              :  * @return True if translation was possible, False if translation failed
     294              :  */
     295            1 : static inline bool pcie_ctrl_region_translate(const struct device *dev, pcie_bdf_t bdf,
     296              :                                           bool mem, bool mem64, uintptr_t bar_bus_addr,
     297              :                                           uintptr_t *bar_addr)
     298              : {
     299              :         const struct pcie_ctrl_driver_api *api =
     300              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     301              : 
     302              :         if (!api->region_translate) {
     303              :                 *bar_addr = bar_bus_addr;
     304              :                 return true;
     305              :         } else {
     306              :                 return api->region_translate(dev, bdf, mem, mem64, bar_bus_addr, bar_addr);
     307              :         }
     308              : }
     309              : 
     310              : #ifdef CONFIG_PCIE_MSI
     311              : static inline uint8_t pcie_ctrl_msi_device_setup(const struct device *dev, unsigned int priority,
     312              :                                                  msi_vector_t *vectors, uint8_t n_vector)
     313              : {
     314              :         const struct pcie_ctrl_driver_api *api =
     315              :                 (const struct pcie_ctrl_driver_api *)dev->api;
     316              : 
     317              :         return api->msi_device_setup(dev, priority, vectors, n_vector);
     318              : }
     319              : #endif
     320              : 
     321              : /** @brief Structure describing a device that supports the PCI Express Controller API
     322              :  */
     323            1 : struct pcie_ctrl_config {
     324              : #ifdef CONFIG_PCIE_MSI
     325              :         const struct device *msi_parent;
     326              : #endif
     327              :         /* Configuration space physical address */
     328            0 :         uintptr_t cfg_addr;
     329              :         /* Configuration space physical size */
     330            0 :         size_t cfg_size;
     331              :         /* BAR regions translation ranges count */
     332            0 :         size_t ranges_count;
     333              :         /* BAR regions translation ranges table */
     334              :         struct {
     335              :                 /* Flags as defined in the PCI Bus Binding to IEEE Std 1275-1994 */
     336            0 :                 uint32_t flags;
     337              :                 /* bus-centric offset from the start of the region */
     338            0 :                 uintptr_t pcie_bus_addr;
     339              :                 /* CPU-centric offset from the start of the region */
     340            0 :                 uintptr_t host_map_addr;
     341              :                 /* region size */
     342            0 :                 size_t map_length;
     343            0 :         } ranges[];
     344              : };
     345              : 
     346              : /*
     347              :  * Fills the pcie_ctrl_config.ranges table from DT
     348              :  */
     349            0 : #define PCIE_RANGE_FORMAT(node_id, idx)                                                 \
     350              : {                                                                                       \
     351              :         .flags = DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx),                        \
     352              :         .pcie_bus_addr = DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx),              \
     353              :         .host_map_addr = DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx),             \
     354              :         .map_length = DT_RANGES_LENGTH_BY_IDX(node_id, idx),                            \
     355              : },
     356              : 
     357              : #ifdef __cplusplus
     358              : }
     359              : #endif
     360              : 
     361              : /**
     362              :  * @}
     363              :  */
     364              : 
     365              : #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_CONTROLLERS_H_ */
        

Generated by: LCOV version 2.0-1