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_MSI_H_ 8 : #define ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ 9 : 10 : /** 11 : * @brief PCIe Host MSI Interface 12 : * @defgroup pcie_host_msi_interface PCIe Host MSI Interface 13 : * @ingroup pcie_host_interface 14 : * @{ 15 : */ 16 : 17 : #include <zephyr/kernel.h> 18 : #include <zephyr/types.h> 19 : #include <stdbool.h> 20 : 21 : #include <zephyr/drivers/pcie/pcie.h> 22 : 23 : #ifdef __cplusplus 24 : extern "C" { 25 : #endif 26 : 27 : #ifdef CONFIG_PCIE_CONTROLLER 28 : struct msi_vector_generic { 29 : unsigned int irq; 30 : uint32_t address; 31 : uint16_t eventid; 32 : unsigned int priority; 33 : }; 34 : 35 : typedef struct msi_vector_generic arch_msi_vector_t; 36 : 37 : #define PCI_DEVID(bus, dev, fn) ((((bus) & 0xff) << 8) | (((dev) & 0x1f) << 3) | ((fn) & 0x07)) 38 : #define PCI_BDF_TO_DEVID(bdf) PCI_DEVID(PCIE_BDF_TO_BUS(bdf), \ 39 : PCIE_BDF_TO_DEV(bdf), \ 40 : PCIE_BDF_TO_FUNC(bdf)) 41 : 42 : #endif 43 : 44 0 : struct msix_vector { 45 0 : uint32_t msg_addr; 46 0 : uint32_t msg_up_addr; 47 0 : uint32_t msg_data; 48 0 : uint32_t vector_ctrl; 49 : } __packed; 50 : 51 0 : struct msi_vector { 52 0 : pcie_bdf_t bdf; 53 0 : arch_msi_vector_t arch; 54 : #ifdef CONFIG_PCIE_MSI_X 55 : struct msix_vector *msix_vector; 56 : bool msix; 57 : #endif /* CONFIG_PCIE_MSI_X */ 58 : }; 59 : 60 0 : typedef struct msi_vector msi_vector_t; 61 : 62 : #ifdef CONFIG_PCIE_MSI_MULTI_VECTOR 63 : 64 : /** 65 : * @brief Allocate vector(s) for the endpoint MSI message(s) 66 : * 67 : * @param bdf the target PCI endpoint 68 : * @param priority the MSI vectors base interrupt priority 69 : * @param vectors an array for storing allocated MSI vectors 70 : * @param n_vector the size of the MSI vectors array 71 : * 72 : * @return the number of allocated MSI vectors. 73 : */ 74 : extern uint8_t pcie_msi_vectors_allocate(pcie_bdf_t bdf, 75 : unsigned int priority, 76 : msi_vector_t *vectors, 77 : uint8_t n_vector); 78 : 79 : /** 80 : * @brief Connect the MSI vector to the handler 81 : * 82 : * @param bdf the target PCI endpoint 83 : * @param vector the MSI vector to connect 84 : * @param routine Interrupt service routine 85 : * @param parameter ISR parameter 86 : * @param flags Arch-specific IRQ configuration flag 87 : * 88 : * @return True on success, false otherwise 89 : */ 90 : extern bool pcie_msi_vector_connect(pcie_bdf_t bdf, 91 : msi_vector_t *vector, 92 : void (*routine)(const void *parameter), 93 : const void *parameter, 94 : uint32_t flags); 95 : 96 : #endif /* CONFIG_PCIE_MSI_MULTI_VECTOR */ 97 : 98 : /** 99 : * @brief Compute the target address for an MSI posted write. 100 : * 101 : * This function is exported by the arch, board or SoC code. 102 : * 103 : * @param irq The IRQ we wish to trigger via MSI. 104 : * @param vector The vector for which you want the address (or NULL) 105 : * @param n_vector the size of the vector array 106 : * @return A (32-bit) value for the MSI MAP register. 107 : */ 108 1 : extern uint32_t pcie_msi_map(unsigned int irq, 109 : msi_vector_t *vector, 110 : uint8_t n_vector); 111 : 112 : /** 113 : * @brief Compute the data for an MSI posted write. 114 : * 115 : * This function is exported by the arch, board or SoC code. 116 : * 117 : * @param irq The IRQ we wish to trigger via MSI. 118 : * @param vector The vector for which you want the data (or NULL) 119 : * @return A (16-bit) value for MSI MDR register. 120 : */ 121 1 : extern uint16_t pcie_msi_mdr(unsigned int irq, 122 : msi_vector_t *vector); 123 : 124 : /** 125 : * @brief Configure the given PCI endpoint to generate MSIs. 126 : * 127 : * @param bdf the target PCI endpoint 128 : * @param vectors an array of allocated vector(s) 129 : * @param n_vector the size of the vector array 130 : * @param irq The IRQ we wish to trigger via MSI. 131 : * @return true if the endpoint supports MSI, false otherwise. 132 : */ 133 1 : extern bool pcie_msi_enable(pcie_bdf_t bdf, 134 : msi_vector_t *vectors, 135 : uint8_t n_vector, 136 : unsigned int irq); 137 : 138 : /** 139 : * @brief Check if the given PCI endpoint supports MSI/MSI-X 140 : * 141 : * @param bdf the target PCI endpoint 142 : * @return true if the endpoint support MSI/MSI-X 143 : */ 144 1 : extern bool pcie_is_msi(pcie_bdf_t bdf); 145 : 146 : /* 147 : * The first word of the MSI capability is shared with the 148 : * capability ID and list link. The high 16 bits are the MCR. 149 : */ 150 : 151 0 : #define PCIE_MSI_MCR 0U 152 : 153 0 : #define PCIE_MSI_MCR_EN 0x00010000U /* enable MSI */ 154 0 : #define PCIE_MSI_MCR_MMC 0x000E0000U /* Multi Messages Capable mask */ 155 0 : #define PCIE_MSI_MCR_MMC_SHIFT 17 156 0 : #define PCIE_MSI_MCR_MME 0x00700000U /* mask of # of enabled IRQs */ 157 0 : #define PCIE_MSI_MCR_MME_SHIFT 20 158 0 : #define PCIE_MSI_MCR_64 0x00800000U /* 64-bit MSI */ 159 : 160 : /* 161 : * The MAP follows the MCR. If PCIE_MSI_MCR_64, then the MAP 162 : * is two words long. The MDR follows immediately after the MAP. 163 : */ 164 : 165 0 : #define PCIE_MSI_MAP0 1U 166 0 : #define PCIE_MSI_MAP1_64 2U 167 0 : #define PCIE_MSI_MDR_32 2U 168 0 : #define PCIE_MSI_MDR_64 3U 169 : 170 : /* 171 : * As for MSI, he first word of the MSI-X capability is shared 172 : * with the capability ID and list link. The high 16 bits are the MCR. 173 : */ 174 : 175 0 : #define PCIE_MSIX_MCR 0U 176 : 177 0 : #define PCIE_MSIX_MCR_EN 0x80000000U /* Enable MSI-X */ 178 0 : #define PCIE_MSIX_MCR_FMASK 0x40000000U /* Function Mask */ 179 0 : #define PCIE_MSIX_MCR_TSIZE 0x07FF0000U /* Table size mask */ 180 0 : #define PCIE_MSIX_MCR_TSIZE_SHIFT 16 181 0 : #define PCIE_MSIR_TABLE_ENTRY_SIZE 16 182 : 183 0 : #define PCIE_MSIX_TR 1U 184 0 : #define PCIE_MSIX_TR_BIR 0x00000007U /* Table BIR mask */ 185 0 : #define PCIE_MSIX_TR_OFFSET 0xFFFFFFF8U /* Offset mask */ 186 : 187 0 : #define PCIE_MSIX_PBA 2U 188 0 : #define PCIE_MSIX_PBA_BIR 0x00000007U /* PBA BIR mask */ 189 0 : #define PCIE_MSIX_PBA_OFFSET 0xFFFFFFF8U /* Offset mask */ 190 : 191 0 : #define PCIE_VTBL_MA 0U /* Msg Address offset */ 192 0 : #define PCIE_VTBL_MUA 4U /* Msg Upper Address offset */ 193 0 : #define PCIE_VTBL_MD 8U /* Msg Data offset */ 194 0 : #define PCIE_VTBL_VCTRL 12U /* Vector control offset */ 195 : 196 : #ifdef __cplusplus 197 : } 198 : #endif 199 : 200 : /** 201 : * @} 202 : */ 203 : 204 : #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ */