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