diff --git a/ChangeLog b/ChangeLog index b527f7aeb..14bff8173 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2013-01-13 Colin Watson + + Remove nested functions from PCI iterators. + + * grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument, + passed to hook. Update all callers to pass appropriate hook data. + * grub-core/bus/emu/pci.c (grub_pci_iterate): Likewise. + * include/grub/pci.h (grub_pci_iteratefunc_t): Add data argument. + Remove NESTED_FUNC_ATTR from here and from all users. + (grub_pci_iterate): Update prototype. + * grub-core/bus/cs5536.c (grub_cs5536_find: hook): Make static + instead of nested. Rename to ... + (grub_cs5536_find_iter): ... this. + * grub-core/kern/efi/mm.c (stop_broadcom: find_card): Likewise. + * grub-core/kern/mips/loongson/init.c (init_pci: set_card): + Likewise. + * grub-core/kern/vga_init.c (grub_qemu_init_cirrus: find_card): + Likewise. + * grub-core/video/bochs.c (grub_video_bochs_setup: find_card): + Likewise. + * grub-core/video/cirrus.c (grub_video_cirrus_setup: find_card): + Likewise. + * grub-core/video/efi_uga.c (find_framebuf: find_card): Likewise. + * grub-core/video/radeon_fuloong2e.c + (grub_video_radeon_fuloong2e_setup: find_card): Likewise. + * grub-core/video/sis315pro.c (grub_video_sis315pro_setup: + find_card): Likewise. + * grub-core/video/sm712.c (grub_video_sm712_setup: find_card): + Likewise. + 2013-01-12 Vladimir Serbinenko * grub-core/commands/verify.c: Mark messages for translating. diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 9e7796ea1..bb9aa27e5 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -29,28 +29,39 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* Context for grub_cs5536_find. */ +struct grub_cs5536_find_ctx +{ + grub_pci_device_t *devp; + int found; +}; + +/* Helper for grub_cs5536_find. */ +static int +grub_cs5536_find_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + struct grub_cs5536_find_ctx *ctx = data; + + if (pciid == GRUB_CS5536_PCIID) + { + *ctx->devp = dev; + ctx->found = 1; + return 1; + } + return 0; +} + int grub_cs5536_find (grub_pci_device_t *devp) { - int found = 0; - auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, - grub_pci_id_t pciid); + struct grub_cs5536_find_ctx ctx = { + .devp = devp, + .found = 0 + }; - int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - if (pciid == GRUB_CS5536_PCIID) - { - *devp = dev; - found = 1; - return 1; - } - return 0; - } + grub_pci_iterate (grub_cs5536_find_iter, &ctx); - grub_pci_iterate (hook); - - return found; + return ctx.found; } grub_uint64_t diff --git a/grub-core/bus/emu/pci.c b/grub-core/bus/emu/pci.c index d1beb561d..9d3296395 100644 --- a/grub-core/bus/emu/pci.c +++ b/grub-core/bus/emu/pci.c @@ -32,7 +32,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) } void -grub_pci_iterate (grub_pci_iteratefunc_t hook) +grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data) { struct pci_device_iterator *iter; struct pci_slot_match slot; @@ -43,7 +43,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) slot.func = PCI_MATCH_ANY; iter = pci_slot_match_iterator_create (&slot); while ((dev = pci_device_next (iter))) - hook (dev, dev->vendor_id | (dev->device_id << 16)); + hook (dev, dev->vendor_id | (dev->device_id << 16), hook_data); pci_iterator_destroy (iter); } diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 17dea30a1..b388ce5c8 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -98,7 +98,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) } void -grub_pci_iterate (grub_pci_iteratefunc_t hook) +grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data) { grub_pci_device_t dev; grub_pci_address_t addr; @@ -125,7 +125,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) continue; } - if (hook (dev, id)) + if (hook (dev, id, hook_data)) return; /* Probe only func = 0 if the device if not multifunction */ diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c index dc5bf719b..b9872b6e2 100644 --- a/grub-core/bus/usb/ehci.c +++ b/grub-core/bus/usb/ehci.c @@ -454,8 +454,9 @@ grub_ehci_reset (struct grub_ehci *e) } /* PCI iteration function... */ -static int NESTED_FUNC_ATTR -grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) +static int +grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { grub_uint8_t release; grub_uint32_t class_code; @@ -1814,7 +1815,7 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed) static void grub_ehci_inithw (void) { - grub_pci_iterate (grub_ehci_pci_iter); + grub_pci_iterate (grub_ehci_pci_iter, NULL); } static grub_err_t diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 6fabb4b4a..b10a9a3e9 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -213,9 +213,9 @@ grub_ohci_writereg32 (struct grub_ohci *o, /* Iterate over all PCI devices. Determine if a device is an OHCI controller. If this is the case, initialize it. */ -static int NESTED_FUNC_ATTR -grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid) +static int +grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { grub_uint32_t interf; grub_uint32_t base; @@ -477,7 +477,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, static void grub_ohci_inithw (void) { - grub_pci_iterate (grub_ohci_pci_iter); + grub_pci_iterate (grub_ohci_pci_iter, NULL); } diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 8f60850de..e405b331d 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -185,9 +185,10 @@ grub_uhci_portstatus (grub_usb_controller_t dev, /* Iterate over all PCI devices. Determine if a device is an UHCI controller. If this is the case, initialize it. */ -static int NESTED_FUNC_ATTR +static int grub_uhci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid __attribute__((unused)), + void *data __attribute__ ((unused))) { grub_uint32_t class_code; grub_uint32_t class; @@ -351,7 +352,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, static void grub_uhci_inithw (void) { - grub_pci_iterate (grub_uhci_pci_iter); + grub_pci_iterate (grub_uhci_pci_iter, NULL); } static grub_uhci_td_t diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c index 3ed40b386..d9d54a2e8 100644 --- a/grub-core/commands/efi/fixvideo.c +++ b/grub-core/commands/efi/fixvideo.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -40,8 +41,9 @@ static struct grub_video_patch {0, 0, 0, 0, 0} }; -static int NESTED_FUNC_ATTR -scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) +static int +scan_card (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { grub_pci_address_t addr; @@ -93,7 +95,7 @@ grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - grub_pci_iterate (scan_card); + grub_pci_iterate (scan_card, NULL); return 0; } diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c index 9f836298f..65213a372 100644 --- a/grub-core/commands/lspci.c +++ b/grub-core/commands/lspci.c @@ -22,6 +22,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -126,8 +127,9 @@ static const struct grub_arg_option options[] = static int iospace; -static int NESTED_FUNC_ATTR -grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) +static int +grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { grub_uint32_t class; const char *sclass; @@ -218,7 +220,7 @@ grub_cmd_lspci (grub_extcmd_context_t ctxt, char **args __attribute__ ((unused))) { iospace = ctxt->state[0].set; - grub_pci_iterate (grub_lspci_iter); + grub_pci_iterate (grub_lspci_iter, NULL); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index fcfec4058..6fdf0e027 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -83,8 +83,9 @@ static int regsize; static grub_uint16_t regaddr; static const char *varname; -static int NESTED_FUNC_ATTR -grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) +static int +grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { grub_uint32_t regval = 0; grub_pci_address_t addr; @@ -320,7 +321,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) return grub_error (GRUB_ERR_BAD_ARGUMENT, "option -v isn't valid for writes"); - grub_pci_iterate (grub_setpci_iter); + grub_pci_iterate (grub_setpci_iter, NULL); return GRUB_ERR_NONE; } diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 4ab2d18db..f229ff11b 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -254,9 +254,10 @@ init_port (struct grub_ahci_device *dev) return 1; } -static int NESTED_FUNC_ATTR +static int grub_ahci_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__ ((unused))) + grub_pci_id_t pciid __attribute__ ((unused)), + void *data __attribute__ ((unused))) { grub_pci_address_t addr; grub_uint32_t class; @@ -394,7 +395,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, static grub_err_t grub_ahci_initialize (void) { - grub_pci_iterate (grub_ahci_pciinit); + grub_pci_iterate (grub_ahci_pciinit, NULL); return grub_errno; } diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 00b04e2d4..07c3d7f3e 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -338,9 +338,10 @@ grub_pata_device_initialize (int port, int device, int addr) } #ifndef GRUB_MACHINE_MIPS_QEMU_MIPS -static int NESTED_FUNC_ATTR +static int grub_pata_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid) + grub_pci_id_t pciid, + void *data __attribute__ ((unused))) { static int compat_use[2] = { 0 }; grub_pci_address_t addr; @@ -446,7 +447,7 @@ grub_pata_pciinit (grub_pci_device_t dev, static grub_err_t grub_pata_initialize (void) { - grub_pci_iterate (grub_pata_pciinit); + grub_pci_iterate (grub_pata_pciinit, NULL); return 0; } #else diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index a2edc84b3..351317b24 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -109,37 +109,36 @@ grub_efi_free_pages (grub_efi_physical_address_t address, #if defined (__i386__) || defined (__x86_64__) +/* Helper for stop_broadcom. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) +{ + grub_pci_address_t addr; + grub_uint8_t cap; + grub_uint16_t pm_state; + + if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) + return 0; + cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); + if (!cap) + return 0; + addr = grub_pci_make_address (dev, cap + 4); + pm_state = grub_pci_read_word (addr); + pm_state = pm_state | 0x03; + grub_pci_write_word (addr, pm_state); + grub_pci_read_word (addr); + return 0; +} + static void stop_broadcom (void) { - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid); - - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint8_t cap; - grub_uint16_t pm_state; - - if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) - return 0; - cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); - if (!cap) - return 0; - addr = grub_pci_make_address (dev, cap + 4); - pm_state = grub_pci_read_word (addr); - pm_state = pm_state | 0x03; - grub_pci_write_word (addr, pm_state); - grub_pci_read_word (addr); - return 0; - } - - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, NULL); } #endif diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 19f2d639b..2109a67b4 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -49,45 +49,47 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) return GRUB_ERR_NONE; } +/* Helper for init_pci. */ +static int +set_card (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) +{ + grub_pci_address_t addr; + /* FIXME: autoscan for BARs and devices. */ + switch (pciid) + { + case GRUB_LOONGSON_OHCI_PCIID: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5025000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); + break; + case GRUB_LOONGSON_EHCI_PCIID: + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0x5026000); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE + | GRUB_PCI_COMMAND_PARITY_ERROR + | GRUB_PCI_COMMAND_BUS_MASTER + | GRUB_PCI_COMMAND_MEM_ENABLED); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); + grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) + | GRUB_PCI_STATUS_CAPABILITIES); + break; + } + return 0; +} + static void init_pci (void) { - auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - /* FIXME: autoscan for BARs and devices. */ - switch (pciid) - { - case GRUB_LOONGSON_OHCI_PCIID: - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, 0x5025000); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE - | GRUB_PCI_COMMAND_PARITY_ERROR - | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); - grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); - break; - case GRUB_LOONGSON_EHCI_PCIID: - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, 0x5026000); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE - | GRUB_PCI_COMMAND_PARITY_ERROR - | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); - grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) - | GRUB_PCI_STATUS_CAPABILITIES); - break; - } - return 0; - } - *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c; *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; @@ -110,7 +112,7 @@ init_pci (void) *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + GRUB_PCI_REG_ADDRESS_REG1)) = 0; - grub_pci_iterate (set_card); + grub_pci_iterate (set_card, NULL); } void diff --git a/grub-core/kern/vga_init.c b/grub-core/kern/vga_init.c index 889d0128e..1119bb33d 100644 --- a/grub-core/kern/vga_init.c +++ b/grub-core/kern/vga_init.c @@ -18,6 +18,7 @@ #ifndef __mips__ #include +#include #endif #include #include @@ -87,38 +88,42 @@ load_palette (void) grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b); } +#ifndef __mips__ +/* Helper for grub_qemu_init_cirrus. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)), + void *data __attribute__ ((unused))) +{ + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA) + return 0; + + /* FIXME: chooose addresses dynamically. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH + | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); + grub_pci_write (addr, 0xf2000000 + | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED + | GRUB_PCI_COMMAND_IO_ENABLED); + + return 1; +} +#endif + void grub_qemu_init_cirrus (void) { #ifndef __mips__ - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA) - return 0; - - /* FIXME: chooose addresses dynamically. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH - | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); - grub_pci_write (addr, 0xf2000000 - | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED - | GRUB_PCI_COMMAND_IO_ENABLED); - - return 1; - } - - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, NULL); #endif grub_outb (GRUB_VGA_IO_MISC_COLOR, diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c index f6db13705..aea486c22 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -199,6 +199,29 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count, return grub_video_fb_set_palette (start, count, palette_data); } +/* Helper for grub_video_bochs_setup. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + int *found = data; + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234) + return 0; + + *found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + framebuffer.dev = dev; + + return 1; +} + static grub_err_t grub_video_bochs_setup (unsigned int width, unsigned int height, grub_video_mode_type_t mode_type, @@ -210,27 +233,6 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, int pitch, bytes_per_pixel; grub_size_t page_size; /* The size of a page in bytes. */ - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234) - return 0; - - found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - framebuffer.dev = dev; - - return 1; - } - /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; @@ -280,7 +282,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, if (page_size > BOCHS_APERTURE_SIZE) return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, &found); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c index e711119da..073c54e41 100644 --- a/grub-core/video/cirrus.c +++ b/grub-core/video/cirrus.c @@ -235,6 +235,29 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count, return grub_video_fb_set_palette (start, count, palette_data); } +/* Helper for grub_video_cirrus_setup. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + int *found = data; + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013) + return 0; + + *found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + framebuffer.dev = dev; + + return 1; +} + static grub_err_t grub_video_cirrus_setup (unsigned int width, unsigned int height, grub_video_mode_type_t mode_type, @@ -245,27 +268,6 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, int found = 0; int pitch, bytes_per_pixel; - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013) - return 0; - - found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - framebuffer.dev = dev; - - return 1; - } - /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; @@ -314,7 +316,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, if (framebuffer.page_size > CIRRUS_APERTURE_SIZE) return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, &found); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c index 016adbbdd..695f01578 100644 --- a/grub-core/video/efi_uga.c +++ b/grub-core/video/efi_uga.c @@ -81,77 +81,88 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) return 0; } +/* Context for find_framebuf. */ +struct find_framebuf_ctx +{ + grub_uint32_t *fb_base; + grub_uint32_t *line_len; + int found; +}; + +/* Helper for find_framebuf. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + struct find_framebuf_ctx *ctx = data; + grub_pci_address_t addr; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + if (grub_pci_read (addr) >> 24 == 0x3) + { + int i; + + grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); + addr += 8; + for (i = 0; i < 6; i++, addr += 4) + { + grub_uint32_t old_bar1, old_bar2, type; + grub_uint64_t base64; + + old_bar1 = grub_pci_read (addr); + if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) + continue; + + type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; + if (type == GRUB_PCI_ADDR_MEM_TYPE_64) + { + if (i == 5) + break; + + old_bar2 = grub_pci_read (addr + 4); + } + else + old_bar2 = 0; + + base64 = old_bar2; + base64 <<= 32; + base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); + + grub_dprintf ("fb", "%s(%d): 0x%llx\n", + ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? + "VMEM" : "MMIO"), i, + (unsigned long long) base64); + + if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found)) + { + *ctx->fb_base = base64; + if (find_line_len (ctx->fb_base, ctx->line_len)) + ctx->found++; + } + + if (type == GRUB_PCI_ADDR_MEM_TYPE_64) + { + i++; + addr += 4; + } + } + } + + return ctx->found; +} + static int find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { - int found = 0; + struct find_framebuf_ctx ctx = { + .fb_base = fb_base, + .line_len = line_len, + .found = 0 + }; - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid); - - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - grub_pci_address_t addr; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - if (grub_pci_read (addr) >> 24 == 0x3) - { - int i; - - grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", - grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), pciid); - addr += 8; - for (i = 0; i < 6; i++, addr += 4) - { - grub_uint32_t old_bar1, old_bar2, type; - grub_uint64_t base64; - - old_bar1 = grub_pci_read (addr); - if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) - continue; - - type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - if (i == 5) - break; - - old_bar2 = grub_pci_read (addr + 4); - } - else - old_bar2 = 0; - - base64 = old_bar2; - base64 <<= 32; - base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); - - grub_dprintf ("fb", "%s(%d): 0x%llx\n", - ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? - "VMEM" : "MMIO"), i, - (unsigned long long) base64); - - if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found)) - { - *fb_base = base64; - if (find_line_len (fb_base, line_len)) - found++; - } - - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - i++; - addr += 4; - } - } - } - - return found; - } - - grub_pci_iterate (find_card); - return found; + grub_pci_iterate (find_card, &ctx); + return ctx.found; } static int diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c index 45a68ed25..c3d65f10e 100644 --- a/grub-core/video/radeon_fuloong2e.c +++ b/grub-core/video/radeon_fuloong2e.c @@ -60,6 +60,32 @@ grub_video_radeon_fuloong2e_video_fini (void) return grub_video_fb_fini (); } +#ifndef TEST +/* Helper for grub_video_radeon_fuloong2e_setup. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + int *found = data; + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + || pciid != 0x515a1002) + return 0; + + *found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr); + framebuffer.dev = dev; + + return 1; +} +#endif + static grub_err_t grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) @@ -69,28 +95,6 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, int found = 0; #ifndef TEST - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA - || pciid != 0x515a1002) - return 0; - - found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr); - framebuffer.dev = dev; - - return 1; - } - /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; @@ -100,7 +104,7 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 640x480x16 is supported"); - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, &found); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); #endif diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c index d21387719..a98666944 100644 --- a/grub-core/video/sis315pro.c +++ b/grub-core/video/sis315pro.c @@ -88,6 +88,37 @@ grub_video_sis315pro_video_fini (void) #include "sis315_init.c" +#ifndef TEST +/* Helper for grub_video_sis315pro_setup. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + int *found = data; + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + || pciid != GRUB_SIS315PRO_PCIID) + return 0; + + *found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); + framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); + framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) + + GRUB_MACHINE_PCI_IO_BASE; + framebuffer.dev = dev; + + return 1; +} +#endif + static grub_err_t grub_video_sis315pro_setup (unsigned int width, unsigned int height, unsigned int mode_type, @@ -99,33 +130,6 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, unsigned i; #ifndef TEST - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA - || pciid != GRUB_SIS315PRO_PCIID) - return 0; - - found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); - framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); - framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) - + GRUB_MACHINE_PCI_IO_BASE; - framebuffer.dev = dev; - - return 1; - } - /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; @@ -135,7 +139,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 640x480x8 is supported"); - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, &found); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); #endif diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c index d780983b4..fb40d6427 100644 --- a/grub-core/video/sm712.c +++ b/grub-core/video/sm712.c @@ -360,6 +360,32 @@ grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda, GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx); } +#if !defined (TEST) && !defined(GENINIT) +/* Helper for grub_video_sm712_setup. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + int *found = data; + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + || pciid != GRUB_SM712_PCIID) + return 0; + + *found = 1; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + framebuffer.base = grub_pci_read (addr); + framebuffer.dev = dev; + + return 1; +} +#endif + static grub_err_t grub_video_sm712_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) @@ -370,28 +396,6 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, grub_err_t err; int found = 0; - auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA - || pciid != GRUB_SM712_PCIID) - return 0; - - found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr); - framebuffer.dev = dev; - - return 1; - } - /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; @@ -401,7 +405,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 1024x600x16 is supported"); - grub_pci_iterate (find_card); + grub_pci_iterate (find_card, &found); if (!found) return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); /* Fill mode info details. */ diff --git a/include/grub/pci.h b/include/grub/pci.h index aaf0101f9..e163d47cb 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -132,13 +132,14 @@ grub_pci_get_function (grub_pci_device_t dev) #include #endif -typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t) - (grub_pci_device_t dev, grub_pci_id_t pciid); +typedef int (*grub_pci_iteratefunc_t) + (grub_pci_device_t dev, grub_pci_id_t pciid, void *data); grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, int reg); -void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); +void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook, + void *hook_data); struct grub_pci_dma_chunk;