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_ */
|