diff --git a/ChangeLog b/ChangeLog index b81bf53cf..c041a685c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-12-22 Vladimir Serbinenko + + * commands/lspci.c (grub_pci_classes): Add "USB Controller". + (options): New variable. + (iospace): Likewise. + (grub_lspci_iter): List IO spaces if "-i" was given. + (grub_cmd_lspci): Parse options. + (GRUB_MOD_INIT(lspci)): Use extcmd. + (GRUB_MOD_FINI(lspci)): Likewise. + 2009-12-22 Felix Zielcke * util/grub.d/30_os-prober.in (osx_entry): Remove non POSIX compliant diff --git a/commands/lspci.c b/commands/lspci.c index 507355687..559bb8242 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include struct grub_pci_classname { @@ -84,6 +84,7 @@ static const struct grub_pci_classname grub_pci_classes[] = { 11, 0x30, "MIPS Processor" }, { 11, 0x40, "Co-Processor" }, { 11, 0x80, "Unknown Processor" }, + { 12, 3, "USB Controller" }, { 12, 0x80, "Serial Bus Controller" }, { 13, 0x80, "Wireless Controller" }, { 14, 0, "I2O" }, @@ -114,12 +115,21 @@ grub_pci_get_class (int class, int subclass) return 0; } +static const struct grub_arg_option options[] = + { + {"iospace", 'i', 0, "show I/O spaces", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static int iospace; + static int NESTED_FUNC_ATTR grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_uint32_t class; const char *sclass; grub_pci_address_t addr; + int reg; grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), @@ -143,27 +153,75 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) grub_printf ("\n"); + if (iospace) + { + reg = 4; + while (reg < 10) + { + grub_uint64_t space; + addr = grub_pci_make_address (dev, reg); + space = grub_pci_read (addr); + + reg++; + + if (space == 0) + continue; + + switch (space & GRUB_PCI_ADDR_SPACE_MASK) + { + case GRUB_PCI_ADDR_SPACE_IO: + grub_printf ("\tIO space %d at 0x%llx\n", (reg - 1) - 4, + (unsigned long long) + (space & GRUB_PCI_ADDR_IO_MASK)); + break; + case GRUB_PCI_ADDR_SPACE_MEMORY: + if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK) + == GRUB_PCI_ADDR_MEM_TYPE_64) + { + addr = grub_pci_make_address (dev, reg); + space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; + reg++; + grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", + (reg - 2) - 4, (unsigned long long) + (space & GRUB_PCI_ADDR_MEM_MASK), + space & GRUB_PCI_ADDR_MEM_PREFETCH + ? "prefetchable" : "non-prefetchable"); + + } + else + grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", + (reg - 1) - 4, (unsigned long long) + (space & GRUB_PCI_ADDR_MEM_MASK), + space & GRUB_PCI_ADDR_MEM_PREFETCH + ? "prefetchable" : "non-prefetchable"); + break; + } + } + } + + return 0; } static grub_err_t -grub_cmd_lspci (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_lspci (grub_extcmd_t cmd, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { + iospace = cmd->state[0].set; grub_pci_iterate (grub_lspci_iter); return GRUB_ERR_NONE; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(lspci) { - cmd = grub_register_command ("lspci", grub_cmd_lspci, - 0, "List PCI devices."); + cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH, + "lspci [-i]", "List PCI devices.", options); } GRUB_MOD_FINI(lspci) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); }