ofw.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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-10-24 GuEe-GUI first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #define DBG_TAG "pci.ofw"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. #include <drivers/pci.h>
  16. #include <drivers/ofw.h>
  17. #include <drivers/ofw_io.h>
  18. #include <drivers/ofw_irq.h>
  19. #include <drivers/ofw_fdt.h>
  20. static rt_err_t pci_ofw_irq_parse(struct rt_pci_device *pdev, struct rt_ofw_cell_args *out_irq)
  21. {
  22. rt_err_t err = RT_EOK;
  23. rt_uint8_t pin;
  24. fdt32_t map_addr[4];
  25. struct rt_pci_device *p2pdev;
  26. struct rt_ofw_node *dev_np, *p2pnode = RT_NULL;
  27. /* Parse device tree if dev have a device node */
  28. dev_np = pdev->parent.ofw_node;
  29. if (dev_np)
  30. {
  31. err = rt_ofw_parse_irq_cells(dev_np, 0, out_irq);
  32. if (err)
  33. {
  34. return err;
  35. }
  36. }
  37. /* Assume #interrupt-cells is 1 */
  38. if ((err = rt_pci_read_config_u8(pdev, PCIR_INTPIN, &pin)))
  39. {
  40. goto _err;
  41. }
  42. /* No pin, exit with no error message. */
  43. if (pin == 0)
  44. {
  45. return -RT_ENOSYS;
  46. }
  47. /* Try local interrupt-map in the device node */
  48. if (rt_ofw_prop_read_raw(dev_np, "interrupt-map", RT_NULL))
  49. {
  50. pin = rt_pci_irq_intx(pdev, pin);
  51. p2pnode = dev_np;
  52. }
  53. /* Walk up the PCI tree */
  54. while (!p2pnode)
  55. {
  56. p2pdev = pdev->bus->self;
  57. /* Is the root bus -> host bridge */
  58. if (rt_pci_is_root_bus(pdev->bus))
  59. {
  60. struct rt_pci_host_bridge *host_bridge = pdev->bus->host_bridge;
  61. p2pnode = host_bridge->parent.ofw_node;
  62. if (!p2pnode)
  63. {
  64. err = -RT_EINVAL;
  65. goto _err;
  66. }
  67. }
  68. else
  69. {
  70. /* Is P2P bridge */
  71. p2pnode = p2pdev->parent.ofw_node;
  72. }
  73. if (p2pnode)
  74. {
  75. break;
  76. }
  77. /* Try get INTx in P2P */
  78. pin = rt_pci_irq_intx(pdev, pin);
  79. pdev = p2pdev;
  80. }
  81. /* For more format detail, please read `components/drivers/ofw/irq.c:ofw_parse_irq_map` */
  82. out_irq->data = map_addr;
  83. out_irq->args_count = 2;
  84. out_irq->args[0] = 3;
  85. out_irq->args[1] = 1;
  86. /* In addr cells */
  87. map_addr[0] = cpu_to_fdt32((pdev->bus->number << 16) | (pdev->devfn << 8));
  88. map_addr[1] = cpu_to_fdt32(0);
  89. map_addr[2] = cpu_to_fdt32(0);
  90. /* In pin cells */
  91. map_addr[3] = cpu_to_fdt32(pin);
  92. err = rt_ofw_parse_irq_map(p2pnode, out_irq);
  93. _err:
  94. if (err == -RT_EEMPTY)
  95. {
  96. LOG_W("PCI-Device<%s> no interrupt-map found, INTx interrupts not available",
  97. rt_dm_dev_get_name(&pdev->parent));
  98. LOG_W("PCI-Device<%s> possibly some PCI slots don't have level triggered interrupts capability",
  99. rt_dm_dev_get_name(&pdev->parent));
  100. }
  101. else if (err && err != -RT_ENOSYS)
  102. {
  103. LOG_E("PCI-Device<%s> irq parse failed with err = %s",
  104. rt_dm_dev_get_name(&pdev->parent), rt_strerror(err));
  105. }
  106. return err;
  107. }
  108. int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev,
  109. rt_uint8_t slot, rt_uint8_t pin)
  110. {
  111. int irq = -1;
  112. rt_err_t status;
  113. struct rt_ofw_cell_args irq_args;
  114. if (!pdev)
  115. {
  116. goto _end;
  117. }
  118. status = pci_ofw_irq_parse(pdev, &irq_args);
  119. if (status)
  120. {
  121. goto _end;
  122. }
  123. irq = rt_ofw_map_irq(&irq_args);
  124. if (irq >= 0)
  125. {
  126. pdev->intx_pic = rt_pic_dynamic_cast(rt_ofw_data(irq_args.data));
  127. }
  128. _end:
  129. return irq;
  130. }
  131. static rt_err_t pci_ofw_parse_ranges(struct rt_ofw_node *dev_np, const char *propname,
  132. int phy_addr_cells, int phy_size_cells, int cpu_addr_cells,
  133. struct rt_pci_bus_region **out_regions, rt_size_t *out_regions_nr)
  134. {
  135. const fdt32_t *cell;
  136. rt_ssize_t total_cells;
  137. int groups, space_code;
  138. rt_uint32_t phy_addr[3];
  139. rt_uint64_t cpu_addr, phy_addr_size;
  140. *out_regions = RT_NULL;
  141. *out_regions_nr = 0;
  142. cell = rt_ofw_prop_read_raw(dev_np, propname, &total_cells);
  143. if (!cell)
  144. {
  145. return -RT_EEMPTY;
  146. }
  147. groups = total_cells / sizeof(*cell) / (phy_addr_cells + phy_size_cells + cpu_addr_cells);
  148. *out_regions = rt_malloc(groups * sizeof(struct rt_pci_bus_region));
  149. if (!*out_regions)
  150. {
  151. return -RT_ENOMEM;
  152. }
  153. for (int i = 0; i < groups; ++i)
  154. {
  155. /*
  156. * ranges:
  157. * phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
  158. * phys.low cell: llllllll llllllll llllllll llllllll
  159. * phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
  160. *
  161. * n: relocatable region flag (doesn't play a role here)
  162. * p: prefetchable (cacheable) region flag
  163. * t: aliased address flag (doesn't play a role here)
  164. * ss: space code
  165. * 00: configuration space
  166. * 01: I/O space
  167. * 10: 32 bit memory space
  168. * 11: 64 bit memory space
  169. * bbbbbbbb: The PCI bus number
  170. * ddddd: The device number
  171. * fff: The function number. Used for multifunction PCI devices.
  172. * rrrrrrrr: Register number; used for configuration cycles.
  173. */
  174. for (int j = 0; j < phy_addr_cells; ++j)
  175. {
  176. phy_addr[j] = rt_fdt_read_number(cell++, 1);
  177. }
  178. space_code = (phy_addr[0] >> 24) & 0x3;
  179. cpu_addr = rt_fdt_read_number(cell, cpu_addr_cells);
  180. cell += cpu_addr_cells;
  181. phy_addr_size = rt_fdt_read_number(cell, phy_size_cells);
  182. cell += phy_size_cells;
  183. (*out_regions)[i].phy_addr = ((rt_uint64_t)phy_addr[1] << 32) | phy_addr[2];
  184. (*out_regions)[i].cpu_addr = cpu_addr;
  185. (*out_regions)[i].size = phy_addr_size;
  186. (*out_regions)[i].bus_start = (*out_regions)[i].phy_addr;
  187. if (space_code & 2)
  188. {
  189. (*out_regions)[i].flags = phy_addr[0] & (1U << 30) ?
  190. PCI_BUS_REGION_F_PREFETCH : PCI_BUS_REGION_F_MEM;
  191. }
  192. else if (space_code & 1)
  193. {
  194. (*out_regions)[i].flags = PCI_BUS_REGION_F_IO;
  195. }
  196. else
  197. {
  198. (*out_regions)[i].flags = PCI_BUS_REGION_F_NONE;
  199. }
  200. ++*out_regions_nr;
  201. }
  202. return RT_EOK;
  203. }
  204. rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
  205. struct rt_pci_host_bridge *host_bridge)
  206. {
  207. rt_err_t err;
  208. int phy_addr_cells = -1, phy_size_cells = -1, cpu_addr_cells;
  209. if (!dev_np || !host_bridge)
  210. {
  211. return -RT_EINVAL;
  212. }
  213. cpu_addr_cells = rt_ofw_io_addr_cells(dev_np);
  214. rt_ofw_prop_read_s32(dev_np, "#address-cells", &phy_addr_cells);
  215. rt_ofw_prop_read_s32(dev_np, "#size-cells", &phy_size_cells);
  216. if (phy_addr_cells != 3 || phy_size_cells < 1 || cpu_addr_cells < 1)
  217. {
  218. return -RT_EINVAL;
  219. }
  220. if (pci_ofw_parse_ranges(dev_np, "ranges",
  221. phy_addr_cells, phy_size_cells, cpu_addr_cells,
  222. &host_bridge->bus_regions, &host_bridge->bus_regions_nr))
  223. {
  224. return -RT_EINVAL;
  225. }
  226. if ((err = rt_pci_region_setup(host_bridge)))
  227. {
  228. rt_free(host_bridge->bus_regions);
  229. host_bridge->bus_regions_nr = 0;
  230. return err;
  231. }
  232. err = pci_ofw_parse_ranges(dev_np, "dma-ranges",
  233. phy_addr_cells, phy_size_cells, cpu_addr_cells,
  234. &host_bridge->dma_regions, &host_bridge->dma_regions_nr);
  235. if (err != -RT_EEMPTY)
  236. {
  237. rt_free(host_bridge->bus_regions);
  238. host_bridge->bus_regions_nr = 0;
  239. LOG_E("%s: Read dma-ranges error = %s", rt_ofw_node_full_name(dev_np),
  240. rt_strerror(err));
  241. return err;
  242. }
  243. return RT_EOK;
  244. }
  245. rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
  246. struct rt_pci_host_bridge *host_bridge)
  247. {
  248. rt_err_t err;
  249. const char *propname;
  250. if (!dev_np || !host_bridge)
  251. {
  252. return -RT_EINVAL;
  253. }
  254. host_bridge->irq_slot = rt_pci_irq_slot;
  255. host_bridge->irq_map = rt_pci_ofw_irq_parse_and_map;
  256. if (rt_ofw_prop_read_u32_array_index(dev_np, "bus-range", 0, 2, host_bridge->bus_range) < 0)
  257. {
  258. return -RT_EIO;
  259. }
  260. propname = rt_ofw_get_prop_fuzzy_name(dev_np, ",pci-domain$");
  261. rt_ofw_prop_read_u32(dev_np, propname, &host_bridge->domain);
  262. err = rt_pci_ofw_parse_ranges(dev_np, host_bridge);
  263. return err;
  264. }
  265. rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus)
  266. {
  267. rt_err_t err = RT_EOK;
  268. return err;
  269. }
  270. rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus)
  271. {
  272. rt_err_t err = RT_EOK;
  273. return err;
  274. }
  275. /*
  276. * RID (Requester ID) is formatted such that:
  277. * Bits [15:8] are the Bus number.
  278. * Bits [7:3] are the Device number.
  279. * Bits [2:0] are the Function number.
  280. *
  281. * msi-map: Maps a Requester ID to an MSI controller and associated
  282. * msi-specifier data. The property is an arbitrary number of tuples of
  283. * (rid-base,msi-controller,msi-base,length), where:
  284. *
  285. * - rid-base is a single cell describing the first RID matched by the entry.
  286. *
  287. * - msi-controller is a single phandle to an MSI controller
  288. *
  289. * - msi-base is an msi-specifier describing the msi-specifier produced for
  290. * the first RID matched by the entry.
  291. *
  292. * - length is a single cell describing how many consecutive RIDs are matched
  293. * following the rid-base.
  294. *
  295. * Any RID r in the interval [rid-base, rid-base + length) is associated with
  296. * the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
  297. *
  298. * msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
  299. * to an msi-specifier per the msi-map property.
  300. *
  301. * msi-parent: Describes the MSI parent of the root complex itself. Where
  302. * the root complex and MSI controller do not pass sideband data with MSI
  303. * writes, this property may be used to describe the MSI controller(s)
  304. * used by PCI devices under the root complex, if defined as such in the
  305. * binding for the root complex.
  306. *
  307. * / {
  308. * #address-cells = <1>;
  309. * #size-cells = <1>;
  310. *
  311. * msi_a: msi-controller@a {
  312. * reg = <0xa 0x1>;
  313. * msi-controller;
  314. * #msi-cells = <1>;
  315. * };
  316. *
  317. * msi_b: msi-controller@b {
  318. * reg = <0xb 0x1>;
  319. * msi-controller;
  320. * #msi-cells = <1>;
  321. * };
  322. *
  323. * msi_c: msi-controller@c {
  324. * reg = <0xc 0x1>;
  325. * msi-controller;
  326. * #msi-cells = <1>;
  327. * };
  328. *
  329. * Example (1)
  330. * ===========
  331. * pci: pci@f {
  332. * reg = <0xf 0x1>;
  333. * device_type = "pci";
  334. *
  335. * // The sideband data provided to the MSI controller is
  336. * // the RID, identity-mapped.
  337. * msi-map = <0x0 &msi_a 0x0 0x10000>;
  338. * };
  339. *
  340. * Example (2)
  341. * ===========
  342. * pci: pci@ff {
  343. * reg = <0xff 0x1>;
  344. * device_type = "pci";
  345. *
  346. * // The sideband data provided to the MSI controller is
  347. * // the RID, masked to only the device and function bits.
  348. * msi-map = <0x0 &msi_a 0x0 0x100>;
  349. * msi-map-mask = <0xff>
  350. * };
  351. *
  352. * Example (3)
  353. * ===========
  354. * pci: pci@fff {
  355. * reg = <0xfff 0x1>;
  356. * device_type = "pci";
  357. *
  358. * // The sideband data provided to the MSI controller is
  359. * // the RID, but the high bit of the bus number is ignored.
  360. * msi-map = <0x0000 &msi_a 0x0000 0x8000>,
  361. * <0x8000 &msi_a 0x0000 0x8000>;
  362. * };
  363. *
  364. * Example (4)
  365. * ===========
  366. * pci: pci@f {
  367. * reg = <0xf 0x1>;
  368. * device_type = "pci";
  369. *
  370. * // The sideband data provided to the MSI controller is
  371. * // the RID, but the high bit of the bus number is negated.
  372. * msi-map = <0x0000 &msi 0x8000 0x8000>,
  373. * <0x8000 &msi 0x0000 0x8000>;
  374. * };
  375. *
  376. * Example (5)
  377. * ===========
  378. * pci: pci@f {
  379. * reg = <0xf 0x1>;
  380. * device_type = "pci";
  381. *
  382. * // The sideband data provided to MSI controller a is the
  383. * // RID, but the high bit of the bus number is negated.
  384. * // The sideband data provided to MSI controller b is the
  385. * // RID, identity-mapped.
  386. * // MSI controller c is not addressable.
  387. * msi-map = <0x0000 &msi_a 0x8000 0x08000>,
  388. * <0x8000 &msi_a 0x0000 0x08000>,
  389. * <0x0000 &msi_b 0x0000 0x10000>;
  390. * };
  391. * };
  392. */
  393. static void ofw_msi_pic_init(struct rt_pci_device *pdev)
  394. {
  395. #ifdef RT_PCI_MSI
  396. rt_uint32_t rid;
  397. struct rt_pci_host_bridge *bridge;
  398. struct rt_ofw_node *np, *msi_ic_np = RT_NULL;
  399. /*
  400. * NOTE: Typically, a device's RID is equal to the PCI device's ID.
  401. * However, in complex bus management scenarios such as servers and PCs,
  402. * the RID needs to be associated with DMA. In these cases,
  403. * the RID should be equal to the DMA alias assigned to the
  404. * PCI device by the system bus.
  405. */
  406. rid = rt_pci_dev_id(pdev);
  407. bridge = rt_pci_find_host_bridge(pdev->bus);
  408. RT_ASSERT(bridge != RT_NULL);
  409. np = bridge->parent.ofw_node;
  410. if (!(msi_ic_np = rt_ofw_parse_phandle(np, "msi-parent", 0)))
  411. {
  412. rt_ofw_map_id(np, rid, "msi-map", "msi-map-mask", &msi_ic_np, RT_NULL);
  413. }
  414. if (!msi_ic_np)
  415. {
  416. LOG_W("%s: MSI PIC not found", rt_dm_dev_get_name(&pdev->parent));
  417. return;
  418. }
  419. pdev->msi_pic = rt_pic_dynamic_cast(rt_ofw_data(msi_ic_np));
  420. if (!pdev->msi_pic)
  421. {
  422. LOG_W("%s: '%s' not supported", rt_dm_dev_get_name(&pdev->parent), "msi-parent");
  423. goto _out_put_msi_parent_node;
  424. }
  425. if (!pdev->msi_pic->ops->irq_compose_msi_msg)
  426. {
  427. LOG_E("%s: MSI pic MUST implemented %s",
  428. rt_ofw_node_full_name(msi_ic_np), "irq_compose_msi_msg");
  429. RT_ASSERT(0);
  430. }
  431. if (!pdev->msi_pic->ops->irq_alloc_msi)
  432. {
  433. LOG_E("%s: MSI pic MUST implemented %s",
  434. rt_ofw_node_full_name(msi_ic_np), "irq_alloc_msi");
  435. RT_ASSERT(0);
  436. }
  437. if (!pdev->msi_pic->ops->irq_free_msi)
  438. {
  439. LOG_E("%s: MSI pic MUST implemented %s",
  440. rt_ofw_node_full_name(msi_ic_np), "irq_free_msi");
  441. RT_ASSERT(0);
  442. }
  443. _out_put_msi_parent_node:
  444. rt_ofw_node_put(msi_ic_np);
  445. #endif
  446. }
  447. static rt_int32_t ofw_pci_devfn(struct rt_ofw_node *np)
  448. {
  449. rt_int32_t res;
  450. rt_uint32_t reg[5];
  451. res = rt_ofw_prop_read_u32_array_index(np, "reg", 0, RT_ARRAY_SIZE(reg), reg);
  452. return res > 0 ? ((reg[0] >> 8) & 0xff) : res;
  453. }
  454. static struct rt_ofw_node *ofw_find_device(struct rt_ofw_node *np, rt_uint32_t devfn)
  455. {
  456. struct rt_ofw_node *dev_np, *mfd_np;
  457. rt_ofw_foreach_child_node(np, dev_np)
  458. {
  459. if (ofw_pci_devfn(dev_np) == devfn)
  460. {
  461. return dev_np;
  462. }
  463. if (rt_ofw_node_tag_equ(dev_np, "multifunc-device"))
  464. {
  465. rt_ofw_foreach_child_node(dev_np, mfd_np)
  466. {
  467. if (ofw_pci_devfn(mfd_np) == devfn)
  468. {
  469. rt_ofw_node_put(dev_np);
  470. return mfd_np;
  471. }
  472. }
  473. }
  474. }
  475. return RT_NULL;
  476. }
  477. rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev)
  478. {
  479. struct rt_ofw_node *np = RT_NULL;
  480. if (!pdev)
  481. {
  482. return -RT_EINVAL;
  483. }
  484. ofw_msi_pic_init(pdev);
  485. if (rt_pci_is_root_bus(pdev->bus) || !pdev->bus->self)
  486. {
  487. struct rt_pci_host_bridge *host_bridge;
  488. host_bridge = rt_pci_find_host_bridge(pdev->bus);
  489. RT_ASSERT(host_bridge != RT_NULL);
  490. np = host_bridge->parent.ofw_node;
  491. }
  492. else
  493. {
  494. np = pdev->bus->self->parent.ofw_node;
  495. }
  496. if (np)
  497. {
  498. pdev->parent.ofw_node = ofw_find_device(np, pdev->devfn);
  499. }
  500. return RT_EOK;
  501. }
  502. rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev)
  503. {
  504. if (!pdev)
  505. {
  506. return -RT_EINVAL;
  507. }
  508. rt_ofw_node_put(pdev->parent.ofw_node);
  509. return RT_EOK;
  510. }