pci.h 19 KB

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