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 Interfaces for PCIe devices.
12 : * @defgroup pcie_interface PCIe
13 : * @ingroup io_interfaces
14 : * @{
15 : * @}
16 : *
17 : * @brief Interfaces for PCIe Host.
18 : * @defgroup pcie_host_interface PCIe Host
19 : * @ingroup pcie_interface
20 : * @{
21 : */
22 :
23 : #include <stddef.h>
24 : #include <zephyr/devicetree.h>
25 : #include <zephyr/dt-bindings/pcie/pcie.h>
26 : #include <zephyr/types.h>
27 : #include <zephyr/kernel.h>
28 : #include <zephyr/sys/iterable_sections.h>
29 :
30 : #ifdef __cplusplus
31 : extern "C" {
32 : #endif
33 :
34 : /**
35 : * @typedef pcie_bdf_t
36 : * @brief A unique PCI(e) endpoint (bus, device, function).
37 : *
38 : * A PCI(e) endpoint is uniquely identified topologically using a
39 : * (bus, device, function) tuple. The internal structure is documented
40 : * in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since
41 : * these tuples are referenced from devicetree.
42 : */
43 1 : typedef uint32_t pcie_bdf_t;
44 :
45 : /**
46 : * @typedef pcie_id_t
47 : * @brief A unique PCI(e) identifier (vendor ID, device ID).
48 : *
49 : * The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID)
50 : * pair, which is meant to tell the system what the PCI(e) endpoint is. Again,
51 : * look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more.
52 : */
53 1 : typedef uint32_t pcie_id_t;
54 :
55 : /* Helper macro to exclude invalid PCIe identifiers. We should really only
56 : * need to look for PCIE_ID_NONE, but because of some broken PCI host controllers
57 : * we have try cases where both VID & DID are zero or just one of them is
58 : * zero (0x0000) and the other is all ones (0xFFFF).
59 : */
60 0 : #define PCIE_ID_IS_VALID(id) ((id != PCIE_ID_NONE) && \
61 : (id != PCIE_ID(0x0000, 0x0000)) && \
62 : (id != PCIE_ID(0xFFFF, 0x0000)) && \
63 : (id != PCIE_ID(0x0000, 0xFFFF)))
64 :
65 0 : struct pcie_dev {
66 0 : pcie_bdf_t bdf;
67 0 : pcie_id_t id;
68 0 : uint32_t class_rev;
69 0 : uint32_t class_rev_mask;
70 : };
71 :
72 : #define Z_DEVICE_PCIE_NAME(node_id) _CONCAT(pcie_dev_, DT_DEP_ORD(node_id))
73 :
74 : /**
75 : * @brief Get the PCIe Vendor and Device ID for a node
76 : *
77 : * @param node_id DTS node identifier
78 : * @return The VID/DID combination as pcie_id_t
79 : */
80 1 : #define PCIE_DT_ID(node_id) PCIE_ID(DT_PROP_OR(node_id, vendor_id, 0xffff), \
81 : DT_PROP_OR(node_id, device_id, 0xffff))
82 :
83 : /**
84 : * @brief Get the PCIe Vendor and Device ID for a node
85 : *
86 : * This is equivalent to
87 : * <tt>PCIE_DT_ID(DT_DRV_INST(inst))</tt>
88 : *
89 : * @param inst Devicetree instance number
90 : * @return The VID/DID combination as pcie_id_t
91 : */
92 1 : #define PCIE_DT_INST_ID(inst) PCIE_DT_ID(DT_DRV_INST(inst))
93 :
94 : /**
95 : * @brief Declare a PCIe context variable for a DTS node
96 : *
97 : * Declares a PCIe context for a DTS node. This must be done before
98 : * using the DEVICE_PCIE_INIT() macro for the same node.
99 : *
100 : * @param node_id DTS node identifier
101 : */
102 1 : #define DEVICE_PCIE_DECLARE(node_id) \
103 : STRUCT_SECTION_ITERABLE(pcie_dev, Z_DEVICE_PCIE_NAME(node_id)) = { \
104 : .bdf = PCIE_BDF_NONE, \
105 : .id = PCIE_DT_ID(node_id), \
106 : .class_rev = DT_PROP_OR(node_id, class_rev, 0), \
107 : .class_rev_mask = DT_PROP_OR(node_id, class_rev_mask, 0), \
108 : }
109 :
110 : /**
111 : * @brief Declare a PCIe context variable for a DTS node
112 : *
113 : * This is equivalent to
114 : * <tt>DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))</tt>
115 : *
116 : * @param inst Devicetree instance number
117 : */
118 1 : #define DEVICE_PCIE_INST_DECLARE(inst) DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))
119 :
120 : /**
121 : * @brief Initialize a named struct member to point at a PCIe context
122 : *
123 : * Initialize PCIe-related information within a specific instance of
124 : * a device config struct, using information from DTS. Using the macro
125 : * requires having first created PCIe context struct using the
126 : * DEVICE_PCIE_DECLARE() macro.
127 : *
128 : * Example for an instance of a driver belonging to the "foo" subsystem
129 : *
130 : * struct foo_config {
131 : * struct pcie_dev *pcie;
132 : * ...
133 : *};
134 : *
135 : * DEVICE_PCIE_ID_DECLARE(DT_DRV_INST(...));
136 : * struct foo_config my_config = {
137 : DEVICE_PCIE_INIT(pcie, DT_DRV_INST(...)),
138 : * ...
139 : * };
140 : *
141 : * @param node_id DTS node identifier
142 : * @param name Member name within config for the MMIO region
143 : */
144 1 : #define DEVICE_PCIE_INIT(node_id, name) .name = &Z_DEVICE_PCIE_NAME(node_id)
145 :
146 : /**
147 : * @brief Initialize a named struct member to point at a PCIe context
148 : *
149 : * This is equivalent to
150 : * <tt>DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)</tt>
151 : *
152 : * @param inst Devicetree instance number
153 : * @param name Name of the struct member (of type struct pcie_dev *)
154 : */
155 1 : #define DEVICE_PCIE_INST_INIT(inst, name) \
156 : DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)
157 :
158 0 : struct pcie_bar {
159 0 : uintptr_t phys_addr;
160 0 : size_t size;
161 : };
162 :
163 : /*
164 : * These functions are arch-, board-, or SoC-specific.
165 : */
166 :
167 : /**
168 : * @brief Read a 32-bit word from an endpoint's configuration space.
169 : *
170 : * This function is exported by the arch/SoC/board code.
171 : *
172 : * @param bdf PCI(e) endpoint
173 : * @param reg the configuration word index (not address)
174 : * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word)
175 : */
176 1 : extern uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg);
177 :
178 : /**
179 : * @brief Write a 32-bit word to an endpoint's configuration space.
180 : *
181 : * This function is exported by the arch/SoC/board code.
182 : *
183 : * @param bdf PCI(e) endpoint
184 : * @param reg the configuration word index (not address)
185 : * @param data the value to write
186 : */
187 1 : extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data);
188 :
189 : /** Callback type used for scanning for PCI endpoints
190 : *
191 : * @param bdf BDF value for a found endpoint.
192 : * @param id Vendor & Device ID for the found endpoint.
193 : * @param cb_data Custom, use case specific data.
194 : *
195 : * @return true to continue scanning, false to stop scanning.
196 : */
197 1 : typedef bool (*pcie_scan_cb_t)(pcie_bdf_t bdf, pcie_id_t id, void *cb_data);
198 :
199 0 : enum {
200 : /** Scan all available PCI host controllers and sub-buses */
201 : PCIE_SCAN_RECURSIVE = BIT(0),
202 : /** Do the callback for all endpoint types, including bridges */
203 : PCIE_SCAN_CB_ALL = BIT(1),
204 : };
205 :
206 : /** Options for performing a scan for PCI devices */
207 1 : struct pcie_scan_opt {
208 : /** Initial bus number to scan */
209 1 : uint8_t bus;
210 :
211 : /** Function to call for each found endpoint */
212 1 : pcie_scan_cb_t cb;
213 :
214 : /** Custom data to pass to the scan callback */
215 1 : void *cb_data;
216 :
217 : /** Scan flags */
218 1 : uint32_t flags;
219 : };
220 :
221 : /** Scan for PCIe devices.
222 : *
223 : * Scan the PCI bus (or buses) for available endpoints.
224 : *
225 : * @param opt Options determining how to perform the scan.
226 : * @return 0 on success, negative POSIX error number on failure.
227 : */
228 1 : int pcie_scan(const struct pcie_scan_opt *opt);
229 :
230 : /**
231 : * @brief Get the MBAR at a specific BAR index
232 : * @param bdf the PCI(e) endpoint
233 : * @param bar_index 0-based BAR index
234 : * @param mbar Pointer to struct pcie_bar
235 : * @return true if the mbar was found and is valid, false otherwise
236 : */
237 1 : extern bool pcie_get_mbar(pcie_bdf_t bdf,
238 : unsigned int bar_index,
239 : struct pcie_bar *mbar);
240 :
241 : /**
242 : * @brief Probe the nth MMIO address assigned to an endpoint.
243 : * @param bdf the PCI(e) endpoint
244 : * @param index (0-based) index
245 : * @param mbar Pointer to struct pcie_bar
246 : * @return true if the mbar was found and is valid, false otherwise
247 : *
248 : * A PCI(e) endpoint has 0 or more memory-mapped regions. This function
249 : * allows the caller to enumerate them by calling with index=0..n.
250 : * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
251 : * are order-preserving with respect to the endpoint BARs: e.g., index 0
252 : * will return the lowest-numbered memory BAR on the endpoint.
253 : */
254 1 : extern bool pcie_probe_mbar(pcie_bdf_t bdf,
255 : unsigned int index,
256 : struct pcie_bar *mbar);
257 :
258 : /**
259 : * @brief Get the I/O BAR at a specific BAR index
260 : * @param bdf the PCI(e) endpoint
261 : * @param bar_index 0-based BAR index
262 : * @param iobar Pointer to struct pcie_bar
263 : * @return true if the I/O BAR was found and is valid, false otherwise
264 : */
265 1 : extern bool pcie_get_iobar(pcie_bdf_t bdf,
266 : unsigned int bar_index,
267 : struct pcie_bar *iobar);
268 :
269 : /**
270 : * @brief Probe the nth I/O BAR address assigned to an endpoint.
271 : * @param bdf the PCI(e) endpoint
272 : * @param index (0-based) index
273 : * @param iobar Pointer to struct pcie_bar
274 : * @return true if the I/O BAR was found and is valid, false otherwise
275 : *
276 : * A PCI(e) endpoint has 0 or more I/O regions. This function
277 : * allows the caller to enumerate them by calling with index=0..n.
278 : * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
279 : * are order-preserving with respect to the endpoint BARs: e.g., index 0
280 : * will return the lowest-numbered I/O BAR on the endpoint.
281 : */
282 1 : extern bool pcie_probe_iobar(pcie_bdf_t bdf,
283 : unsigned int index,
284 : struct pcie_bar *iobar);
285 :
286 : /**
287 : * @brief Set or reset bits in the endpoint command/status register.
288 : *
289 : * @param bdf the PCI(e) endpoint
290 : * @param bits the powerset of bits of interest
291 : * @param on use true to set bits, false to reset them
292 : */
293 1 : extern void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on);
294 :
295 : #ifndef CONFIG_PCIE_CONTROLLER
296 : /**
297 : * @brief Allocate an IRQ for an endpoint.
298 : *
299 : * This function first checks the IRQ register and if it contains a valid
300 : * value this is returned. If the register does not contain a valid value
301 : * allocation of a new one is attempted.
302 : * Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset.
303 : * It is thus available where architecture tied dynamic IRQ allocation for
304 : * PCIe device makes sense.
305 : *
306 : * @param bdf the PCI(e) endpoint
307 : * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed.
308 : */
309 1 : extern unsigned int pcie_alloc_irq(pcie_bdf_t bdf);
310 : #endif /* CONFIG_PCIE_CONTROLLER */
311 :
312 : /**
313 : * @brief Return the IRQ assigned by the firmware/board to an endpoint.
314 : *
315 : * @param bdf the PCI(e) endpoint
316 : * @return the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown.
317 : */
318 1 : extern unsigned int pcie_get_irq(pcie_bdf_t bdf);
319 :
320 : /**
321 : * @brief Enable the PCI(e) endpoint to generate the specified IRQ.
322 : *
323 : * @param bdf the PCI(e) endpoint
324 : * @param irq the IRQ to generate
325 : *
326 : * If MSI is enabled and the endpoint supports it, the endpoint will
327 : * be configured to generate the specified IRQ via MSI. Otherwise, it
328 : * is assumed that the IRQ has been routed by the boot firmware
329 : * to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or
330 : * wherever appropriate).
331 : */
332 1 : extern void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq);
333 :
334 : /**
335 : * @brief Find a PCI(e) capability in an endpoint's configuration space.
336 : *
337 : * @param bdf the PCI endpoint to examine
338 : * @param cap_id the capability ID of interest
339 : * @return the index of the configuration word, or 0 if no capability.
340 : */
341 1 : extern uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id);
342 :
343 : /**
344 : * @brief Find an Extended PCI(e) capability in an endpoint's configuration space.
345 : *
346 : * @param bdf the PCI endpoint to examine
347 : * @param cap_id the capability ID of interest
348 : * @return the index of the configuration word, or 0 if no capability.
349 : */
350 1 : extern uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id);
351 :
352 : /**
353 : * @brief Dynamically connect a PCIe endpoint IRQ to an ISR handler
354 : *
355 : * @param bdf the PCI endpoint to examine
356 : * @param irq the IRQ to connect (see pcie_alloc_irq())
357 : * @param priority priority of the IRQ
358 : * @param routine the ISR handler to connect to the IRQ
359 : * @param parameter the parameter to provide to the handler
360 : * @param flags IRQ connection flags
361 : * @return true if connected, false otherwise
362 : */
363 1 : extern bool pcie_connect_dynamic_irq(pcie_bdf_t bdf,
364 : unsigned int irq,
365 : unsigned int priority,
366 : void (*routine)(const void *parameter),
367 : const void *parameter,
368 : uint32_t flags);
369 :
370 : /**
371 : * @brief Get the BDF for a given PCI host controller
372 : *
373 : * This macro is useful when the PCI host controller behind PCIE_BDF(0, 0, 0)
374 : * indicates a multifunction device. In such a case each function of this
375 : * endpoint is a potential host controller itself.
376 : *
377 : * @param n Bus number
378 : * @return BDF value of the given host controller
379 : */
380 1 : #define PCIE_HOST_CONTROLLER(n) PCIE_BDF(0, 0, n)
381 :
382 : /*
383 : * Configuration word 13 contains the head of the capabilities list.
384 : */
385 :
386 0 : #define PCIE_CONF_CAPPTR 13U /* capabilities pointer */
387 0 : #define PCIE_CONF_CAPPTR_FIRST(w) (((w) >> 2) & 0x3FU)
388 :
389 : /*
390 : * The first word of every capability contains a capability identifier,
391 : * and a link to the next capability (or 0) in configuration space.
392 : */
393 :
394 0 : #define PCIE_CONF_CAP_ID(w) ((w) & 0xFFU)
395 0 : #define PCIE_CONF_CAP_NEXT(w) (((w) >> 10) & 0x3FU)
396 :
397 : /*
398 : * The extended PCI Express capabilities lie at the end of the PCI configuration space
399 : */
400 :
401 0 : #define PCIE_CONF_EXT_CAPPTR 64U
402 :
403 : /*
404 : * The first word of every capability contains an extended capability identifier,
405 : * and a link to the next capability (or 0) in the extended configuration space.
406 : */
407 :
408 0 : #define PCIE_CONF_EXT_CAP_ID(w) ((w) & 0xFFFFU)
409 0 : #define PCIE_CONF_EXT_CAP_VER(w) (((w) >> 16) & 0xFU)
410 0 : #define PCIE_CONF_EXT_CAP_NEXT(w) (((w) >> 20) & 0xFFFU)
411 :
412 : /*
413 : * Configuration word 0 aligns directly with pcie_id_t.
414 : */
415 :
416 0 : #define PCIE_CONF_ID 0U
417 :
418 : /*
419 : * Configuration word 1 contains command and status bits.
420 : */
421 :
422 0 : #define PCIE_CONF_CMDSTAT 1U /* command/status register */
423 :
424 0 : #define PCIE_CONF_CMDSTAT_IO 0x00000001U /* I/O access enable */
425 0 : #define PCIE_CONF_CMDSTAT_MEM 0x00000002U /* mem access enable */
426 0 : #define PCIE_CONF_CMDSTAT_MASTER 0x00000004U /* bus master enable */
427 0 : #define PCIE_CONF_CMDSTAT_SERR 0x00000010U /* SERR# enable */
428 0 : #define PCIE_CONF_CMDSTAT_INTERRUPT 0x00080000U /* interrupt status */
429 0 : #define PCIE_CONF_CMDSTAT_CAPS 0x00100000U /* capabilities list */
430 :
431 : /*
432 : * Configuration word 2 has additional function identification that
433 : * we only care about for debug output (PCIe shell commands).
434 : */
435 :
436 0 : #define PCIE_CONF_CLASSREV 2U /* class/revision register */
437 :
438 0 : #define PCIE_CONF_CLASSREV_CLASS(w) (((w) >> 24) & 0xFFU)
439 0 : #define PCIE_CONF_CLASSREV_SUBCLASS(w) (((w) >> 16) & 0xFFU)
440 0 : #define PCIE_CONF_CLASSREV_PROGIF(w) (((w) >> 8) & 0xFFU)
441 0 : #define PCIE_CONF_CLASSREV_REV(w) ((w) & 0xFFU)
442 :
443 : /*
444 : * The only part of configuration word 3 that is of interest to us is
445 : * the header type, as we use it to distinguish functional endpoints
446 : * from bridges (which are, for our purposes, transparent).
447 : */
448 :
449 0 : #define PCIE_CONF_TYPE 3U
450 :
451 0 : #define PCIE_CONF_MULTIFUNCTION(w) (((w) & 0x00800000U) != 0U)
452 0 : #define PCIE_CONF_TYPE_BRIDGE(w) (((w) & 0x007F0000U) != 0U)
453 0 : #define PCIE_CONF_TYPE_GET(w) (((w) >> 16) & 0x7F)
454 :
455 0 : #define PCIE_CONF_TYPE_STANDARD 0x0U
456 0 : #define PCIE_CONF_TYPE_PCI_BRIDGE 0x1U
457 0 : #define PCIE_CONF_TYPE_CARDBUS_BRIDGE 0x2U
458 :
459 : /*
460 : * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may
461 : * be 64-bit decoders, in which case the next configuration word holds
462 : * the high-order bits (and is, thus, not a BAR itself).
463 : */
464 :
465 0 : #define PCIE_CONF_BAR0 4U
466 0 : #define PCIE_CONF_BAR1 5U
467 0 : #define PCIE_CONF_BAR2 6U
468 0 : #define PCIE_CONF_BAR3 7U
469 0 : #define PCIE_CONF_BAR4 8U
470 0 : #define PCIE_CONF_BAR5 9U
471 :
472 0 : #define PCIE_CONF_BAR_IO(w) (((w) & 0x00000001U) == 0x00000001U)
473 0 : #define PCIE_CONF_BAR_MEM(w) (((w) & 0x00000001U) != 0x00000001U)
474 0 : #define PCIE_CONF_BAR_64(w) (((w) & 0x00000006U) == 0x00000004U)
475 0 : #define PCIE_CONF_BAR_ADDR(w) ((w) & ~0xfUL)
476 0 : #define PCIE_CONF_BAR_IO_ADDR(w) ((w) & ~0x3UL)
477 0 : #define PCIE_CONF_BAR_FLAGS(w) ((w) & 0xfUL)
478 0 : #define PCIE_CONF_BAR_NONE 0U
479 :
480 0 : #define PCIE_CONF_BAR_INVAL 0xFFFFFFF0U
481 0 : #define PCIE_CONF_BAR_INVAL64 0xFFFFFFFFFFFFFFF0UL
482 :
483 0 : #define PCIE_CONF_BAR_INVAL_FLAGS(w) \
484 : ((((w) & 0x00000006U) == 0x00000006U) || \
485 : (((w) & 0x00000006U) == 0x00000002U))
486 :
487 : /*
488 : * Type 1 Header has files related to bus management
489 : */
490 0 : #define PCIE_BUS_NUMBER 6U
491 :
492 0 : #define PCIE_BUS_PRIMARY_NUMBER(w) ((w) & 0xffUL)
493 0 : #define PCIE_BUS_SECONDARY_NUMBER(w) (((w) >> 8) & 0xffUL)
494 0 : #define PCIE_BUS_SUBORDINATE_NUMBER(w) (((w) >> 16) & 0xffUL)
495 0 : #define PCIE_SECONDARY_LATENCY_TIMER(w) (((w) >> 24) & 0xffUL)
496 :
497 0 : #define PCIE_BUS_NUMBER_VAL(prim, sec, sub, lat) \
498 : (((prim) & 0xffUL) | \
499 : (((sec) & 0xffUL) << 8) | \
500 : (((sub) & 0xffUL) << 16) | \
501 : (((lat) & 0xffUL) << 24))
502 :
503 : /*
504 : * Type 1 words 7 to 12 setups Bridge Memory base and limits
505 : */
506 0 : #define PCIE_IO_SEC_STATUS 7U
507 :
508 0 : #define PCIE_IO_BASE(w) ((w) & 0xffUL)
509 0 : #define PCIE_IO_LIMIT(w) (((w) >> 8) & 0xffUL)
510 0 : #define PCIE_SEC_STATUS(w) (((w) >> 16) & 0xffffUL)
511 :
512 0 : #define PCIE_IO_SEC_STATUS_VAL(iob, iol, sec_status) \
513 : (((iob) & 0xffUL) | \
514 : (((iol) & 0xffUL) << 8) | \
515 : (((sec_status) & 0xffffUL) << 16))
516 :
517 0 : #define PCIE_MEM_BASE_LIMIT 8U
518 :
519 0 : #define PCIE_MEM_BASE(w) ((w) & 0xffffUL)
520 0 : #define PCIE_MEM_LIMIT(w) (((w) >> 16) & 0xffffUL)
521 :
522 0 : #define PCIE_MEM_BASE_LIMIT_VAL(memb, meml) \
523 : (((memb) & 0xffffUL) | \
524 : (((meml) & 0xffffUL) << 16))
525 :
526 0 : #define PCIE_PREFETCH_BASE_LIMIT 9U
527 :
528 0 : #define PCIE_PREFETCH_BASE(w) ((w) & 0xffffUL)
529 0 : #define PCIE_PREFETCH_LIMIT(w) (((w) >> 16) & 0xffffUL)
530 :
531 0 : #define PCIE_PREFETCH_BASE_LIMIT_VAL(pmemb, pmeml) \
532 : (((pmemb) & 0xffffUL) | \
533 : (((pmeml) & 0xffffUL) << 16))
534 :
535 0 : #define PCIE_PREFETCH_BASE_UPPER 10U
536 :
537 0 : #define PCIE_PREFETCH_LIMIT_UPPER 11U
538 :
539 0 : #define PCIE_IO_BASE_LIMIT_UPPER 12U
540 :
541 0 : #define PCIE_IO_BASE_UPPER(w) ((w) & 0xffffUL)
542 0 : #define PCIE_IO_LIMIT_UPPER(w) (((w) >> 16) & 0xffffUL)
543 :
544 0 : #define PCIE_IO_BASE_LIMIT_UPPER_VAL(iobu, iolu) \
545 : (((iobu) & 0xffffUL) | \
546 : (((iolu) & 0xffffUL) << 16))
547 :
548 : /*
549 : * Word 15 contains information related to interrupts.
550 : *
551 : * We're only interested in the low byte, which is [supposed to be] set by
552 : * the firmware to indicate which wire IRQ the device interrupt is routed to.
553 : */
554 :
555 0 : #define PCIE_CONF_INTR 15U
556 :
557 0 : #define PCIE_CONF_INTR_IRQ(w) ((w) & 0xFFU)
558 0 : #define PCIE_CONF_INTR_IRQ_NONE 0xFFU /* no interrupt routed */
559 :
560 0 : #define PCIE_MAX_BUS (0xFFFFFFFFU & PCIE_BDF_BUS_MASK)
561 0 : #define PCIE_MAX_DEV (0xFFFFFFFFU & PCIE_BDF_DEV_MASK)
562 0 : #define PCIE_MAX_FUNC (0xFFFFFFFFU & PCIE_BDF_FUNC_MASK)
563 :
564 : /**
565 : * @brief Initialize an interrupt handler for a PCIe endpoint IRQ
566 : *
567 : * This routine is only meant to be used by drivers using PCIe bus and having
568 : * fixed or MSI based IRQ (so no runtime detection of the IRQ). In case
569 : * of runtime detection see pcie_connect_dynamic_irq()
570 : *
571 : * @param bdf_p PCIe endpoint BDF
572 : * @param irq_p IRQ line number.
573 : * @param priority_p Interrupt priority.
574 : * @param isr_p Address of interrupt service routine.
575 : * @param isr_param_p Parameter passed to interrupt service routine.
576 : * @param flags_p Architecture-specific IRQ configuration flags..
577 : */
578 : #define PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p, \
579 1 : isr_p, isr_param_p, flags_p) \
580 : ARCH_PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p, \
581 : isr_p, isr_param_p, flags_p)
582 :
583 : #ifdef __cplusplus
584 : }
585 : #endif
586 :
587 : /**
588 : * @}
589 : */
590 :
591 : #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */
|