diff options
author | Simon Glass <sjg@chromium.org> | 2017-04-08 19:10:06 (GMT) |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-04-13 13:41:08 (GMT) |
commit | b997a73ee63170579c3708a765d234f17f8effac (patch) | |
tree | 217cc59d831b8f556e215f48760ca552ba4707e7 | |
parent | b2aa88941110868485d38719d119ab79ef9cddfe (diff) | |
download | u-boot-b997a73ee63170579c3708a765d234f17f8effac.tar.xz |
pci: Add a command to show PCI regions
Add 'pci regions' which lists the I/O and memory regions accessible from
the PCI controller.
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | cmd/pci.c | 51 |
1 files changed, 49 insertions, 2 deletions
@@ -606,6 +606,47 @@ static int pci_cfg_modify(pci_dev_t bdf, ulong addr, ulong size, ulong value, return 0; } +#ifdef CONFIG_DM_PCI +static const struct pci_flag_info { + uint flag; + const char *name; +} pci_flag_info[] = { + { PCI_REGION_IO, "io" }, + { PCI_REGION_PREFETCH, "prefetch" }, + { PCI_REGION_SYS_MEMORY, "sysmem" }, + { PCI_REGION_RO, "readonly" }, + { PCI_REGION_IO, "io" }, +}; + +static void pci_show_regions(struct udevice *bus) +{ + struct pci_controller *hose = dev_get_uclass_priv(bus); + const struct pci_region *reg; + int i, j; + + if (!hose) { + printf("Bus '%s' is not a PCI controller\n", bus->name); + return; + } + + printf("# %-16s %-16s %-16s %s\n", "Bus start", "Phys start", "Size", + "Flags"); + for (i = 0, reg = hose->regions; i < hose->region_count; i++, reg++) { + printf("%d %#016llx %#016llx %#016llx ", i, + (unsigned long long)reg->bus_start, + (unsigned long long)reg->phys_start, + (unsigned long long)reg->size); + if (!(reg->flags & PCI_REGION_TYPE)) + printf("mem "); + for (j = 0; j < ARRAY_SIZE(pci_flag_info); j++) { + if (reg->flags & pci_flag_info[j].flag) + printf("%s ", pci_flag_info[j].name); + } + printf("\n"); + } +} +#endif + /* PCI Configuration Space access commands * * Syntax: @@ -657,10 +698,11 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) pci_init(); return 0; #endif + case 'r': /* no break */ default: /* scan bus */ value = 1; /* short listing */ if (argc > 1) { - if (argv[argc-1][0] == 'l') { + if (cmd != 'r' && argv[argc-1][0] == 'l') { value = 0; argc--; } @@ -673,7 +715,10 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("No such bus\n"); return CMD_RET_FAILURE; } - pciinfo(bus, value); + if (cmd == 'r') + pci_show_regions(bus); + else + pciinfo(bus, value); #else pciinfo(busnum, value); #endif @@ -745,6 +790,8 @@ static char pci_help_text[] = #ifdef CONFIG_DM_PCI "pci bar b.d.f\n" " - show BARs base and size for device b.d.f'\n" + "pci regions\n" + " - show PCI regions\n" #endif "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n" " - display PCI configuration space (CFG)\n" |