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>
This commit is contained in:
Stefan Reinauer 2011-10-12 14:30:59 -07:00 committed by Stefan Reinauer
parent 216fa4633a
commit c1efb90384
10 changed files with 151 additions and 41 deletions

View File

@ -516,13 +516,42 @@ 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 FRAMEBUFFER_SET_VESA_MODE
prompt "Set VESA framebuffer mode"
bool
depends on PCI_OPTION_ROM_RUN_YABEL || PCI_OPTION_ROM_RUN_REALMODE
help
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 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
some day make this a "choice".
config FRAMEBUFFER_KEEP_VESA_MODE
prompt "Keep VESA framebuffer"
bool
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
framebuffer entry in its coreboot table and the payload will need a
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 PCI_OPTION_ROM_RUN_YABEL
depends on FRAMEBUFFER_SET_VESA_MODE
help
This option shows a graphical bootsplash screen. The grapics are
loaded from the CBFS file bootsplash.jpg.
@ -534,29 +563,6 @@ config BOOTSPLASH_FILE
help
The path and filename of the file to use as graphical bootsplash
screen. The file format has to be jpg.
# TODO: Turn this into a "choice".
config FRAMEBUFFER_VESA_MODE
prompt "VESA framebuffer video mode"
hex
default 0x117
depends on BOOTSPLASH
help
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
prompt "Keep VESA framebuffer"
bool
depends on BOOTSPLASH
help
This option keeps the framebuffer mode set after coreboot finishes
execution. If this option is enabled, coreboot will pass a
framebuffer entry in its coreboot table and the payload will need a
framebuffer driver. If this option is disabled, coreboot will switch
back to text mode before handing control to a payload.
endmenu
menu "Debugging"

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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)));

View File

@ -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(.)

View File

@ -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
}

View File

@ -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) {

View File

@ -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)

View File

@ -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();