From 9902d0472567094a6419586ffaf0cd33c82ed4ea Mon Sep 17 00:00:00 2001 From: bean Date: Sun, 1 Mar 2009 17:57:57 +0000 Subject: [PATCH] 2009-03-01 Bean * include/grub/efi/api.h (GRUB_EFI_MPS_TABALE_GUID): New constant. (GRUB_EFI_ACPI_TABLE_GUID): Likewise. (GRUB_EFI_ACPI_20_TABLE_GUID): Likewise. (GRUB_EFI_SMBIOS_TABLE_GUID): Likewise. * loader/i386/efi/linux.c (acpi_guid): New variable. (acpi_guid): Likewise. (EBDA_SEG_ADDR): New constant. (LOW_MEM_ADDR): Likewise. (FAKE_EBDA_SEG): Likewise. (fake_bios_data): New function. (grub_linux_boot): Call fake_bios_data. --- ChangeLog | 15 +++++++++++ include/grub/efi/api.h | 20 +++++++++++++++ loader/i386/efi/linux.c | 57 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6cb872350..098840de5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-03-01 Bean + + * include/grub/efi/api.h (GRUB_EFI_MPS_TABALE_GUID): New constant. + (GRUB_EFI_ACPI_TABLE_GUID): Likewise. + (GRUB_EFI_ACPI_20_TABLE_GUID): Likewise. + (GRUB_EFI_SMBIOS_TABLE_GUID): Likewise. + + * loader/i386/efi/linux.c (acpi_guid): New variable. + (acpi_guid): Likewise. + (EBDA_SEG_ADDR): New constant. + (LOW_MEM_ADDR): Likewise. + (FAKE_EBDA_SEG): Likewise. + (fake_bios_data): New function. + (grub_linux_boot): Call fake_bios_data. + 2009-03-01 Bean * commands/terminal.c: Removed. diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 50556bfe7..a764b370d 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -88,6 +88,26 @@ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } +#define GRUB_EFI_MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, \ + { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +#define GRUB_EFI_SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + /* Enumerations. */ enum grub_efi_timer_delay { diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 4528c216e..cd6f3a59f 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -283,6 +283,57 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, } } +static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; +static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID; + +#define EBDA_SEG_ADDR 0x40e +#define LOW_MEM_ADDR 0x413 +#define FAKE_EBDA_SEG 0x9fc0 + +static void +fake_bios_data (void) +{ + unsigned i; + void *acpi; + grub_uint16_t *ebda_seg_ptr, *low_mem_ptr; + + acpi = 0; + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + { + grub_efi_guid_t *guid = + &grub_efi_system_table->configuration_table[i].vendor_guid; + + if (! grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t))) + { + acpi = grub_efi_system_table->configuration_table[i].vendor_table; + grub_printf ("ACPI2: %p\n", acpi); + } + else if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t))) + { + void *t; + + t = grub_efi_system_table->configuration_table[i].vendor_table; + if (! acpi) + acpi = t; + grub_printf ("ACPI: %p\n", t); + } + } + + if (acpi == 0) + return; + + ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR; + low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR; + + if ((*ebda_seg_ptr) || (*low_mem_ptr)) + return; + + *ebda_seg_ptr = FAKE_EBDA_SEG; + *low_mem_ptr = FAKE_EBDA_SEG >> 6; + + grub_memcpy ((char *) (FAKE_EBDA_SEG << 4), acpi, 1024); +} + #ifdef __x86_64__ struct { @@ -302,6 +353,8 @@ grub_linux_boot (void) grub_efi_memory_descriptor_t *desc; int e820_num; + fake_bios_data (); + params = real_mode_mem; grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n", @@ -522,8 +575,8 @@ grub_linux_setup_video (struct linux_kernel_params *params) grub_efi_set_text_mode (0); pixel = RGB_MAGIC; - efi_call_10 (c->blt, c, &pixel, GRUB_EFI_UGA_VIDEO_FILL, - 0, 0, 0, 0, 1, height, 0); + efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel, + GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0); ret = find_framebuf (&fb_base, &line_len); grub_efi_set_text_mode (1);