diff options
author | Stefan Reinauer <reinauer@chromium.org> | 2011-10-12 14:30:59 -0700 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2011-10-13 20:00:50 +0200 |
commit | c1efb9038402af268a0a25957ac236d047b21f22 (patch) | |
tree | cf03bd6d38a9731d391e84e92e5ebf44dcff3b2b | |
parent | 216fa4633a583fcc278186e1f927f32332d1e5c5 (diff) |
refactor vesa mode setting code and bootsplash code
- adds possibility to set a vesa mode without showing a bootsplash
- make bootsplash / mode setting code available in real mode.
Change-Id: I0045c9d75757657f4ce531889593102ea1e39ce5
Signed-off-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/256
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
-rw-r--r-- | src/Kconfig | 46 | ||||
-rw-r--r-- | src/arch/x86/boot/coreboot_table.c | 2 | ||||
-rw-r--r-- | src/devices/oprom/include/vbe.h | 8 | ||||
-rw-r--r-- | src/devices/oprom/x86.c | 103 | ||||
-rw-r--r-- | src/devices/oprom/x86.h | 1 | ||||
-rw-r--r-- | src/devices/oprom/x86_asm.S | 5 | ||||
-rw-r--r-- | src/devices/oprom/yabel/compat/functions.c | 2 | ||||
-rw-r--r-- | src/devices/oprom/yabel/device.c | 2 | ||||
-rw-r--r-- | src/devices/oprom/yabel/vbe.c | 9 | ||||
-rw-r--r-- | src/lib/fallback_boot.c | 2 |
10 files changed, 145 insertions, 35 deletions
diff --git a/src/Kconfig b/src/Kconfig index e9ceed5e10..525d452f4d 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -516,40 +516,31 @@ config MBI_FILE endmenu -menu "Bootsplash" - depends on PCI_OPTION_ROM_RUN_YABEL +menu "Display" + depends on PCI_OPTION_ROM_RUN_YABEL || PCI_OPTION_ROM_RUN_REALMODE -config BOOTSPLASH - prompt "Show graphical bootsplash" +config FRAMEBUFFER_SET_VESA_MODE + prompt "Set VESA framebuffer mode" bool - depends on PCI_OPTION_ROM_RUN_YABEL + depends on PCI_OPTION_ROM_RUN_YABEL || PCI_OPTION_ROM_RUN_REALMODE help - This option shows a graphical bootsplash screen. The grapics are - loaded from the CBFS file bootsplash.jpg. - -config BOOTSPLASH_FILE - string "Bootsplash path and filename" - depends on BOOTSPLASH - default "bootsplash.jpg" - help - The path and filename of the file to use as graphical bootsplash - screen. The file format has to be jpg. + Set VESA framebuffer mode (needed for bootsplash) # TODO: Turn this into a "choice". config FRAMEBUFFER_VESA_MODE prompt "VESA framebuffer video mode" hex default 0x117 - depends on BOOTSPLASH + depends on FRAMEBUFFER_SET_VESA_MODE help - This option sets the resolution used for the coreboot framebuffer and - bootsplash screen. Set to 0x117 for 1024x768x16. A diligent soul will + This option sets the resolution used for the coreboot framebuffer (and + bootsplash screen). Set to 0x117 for 1024x768x16. A diligent soul will some day make this a "choice". -config COREBOOT_KEEP_FRAMEBUFFER +config FRAMEBUFFER_KEEP_VESA_MODE prompt "Keep VESA framebuffer" bool - depends on BOOTSPLASH + depends on PCI_OPTION_ROM_RUN_YABEL || PCI_OPTION_ROM_RUN_REALMODE help This option keeps the framebuffer mode set after coreboot finishes execution. If this option is enabled, coreboot will pass a @@ -557,6 +548,21 @@ config COREBOOT_KEEP_FRAMEBUFFER framebuffer driver. If this option is disabled, coreboot will switch back to text mode before handing control to a payload. +config BOOTSPLASH + prompt "Show graphical bootsplash" + bool + depends on FRAMEBUFFER_SET_VESA_MODE + help + This option shows a graphical bootsplash screen. The grapics are + loaded from the CBFS file bootsplash.jpg. + +config BOOTSPLASH_FILE + string "Bootsplash path and filename" + depends on BOOTSPLASH + default "bootsplash.jpg" + help + The path and filename of the file to use as graphical bootsplash + screen. The file format has to be jpg. endmenu menu "Debugging" diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c index db3a8a9b5f..d53a23a9ee 100644 --- a/src/arch/x86/boot/coreboot_table.c +++ b/src/arch/x86/boot/coreboot_table.c @@ -148,7 +148,7 @@ static void lb_console(struct lb_header *header) static void lb_framebuffer(struct lb_header *header) { -#if CONFIG_BOOTSPLASH && CONFIG_COREBOOT_KEEP_FRAMEBUFFER +#if CONFIG_FRAMEBUFFER_KEEP_VESA_MODE void fill_lb_framebuffer(struct lb_framebuffer *framebuffer); struct lb_framebuffer *framebuffer; diff --git a/src/devices/oprom/include/vbe.h b/src/devices/oprom/include/vbe.h index b87b0d5506..f857b67af2 100644 --- a/src/devices/oprom/include/vbe.h +++ b/src/devices/oprom/include/vbe.h @@ -104,9 +104,11 @@ typedef struct { struct lb_framebuffer; -void vbe_set_graphics(void); // yabel only - -void fill_lb_framebuffer(struct lb_framebuffer *framebuffer); +void vbe_set_graphics(void); void vbe_textmode_console(void); +void fill_lb_framebuffer(struct lb_framebuffer *framebuffer); +#define VESA_GET_INFO 0x4f00 +#define VESA_GET_MODE_INFO 0x4f01 +#define VESA_SET_MODE 0x4f02 diff --git a/src/devices/oprom/x86.c b/src/devices/oprom/x86.c index 9a6ce41029..22fc2c5da0 100644 --- a/src/devices/oprom/x86.c +++ b/src/devices/oprom/x86.c @@ -25,14 +25,19 @@ #include <arch/registers.h> #include <console/console.h> #include <arch/interrupt.h> - +#include <cbfs.h> +#include <delay.h> #include "x86.h" +#include "vbe.h" +#include "../../src/lib/jpeg.h" void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx, - u32 esi, u32 edi) __attribute__((regparm(0))) = (void *)&__realmode_call; + u32 esi, u32 edi) __attribute__((regparm(0))) = + (void *)&__realmode_call; void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx, u32 edx, - u32 esi, u32 edi) __attribute__((regparm(0))) = (void *)&__realmode_interrupt; + u32 esi, u32 edi) __attribute__((regparm(0))) = + (void *)&__realmode_interrupt; static void setup_bda(void) { @@ -107,9 +112,9 @@ static void setup_interrupt_handlers(void) if(!intXX_handler[i]) { /* Now set the default functions that are actually - * needed to initialize the option roms. This is very - * slick, as it allows us to implement mainboard specific - * interrupt handlers, such as the int15 + * needed to initialize the option roms. This is + * very slick, as it allows us to implement mainboard + * specific interrupt handlers, such as the int15. */ switch (i) { case 0x10: @@ -178,6 +183,88 @@ static void setup_realmode_idt(void) write_idt_stub((void *)0xffe6e, 0x1a); } +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE +static u8 vbe_get_mode_info(vbe_mode_info_t * mode_info) +{ + char *buffer = (char *)&__buffer; + u16 buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00; + u16 buffer_adr = ((unsigned long)buffer) & 0xffff; + realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000, + mode_info->video_mode, 0x0000, buffer_seg, buffer_adr); + memcpy(mode_info, buffer, sizeof(vbe_mode_info_t)); + return 0; +} + +static u8 vbe_set_mode(vbe_mode_info_t * mode_info) +{ + // request linear framebuffer mode + mode_info->video_mode |= (1 << 14); + // request clearing of framebuffer + mode_info->video_mode &= ~(1 << 15); + realmode_interrupt(0x10, VESA_SET_MODE, mode_info->video_mode, + 0x0000, 0x0000, 0x0000, 0x0000); + return 0; +} + +vbe_mode_info_t mode_info; + +/* These two functions could probably even be generic between + * yabel and x86 native. TBD later. + */ +void vbe_set_graphics(void) +{ + mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE; + vbe_get_mode_info(&mode_info); + unsigned char *framebuffer = + (unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr); + printk(BIOS_DEBUG, "framebuffer: %p\n", framebuffer); + printk(BIOS_DEBUG, "framebuffer: %x\n", mode_info.vesa.phys_base_ptr); + vbe_set_mode(&mode_info); +#if CONFIG_BOOTSPLASH + struct jpeg_decdata *decdata; + decdata = malloc(sizeof(*decdata)); + unsigned char *jpeg = cbfs_find_file("bootsplash.jpg", + CBFS_TYPE_BOOTSPLASH); + if (!jpeg) { + return; + } + int ret = 0; + ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata); +#endif +} + +void vbe_textmode_console(void) +{ + delay(2); + realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000); +} + +void fill_lb_framebuffer(struct lb_framebuffer *framebuffer) +{ + framebuffer->physical_address = + le32_to_cpu(mode_info.vesa.phys_base_ptr); + + framebuffer->x_resolution = le16_to_cpu(mode_info.vesa.x_resolution); + framebuffer->y_resolution = le16_to_cpu(mode_info.vesa.y_resolution); + framebuffer->bytes_per_line = + le16_to_cpu(mode_info.vesa.bytes_per_scanline); + framebuffer->bits_per_pixel = mode_info.vesa.bits_per_pixel; + + framebuffer->red_mask_pos = mode_info.vesa.red_mask_pos; + framebuffer->red_mask_size = mode_info.vesa.red_mask_size; + + framebuffer->green_mask_pos = mode_info.vesa.green_mask_pos; + framebuffer->green_mask_size = mode_info.vesa.green_mask_size; + + framebuffer->blue_mask_pos = mode_info.vesa.blue_mask_pos; + framebuffer->blue_mask_size = mode_info.vesa.blue_mask_size; + + framebuffer->reserved_mask_pos = mode_info.vesa.reserved_mask_pos; + framebuffer->reserved_mask_size = mode_info.vesa.reserved_mask_size; +} +#endif + void run_bios(struct device *dev, unsigned long addr) { u32 num_dev = (dev->bus->secondary << 8) | dev->path.pci.devfn; @@ -203,6 +290,10 @@ void run_bios(struct device *dev, unsigned long addr) /* Option ROM entry point is at OPROM start + 3 */ realmode_call(addr + 0x0003, num_dev, 0xffff, 0x0000, 0xffff, 0x0, 0x0); printk(BIOS_DEBUG, "... Option ROM returned.\n"); + +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE + vbe_set_graphics(); +#endif } #if CONFIG_GEODE_VSA diff --git a/src/devices/oprom/x86.h b/src/devices/oprom/x86.h index 0bc24122e1..40c5778de5 100644 --- a/src/devices/oprom/x86.h +++ b/src/devices/oprom/x86.h @@ -30,6 +30,7 @@ void x86_exception(struct eregs *info); extern unsigned char __idt_handler, __idt_handler_size; extern unsigned char __realmode_code, __realmode_code_size; extern unsigned char __realmode_call, __realmode_interrupt; +extern unsigned char __buffer; extern void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx, u32 esi, u32 edi) __attribute__((regparm(0))); diff --git a/src/devices/oprom/x86_asm.S b/src/devices/oprom/x86_asm.S index d5b5e1859f..57c5338914 100644 --- a/src/devices/oprom/x86_asm.S +++ b/src/devices/oprom/x86_asm.S @@ -66,6 +66,11 @@ __registers = RELOCATED(.) .long 0 /* 16 - ESI */ .long 0 /* 20 - EDI */ +/* 256 byte buffer, used by int10 */ + .globl __buffer +__buffer = RELOCATED(.) + .skip 256 + .code32 .globl __realmode_call __realmode_call = RELOCATED(.) diff --git a/src/devices/oprom/yabel/compat/functions.c b/src/devices/oprom/yabel/compat/functions.c index db37fbc6f9..542c81f315 100644 --- a/src/devices/oprom/yabel/compat/functions.c +++ b/src/devices/oprom/yabel/compat/functions.c @@ -38,7 +38,7 @@ void run_bios(struct device * dev, unsigned long addr) biosemu(vmem, VMEM_SIZE, dev, addr); -#if CONFIG_BOOTSPLASH +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE vbe_set_graphics(); #endif } diff --git a/src/devices/oprom/yabel/device.c b/src/devices/oprom/yabel/device.c index 82595945a8..b09f50e4ac 100644 --- a/src/devices/oprom/yabel/device.c +++ b/src/devices/oprom/yabel/device.c @@ -364,6 +364,7 @@ biosemu_dev_check_exprom(unsigned long rom_base_addr) pci_ds.device_id = in16le(&pci_ds.device_id); pci_ds.img_length = in16le(&pci_ds.img_length); pci_ds.pci_ds_length = in16le(&pci_ds.pci_ds_length); +#ifdef DO_THIS_TEST_TWICE if (pci_ds.vendor_id != bios_device.pci_vendor_id) { printf ("Image has invalid Vendor ID: %04x, expected: %04x\n", @@ -376,6 +377,7 @@ biosemu_dev_check_exprom(unsigned long rom_base_addr) pci_ds.device_id, bios_device.pci_device_id); break; } +#endif DEBUG_PRINTF("Image Length: %d\n", pci_ds.img_length * 512); DEBUG_PRINTF("Image Code Type: %d\n", pci_ds.code_type); if (pci_ds.code_type == 0) { diff --git a/src/devices/oprom/yabel/vbe.c b/src/devices/oprom/yabel/vbe.c index 27bf5e62b0..b1d6984d77 100644 --- a/src/devices/oprom/yabel/vbe.c +++ b/src/devices/oprom/yabel/vbe.c @@ -13,7 +13,7 @@ #include <string.h> #include <types.h> -#if CONFIG_BOOTSPLASH +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE #include <boot/coreboot_tables.h> #endif @@ -64,7 +64,7 @@ vbe_prepare(void) return 0; // successfull init } -#if CONFIG_BOOTSPLASH +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE // VBE Function 00h static u8 vbe_info(vbe_info_t * info) @@ -704,10 +704,12 @@ void vbe_set_graphics(void) mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE; vbe_get_mode_info(&mode_info); + vbe_set_mode(&mode_info); + +#if CONFIG_BOOTSPLASH unsigned char *framebuffer = (unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr); DEBUG_PRINTF_VBE("FRAMEBUFFER: 0x%p\n", framebuffer); - vbe_set_mode(&mode_info); struct jpeg_decdata *decdata; decdata = malloc(sizeof(*decdata)); @@ -728,6 +730,7 @@ void vbe_set_graphics(void) DEBUG_PRINTF_VBE("Decompressing boot splash screen...\n"); ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata); DEBUG_PRINTF_VBE("returns %x\n", ret); +#endif } void fill_lb_framebuffer(struct lb_framebuffer *framebuffer) diff --git a/src/lib/fallback_boot.c b/src/lib/fallback_boot.c index a8fe377125..b5ec6c3030 100644 --- a/src/lib/fallback_boot.c +++ b/src/lib/fallback_boot.c @@ -28,7 +28,7 @@ void set_boot_successful(void) void boot_successful(void) { -#if CONFIG_BOOTSPLASH && !CONFIG_COREBOOT_KEEP_FRAMEBUFFER +#if CONFIG_FRAMEBUFFER_SET_VESA_MODE && !CONFIG_FRAMEBUFFER_KEEP_VESA_MODE void vbe_textmode_console(void); vbe_textmode_console(); |