pci.c 21 KB

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