X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fpci%2Fpci_rom.c;h=ad1167e2b65ad436824132eaf2d671b683d3151c;hb=7ba34ff09f1ef105521f914e4ad4e4ac19975bac;hp=af6a3ae00cfdcfe5364dc57fe4782bfd6bd1b1fa;hpb=88342103cccf73b39c764bfb1473e7bf29b52b88;p=oweals%2Fu-boot.git diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index af6a3ae00c..ad1167e2b6 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -31,10 +31,7 @@ #include #include #include - -#ifdef CONFIG_HAVE_ACPI_RESUME -#include -#endif +#include __weak bool board_should_run_oprom(pci_dev_t dev) { @@ -43,10 +40,6 @@ __weak bool board_should_run_oprom(pci_dev_t dev) static bool should_load_oprom(pci_dev_t dev) { -#ifdef CONFIG_HAVE_ACPI_RESUME - if (acpi_get_slp_type() == 3) - return false; -#endif if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM)) return 1; if (board_should_run_oprom(dev)) @@ -66,6 +59,8 @@ static int pci_rom_probe(pci_dev_t dev, uint class, struct pci_rom_header *rom_header; struct pci_rom_data *rom_data; u16 vendor, device; + u16 rom_vendor, rom_device; + u32 rom_class; u32 vendev; u32 mapped_vendev; u32 rom_address; @@ -77,10 +72,10 @@ static int pci_rom_probe(pci_dev_t dev, uint class, if (vendev != mapped_vendev) debug("Device ID mapped to %#08x\n", mapped_vendev); -#ifdef CONFIG_X86_OPTION_ROM_ADDR - rom_address = CONFIG_X86_OPTION_ROM_ADDR; +#ifdef CONFIG_VGA_BIOS_ADDR + rom_address = CONFIG_VGA_BIOS_ADDR; #else - pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK); + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { debug("%s: rom_address=%x\n", __func__, rom_address); @@ -92,45 +87,51 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_address | PCI_ROM_ADDRESS_ENABLE); #endif debug("Option ROM address %x\n", rom_address); - rom_header = (struct pci_rom_header *)rom_address; + rom_header = (struct pci_rom_header *)(unsigned long)rom_address; debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", - le32_to_cpu(rom_header->signature), - rom_header->size * 512, le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->signature), + rom_header->size * 512, le16_to_cpu(rom_header->data)); - if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { + if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) { printf("Incorrect expansion ROM header signature %04x\n", - le32_to_cpu(rom_header->signature)); + le16_to_cpu(rom_header->signature)); +#ifndef CONFIG_VGA_BIOS_ADDR + /* Disable expansion ROM address decoding */ + pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address); +#endif return -EINVAL; } - rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data)); + rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data)); + rom_vendor = le16_to_cpu(rom_data->vendor); + rom_device = le16_to_cpu(rom_data->device); debug("PCI ROM image, vendor ID %04x, device ID %04x,\n", - rom_data->vendor, rom_data->device); + rom_vendor, rom_device); /* If the device id is mapped, a mismatch is expected */ - if ((vendor != rom_data->vendor || device != rom_data->device) && + if ((vendor != rom_vendor || device != rom_device) && (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", - rom_data->vendor, rom_data->device); - return -EPERM; + rom_vendor, rom_device); + /* Continue anyway */ } - debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n", - rom_data->class_hi, rom_data->class_lo, rom_data->type); + rom_class = (le16_to_cpu(rom_data->class_hi) << 8) | rom_data->class_lo; + debug("PCI ROM image, Class Code %06x, Code Type %02x\n", + rom_class, rom_data->type); - if (class != ((rom_data->class_hi << 8) | rom_data->class_lo)) { - debug("Class Code mismatch ROM %08x, dev %08x\n", - (rom_data->class_hi << 8) | rom_data->class_lo, - class); + if (class != rom_class) { + debug("Class Code mismatch ROM %06x, dev %06x\n", + rom_class, class); } *hdrp = rom_header; return 0; } -int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, +int pci_rom_load(struct pci_rom_header *rom_header, struct pci_rom_header **ram_headerp) { struct pci_rom_data *rom_data; @@ -144,18 +145,26 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, image_size); rom_data = (struct pci_rom_data *)((void *)rom_header + - le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->data)); - image_size = le32_to_cpu(rom_data->ilen) * 512; - } while ((rom_data->type != 0) && (rom_data->indicator != 0)); + image_size = le16_to_cpu(rom_data->ilen) * 512; + } while ((rom_data->type != 0) && (rom_data->indicator == 0)); if (rom_data->type != 0) return -EACCES; rom_size = rom_header->size * 512; +#ifdef PCI_VGA_RAM_IMAGE_START target = (void *)PCI_VGA_RAM_IMAGE_START; +#else + target = (void *)malloc(rom_size); + if (!target) + return -ENOMEM; +#endif if (target != rom_header) { + ulong start = get_timer(0); + debug("Copying VGA ROM Image from %p to %p, 0x%x bytes\n", rom_header, target, rom_size); memcpy(target, rom_header, rom_size); @@ -163,13 +172,14 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, printf("VGA ROM copy failed\n"); return -EFAULT; } + debug("Copy took %lums\n", get_timer(start)); } *ram_headerp = target; return 0; } -static struct vbe_mode_info mode_info; +struct vbe_mode_info mode_info; int vbe_get_video_info(struct graphic_device *gdev) { @@ -185,6 +195,7 @@ int vbe_get_video_info(struct graphic_device *gdev) gdev->gdfBytesPP = vesa->bits_per_pixel / 8; switch (vesa->bits_per_pixel) { + case 32: case 24: gdev->gdfIndex = GDF_32BIT_X888RGB; break; @@ -205,26 +216,57 @@ int vbe_get_video_info(struct graphic_device *gdev) gdev->vprBase = vesa->phys_base_ptr; gdev->cprBase = vesa->phys_base_ptr; - return 0; + return gdev->winSizeX ? 0 : -ENOSYS; #else return -ENOSYS; #endif } -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) +void setup_video(struct screen_info *screen_info) +{ + struct vesa_mode_info *vesa = &mode_info.vesa; + + /* Sanity test on VESA parameters */ + if (!vesa->x_resolution || !vesa->y_resolution) + return; + + screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; + + screen_info->lfb_width = vesa->x_resolution; + screen_info->lfb_height = vesa->y_resolution; + screen_info->lfb_depth = vesa->bits_per_pixel; + screen_info->lfb_linelength = vesa->bytes_per_scanline; + screen_info->lfb_base = vesa->phys_base_ptr; + screen_info->lfb_size = + ALIGN(screen_info->lfb_linelength * screen_info->lfb_height, + 65536); + screen_info->lfb_size >>= 16; + screen_info->red_size = vesa->red_mask_size; + screen_info->red_pos = vesa->red_mask_pos; + screen_info->green_size = vesa->green_mask_size; + screen_info->green_pos = vesa->green_mask_pos; + screen_info->blue_size = vesa->blue_mask_size; + screen_info->blue_pos = vesa->blue_mask_pos; + screen_info->rsvd_size = vesa->reserved_mask_size; + screen_info->rsvd_pos = vesa->reserved_mask_pos; +} + +int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) { struct pci_rom_header *rom, *ram; int vesa_mode = -1; - uint16_t class; + uint class; + bool emulate; int ret; /* Only execute VGA ROMs */ - pci_read_config_word(dev, PCI_CLASS_DEVICE, &class); - if ((class ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) { + pci_read_config_dword(dev, PCI_REVISION_ID, &class); + if (((class >> 16) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) { debug("%s: Class %#x, should be %#x\n", __func__, class, PCI_CLASS_DISPLAY_VGA); return -ENODEV; } + class >>= 8; if (!should_load_oprom(dev)) return -ENXIO; @@ -233,7 +275,7 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) if (ret) return ret; - ret = pci_rom_load(class, rom, &ram); + ret = pci_rom_load(rom, &ram); if (ret) return ret; @@ -244,7 +286,30 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) defined(CONFIG_FRAMEBUFFER_VESA_MODE) vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE; #endif - debug("Selected vesa mode %d\b", vesa_mode); + debug("Selected vesa mode %#x\n", vesa_mode); + + if (exec_method & PCI_ROM_USE_NATIVE) { +#ifdef CONFIG_X86 + emulate = false; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS native execution is only available on x86\n"); + return -ENOSYS; + } + emulate = true; +#endif + } else { +#ifdef CONFIG_BIOSEMU + emulate = true; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); + return -ENOSYS; + } + emulate = false; +#endif + } + if (emulate) { #ifdef CONFIG_BIOSEMU BE_VGAInfo *info; @@ -257,9 +322,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) vesa_mode, &mode_info); if (ret) return ret; -#else - printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); - return -ENOSYS; #endif } else { #ifdef CONFIG_X86 @@ -267,12 +329,9 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) bios_run_on_x86(dev, (unsigned long)ram, vesa_mode, &mode_info); -#else - printf("BIOS native execution is only available on x86\n"); - return -ENOSYS; #endif } - debug("Final vesa mode %d\n", mode_info.video_mode); + debug("Final vesa mode %#x\n", mode_info.video_mode); return 0; }