1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-08-25 GuEe-GUI first version
9 */
10
11 #ifndef __PCI_H__
12 #define __PCI_H__
13
14 #include <rtdef.h>
15 #include <bitmap.h>
16 #include <ioremap.h>
17 #include <drivers/ofw.h>
18 #include <drivers/pic.h>
19 #include <drivers/core/dm.h>
20 #include <drivers/core/driver.h>
21
22 #include "../../pci/pci_ids.h"
23 #include "../../pci/pci_regs.h"
24
25 #define RT_PCI_INTX_PIN_MAX 4
26 #define RT_PCI_BAR_NR_MAX 6
27 #define RT_PCI_DEVICE_MAX 32
28 #define RT_PCI_FUNCTION_MAX 8
29
30 #define RT_PCI_FIND_CAP_TTL 48
31
32 /*
33 * The PCI interface treats multi-function devices as independent
34 * devices. The slot/function address of each device is encoded
35 * in a single byte as follows:
36 *
37 * 7:3 = slot
38 * 2:0 = function
39 */
40 #define RT_PCI_DEVID(bus, devfn) ((((rt_uint16_t)(bus)) << 8) | (devfn))
41 #define RT_PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
42 #define RT_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
43 #define RT_PCI_FUNC(devfn) ((devfn) & 0x07)
44
45 #define PCIE_LINK_STATE_L0S RT_BIT(0)
46 #define PCIE_LINK_STATE_L1 RT_BIT(1)
47 #define PCIE_LINK_STATE_CLKPM RT_BIT(2)
48 #define PCIE_LINK_STATE_L1_1 RT_BIT(3)
49 #define PCIE_LINK_STATE_L1_2 RT_BIT(4)
50 #define PCIE_LINK_STATE_L1_1_PCIPM RT_BIT(5)
51 #define PCIE_LINK_STATE_L1_2_PCIPM RT_BIT(6)
52 #define PCIE_LINK_STATE_ALL \
53 ( \
54 PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | \
55 PCIE_LINK_STATE_CLKPM | \
56 PCIE_LINK_STATE_L1_1 | PCIE_LINK_STATE_L1_2 | \
57 PCIE_LINK_STATE_L1_1_PCIPM | PCIE_LINK_STATE_L1_2_PCIPM \
58 )
59
60 struct rt_pci_bus_region
61 {
62 rt_uint64_t phy_addr;
63 rt_uint64_t cpu_addr;
64 rt_uint64_t size;
65
66 rt_uint64_t bus_start;
67
68 #define PCI_BUS_REGION_F_NONE 0xffffffff /* PCI no memory */
69 #define PCI_BUS_REGION_F_MEM 0x00000000 /* PCI memory space */
70 #define PCI_BUS_REGION_F_IO 0x00000001 /* PCI IO space */
71 #define PCI_BUS_REGION_F_PREFETCH 0x00000008 /* Prefetchable PCI memory */
72 rt_ubase_t flags;
73 };
74
75 struct rt_pci_bus_resource
76 {
77 rt_ubase_t base;
78 rt_size_t size;
79
80 rt_ubase_t flags;
81 };
82
83 /*
84 * PCI topology:
85 *
86 * +-----+-----+ +-------------+ PCI Bus 0 +------------+ PCI Bus 1
87 * | RAM | CPU |---------| Host Bridge |--------+-----| PCI Bridge |-----+
88 * +-----+-----+ +-------------+ | +------------+ | +-------------+
89 * | +----| End Point 2 |
90 * +-------------+ +-------------+ | +-------------+ | +-------------+
91 * | End Point 5 |----+ | End Point 0 |-------+ | End Point 3 |----+
92 * +-------------+ | +-------------+ | +-------------+ |
93 * | | |
94 * +-------------+ | +-------------+ | +-------------+ | +-------------+
95 * | End Point 6 |----+----| ISA Bridge |-------+-----| End Point 1 | +----| End Point 4 |
96 * +-------------+ +-------------+ | +-------------+ +-------------+
97 * |
98 * +------+ +----------------+ |
99 * | Port |---------| CardBus Bridge |----+
100 * +------+ +----------------+
101 */
102
103 struct rt_pci_bus;
104
105 struct rt_pci_device_id
106 {
107 #define PCI_ANY_ID (~0)
108 #define RT_PCI_DEVICE_ID(vend, dev) \
109 .vendor = (vend), \
110 .device = (dev), \
111 .subsystem_vendor = PCI_ANY_ID, \
112 .subsystem_device = PCI_ANY_ID
113
114 #define RT_PCI_DEVICE_CLASS(dev_class, dev_class_mask) \
115 .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
116 .subsystem_vendor = PCI_ANY_ID, \
117 .subsystem_device = PCI_ANY_ID, \
118 .class = (dev_class), .class_mask = (dev_class_mask),
119
120 rt_uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID */
121 rt_uint32_t subsystem_vendor; /* Subsystem ID's or PCI_ANY_ID */
122 rt_uint32_t subsystem_device; /* Subsystem ID's or PCI_ANY_ID */
123 rt_uint32_t class, class_mask; /* (class, subclass, prog-if) triplet */
124
125 const void *data;
126 };
127
128 struct rt_pci_device
129 {
130 struct rt_device parent;
131 const char *name;
132
133 rt_list_t list;
134 struct rt_pci_bus *bus;
135 struct rt_pci_bus *subbus; /* In PCI-to-PCI bridge, 'End Point' or 'Port' is NULL */
136
137 const struct rt_pci_device_id *id;
138
139 rt_uint32_t devfn; /* Encoded device & function index */
140 rt_uint16_t vendor;
141 rt_uint16_t device;
142 rt_uint16_t subsystem_vendor;
143 rt_uint16_t subsystem_device;
144 rt_uint32_t class; /* 3 bytes: (base, sub, prog-if) */
145 rt_uint8_t revision;
146 rt_uint8_t hdr_type;
147 rt_uint8_t max_latency;
148 rt_uint8_t min_grantl;
149 rt_uint8_t int_pin;
150 rt_uint8_t int_line;
151 rt_uint16_t exp_flags;
152 rt_uint32_t cfg_size;
153
154 void *sysdata;
155
156 int irq;
157 rt_uint8_t pin;
158 struct rt_pic *intx_pic;
159
160 rt_bool_t pm_enabled;
161
162 struct rt_pci_bus_resource resource[RT_PCI_BAR_NR_MAX];
163 struct rt_pci_bus_resource rom;
164
165 rt_uint8_t pme_cap;
166 rt_uint8_t msi_cap;
167 rt_uint8_t msix_cap;
168 rt_uint8_t pcie_cap;
169
170 rt_uint8_t busmaster:1; /* Is the bus master */
171 rt_uint8_t multi_function:1; /* Multi-function device */
172 rt_uint8_t ari_enabled:1; /* Alternative Routing-ID Interpretation */
173 rt_uint8_t no_msi:1; /* May not use MSI */
174 rt_uint8_t no_64bit_msi:1; /* May only use 32-bit MSIs */
175 rt_uint8_t msi_enabled:1; /* MSI enable */
176 rt_uint8_t msix_enabled:1; /* MSIx enable */
177 rt_uint8_t broken_intx_masking:1; /* INTx masking can't be used */
178 rt_uint8_t pme_support:5; /* Bitmask of states from which PME# can be generated */
179
180 #ifdef RT_PCI_MSI
181 void *msix_base;
182 struct rt_pic *msi_pic;
183 rt_list_t msi_desc_nodes;
184 struct rt_spinlock msi_lock;
185 #endif
186 };
187
188 struct rt_pci_host_bridge
189 {
190 struct rt_device parent;
191
192 rt_uint32_t domain;
193
194 struct rt_pci_bus *root_bus;
195 const struct rt_pci_ops *ops;
196 const struct rt_pci_ops *child_ops;
197
198 rt_uint32_t bus_range[2];
199 rt_size_t bus_regions_nr;
200 struct rt_pci_bus_region *bus_regions;
201 rt_size_t dma_regions_nr;
202 struct rt_pci_bus_region *dma_regions;
203
204 rt_uint8_t (*irq_slot)(struct rt_pci_device *pdev, rt_uint8_t *pinp);
205 int (*irq_map)(struct rt_pci_device *pdev, rt_uint8_t slot, rt_uint8_t pin);
206
207 void *sysdata;
208 rt_uint8_t priv[0];
209 };
210 #define rt_device_to_pci_host_bridge(dev) rt_container_of(dev, struct rt_pci_host_bridge, parent)
211
212 struct rt_pci_ops
213 {
214 rt_err_t (*add)(struct rt_pci_bus *bus);
215 rt_err_t (*remove)(struct rt_pci_bus *bus);
216
217 void *(*map)(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg);
218
219 rt_err_t (*read)(struct rt_pci_bus *bus,
220 rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
221 rt_err_t (*write)(struct rt_pci_bus *bus,
222 rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
223 };
224
225 struct rt_pci_bus
226 {
227 rt_list_t list;
228 rt_list_t children_nodes;
229 rt_list_t devices_nodes;
230 struct rt_pci_bus *parent;
231
232 union
233 {
234 /* In PCI-to-PCI bridge, parent is not NULL */
235 struct rt_pci_device *self;
236 /* In Host bridge, this is Root bus ('PCI Bus 0') */
237 struct rt_pci_host_bridge *host_bridge;
238 };
239
240 const struct rt_pci_ops *ops;
241
242 char name[48];
243 char number;
244 struct rt_spinlock lock;
245
246 void *sysdata;
247 };
248
249 struct rt_pci_driver
250 {
251 struct rt_driver parent;
252
253 const char *name;
254 const struct rt_pci_device_id *ids;
255
256 rt_err_t (*probe)(struct rt_pci_device *pdev);
257 rt_err_t (*remove)(struct rt_pci_device *pdev);
258 rt_err_t (*shutdown)(struct rt_pci_device *pdev);
259 };
260
261 struct rt_pci_msix_entry
262 {
263 int irq;
264 int index;
265 };
266
267 enum rt_pci_power
268 {
269 RT_PCI_D0,
270 RT_PCI_D1,
271 RT_PCI_D2,
272 RT_PCI_D3HOT,
273 RT_PCI_D3COLD,
274
275 RT_PCI_PME_MAX,
276 };
277
278 void rt_pci_pme_init(struct rt_pci_device *pdev);
279 void rt_pci_pme_active(struct rt_pci_device *pdev, rt_bool_t enable);
280 rt_err_t rt_pci_enable_wake(struct rt_pci_device *pci_dev,
281 enum rt_pci_power state, rt_bool_t enable);
rt_pci_pme_capable(struct rt_pci_device * pdev,enum rt_pci_power state)282 rt_inline rt_bool_t rt_pci_pme_capable(struct rt_pci_device *pdev,
283 enum rt_pci_power state)
284 {
285 if (!pdev->pme_cap)
286 {
287 return RT_FALSE;
288 }
289
290 return !!(pdev->pme_support & (1 << state));
291 }
292
293 void rt_pci_msi_init(struct rt_pci_device *pdev);
294 void rt_pci_msix_init(struct rt_pci_device *pdev);
295
296 void rt_pci_set_master(struct rt_pci_device *pdev);
297 void rt_pci_clear_master(struct rt_pci_device *pdev);
298
299 struct rt_pci_host_bridge *rt_pci_host_bridge_alloc(rt_size_t priv_size);
300 rt_err_t rt_pci_host_bridge_free(struct rt_pci_host_bridge *);
301 rt_err_t rt_pci_host_bridge_init(struct rt_pci_host_bridge *host_bridge);
302 rt_err_t rt_pci_host_bridge_probe(struct rt_pci_host_bridge *host_bridge);
303
304 struct rt_pci_device *rt_pci_alloc_device(struct rt_pci_bus *bus);
305 struct rt_pci_device *rt_pci_scan_single_device(struct rt_pci_bus *bus, rt_uint32_t devfn);
306 rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev);
307 rt_size_t rt_pci_scan_slot(struct rt_pci_bus *bus, rt_uint32_t devfn);
308 rt_uint32_t rt_pci_scan_child_buses(struct rt_pci_bus *bus, rt_size_t buses);
309 rt_uint32_t rt_pci_scan_child_bus(struct rt_pci_bus *bus);
310
311 rt_err_t rt_pci_host_bridge_register(struct rt_pci_host_bridge *host_bridge);
312 rt_err_t rt_pci_scan_root_bus_bridge(struct rt_pci_host_bridge *host_bridge);
313
314 rt_err_t rt_pci_host_bridge_remove(struct rt_pci_host_bridge *host_bridge);
315 rt_err_t rt_pci_bus_remove(struct rt_pci_bus *bus);
316 rt_err_t rt_pci_device_remove(struct rt_pci_device *pdev);
317
318 rt_uint32_t rt_pci_domain(struct rt_pci_device *pdev);
319
320 rt_uint8_t rt_pci_bus_find_capability(struct rt_pci_bus *bus, rt_uint32_t devfn, int cap);
321 rt_uint8_t rt_pci_find_capability(struct rt_pci_device *pdev, int cap);
322 rt_uint8_t rt_pci_find_next_capability(struct rt_pci_device *pdev, rt_uint8_t pos, int cap);
323
324 rt_uint16_t rt_pci_find_ext_capability(struct rt_pci_device *pdev, int cap);
325 rt_uint16_t rt_pci_find_ext_next_capability(struct rt_pci_device *pdev, rt_uint16_t pos, int cap);
326
327 struct rt_pci_bus *rt_pci_find_root_bus(struct rt_pci_bus *bus);
328 struct rt_pci_host_bridge *rt_pci_find_host_bridge(struct rt_pci_bus *bus);
329
rt_pci_dev_id(struct rt_pci_device * pdev)330 rt_inline rt_uint16_t rt_pci_dev_id(struct rt_pci_device *pdev)
331 {
332 return RT_PCI_DEVID(pdev->bus->number, pdev->devfn);
333 }
334
rt_pci_is_root_bus(struct rt_pci_bus * bus)335 rt_inline rt_bool_t rt_pci_is_root_bus(struct rt_pci_bus *bus)
336 {
337 return bus->parent ? RT_FALSE : RT_TRUE;
338 }
339
rt_pci_is_bridge(struct rt_pci_device * pdev)340 rt_inline rt_bool_t rt_pci_is_bridge(struct rt_pci_device *pdev)
341 {
342 return pdev->hdr_type == PCIM_HDRTYPE_BRIDGE ||
343 pdev->hdr_type == PCIM_HDRTYPE_CARDBUS;
344 }
345
rt_pci_is_pcie(struct rt_pci_device * pdev)346 rt_inline rt_bool_t rt_pci_is_pcie(struct rt_pci_device *pdev)
347 {
348 return !!pdev->pcie_cap;
349 }
350
351 #define rt_pci_foreach_bridge(pdev, bus) \
352 rt_list_for_each_entry(pdev, &bus->devices_nodes, list) \
353 if (rt_pci_is_bridge(pdev))
354
355 rt_err_t rt_pci_bus_read_config_u8(struct rt_pci_bus *bus,
356 rt_uint32_t devfn, int pos, rt_uint8_t *value);
357 rt_err_t rt_pci_bus_read_config_u16(struct rt_pci_bus *bus,
358 rt_uint32_t devfn, int pos, rt_uint16_t *value);
359 rt_err_t rt_pci_bus_read_config_u32(struct rt_pci_bus *bus,
360 rt_uint32_t devfn, int pos, rt_uint32_t *value);
361
362 rt_err_t rt_pci_bus_write_config_u8(struct rt_pci_bus *bus,
363 rt_uint32_t devfn, int reg, rt_uint8_t value);
364 rt_err_t rt_pci_bus_write_config_u16(struct rt_pci_bus *bus,
365 rt_uint32_t devfn, int reg, rt_uint16_t value);
366 rt_err_t rt_pci_bus_write_config_u32(struct rt_pci_bus *bus,
367 rt_uint32_t devfn, int reg, rt_uint32_t value);
368
369 rt_err_t rt_pci_bus_read_config_uxx(struct rt_pci_bus *bus,
370 rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
371 rt_err_t rt_pci_bus_write_config_uxx(struct rt_pci_bus *bus,
372 rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
373
374 rt_err_t rt_pci_bus_read_config_generic_u32(struct rt_pci_bus *bus,
375 rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
376 rt_err_t rt_pci_bus_write_config_generic_u32(struct rt_pci_bus *bus,
377 rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
378
rt_pci_read_config_u8(const struct rt_pci_device * pdev,int reg,rt_uint8_t * value)379 rt_inline rt_err_t rt_pci_read_config_u8(const struct rt_pci_device *pdev,
380 int reg, rt_uint8_t *value)
381 {
382 return rt_pci_bus_read_config_u8(pdev->bus, pdev->devfn, reg, value);
383 }
384
rt_pci_read_config_u16(const struct rt_pci_device * pdev,int reg,rt_uint16_t * value)385 rt_inline rt_err_t rt_pci_read_config_u16(const struct rt_pci_device *pdev,
386 int reg, rt_uint16_t *value)
387 {
388 return rt_pci_bus_read_config_u16(pdev->bus, pdev->devfn, reg, value);
389 }
390
rt_pci_read_config_u32(const struct rt_pci_device * pdev,int reg,rt_uint32_t * value)391 rt_inline rt_err_t rt_pci_read_config_u32(const struct rt_pci_device *pdev,
392 int reg, rt_uint32_t *value)
393 {
394 return rt_pci_bus_read_config_u32(pdev->bus, pdev->devfn, reg, value);
395 }
396
rt_pci_write_config_u8(const struct rt_pci_device * pdev,int reg,rt_uint8_t value)397 rt_inline rt_err_t rt_pci_write_config_u8(const struct rt_pci_device *pdev,
398 int reg, rt_uint8_t value)
399 {
400 return rt_pci_bus_write_config_u8(pdev->bus, pdev->devfn, reg, value);
401 }
402
rt_pci_write_config_u16(const struct rt_pci_device * pdev,int reg,rt_uint16_t value)403 rt_inline rt_err_t rt_pci_write_config_u16(const struct rt_pci_device *pdev,
404 int reg, rt_uint16_t value)
405 {
406 return rt_pci_bus_write_config_u16(pdev->bus, pdev->devfn, reg, value);
407 }
408
rt_pci_write_config_u32(const struct rt_pci_device * pdev,int reg,rt_uint32_t value)409 rt_inline rt_err_t rt_pci_write_config_u32(const struct rt_pci_device *pdev,
410 int reg, rt_uint32_t value)
411 {
412 return rt_pci_bus_write_config_u32(pdev->bus, pdev->devfn, reg, value);
413 }
414
415 #ifdef RT_USING_OFW
416 int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev,
417 rt_uint8_t slot, rt_uint8_t pin);
418
419 rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
420 struct rt_pci_host_bridge *host_bridge);
421
422 rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
423 struct rt_pci_host_bridge *host_bridge);
424
425 rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus);
426 rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus);
427 rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev);
428 rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev);
429 #else
rt_pci_ofw_host_bridge_init(struct rt_ofw_node * dev_np,struct rt_pci_host_bridge * host_bridge)430 rt_inline rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
431 struct rt_pci_host_bridge *host_bridge)
432 {
433 return RT_EOK;
434 }
rt_pci_ofw_bus_init(struct rt_pci_bus * bus)435 rt_inline rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus)
436 {
437 return RT_EOK;
438 }
rt_pci_ofw_bus_free(struct rt_pci_bus * bus)439 rt_inline rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus)
440 {
441 return RT_EOK;
442 }
rt_pci_ofw_device_init(struct rt_pci_device * pdev)443 rt_inline rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev)
444 {
445 return RT_EOK;
446 }
rt_pci_ofw_device_free(struct rt_pci_device * pdev)447 rt_inline rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev)
448 {
449 return RT_EOK;
450 }
rt_pci_ofw_irq_parse_and_map(struct rt_pci_device * pdev,rt_uint8_t slot,rt_uint8_t pin)451 rt_inline int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev,
452 rt_uint8_t slot, rt_uint8_t pin)
453 {
454 return -1;
455 }
rt_pci_ofw_parse_ranges(struct rt_ofw_node * dev_np,struct rt_pci_host_bridge * host_bridge)456 rt_inline rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
457 struct rt_pci_host_bridge *host_bridge)
458 {
459 return -RT_ENOSYS;
460 }
461 #endif /* RT_USING_OFW */
462
rt_pci_iomap(struct rt_pci_device * pdev,int bar_idx)463 rt_inline void *rt_pci_iomap(struct rt_pci_device *pdev, int bar_idx)
464 {
465 struct rt_pci_bus_resource *res = &pdev->resource[bar_idx];
466
467 RT_ASSERT(bar_idx < RT_ARRAY_SIZE(pdev->resource));
468
469 return rt_ioremap((void *)res->base, res->size);
470 }
471
472 rt_uint8_t rt_pci_irq_intx(struct rt_pci_device *pdev, rt_uint8_t pin);
473 rt_uint8_t rt_pci_irq_slot(struct rt_pci_device *pdev, rt_uint8_t *pinp);
474
475 void rt_pci_assign_irq(struct rt_pci_device *pdev);
476
477 void rt_pci_intx(struct rt_pci_device *pdev, rt_bool_t enable);
478 rt_bool_t rt_pci_check_and_mask_intx(struct rt_pci_device *pdev);
479 rt_bool_t rt_pci_check_and_unmask_intx(struct rt_pci_device *pdev);
480
481 void rt_pci_irq_mask(struct rt_pci_device *pdev);
482 void rt_pci_irq_unmask(struct rt_pci_device *pdev);
483
484 #define RT_PCI_IRQ_F_LEGACY RT_BIT(0) /* Allow legacy interrupts */
485 #define RT_PCI_IRQ_F_MSI RT_BIT(1) /* Allow MSI interrupts */
486 #define RT_PCI_IRQ_F_MSIX RT_BIT(2) /* Allow MSI-X interrupts */
487 #define RT_PCI_IRQ_F_AFFINITY RT_BIT(3) /* Auto-assign affinity */
488 #define RT_PCI_IRQ_F_ALL_TYPES (RT_PCI_IRQ_F_LEGACY | RT_PCI_IRQ_F_MSI | RT_PCI_IRQ_F_MSIX)
489
490 #ifdef RT_PCI_MSI
491 rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max,
492 rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities)));
493 void rt_pci_free_vector(struct rt_pci_device *pdev);
494
495 rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev);
496 rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev);
497 rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev,
498 int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities)));
499
500 rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev);
501 rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev);
502 rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev,
503 struct rt_pci_msix_entry *entries, int min, int max,
504 RT_IRQ_AFFINITY_DECLARE((*affinities)));
505 #else
rt_pci_alloc_vector(struct rt_pci_device * pdev,int min,int max,rt_uint32_t flags,RT_IRQ_AFFINITY_DECLARE ((* affinities)))506 rt_inline rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max,
507 rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities)))
508 {
509 return -RT_ENOSYS;
510 }
511
rt_pci_free_vector(struct rt_pci_device * pdev)512 rt_inline void rt_pci_free_vector(struct rt_pci_device *pdev)
513 {
514 return;
515 }
516
rt_pci_msi_vector_count(struct rt_pci_device * pdev)517 rt_inline rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev)
518 {
519 return 0;
520 }
521
rt_pci_msi_disable(struct rt_pci_device * pdev)522 rt_inline rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev)
523 {
524 return RT_EOK;
525 }
526
rt_pci_msi_enable_range_affinity(struct rt_pci_device * pdev,int min,int max,RT_IRQ_AFFINITY_DECLARE ((* affinities)))527 rt_inline rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev,
528 int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities)))
529 {
530 return -RT_ENOSYS;
531 }
532
rt_pci_msix_vector_count(struct rt_pci_device * pdev)533 rt_inline rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev)
534 {
535 return 0;
536 }
537
rt_pci_msix_disable(struct rt_pci_device * pdev)538 rt_inline rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev)
539 {
540 return RT_EOK;
541 }
542
rt_pci_msix_enable_range_affinity(struct rt_pci_device * pdev,struct rt_pci_msix_entry * entries,int min,int max,RT_IRQ_AFFINITY_DECLARE ((* affinities)))543 rt_inline rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev,
544 struct rt_pci_msix_entry *entries, int min, int max,
545 RT_IRQ_AFFINITY_DECLARE((*affinities)))
546 {
547 return -RT_ENOSYS;
548 }
549 #endif /* RT_PCI_MSI */
550
rt_pci_msix_entry_index_linear(struct rt_pci_msix_entry * entries,rt_size_t nvectors)551 rt_inline void rt_pci_msix_entry_index_linear(struct rt_pci_msix_entry *entries,
552 rt_size_t nvectors)
553 {
554 for (int i = 0; i < nvectors; ++i)
555 {
556 entries[i].index = i;
557 }
558 }
559
rt_pci_msi_enable_range(struct rt_pci_device * pdev,int min,int max)560 rt_inline rt_ssize_t rt_pci_msi_enable_range(struct rt_pci_device *pdev,
561 int min, int max)
562 {
563 return rt_pci_msi_enable_range_affinity(pdev, min, max, RT_NULL);
564 }
565
rt_pci_msi_enable(struct rt_pci_device * pdev)566 rt_inline rt_err_t rt_pci_msi_enable(struct rt_pci_device *pdev)
567 {
568 rt_ssize_t res = rt_pci_msi_enable_range(pdev, 1, 1);
569 return res == 1 ? res : RT_EOK;
570 }
571
rt_pci_msix_enable_range(struct rt_pci_device * pdev,struct rt_pci_msix_entry * entries,int min,int max)572 rt_inline rt_ssize_t rt_pci_msix_enable_range(struct rt_pci_device *pdev,
573 struct rt_pci_msix_entry *entries, int min, int max)
574 {
575 return rt_pci_msix_enable_range_affinity(pdev, entries, min, max, RT_NULL);
576 }
577
rt_pci_msix_enable(struct rt_pci_device * pdev,struct rt_pci_msix_entry * entries,int count)578 rt_inline rt_ssize_t rt_pci_msix_enable(struct rt_pci_device *pdev,
579 struct rt_pci_msix_entry *entries, int count)
580 {
581 return rt_pci_msix_enable_range(pdev, entries, count, count);
582 }
583
584 rt_err_t rt_pci_region_setup(struct rt_pci_host_bridge *host_bridge);
585 struct rt_pci_bus_region *rt_pci_region_alloc(struct rt_pci_host_bridge *host_bridge,
586 void **out_addr, rt_size_t size, rt_ubase_t flags, rt_bool_t mem64);
587
588 rt_err_t rt_pci_device_alloc_resource(struct rt_pci_host_bridge *host_bridge,
589 struct rt_pci_device *pdev);
590
591 void rt_pci_enum_device(struct rt_pci_bus *bus,
592 rt_bool_t (callback(struct rt_pci_device *, void *)), void *data);
593
594 const struct rt_pci_device_id *rt_pci_match_id(struct rt_pci_device *pdev,
595 const struct rt_pci_device_id *id);
596
597 const struct rt_pci_device_id *rt_pci_match_ids(struct rt_pci_device *pdev,
598 const struct rt_pci_device_id *ids);
599
600 rt_err_t rt_pci_driver_register(struct rt_pci_driver *pdrv);
601 rt_err_t rt_pci_device_register(struct rt_pci_device *pdev);
602 struct rt_pci_bus_resource *rt_pci_find_bar(struct rt_pci_device* pdev,rt_ubase_t flags,int index);
603 #define RT_PCI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, pci, BUILIN)
604
605 extern struct rt_spinlock rt_pci_lock;
606
607 #endif /* __PCI_H__ */
608