pci.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4. * Andreas Heppel <aheppel@sysgo.de>
  5. *
  6. * (C) Copyright 2002
  7. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  8. * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
  9. */
  10. /*
  11. * PCI routines
  12. */
  13. #include <common.h>
  14. #include <bootretry.h>
  15. #include <cli.h>
  16. #include <command.h>
  17. #include <console.h>
  18. #include <dm.h>
  19. #include <asm/processor.h>
  20. #include <asm/io.h>
  21. #include <pci.h>
  22. struct pci_reg_info {
  23. const char *name;
  24. enum pci_size_t size;
  25. u8 offset;
  26. };
  27. static int pci_byte_size(enum pci_size_t size)
  28. {
  29. switch (size) {
  30. case PCI_SIZE_8:
  31. return 1;
  32. case PCI_SIZE_16:
  33. return 2;
  34. case PCI_SIZE_32:
  35. default:
  36. return 4;
  37. }
  38. }
  39. static int pci_field_width(enum pci_size_t size)
  40. {
  41. return pci_byte_size(size) * 2;
  42. }
  43. #ifdef CONFIG_DM_PCI
  44. static void pci_show_regs(struct udevice *dev, struct pci_reg_info *regs)
  45. {
  46. for (; regs->name; regs++) {
  47. unsigned long val;
  48. dm_pci_read_config(dev, regs->offset, &val, regs->size);
  49. printf(" %s =%*s%#.*lx\n", regs->name,
  50. (int)(28 - strlen(regs->name)), "",
  51. pci_field_width(regs->size), val);
  52. }
  53. }
  54. #else
  55. static unsigned long pci_read_config(pci_dev_t dev, int offset,
  56. enum pci_size_t size)
  57. {
  58. u32 val32;
  59. u16 val16;
  60. u8 val8;
  61. switch (size) {
  62. case PCI_SIZE_8:
  63. pci_read_config_byte(dev, offset, &val8);
  64. return val8;
  65. case PCI_SIZE_16:
  66. pci_read_config_word(dev, offset, &val16);
  67. return val16;
  68. case PCI_SIZE_32:
  69. default:
  70. pci_read_config_dword(dev, offset, &val32);
  71. return val32;
  72. }
  73. }
  74. static void pci_show_regs(pci_dev_t dev, struct pci_reg_info *regs)
  75. {
  76. for (; regs->name; regs++) {
  77. printf(" %s =%*s%#.*lx\n", regs->name,
  78. (int)(28 - strlen(regs->name)), "",
  79. pci_field_width(regs->size),
  80. pci_read_config(dev, regs->offset, regs->size));
  81. }
  82. }
  83. #endif
  84. #ifdef CONFIG_DM_PCI
  85. int pci_bar_show(struct udevice *dev)
  86. {
  87. u8 header_type;
  88. int bar_cnt, bar_id, mem_type;
  89. bool is_64, is_io;
  90. u32 base_low, base_high;
  91. u32 size_low, size_high;
  92. u64 base, size;
  93. u32 reg_addr;
  94. int prefetchable;
  95. dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
  96. if (header_type == PCI_HEADER_TYPE_CARDBUS) {
  97. printf("CardBus doesn't support BARs\n");
  98. return -ENOSYS;
  99. }
  100. bar_cnt = (header_type == PCI_HEADER_TYPE_NORMAL) ? 6 : 2;
  101. printf("ID Base Size Width Type\n");
  102. printf("----------------------------------------------------------\n");
  103. bar_id = 0;
  104. reg_addr = PCI_BASE_ADDRESS_0;
  105. while (bar_cnt) {
  106. dm_pci_read_config32(dev, reg_addr, &base_low);
  107. dm_pci_write_config32(dev, reg_addr, 0xffffffff);
  108. dm_pci_read_config32(dev, reg_addr, &size_low);
  109. dm_pci_write_config32(dev, reg_addr, base_low);
  110. reg_addr += 4;
  111. base = base_low & ~0xf;
  112. size = size_low & ~0xf;
  113. base_high = 0x0;
  114. size_high = 0xffffffff;
  115. is_64 = 0;
  116. prefetchable = base_low & PCI_BASE_ADDRESS_MEM_PREFETCH;
  117. is_io = base_low & PCI_BASE_ADDRESS_SPACE_IO;
  118. mem_type = base_low & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
  119. if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
  120. dm_pci_read_config32(dev, reg_addr, &base_high);
  121. dm_pci_write_config32(dev, reg_addr, 0xffffffff);
  122. dm_pci_read_config32(dev, reg_addr, &size_high);
  123. dm_pci_write_config32(dev, reg_addr, base_high);
  124. bar_cnt--;
  125. reg_addr += 4;
  126. is_64 = 1;
  127. }
  128. base = base | ((u64)base_high << 32);
  129. size = size | ((u64)size_high << 32);
  130. if ((!is_64 && size_low) || (is_64 && size)) {
  131. size = ~size + 1;
  132. printf(" %d %#018llx %#018llx %d %s %s\n",
  133. bar_id, (unsigned long long)base,
  134. (unsigned long long)size, is_64 ? 64 : 32,
  135. is_io ? "I/O" : "MEM",
  136. prefetchable ? "Prefetchable" : "");
  137. }
  138. bar_id++;
  139. bar_cnt--;
  140. }
  141. return 0;
  142. }
  143. #endif
  144. static struct pci_reg_info regs_start[] = {
  145. { "vendor ID", PCI_SIZE_16, PCI_VENDOR_ID },
  146. { "device ID", PCI_SIZE_16, PCI_DEVICE_ID },
  147. { "command register ID", PCI_SIZE_16, PCI_COMMAND },
  148. { "status register", PCI_SIZE_16, PCI_STATUS },
  149. { "revision ID", PCI_SIZE_8, PCI_REVISION_ID },
  150. {},
  151. };
  152. static struct pci_reg_info regs_rest[] = {
  153. { "sub class code", PCI_SIZE_8, PCI_CLASS_SUB_CODE },
  154. { "programming interface", PCI_SIZE_8, PCI_CLASS_PROG },
  155. { "cache line", PCI_SIZE_8, PCI_CACHE_LINE_SIZE },
  156. { "latency time", PCI_SIZE_8, PCI_LATENCY_TIMER },
  157. { "header type", PCI_SIZE_8, PCI_HEADER_TYPE },
  158. { "BIST", PCI_SIZE_8, PCI_BIST },
  159. { "base address 0", PCI_SIZE_32, PCI_BASE_ADDRESS_0 },
  160. {},
  161. };
  162. static struct pci_reg_info regs_normal[] = {
  163. { "base address 1", PCI_SIZE_32, PCI_BASE_ADDRESS_1 },
  164. { "base address 2", PCI_SIZE_32, PCI_BASE_ADDRESS_2 },
  165. { "base address 3", PCI_SIZE_32, PCI_BASE_ADDRESS_3 },
  166. { "base address 4", PCI_SIZE_32, PCI_BASE_ADDRESS_4 },
  167. { "base address 5", PCI_SIZE_32, PCI_BASE_ADDRESS_5 },
  168. { "cardBus CIS pointer", PCI_SIZE_32, PCI_CARDBUS_CIS },
  169. { "sub system vendor ID", PCI_SIZE_16, PCI_SUBSYSTEM_VENDOR_ID },
  170. { "sub system ID", PCI_SIZE_16, PCI_SUBSYSTEM_ID },
  171. { "expansion ROM base address", PCI_SIZE_32, PCI_ROM_ADDRESS },
  172. { "interrupt line", PCI_SIZE_8, PCI_INTERRUPT_LINE },
  173. { "interrupt pin", PCI_SIZE_8, PCI_INTERRUPT_PIN },
  174. { "min Grant", PCI_SIZE_8, PCI_MIN_GNT },
  175. { "max Latency", PCI_SIZE_8, PCI_MAX_LAT },
  176. {},
  177. };
  178. static struct pci_reg_info regs_bridge[] = {
  179. { "base address 1", PCI_SIZE_32, PCI_BASE_ADDRESS_1 },
  180. { "primary bus number", PCI_SIZE_8, PCI_PRIMARY_BUS },
  181. { "secondary bus number", PCI_SIZE_8, PCI_SECONDARY_BUS },
  182. { "subordinate bus number", PCI_SIZE_8, PCI_SUBORDINATE_BUS },
  183. { "secondary latency timer", PCI_SIZE_8, PCI_SEC_LATENCY_TIMER },
  184. { "IO base", PCI_SIZE_8, PCI_IO_BASE },
  185. { "IO limit", PCI_SIZE_8, PCI_IO_LIMIT },
  186. { "secondary status", PCI_SIZE_16, PCI_SEC_STATUS },
  187. { "memory base", PCI_SIZE_16, PCI_MEMORY_BASE },
  188. { "memory limit", PCI_SIZE_16, PCI_MEMORY_LIMIT },
  189. { "prefetch memory base", PCI_SIZE_16, PCI_PREF_MEMORY_BASE },
  190. { "prefetch memory limit", PCI_SIZE_16, PCI_PREF_MEMORY_LIMIT },
  191. { "prefetch memory base upper", PCI_SIZE_32, PCI_PREF_BASE_UPPER32 },
  192. { "prefetch memory limit upper", PCI_SIZE_32, PCI_PREF_LIMIT_UPPER32 },
  193. { "IO base upper 16 bits", PCI_SIZE_16, PCI_IO_BASE_UPPER16 },
  194. { "IO limit upper 16 bits", PCI_SIZE_16, PCI_IO_LIMIT_UPPER16 },
  195. { "expansion ROM base address", PCI_SIZE_32, PCI_ROM_ADDRESS1 },
  196. { "interrupt line", PCI_SIZE_8, PCI_INTERRUPT_LINE },
  197. { "interrupt pin", PCI_SIZE_8, PCI_INTERRUPT_PIN },
  198. { "bridge control", PCI_SIZE_16, PCI_BRIDGE_CONTROL },
  199. {},
  200. };
  201. static struct pci_reg_info regs_cardbus[] = {
  202. { "capabilities", PCI_SIZE_8, PCI_CB_CAPABILITY_LIST },
  203. { "secondary status", PCI_SIZE_16, PCI_CB_SEC_STATUS },
  204. { "primary bus number", PCI_SIZE_8, PCI_CB_PRIMARY_BUS },
  205. { "CardBus number", PCI_SIZE_8, PCI_CB_CARD_BUS },
  206. { "subordinate bus number", PCI_SIZE_8, PCI_CB_SUBORDINATE_BUS },
  207. { "CardBus latency timer", PCI_SIZE_8, PCI_CB_LATENCY_TIMER },
  208. { "CardBus memory base 0", PCI_SIZE_32, PCI_CB_MEMORY_BASE_0 },
  209. { "CardBus memory limit 0", PCI_SIZE_32, PCI_CB_MEMORY_LIMIT_0 },
  210. { "CardBus memory base 1", PCI_SIZE_32, PCI_CB_MEMORY_BASE_1 },
  211. { "CardBus memory limit 1", PCI_SIZE_32, PCI_CB_MEMORY_LIMIT_1 },
  212. { "CardBus IO base 0", PCI_SIZE_16, PCI_CB_IO_BASE_0 },
  213. { "CardBus IO base high 0", PCI_SIZE_16, PCI_CB_IO_BASE_0_HI },
  214. { "CardBus IO limit 0", PCI_SIZE_16, PCI_CB_IO_LIMIT_0 },
  215. { "CardBus IO limit high 0", PCI_SIZE_16, PCI_CB_IO_LIMIT_0_HI },
  216. { "CardBus IO base 1", PCI_SIZE_16, PCI_CB_IO_BASE_1 },
  217. { "CardBus IO base high 1", PCI_SIZE_16, PCI_CB_IO_BASE_1_HI },
  218. { "CardBus IO limit 1", PCI_SIZE_16, PCI_CB_IO_LIMIT_1 },
  219. { "CardBus IO limit high 1", PCI_SIZE_16, PCI_CB_IO_LIMIT_1_HI },
  220. { "interrupt line", PCI_SIZE_8, PCI_INTERRUPT_LINE },
  221. { "interrupt pin", PCI_SIZE_8, PCI_INTERRUPT_PIN },
  222. { "bridge control", PCI_SIZE_16, PCI_CB_BRIDGE_CONTROL },
  223. { "subvendor ID", PCI_SIZE_16, PCI_CB_SUBSYSTEM_VENDOR_ID },
  224. { "subdevice ID", PCI_SIZE_16, PCI_CB_SUBSYSTEM_ID },
  225. { "PC Card 16bit base address", PCI_SIZE_32, PCI_CB_LEGACY_MODE_BASE },
  226. {},
  227. };
  228. /**
  229. * pci_header_show() - Show the header of the specified PCI device.
  230. *
  231. * @dev: Bus+Device+Function number
  232. */
  233. #ifdef CONFIG_DM_PCI
  234. void pci_header_show(struct udevice *dev)
  235. #else
  236. void pci_header_show(pci_dev_t dev)
  237. #endif
  238. {
  239. #ifdef CONFIG_DM_PCI
  240. unsigned long class, header_type;
  241. dm_pci_read_config(dev, PCI_CLASS_CODE, &class, PCI_SIZE_8);
  242. dm_pci_read_config(dev, PCI_HEADER_TYPE, &header_type, PCI_SIZE_8);
  243. #else
  244. u8 class, header_type;
  245. pci_read_config_byte(dev, PCI_CLASS_CODE, &class);
  246. pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
  247. #endif
  248. pci_show_regs(dev, regs_start);
  249. printf(" class code = 0x%.2x (%s)\n", (int)class,
  250. pci_class_str(class));
  251. pci_show_regs(dev, regs_rest);
  252. switch (header_type & 0x03) {
  253. case PCI_HEADER_TYPE_NORMAL: /* "normal" PCI device */
  254. pci_show_regs(dev, regs_normal);
  255. break;
  256. case PCI_HEADER_TYPE_BRIDGE: /* PCI-to-PCI bridge */
  257. pci_show_regs(dev, regs_bridge);
  258. break;
  259. case PCI_HEADER_TYPE_CARDBUS: /* PCI-to-CardBus bridge */
  260. pci_show_regs(dev, regs_cardbus);
  261. break;
  262. default:
  263. printf("unknown header\n");
  264. break;
  265. }
  266. }
  267. void pciinfo_header(int busnum, bool short_listing)
  268. {
  269. printf("Scanning PCI devices on bus %d\n", busnum);
  270. if (short_listing) {
  271. printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n");
  272. printf("_____________________________________________________________\n");
  273. }
  274. }
  275. #ifdef CONFIG_DM_PCI
  276. /**
  277. * pci_header_show_brief() - Show the short-form PCI device header
  278. *
  279. * Reads and prints the header of the specified PCI device in short form.
  280. *
  281. * @dev: PCI device to show
  282. */
  283. static void pci_header_show_brief(struct udevice *dev)
  284. {
  285. ulong vendor, device;
  286. ulong class, subclass;
  287. dm_pci_read_config(dev, PCI_VENDOR_ID, &vendor, PCI_SIZE_16);
  288. dm_pci_read_config(dev, PCI_DEVICE_ID, &device, PCI_SIZE_16);
  289. dm_pci_read_config(dev, PCI_CLASS_CODE, &class, PCI_SIZE_8);
  290. dm_pci_read_config(dev, PCI_CLASS_SUB_CODE, &subclass, PCI_SIZE_8);
  291. printf("0x%.4lx 0x%.4lx %-23s 0x%.2lx\n",
  292. vendor, device,
  293. pci_class_str(class), subclass);
  294. }
  295. static void pciinfo(struct udevice *bus, bool short_listing)
  296. {
  297. struct udevice *dev;
  298. pciinfo_header(bus->seq, short_listing);
  299. for (device_find_first_child(bus, &dev);
  300. dev;
  301. device_find_next_child(&dev)) {
  302. struct pci_child_platdata *pplat;
  303. pplat = dev_get_parent_platdata(dev);
  304. if (short_listing) {
  305. printf("%02x.%02x.%02x ", bus->seq,
  306. PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
  307. pci_header_show_brief(dev);
  308. } else {
  309. printf("\nFound PCI device %02x.%02x.%02x:\n", bus->seq,
  310. PCI_DEV(pplat->devfn), PCI_FUNC(pplat->devfn));
  311. pci_header_show(dev);
  312. }
  313. }
  314. }
  315. #else
  316. /**
  317. * pci_header_show_brief() - Show the short-form PCI device header
  318. *
  319. * Reads and prints the header of the specified PCI device in short form.
  320. *
  321. * @dev: Bus+Device+Function number
  322. */
  323. void pci_header_show_brief(pci_dev_t dev)
  324. {
  325. u16 vendor, device;
  326. u8 class, subclass;
  327. pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
  328. pci_read_config_word(dev, PCI_DEVICE_ID, &device);
  329. pci_read_config_byte(dev, PCI_CLASS_CODE, &class);
  330. pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &subclass);
  331. printf("0x%.4x 0x%.4x %-23s 0x%.2x\n",
  332. vendor, device,
  333. pci_class_str(class), subclass);
  334. }
  335. /**
  336. * pciinfo() - Show a list of devices on the PCI bus
  337. *
  338. * Show information about devices on PCI bus. Depending on @short_pci_listing
  339. * the output will be more or less exhaustive.
  340. *
  341. * @bus_num: The number of the bus to be scanned
  342. * @short_pci_listing: true to use short form, showing only a brief header
  343. * for each device
  344. */
  345. void pciinfo(int bus_num, int short_pci_listing)
  346. {
  347. struct pci_controller *hose = pci_bus_to_hose(bus_num);
  348. int device;
  349. int function;
  350. unsigned char header_type;
  351. unsigned short vendor_id;
  352. pci_dev_t dev;
  353. int ret;
  354. if (!hose)
  355. return;
  356. pciinfo_header(bus_num, short_pci_listing);
  357. for (device = 0; device < PCI_MAX_PCI_DEVICES; device++) {
  358. header_type = 0;
  359. vendor_id = 0;
  360. for (function = 0; function < PCI_MAX_PCI_FUNCTIONS;
  361. function++) {
  362. /*
  363. * If this is not a multi-function device, we skip
  364. * the rest.
  365. */
  366. if (function && !(header_type & 0x80))
  367. break;
  368. dev = PCI_BDF(bus_num, device, function);
  369. if (pci_skip_dev(hose, dev))
  370. continue;
  371. ret = pci_read_config_word(dev, PCI_VENDOR_ID,
  372. &vendor_id);
  373. if (ret)
  374. goto error;
  375. if ((vendor_id == 0xFFFF) || (vendor_id == 0x0000))
  376. continue;
  377. if (!function) {
  378. pci_read_config_byte(dev, PCI_HEADER_TYPE,
  379. &header_type);
  380. }
  381. if (short_pci_listing) {
  382. printf("%02x.%02x.%02x ", bus_num, device,
  383. function);
  384. pci_header_show_brief(dev);
  385. } else {
  386. printf("\nFound PCI device %02x.%02x.%02x:\n",
  387. bus_num, device, function);
  388. pci_header_show(dev);
  389. }
  390. }
  391. }
  392. return;
  393. error:
  394. printf("Cannot read bus configuration: %d\n", ret);
  395. }
  396. #endif
  397. /**
  398. * get_pci_dev() - Convert the "bus.device.function" identifier into a number
  399. *
  400. * @name: Device string in the form "bus.device.function" where each is in hex
  401. * @return encoded pci_dev_t or -1 if the string was invalid
  402. */
  403. static pci_dev_t get_pci_dev(char *name)
  404. {
  405. char cnum[12];
  406. int len, i, iold, n;
  407. int bdfs[3] = {0,0,0};
  408. len = strlen(name);
  409. if (len > 8)
  410. return -1;
  411. for (i = 0, iold = 0, n = 0; i < len; i++) {
  412. if (name[i] == '.') {
  413. memcpy(cnum, &name[iold], i - iold);
  414. cnum[i - iold] = '\0';
  415. bdfs[n++] = simple_strtoul(cnum, NULL, 16);
  416. iold = i + 1;
  417. }
  418. }
  419. strcpy(cnum, &name[iold]);
  420. if (n == 0)
  421. n = 1;
  422. bdfs[n] = simple_strtoul(cnum, NULL, 16);
  423. return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]);
  424. }
  425. #ifdef CONFIG_DM_PCI
  426. static int pci_cfg_display(struct udevice *dev, ulong addr,
  427. enum pci_size_t size, ulong length)
  428. #else
  429. static int pci_cfg_display(pci_dev_t bdf, ulong addr, enum pci_size_t size,
  430. ulong length)
  431. #endif
  432. {
  433. #define DISP_LINE_LEN 16
  434. ulong i, nbytes, linebytes;
  435. int byte_size;
  436. int rc = 0;
  437. byte_size = pci_byte_size(size);
  438. if (length == 0)
  439. length = 0x40 / byte_size; /* Standard PCI config space */
  440. /* Print the lines.
  441. * once, and all accesses are with the specified bus width.
  442. */
  443. nbytes = length * byte_size;
  444. do {
  445. printf("%08lx:", addr);
  446. linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
  447. for (i = 0; i < linebytes; i += byte_size) {
  448. unsigned long val;
  449. #ifdef CONFIG_DM_PCI
  450. dm_pci_read_config(dev, addr, &val, size);
  451. #else
  452. val = pci_read_config(bdf, addr, size);
  453. #endif
  454. printf(" %0*lx", pci_field_width(size), val);
  455. addr += byte_size;
  456. }
  457. printf("\n");
  458. nbytes -= linebytes;
  459. if (ctrlc()) {
  460. rc = 1;
  461. break;
  462. }
  463. } while (nbytes > 0);
  464. return (rc);
  465. }
  466. #ifndef CONFIG_DM_PCI
  467. static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value)
  468. {
  469. if (size == 4) {
  470. pci_write_config_dword(bdf, addr, value);
  471. }
  472. else if (size == 2) {
  473. ushort val = value & 0xffff;
  474. pci_write_config_word(bdf, addr, val);
  475. }
  476. else {
  477. u_char val = value & 0xff;
  478. pci_write_config_byte(bdf, addr, val);
  479. }
  480. return 0;
  481. }
  482. #endif
  483. #ifdef CONFIG_DM_PCI
  484. static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
  485. ulong value, int incrflag)
  486. #else
  487. static int pci_cfg_modify(pci_dev_t bdf, ulong addr, ulong size, ulong value,
  488. int incrflag)
  489. #endif
  490. {
  491. ulong i;
  492. int nbytes;
  493. ulong val;
  494. /* Print the address, followed by value. Then accept input for
  495. * the next value. A non-converted value exits.
  496. */
  497. do {
  498. printf("%08lx:", addr);
  499. #ifdef CONFIG_DM_PCI
  500. dm_pci_read_config(dev, addr, &val, size);
  501. #else
  502. val = pci_read_config(bdf, addr, size);
  503. #endif
  504. printf(" %0*lx", pci_field_width(size), val);
  505. nbytes = cli_readline(" ? ");
  506. if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
  507. /* <CR> pressed as only input, don't modify current
  508. * location and move to next. "-" pressed will go back.
  509. */
  510. if (incrflag)
  511. addr += nbytes ? -size : size;
  512. nbytes = 1;
  513. /* good enough to not time out */
  514. bootretry_reset_cmd_timeout();
  515. }
  516. #ifdef CONFIG_BOOT_RETRY_TIME
  517. else if (nbytes == -2) {
  518. break; /* timed out, exit the command */
  519. }
  520. #endif
  521. else {
  522. char *endp;
  523. i = simple_strtoul(console_buffer, &endp, 16);
  524. nbytes = endp - console_buffer;
  525. if (nbytes) {
  526. /* good enough to not time out
  527. */
  528. bootretry_reset_cmd_timeout();
  529. #ifdef CONFIG_DM_PCI
  530. dm_pci_write_config(dev, addr, i, size);
  531. #else
  532. pci_cfg_write(bdf, addr, size, i);
  533. #endif
  534. if (incrflag)
  535. addr += size;
  536. }
  537. }
  538. } while (nbytes);
  539. return 0;
  540. }
  541. #ifdef CONFIG_DM_PCI
  542. static const struct pci_flag_info {
  543. uint flag;
  544. const char *name;
  545. } pci_flag_info[] = {
  546. { PCI_REGION_IO, "io" },
  547. { PCI_REGION_PREFETCH, "prefetch" },
  548. { PCI_REGION_SYS_MEMORY, "sysmem" },
  549. { PCI_REGION_RO, "readonly" },
  550. { PCI_REGION_IO, "io" },
  551. };
  552. static void pci_show_regions(struct udevice *bus)
  553. {
  554. struct pci_controller *hose = dev_get_uclass_priv(bus);
  555. const struct pci_region *reg;
  556. int i, j;
  557. if (!hose) {
  558. printf("Bus '%s' is not a PCI controller\n", bus->name);
  559. return;
  560. }
  561. printf("# %-18s %-18s %-18s %s\n", "Bus start", "Phys start", "Size",
  562. "Flags");
  563. for (i = 0, reg = hose->regions; i < hose->region_count; i++, reg++) {
  564. printf("%d %#018llx %#018llx %#018llx ", i,
  565. (unsigned long long)reg->bus_start,
  566. (unsigned long long)reg->phys_start,
  567. (unsigned long long)reg->size);
  568. if (!(reg->flags & PCI_REGION_TYPE))
  569. printf("mem ");
  570. for (j = 0; j < ARRAY_SIZE(pci_flag_info); j++) {
  571. if (reg->flags & pci_flag_info[j].flag)
  572. printf("%s ", pci_flag_info[j].name);
  573. }
  574. printf("\n");
  575. }
  576. }
  577. #endif
  578. /* PCI Configuration Space access commands
  579. *
  580. * Syntax:
  581. * pci display[.b, .w, .l] bus.device.function} [addr] [len]
  582. * pci next[.b, .w, .l] bus.device.function [addr]
  583. * pci modify[.b, .w, .l] bus.device.function [addr]
  584. * pci write[.b, .w, .l] bus.device.function addr value
  585. */
  586. static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  587. {
  588. ulong addr = 0, value = 0, cmd_size = 0;
  589. enum pci_size_t size = PCI_SIZE_32;
  590. #ifdef CONFIG_DM_PCI
  591. struct udevice *dev, *bus;
  592. #else
  593. pci_dev_t dev;
  594. #endif
  595. int busnum = 0;
  596. pci_dev_t bdf = 0;
  597. char cmd = 's';
  598. int ret = 0;
  599. if (argc > 1)
  600. cmd = argv[1][0];
  601. switch (cmd) {
  602. case 'd': /* display */
  603. case 'n': /* next */
  604. case 'm': /* modify */
  605. case 'w': /* write */
  606. /* Check for a size specification. */
  607. cmd_size = cmd_get_data_size(argv[1], 4);
  608. size = (cmd_size == 4) ? PCI_SIZE_32 : cmd_size - 1;
  609. if (argc > 3)
  610. addr = simple_strtoul(argv[3], NULL, 16);
  611. if (argc > 4)
  612. value = simple_strtoul(argv[4], NULL, 16);
  613. case 'h': /* header */
  614. #ifdef CONFIG_DM_PCI
  615. case 'b': /* bars */
  616. #endif
  617. if (argc < 3)
  618. goto usage;
  619. if ((bdf = get_pci_dev(argv[2])) == -1)
  620. return 1;
  621. break;
  622. #if defined(CONFIG_DM_PCI)
  623. case 'e':
  624. pci_init();
  625. return 0;
  626. #endif
  627. case 'r': /* no break */
  628. default: /* scan bus */
  629. value = 1; /* short listing */
  630. if (argc > 1) {
  631. if (cmd != 'r' && argv[argc-1][0] == 'l') {
  632. value = 0;
  633. argc--;
  634. }
  635. if (argc > 1)
  636. busnum = simple_strtoul(argv[1], NULL, 16);
  637. }
  638. #ifdef CONFIG_DM_PCI
  639. ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
  640. if (ret) {
  641. printf("No such bus\n");
  642. return CMD_RET_FAILURE;
  643. }
  644. if (cmd == 'r')
  645. pci_show_regions(bus);
  646. else
  647. pciinfo(bus, value);
  648. #else
  649. pciinfo(busnum, value);
  650. #endif
  651. return 0;
  652. }
  653. #ifdef CONFIG_DM_PCI
  654. ret = dm_pci_bus_find_bdf(bdf, &dev);
  655. if (ret) {
  656. printf("No such device\n");
  657. return CMD_RET_FAILURE;
  658. }
  659. #else
  660. dev = bdf;
  661. #endif
  662. switch (argv[1][0]) {
  663. case 'h': /* header */
  664. pci_header_show(dev);
  665. break;
  666. case 'd': /* display */
  667. return pci_cfg_display(dev, addr, size, value);
  668. case 'n': /* next */
  669. if (argc < 4)
  670. goto usage;
  671. ret = pci_cfg_modify(dev, addr, size, value, 0);
  672. break;
  673. case 'm': /* modify */
  674. if (argc < 4)
  675. goto usage;
  676. ret = pci_cfg_modify(dev, addr, size, value, 1);
  677. break;
  678. case 'w': /* write */
  679. if (argc < 5)
  680. goto usage;
  681. #ifdef CONFIG_DM_PCI
  682. ret = dm_pci_write_config(dev, addr, value, size);
  683. #else
  684. ret = pci_cfg_write(dev, addr, size, value);
  685. #endif
  686. break;
  687. #ifdef CONFIG_DM_PCI
  688. case 'b': /* bars */
  689. return pci_bar_show(dev);
  690. #endif
  691. default:
  692. ret = CMD_RET_USAGE;
  693. break;
  694. }
  695. return ret;
  696. usage:
  697. return CMD_RET_USAGE;
  698. }
  699. /***************************************************/
  700. #ifdef CONFIG_SYS_LONGHELP
  701. static char pci_help_text[] =
  702. "[bus] [long]\n"
  703. " - short or long list of PCI devices on bus 'bus'\n"
  704. #if defined(CONFIG_DM_PCI)
  705. "pci enum\n"
  706. " - Enumerate PCI buses\n"
  707. #endif
  708. "pci header b.d.f\n"
  709. " - show header of PCI device 'bus.device.function'\n"
  710. #ifdef CONFIG_DM_PCI
  711. "pci bar b.d.f\n"
  712. " - show BARs base and size for device b.d.f'\n"
  713. "pci regions\n"
  714. " - show PCI regions\n"
  715. #endif
  716. "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n"
  717. " - display PCI configuration space (CFG)\n"
  718. "pci next[.b, .w, .l] b.d.f address\n"
  719. " - modify, read and keep CFG address\n"
  720. "pci modify[.b, .w, .l] b.d.f address\n"
  721. " - modify, auto increment CFG address\n"
  722. "pci write[.b, .w, .l] b.d.f address value\n"
  723. " - write to CFG address";
  724. #endif
  725. U_BOOT_CMD(
  726. pci, 5, 1, do_pci,
  727. "list and access PCI Configuration Space", pci_help_text
  728. );