1 /*
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 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 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 #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 struct pcie_dev {
60 	pcie_bdf_t bdf;
61 	pcie_id_t  id;
62 	uint32_t   class_rev;
63 	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 #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 #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 #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 #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 #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 #define DEVICE_PCIE_INST_INIT(inst, name) \
150 	DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)
151 
152 struct pcie_bar {
153 	uintptr_t phys_addr;
154 	size_t size;
155 };
156 
157 /*
158  * These functions are arch-, board-, or SoC-specific.
159  */
160 
161 /**
162  * @brief Look up the BDF based on PCI(e) vendor & device ID
163  *
164  * This function is used to look up the BDF for a device given its
165  * vendor and device ID.
166  *
167  * @deprecated
168  * @see DEVICE_PCIE_DECLARE
169  *
170  * @param id PCI(e) vendor & device ID encoded using PCIE_ID()
171  * @return The BDF for the device, or PCIE_BDF_NONE if it was not found
172  */
173 __deprecated extern pcie_bdf_t pcie_bdf_lookup(pcie_id_t id);
174 
175 /**
176  * @brief Read a 32-bit word from an endpoint's configuration space.
177  *
178  * This function is exported by the arch/SoC/board code.
179  *
180  * @param bdf PCI(e) endpoint
181  * @param reg the configuration word index (not address)
182  * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
183  */
184 extern uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg);
185 
186 /**
187  * @brief Write a 32-bit word to an endpoint's configuration space.
188  *
189  * This function is exported by the arch/SoC/board code.
190  *
191  * @param bdf PCI(e) endpoint
192  * @param reg the configuration word index (not address)
193  * @param data the value to write
194  */
195 extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data);
196 
197 /** Callback type used for scanning for PCI endpoints
198  *
199  * @param bdf      BDF value for a found endpoint.
200  * @param id       Vendor & Device ID for the found endpoint.
201  * @param cb_data  Custom, use case specific data.
202  *
203  * @return true to continue scanning, false to stop scanning.
204  */
205 typedef bool (*pcie_scan_cb_t)(pcie_bdf_t bdf, pcie_id_t id, void *cb_data);
206 
207 enum {
208 	/** Scan all available PCI host controllers and sub-busses */
209 	PCIE_SCAN_RECURSIVE = BIT(0),
210 	/** Do the callback for all endpoint types, including bridges */
211 	PCIE_SCAN_CB_ALL = BIT(1),
212 };
213 
214 /** Options for performing a scan for PCI devices */
215 struct pcie_scan_opt {
216 	/** Initial bus number to scan */
217 	uint8_t bus;
218 
219 	/** Function to call for each found endpoint */
220 	pcie_scan_cb_t cb;
221 
222 	/** Custom data to pass to the scan callback */
223 	void *cb_data;
224 
225 	/** Scan flags */
226 	uint32_t flags;
227 };
228 
229 /** Scan for PCIe devices.
230  *
231  * Scan the PCI bus (or busses) for available endpoints.
232  *
233  * @param opt Options determining how to perform the scan.
234  * @return 0 on success, negative POSIX error number on failure.
235  */
236 int pcie_scan(const struct pcie_scan_opt *opt);
237 
238 /**
239  * @brief Probe for the presence of a PCI(e) endpoint.
240  *
241  * @deprecated
242  * @see DEVICE_PCIE_DECLARE
243  *
244  * @param bdf the endpoint to probe
245  * @param id the endpoint ID to expect, or PCIE_ID_NONE for "any device"
246  * @return true if the device is present, false otherwise
247  */
248 __deprecated extern bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id);
249 
250 /**
251  * @brief Get the MBAR at a specific BAR index
252  * @param bdf the PCI(e) endpoint
253  * @param bar_index 0-based BAR index
254  * @param mbar Pointer to struct pcie_bar
255  * @return true if the mbar was found and is valid, false otherwise
256  */
257 extern bool pcie_get_mbar(pcie_bdf_t bdf,
258 			  unsigned int bar_index,
259 			  struct pcie_bar *mbar);
260 
261 /**
262  * @brief Probe the nth MMIO address assigned to an endpoint.
263  * @param bdf the PCI(e) endpoint
264  * @param index (0-based) index
265  * @param mbar Pointer to struct pcie_bar
266  * @return true if the mbar was found and is valid, false otherwise
267  *
268  * A PCI(e) endpoint has 0 or more memory-mapped regions. This function
269  * allows the caller to enumerate them by calling with index=0..n.
270  * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
271  * are order-preserving with respect to the endpoint BARs: e.g., index 0
272  * will return the lowest-numbered memory BAR on the endpoint.
273  */
274 extern bool pcie_probe_mbar(pcie_bdf_t bdf,
275 			    unsigned int index,
276 			    struct pcie_bar *mbar);
277 
278 /**
279  * @brief Get the I/O BAR at a specific BAR index
280  * @param bdf the PCI(e) endpoint
281  * @param bar_index 0-based BAR index
282  * @param iobar Pointer to struct pcie_bar
283  * @return true if the I/O BAR was found and is valid, false otherwise
284  */
285 extern bool pcie_get_iobar(pcie_bdf_t bdf,
286 			   unsigned int bar_index,
287 			   struct pcie_bar *iobar);
288 
289 /**
290  * @brief Probe the nth I/O BAR address assigned to an endpoint.
291  * @param bdf the PCI(e) endpoint
292  * @param index (0-based) index
293  * @param iobar Pointer to struct pcie_bar
294  * @return true if the I/O BAR was found and is valid, false otherwise
295  *
296  * A PCI(e) endpoint has 0 or more I/O regions. This function
297  * allows the caller to enumerate them by calling with index=0..n.
298  * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
299  * are order-preserving with respect to the endpoint BARs: e.g., index 0
300  * will return the lowest-numbered I/O BAR on the endpoint.
301  */
302 extern bool pcie_probe_iobar(pcie_bdf_t bdf,
303 			     unsigned int index,
304 			     struct pcie_bar *iobar);
305 
306 /**
307  * @brief Set or reset bits in the endpoint command/status register.
308  *
309  * @param bdf the PCI(e) endpoint
310  * @param bits the powerset of bits of interest
311  * @param on use true to set bits, false to reset them
312  */
313 extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on);
314 
315 #ifndef CONFIG_PCIE_CONTROLLER
316 /**
317  * @brief Allocate an IRQ for an endpoint.
318  *
319  * This function first checks the IRQ register and if it contains a valid
320  * value this is returned. If the register does not contain a valid value
321  * allocation of a new one is attempted.
322  * Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset.
323  * It is thus available where architecture tied dynamic IRQ allocation for
324  * PCIe device makes sense.
325  *
326  * @param bdf the PCI(e) endpoint
327  * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed.
328  */
329 extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf);
330 #endif /* CONFIG_PCIE_CONTROLLER */
331 
332 /**
333  * @brief Return the IRQ assigned by the firmware/board to an endpoint.
334  *
335  * @param bdf the PCI(e) endpoint
336  * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown.
337  */
338 extern unsigned int pcie_get_irq(pcie_bdf_t bdf);
339 
340 /**
341  * @brief Enable the PCI(e) endpoint to generate the specified IRQ.
342  *
343  * @param bdf the PCI(e) endpoint
344  * @param irq the IRQ to generate
345  *
346  * If MSI is enabled and the endpoint supports it, the endpoint will
347  * be configured to generate the specified IRQ via MSI. Otherwise, it
348  * is assumed that the IRQ has been routed by the boot firmware
349  * to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or
350  * wherever appropriate).
351  */
352 extern void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq);
353 
354 /**
355  * @brief Find a PCI(e) capability in an endpoint's configuration space.
356  *
357  * @param bdf the PCI endpoint to examine
358  * @param cap_id the capability ID of interest
359  * @return the index of the configuration word, or 0 if no capability.
360  */
361 extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id);
362 
363 /**
364  * @brief Find an Extended PCI(e) capability in an endpoint's configuration space.
365  *
366  * @param bdf the PCI endpoint to examine
367  * @param cap_id the capability ID of interest
368  * @return the index of the configuration word, or 0 if no capability.
369  */
370 extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id);
371 
372 /**
373  * @brief Dynamically connect a PCIe endpoint IRQ to an ISR handler
374  *
375  * @param bdf the PCI endpoint to examine
376  * @param irq the IRQ to connect (see pcie_alloc_irq())
377  * @param priority priority of the IRQ
378  * @param routine the ISR handler to connect to the IRQ
379  * @param parameter the parameter to provide to the handler
380  * @param flags IRQ connection flags
381  * @return true if connected, false otherwise
382  */
383 extern bool pcie_connect_dynamic_irq(pcie_bdf_t bdf,
384 				     unsigned int irq,
385 				     unsigned int priority,
386 				     void (*routine)(const void *parameter),
387 				     const void *parameter,
388 				     uint32_t flags);
389 
390 /**
391  * @brief Get the BDF for a given PCI host controller
392  *
393  * This macro is useful when the PCI host controller behind PCIE_BDF(0, 0, 0)
394  * indicates a multifunction device. In such a case each function of this
395  * endpoint is a potential host controller itself.
396  *
397  * @param n Bus number
398  * @return BDF value of the given host controller
399  */
400 #define PCIE_HOST_CONTROLLER(n) PCIE_BDF(0, 0, n)
401 
402 /*
403  * Configuration word 13 contains the head of the capabilities list.
404  */
405 
406 #define PCIE_CONF_CAPPTR	13U	/* capabilities pointer */
407 #define PCIE_CONF_CAPPTR_FIRST(w)	(((w) >> 2) & 0x3FU)
408 
409 /*
410  * The first word of every capability contains a capability identifier,
411  * and a link to the next capability (or 0) in configuration space.
412  */
413 
414 #define PCIE_CONF_CAP_ID(w)		((w) & 0xFFU)
415 #define PCIE_CONF_CAP_NEXT(w)		(((w) >> 10) & 0x3FU)
416 
417 /*
418  * The extended PCI Express capabilities lie at the end of the PCI configuration space
419  */
420 
421 #define PCIE_CONF_EXT_CAPPTR	64U
422 
423 /*
424  * The first word of every capability contains an extended capability identifier,
425  * and a link to the next capability (or 0) in the extended configuration space.
426  */
427 
428 #define PCIE_CONF_EXT_CAP_ID(w)		((w) & 0xFFFFU)
429 #define PCIE_CONF_EXT_CAP_VER(w)	(((w) >> 16) & 0xFU)
430 #define PCIE_CONF_EXT_CAP_NEXT(w)	(((w) >> 20) & 0xFFFU)
431 
432 /*
433  * Configuration word 0 aligns directly with pcie_id_t.
434  */
435 
436 #define PCIE_CONF_ID		0U
437 
438 /*
439  * Configuration word 1 contains command and status bits.
440  */
441 
442 #define PCIE_CONF_CMDSTAT	1U	/* command/status register */
443 
444 #define PCIE_CONF_CMDSTAT_IO		0x00000001U  /* I/O access enable */
445 #define PCIE_CONF_CMDSTAT_MEM		0x00000002U  /* mem access enable */
446 #define PCIE_CONF_CMDSTAT_MASTER	0x00000004U  /* bus master enable */
447 #define PCIE_CONF_CMDSTAT_INTERRUPT	0x00080000U  /* interrupt status */
448 #define PCIE_CONF_CMDSTAT_CAPS		0x00100000U  /* capabilities list */
449 
450 /*
451  * Configuration word 2 has additional function identification that
452  * we only care about for debug output (PCIe shell commands).
453  */
454 
455 #define PCIE_CONF_CLASSREV	2U	/* class/revision register */
456 
457 #define PCIE_CONF_CLASSREV_CLASS(w)	(((w) >> 24) & 0xFFU)
458 #define PCIE_CONF_CLASSREV_SUBCLASS(w)  (((w) >> 16) & 0xFFU)
459 #define PCIE_CONF_CLASSREV_PROGIF(w)	(((w) >> 8) & 0xFFU)
460 #define PCIE_CONF_CLASSREV_REV(w)	((w) & 0xFFU)
461 
462 /*
463  * The only part of configuration word 3 that is of interest to us is
464  * the header type, as we use it to distinguish functional endpoints
465  * from bridges (which are, for our purposes, transparent).
466  */
467 
468 #define PCIE_CONF_TYPE		3U
469 
470 #define PCIE_CONF_MULTIFUNCTION(w)	(((w) & 0x00800000U) != 0U)
471 #define PCIE_CONF_TYPE_BRIDGE(w)	(((w) & 0x007F0000U) != 0U)
472 #define PCIE_CONF_TYPE_GET(w)		(((w) >> 16) & 0x7F)
473 
474 #define PCIE_CONF_TYPE_STANDARD         0x0U
475 #define PCIE_CONF_TYPE_PCI_BRIDGE       0x1U
476 #define PCIE_CONF_TYPE_CARDBUS_BRIDGE   0x2U
477 
478 /*
479  * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may
480  * be 64-bit decoders, in which case the next configuration word holds
481  * the high-order bits (and is, thus, not a BAR itself).
482  */
483 
484 #define PCIE_CONF_BAR0		4U
485 #define PCIE_CONF_BAR1		5U
486 #define PCIE_CONF_BAR2		6U
487 #define PCIE_CONF_BAR3		7U
488 #define PCIE_CONF_BAR4		8U
489 #define PCIE_CONF_BAR5		9U
490 
491 #define PCIE_CONF_BAR_IO(w)		(((w) & 0x00000001U) == 0x00000001U)
492 #define PCIE_CONF_BAR_MEM(w)		(((w) & 0x00000001U) != 0x00000001U)
493 #define PCIE_CONF_BAR_64(w)		(((w) & 0x00000006U) == 0x00000004U)
494 #define PCIE_CONF_BAR_ADDR(w)		((w) & ~0xfUL)
495 #define PCIE_CONF_BAR_IO_ADDR(w)	((w) & ~0x3UL)
496 #define PCIE_CONF_BAR_FLAGS(w)		((w) & 0xfUL)
497 #define PCIE_CONF_BAR_NONE		0U
498 
499 #define PCIE_CONF_BAR_INVAL		0xFFFFFFF0U
500 #define PCIE_CONF_BAR_INVAL64		0xFFFFFFFFFFFFFFF0UL
501 
502 #define PCIE_CONF_BAR_INVAL_FLAGS(w)			\
503 	((((w) & 0x00000006U) == 0x00000006U) ||	\
504 	 (((w) & 0x00000006U) == 0x00000002U))
505 
506 /*
507  * Type 1 Header has files related to bus management
508  */
509 #define PCIE_BUS_NUMBER         6U
510 
511 #define PCIE_BUS_PRIMARY_NUMBER(w)      ((w) & 0xffUL)
512 #define PCIE_BUS_SECONDARY_NUMBER(w)    (((w) >> 8) & 0xffUL)
513 #define PCIE_BUS_SUBORDINATE_NUMBER(w)  (((w) >> 16) & 0xffUL)
514 #define PCIE_SECONDARY_LATENCY_TIMER(w) (((w) >> 24) & 0xffUL)
515 
516 #define PCIE_BUS_NUMBER_VAL(prim, sec, sub, lat) \
517 	(((prim) & 0xffUL) |			 \
518 	 (((sec) & 0xffUL) << 8) |		 \
519 	 (((sub) & 0xffUL) << 16) |		 \
520 	 (((lat) & 0xffUL) << 24))
521 
522 /*
523  * Type 1 words 7 to 12 setups Bridge Memory base and limits
524  */
525 #define PCIE_IO_SEC_STATUS      7U
526 
527 #define PCIE_IO_BASE(w)         ((w) & 0xffUL)
528 #define PCIE_IO_LIMIT(w)        (((w) >> 8) & 0xffUL)
529 #define PCIE_SEC_STATUS(w)      (((w) >> 16) & 0xffffUL)
530 
531 #define PCIE_IO_SEC_STATUS_VAL(iob, iol, sec_status) \
532 	(((iob) & 0xffUL) |			     \
533 	 (((iol) & 0xffUL) << 8) |		     \
534 	 (((sec_status) & 0xffffUL) << 16))
535 
536 #define PCIE_MEM_BASE_LIMIT     8U
537 
538 #define PCIE_MEM_BASE(w)        ((w) & 0xffffUL)
539 #define PCIE_MEM_LIMIT(w)       (((w) >> 16) & 0xffffUL)
540 
541 #define PCIE_MEM_BASE_LIMIT_VAL(memb, meml) \
542 	(((memb) & 0xffffUL) |		    \
543 	 (((meml) & 0xffffUL) << 16))
544 
545 #define PCIE_PREFETCH_BASE_LIMIT        9U
546 
547 #define PCIE_PREFETCH_BASE(w)   ((w) & 0xffffUL)
548 #define PCIE_PREFETCH_LIMIT(w)  (((w) >> 16) & 0xffffUL)
549 
550 #define PCIE_PREFETCH_BASE_LIMIT_VAL(pmemb, pmeml) \
551 	(((pmemb) & 0xffffUL) |			   \
552 	 (((pmeml) & 0xffffUL) << 16))
553 
554 #define PCIE_PREFETCH_BASE_UPPER        10U
555 
556 #define PCIE_PREFETCH_LIMIT_UPPER       11U
557 
558 #define PCIE_IO_BASE_LIMIT_UPPER        12U
559 
560 #define PCIE_IO_BASE_UPPER(w)   ((w) & 0xffffUL)
561 #define PCIE_IO_LIMIT_UPPER(w)  (((w) >> 16) & 0xffffUL)
562 
563 #define PCIE_IO_BASE_LIMIT_UPPER_VAL(iobu, iolu) \
564 	(((iobu) & 0xffffUL) |			 \
565 	 (((iolu) & 0xffffUL) << 16))
566 
567 /*
568  * Word 15 contains information related to interrupts.
569  *
570  * We're only interested in the low byte, which is [supposed to be] set by
571  * the firmware to indicate which wire IRQ the device interrupt is routed to.
572  */
573 
574 #define PCIE_CONF_INTR		15U
575 
576 #define PCIE_CONF_INTR_IRQ(w)	((w) & 0xFFU)
577 #define PCIE_CONF_INTR_IRQ_NONE	0xFFU  /* no interrupt routed */
578 
579 #define PCIE_MAX_BUS  (0xFFFFFFFFU & PCIE_BDF_BUS_MASK)
580 #define PCIE_MAX_DEV  (0xFFFFFFFFU & PCIE_BDF_DEV_MASK)
581 #define PCIE_MAX_FUNC (0xFFFFFFFFU & PCIE_BDF_FUNC_MASK)
582 
583 /**
584  * @brief Initialize an interrupt handler for a PCIe endpoint IRQ
585  *
586  * This routine is only meant to be used by drivers using PCIe bus and having
587  * fixed or MSI based IRQ (so no runtime detection of the IRQ). In case
588  * of runtime detection see pcie_connect_dynamic_irq()
589  *
590  * @param bdf_p PCIe endpoint BDF
591  * @param irq_p IRQ line number.
592  * @param priority_p Interrupt priority.
593  * @param isr_p Address of interrupt service routine.
594  * @param isr_param_p Parameter passed to interrupt service routine.
595  * @param flags_p Architecture-specific IRQ configuration flags..
596  */
597 #define PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p,			\
598 			 isr_p, isr_param_p, flags_p)			\
599 	ARCH_PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p,			\
600 			      isr_p, isr_param_p, flags_p)
601 
602 #ifdef __cplusplus
603 }
604 #endif
605 
606 /**
607  * @}
608  */
609 
610 #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */
611