diff --git a/ChangeLog.pciclean b/ChangeLog.pciclean new file mode 100644 index 000000000..f50a48875 --- /dev/null +++ b/ChangeLog.pciclean @@ -0,0 +1,52 @@ +2009-12-22 Vladimir Serbinenko + + Byte-addressable PCI configuration space. + + * bus/pci.c (grub_pci_make_address): Use byte address instead of + dword address. + (grub_pci_iterate): Use macroses GRUB_PCI_REG_PCI_ID and + GRUB_PCI_REG_CACHELINE. + * bus/usb/ohci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG0. + * bus/usb/uhci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG4. + * commands/efi/fixvideo.c (scan_card): Use macros GRUB_PCI_REG_CLASS. + * commands/efi/loadbios.c (enable_rom_area): Pass byte-address to + grub_pci_make_address. + (lock_rom_area): Likewise. + * commands/lspci.c (grub_lspci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESSES. Handle byte-addressing + of grub_pci_make_address. + * disk/ata.c (grub_ata_pciinit): Likewise. + * include/grub/pci.h (GRUB_PCI_REG_PCI_ID): New macro. + (GRUB_PCI_REG_VENDOR): Likewise. + (GRUB_PCI_REG_DEVICE): Likewise. + (GRUB_PCI_REG_COMMAND): Likewise. + (GRUB_PCI_REG_STATUS): Likewise. + (GRUB_PCI_REG_REVISION): Likewise. + (GRUB_PCI_REG_CLASS): Likewise. + (GRUB_PCI_REG_CACHELINE): Likewise. + (GRUB_PCI_REG_LAT_TIMER): Likewise. + (GRUB_PCI_REG_HEADER_TYPE): Likewise. + (GRUB_PCI_REG_BIST): Likewise. + (GRUB_PCI_REG_ADDRESSES): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_CIS_POINTER): Likewise. + (GRUB_PCI_REG_SUBVENDOR): Likewise. + (GRUB_PCI_REG_SUBSYSTEM): Likewise. + (GRUB_PCI_REG_ROM_ADDRESS): Likewise. + (GRUB_PCI_REG_CAP_POINTER): Likewise. + (GRUB_PCI_REG_IRQ_LINE): Likewise. + (GRUB_PCI_REG_IRQ_PIN): Likewise. + (GRUB_PCI_REG_MIN_GNT): Likewise. + (GRUB_PCI_REG_MAX_LAT): Likewise. + * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. + * loader/i386/efi/xnu.c (find_framebuf): Likewise. + * video/efi_uga.c (find_framebuf): Likewise. + * util/pci.c (grub_pci_make_address): Use byte-addressed configuration + space. diff --git a/bus/pci.c b/bus/pci.c index fe4cad181..13b67c908 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -24,7 +24,7 @@ grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) { return (1 << 31) | (dev.bus << 16) | (dev.device << 11) - | (dev.function << 8) | (reg << 2); + | (dev.function << 8) | reg; } void @@ -41,7 +41,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) { for (dev.function = 0; dev.function < 8; dev.function++) { - addr = grub_pci_make_address (dev, 0); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID); id = grub_pci_read (addr); /* Check if there is a device present. */ @@ -54,7 +54,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) /* Probe only func = 0 if the device if not multifunction */ if (dev.function == 0) { - addr = grub_pci_make_address (dev, 3); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE); hdr = grub_pci_read (addr); if (!(hdr & 0x800000)) break; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 5fe9c9507..6d185bc7f 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -126,7 +126,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_uint32_t revision; grub_uint32_t frame_interval; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -138,7 +138,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 4); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); base = grub_pci_read (addr); #if 0 diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index e83fccc1d..947f2367b 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -150,7 +150,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, struct grub_uhci *u; int i; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -162,7 +162,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 8); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4); base = grub_pci_read (addr); /* Stop if there is no IO space base address defined. */ if (! (base & 1)) diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c index 685662237..dea69c8b1 100644 --- a/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -42,7 +42,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index d7ad42690..183ba7e85 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -50,7 +50,7 @@ enable_rom_area (void) return 0; } - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); grub_pci_write_byte (addr++, 0x33); @@ -76,7 +76,7 @@ lock_rom_area (void) grub_pci_address_t addr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); grub_pci_write_byte (addr++, 0x11); diff --git a/commands/lspci.c b/commands/lspci.c index 559bb8242..c515da762 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -134,7 +134,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), pciid & 0xFFFF, pciid >> 16); - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Lookup the class name, if there isn't a specific one, @@ -155,14 +155,14 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (iospace) { - reg = 4; - while (reg < 10) + reg = GRUB_PCI_REG_ADDRESSES; + while (reg < GRUB_PCI_REG_CIS_POINTER) { grub_uint64_t space; addr = grub_pci_make_address (dev, reg); space = grub_pci_read (addr); - reg++; + reg += sizeof (grub_uint32_t); if (space == 0) continue; @@ -170,7 +170,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) 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, + grub_printf ("\tIO space %d at 0x%llx\n", + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_IO_MASK)); break; @@ -180,9 +182,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { addr = grub_pci_make_address (dev, reg); space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; - reg++; + reg += sizeof (grub_uint32_t); grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", - (reg - 2) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 2, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); @@ -190,7 +194,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } else grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", - (reg - 1) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); diff --git a/disk/ata.c b/disk/ata.c index af8c87180..bc8383d4e 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -402,7 +402,7 @@ grub_ata_pciinit (grub_pci_device_t dev, static int controller = 0; /* Read class. */ - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Check if this class ID matches that of a PCI IDE Controller. */ @@ -429,9 +429,12 @@ grub_ata_pciinit (grub_pci_device_t dev, { /* Read the BARs, which either contain a mmapped IO address or the IO port address. */ - addr = grub_pci_make_address (dev, 4 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i); bar1 = grub_pci_read (addr); - addr = grub_pci_make_address (dev, 5 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i + + sizeof (grub_uint32_t)); bar2 = grub_pci_read (addr); /* Check if the BARs describe an IO region. */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 2bea05410..1f3ac7fc7 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -35,6 +35,37 @@ #define GRUB_PCI_ADDR_MEM_MASK ~0xf #define GRUB_PCI_ADDR_IO_MASK ~0x03 +#define GRUB_PCI_REG_PCI_ID 0x00 +#define GRUB_PCI_REG_VENDOR 0x00 +#define GRUB_PCI_REG_DEVICE 0x02 +#define GRUB_PCI_REG_COMMAND 0x04 +#define GRUB_PCI_REG_STATUS 0x06 +#define GRUB_PCI_REG_REVISION 0x08 +#define GRUB_PCI_REG_CLASS 0x08 +#define GRUB_PCI_REG_CACHELINE 0x0c +#define GRUB_PCI_REG_LAT_TIMER 0x0d +#define GRUB_PCI_REG_HEADER_TYPE 0x0e +#define GRUB_PCI_REG_BIST 0x0f +#define GRUB_PCI_REG_ADDRESSES 0x10 + +/* Beware that 64-bit address takes 2 registers. */ +#define GRUB_PCI_REG_ADDRESS_REG0 0x10 +#define GRUB_PCI_REG_ADDRESS_REG1 0x14 +#define GRUB_PCI_REG_ADDRESS_REG2 0x18 +#define GRUB_PCI_REG_ADDRESS_REG3 0x1c +#define GRUB_PCI_REG_ADDRESS_REG4 0x20 +#define GRUB_PCI_REG_ADDRESS_REG5 0x24 + +#define GRUB_PCI_REG_CIS_POINTER 0x28 +#define GRUB_PCI_REG_SUBVENDOR 0x2c +#define GRUB_PCI_REG_SUBSYSTEM 0x2e +#define GRUB_PCI_REG_ROM_ADDRESS 0x30 +#define GRUB_PCI_REG_CAP_POINTER 0x34 +#define GRUB_PCI_REG_IRQ_LINE 0x3c +#define GRUB_PCI_REG_IRQ_PIN 0x3d +#define GRUB_PCI_REG_MIN_GNT 0x3e +#define GRUB_PCI_REG_MAX_LAT 0x3f + typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_UTIL diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 8cd4d23f2..ad09f7c36 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -477,7 +477,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 236732804..af54ac5c1 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -79,7 +79,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/util/pci.c b/util/pci.c index a0c1867be..420ae320b 100644 --- a/util/pci.c +++ b/util/pci.c @@ -26,7 +26,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) { grub_pci_address_t ret; ret.dev = dev; - ret.pos = reg << 2; + ret.pos = reg; return ret; } diff --git a/video/efi_uga.c b/video/efi_uga.c index 9bca64306..959b266a9 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -92,7 +92,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i;