diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2011-06-01 16:49:03 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2011-06-01 16:49:03 +0100 |
commit | c95ba9ebe198b2cc17213927236e9a8b63d503e6 (patch) | |
tree | 4d65551004bb1aa362c93fc23862d15f5c482298 /tools/firmware | |
parent | 814c326008ce506d33c87d3a26472b821ec12b87 (diff) | |
download | xen-c95ba9ebe198b2cc17213927236e9a8b63d503e6.tar.gz xen-c95ba9ebe198b2cc17213927236e9a8b63d503e6.tar.bz2 xen-c95ba9ebe198b2cc17213927236e9a8b63d503e6.zip |
hvmloader: further support for SeaBIOS
Build the various BIOS tables and arrange for them to be passed to
SeaBIOS. We define a simple data structure structure at a known
physical address for this purpose.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/firmware')
-rw-r--r-- | tools/firmware/hvmloader/config-seabios.h | 2 | ||||
-rw-r--r-- | tools/firmware/hvmloader/seabios.c | 101 |
2 files changed, 97 insertions, 6 deletions
diff --git a/tools/firmware/hvmloader/config-seabios.h b/tools/firmware/hvmloader/config-seabios.h index 56fb7bceae..8d7699be41 100644 --- a/tools/firmware/hvmloader/config-seabios.h +++ b/tools/firmware/hvmloader/config-seabios.h @@ -1,6 +1,8 @@ #ifndef __HVMLOADER_CONFIG_SEABIOS_H__ #define __HVMLOADER_CONFIG_SEABIOS_H__ +#define BIOS_INFO_PHYSICAL_ADDRESS 0x00001000 + #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 #endif /* __HVMLOADER_CONFIG_SEABIOS_H__ */ diff --git a/tools/firmware/hvmloader/seabios.c b/tools/firmware/hvmloader/seabios.c index 0bc1975c22..babba6eea1 100644 --- a/tools/firmware/hvmloader/seabios.c +++ b/tools/firmware/hvmloader/seabios.c @@ -25,9 +25,98 @@ #include "util.h" +#include "smbios_types.h" +#include "acpi/acpi2_0.h" + #define ROM_INCLUDE_SEABIOS #include "roms.inc" +struct seabios_info { + char signature[14]; /* XenHVMSeaBIOS\0 */ + uint8_t length; /* Length of this struct */ + uint8_t checksum; /* Set such that the sum over bytes 0..length == 0 */ + /* + * Physical address of an array of tables_nr elements. + * + * Each element is a 32 bit value contianing the physical address + * of a BIOS table. + */ + uint32_t tables; + uint32_t tables_nr; + /* + * Physical address of the e820 table, contains e820_nr entries. + */ + uint32_t e820; + uint32_t e820_nr; +} __attribute__ ((packed)); + +#define MAX_TABLES 4 + +static void seabios_setup_bios_info(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + + memset(info, 0, sizeof(*info)); + + memcpy(info->signature, "XenHVMSeaBIOS", sizeof(info->signature)); + info->length = sizeof(*info); + + info->tables = (uint32_t)scratch_alloc(MAX_TABLES*sizeof(uint32_t), 0); +} + +static void seabios_finish_bios_info(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + uint32_t i; + uint8_t checksum; + + checksum = 0; + for (i = 0; i < info->length; ++i) + checksum += ((uint8_t *)(info))[i]; + + info->checksum = -checksum; +} + +static void add_table(uint32_t t) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + uint32_t *ts = (uint32_t *)info->tables; + + ASSERT(info->tables_nr < MAX_TABLES); + + ts[info->tables_nr] = t; + info->tables_nr++; +} + +static void seabios_acpi_build_tables(void) +{ + uint32_t rsdp = (uint32_t)scratch_alloc(sizeof(struct acpi_20_rsdp), 0); + acpi_build_tables(rsdp); + add_table(rsdp); +} + +static void seabios_create_mp_tables(void) +{ + add_table(create_mp_tables(NULL)); +} + +static void seabios_create_smbios_tables(void) +{ + uint32_t ep = (uint32_t)scratch_alloc(sizeof(struct smbios_entry_point), 0); + uint32_t t = (uint32_t)mem_alloc(32*1024, 0); + hvm_write_smbios_tables(ep, t, 32*1024); + add_table(ep); +} + +static void seabios_setup_e820(void) +{ + struct seabios_info *info = (void *)BIOS_INFO_PHYSICAL_ADDRESS; + struct e820entry *e820 = scratch_alloc(sizeof(struct e820entry)*16, 0); + info->e820 = (uint32_t)e820; + info->e820_nr = build_e820_table(e820); + dump_e820_table(e820, info->e820_nr); +} + //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS)); struct bios_config seabios_config = { @@ -43,17 +132,17 @@ struct bios_config seabios_config = { .optionrom_start = 0, .optionrom_end = 0, - .bios_info_setup = NULL, - .bios_info_finish = NULL, + .bios_info_setup = seabios_setup_bios_info, + .bios_info_finish = seabios_finish_bios_info, .bios_relocate = NULL, .vm86_setup = NULL, - .e820_setup = NULL, + .e820_setup = seabios_setup_e820, - .acpi_build_tables = NULL, - .create_mp_tables = NULL, - .create_smbios_tables = NULL, + .acpi_build_tables = seabios_acpi_build_tables, + .create_mp_tables = seabios_create_mp_tables, + .create_smbios_tables = seabios_create_smbios_tables, }; /* |