[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] General hvmloader cleanups and write memory fields of CMOS with
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1174088064 0 # Node ID cf32c9e54c8f44e45fcab47bc98c37e181f93771 # Parent 519d32076d48317f798c6670ca32c9bdabc14d10 General hvmloader cleanups and write memory fields of CMOS with correct values. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/firmware/hvmloader/32bitbios_support.c | 118 ++++++++++++--------------- tools/firmware/hvmloader/acpi/build.c | 1 tools/firmware/hvmloader/hvmloader.c | 67 +++++++++++---- tools/firmware/hvmloader/smbios.c | 48 +++------- tools/firmware/hvmloader/util.c | 21 +++- tools/firmware/hvmloader/util.h | 10 ++ 6 files changed, 144 insertions(+), 121 deletions(-) diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/32bitbios_support.c --- a/tools/firmware/hvmloader/32bitbios_support.c Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/32bitbios_support.c Fri Mar 16 23:34:24 2007 +0000 @@ -17,58 +17,64 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. */ + #include <inttypes.h> #include <elf.h> #ifdef __sun__ #include <sys/machelf.h> #endif -#include <xen/hvm/e820.h> #include "util.h" #include "config.h" #include "../rombios/32bit/32bitbios_flat.h" #include "../rombios/32bit/jumptable.h" - -/* - * relocate ELF file of type ET_REL - */ -static int relocate_elf(unsigned char *elfarray) { +/* Relocate ELF file of type ET_REL */ +static int relocate_elf(char *elfarray) +{ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; int i; - if (ehdr->e_type != ET_REL) { + if ( ehdr->e_type != ET_REL ) + { printf("Not a relocatable BIOS object file. Has type %d, need %d\n", ehdr->e_type, ET_REL); return -1; } - for (i = 0; i < ehdr->e_shnum; i++) + for ( i = 0; i < ehdr->e_shnum; i++ ) shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset]; - for (i = 0; i < ehdr->e_shnum; i++) { - if (shdr[i].sh_type == SHT_REL) { + for ( i = 0; i < ehdr->e_shnum; i++ ) + { + if ( shdr[i].sh_type == SHT_RELA ) + return -2; + + if ( shdr[i].sh_type == SHT_REL ) + { Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]); Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]); Elf32_Sym *syms = (Elf32_Sym *)symtabsec->sh_addr; Elf32_Rel *rels = (Elf32_Rel *)shdr[i].sh_addr; - unsigned char *code = (unsigned char *)targetsec->sh_addr; + char *code = (char *)targetsec->sh_addr; int j; /* must not have been stripped */ - if (shdr[i].sh_size == 0) + if ( shdr[i].sh_size == 0 ) return -6; - for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) { + for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ ) + { int idx = ELF32_R_SYM(rels[j].r_info); Elf32_Sym *symbol = &syms[idx]; uint32_t *loc = (uint32_t *)&code[rels[j].r_offset]; uint32_t fix = shdr[symbol->st_shndx].sh_addr + symbol->st_value; - switch (ELF32_R_TYPE(rels[j].r_info)) { + switch ( ELF32_R_TYPE(rels[j].r_info) ) + { case R_386_PC32: *loc += (fix - (uint32_t)loc); break; @@ -78,96 +84,80 @@ static int relocate_elf(unsigned char *e break; } } - } else if (shdr[i].sh_type == SHT_RELA) { - return -2; } } return 0; } -/* scan the rombios for the destination of the jumptable */ -static char* get_jump_table_start(void) +/* Scan the rombios for the destination of the jump table. */ +static char *get_jump_table_start(void) { char *bios_mem; for ( bios_mem = (char *)ROMBIOS_BEGIN; bios_mem != (char *)ROMBIOS_END; - bios_mem++ ) { - if (strncmp(bios_mem, "___JMPT", 7) == 0) + bios_mem++ ) + { + if ( strncmp(bios_mem, "___JMPT", 7) == 0 ) return bios_mem; } return NULL; } -/* copy relocated jumptable into the rombios */ -static int copy_jumptable(unsigned char *elfarray) +/* Copy relocated jumptable into the rombios. */ +static int copy_jumptable(char *elfarray) { - int rc = 0; Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx]; char *secstrings = (char *)&elfarray[shdr_strings->sh_offset]; uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start(); - uint32_t *biosjumptable = NULL; int i; - if (rombiosjumptable == NULL) { + if ( rombiosjumptable == NULL ) return -3; + + /* Find the section with the jump table and copy to lower BIOS memory. */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) ) + break; + + if ( i == ehdr->e_shnum ) + { + printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); + return -4; } - /* find the section with the jump table and copy to lower BIOS memory */ - for (i = 0; i < ehdr->e_shnum; i++) { - if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) { - uint32_t biosjumptableentries; - biosjumptable = (uint32_t *)shdr[i].sh_addr; - biosjumptableentries = shdr[i].sh_size / 4; - for (int j = 0; j < biosjumptableentries; j++) { - rombiosjumptable[j] = biosjumptable[j]; - if (biosjumptable[j] == 0 && - j < (biosjumptableentries - 1)) { - printf("WARNING: jumptable entry %d is NULL!\n",j); - } - } - break; - } - } - - if (biosjumptable == NULL) { - printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); - rc = -4; - } + memcpy(rombiosjumptable, (uint32_t *)shdr[i].sh_addr, shdr[i].sh_size); return 0; } -static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize) +static int relocate_32bitbios(char *elfarray, uint32_t elfarraysize) { - int rc = 0; uint32_t mask = (64 * 1024) - 1; - uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */ - unsigned char *highbiosarea; + char *highbiosarea; + int rc; - highbiosarea = (unsigned char *)(long) - e820_malloc((uint64_t)to_malloc, - E820_RESERVED, - (uint64_t)0xffffffff); + highbiosarea = (char *)(long) + e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */ + E820_RESERVED, + (uint64_t)0xffffffff); - if (highbiosarea != 0) { - memcpy(highbiosarea, elfarray, elfarraysize); - rc = relocate_elf(highbiosarea); - if (rc == 0) { - rc = copy_jumptable(highbiosarea); - } - } else { - rc = -5; - } + if ( highbiosarea == NULL ) + return -5; + + memcpy(highbiosarea, elfarray, elfarraysize); + rc = relocate_elf(highbiosarea); + if ( rc == 0 ) + rc = copy_jumptable(highbiosarea); return rc; } int highbios_setup(void) { - return relocate_32bitbios((unsigned char *)highbios_array, + return relocate_32bitbios((char *)highbios_array, sizeof(highbios_array)); } diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/acpi/build.c Fri Mar 16 23:34:24 2007 +0000 @@ -20,7 +20,6 @@ #include "ssdt_tpm.h" #include "../config.h" #include "../util.h" -#include <xen/hvm/e820.h> #define align16(sz) (((sz) + 15) & ~15) #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d)) diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Mar 16 23:34:24 2007 +0000 @@ -29,7 +29,6 @@ #include "pci_regs.h" #include <xen/version.h> #include <xen/hvm/params.h> -#include <xen/hvm/e820.h> /* memory map */ #define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 @@ -297,25 +296,57 @@ static void pci_setup(void) } } -static -int must_load_nic(void) -{ - /* If the network card is in the boot order, load the Etherboot - * option ROM. Read the boot order bytes from CMOS and check - * if any of them are 0x4. */ +/* + * If the network card is in the boot order, load the Etherboot option ROM. + * Read the boot order bytes from CMOS and check if any of them are 0x4. + */ +static int must_load_nic(void) +{ uint8_t boot_order; - /* Read CMOS register 0x3d (boot choices 0 and 1) */ - outb(0x70, 0x3d); - boot_order = inb(0x71); - if ( (boot_order & 0xf) == 0x4 || (boot_order & 0xf0) == 0x40 ) + /* Read CMOS register 0x3d (boot choices 0 and 1). */ + boot_order = cmos_inb(0x3d); + if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) ) return 1; - /* Read CMOS register 0x38 (boot choice 2 and FDD test flag) */ - outb(0x70, 0x38); - boot_order = inb(0x71); - if ( (boot_order & 0xf0) == 0x40 ) - return 1; - return 0; + + /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */ + boot_order = cmos_inb(0x38); + return ((boot_order & 0xf0) == 0x40); +} + +/* Replace possibly erroneous memory-size CMOS fields with correct values. */ +static void cmos_write_memory_size(void) +{ + struct e820entry *map = E820_MAP; + int i, nr = *E820_MAP_NR; + uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0; + + for ( i = 0; i < nr; i++ ) + if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) ) + break; + + if ( i != nr ) + { + alt_mem = ext_mem = map[i].addr + map[i].size; + ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0; + if ( ext_mem > 0xffff ) + ext_mem = 0xffff; + alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0; + } + + /* All BIOSes: conventional memory (640kB). */ + cmos_outb(0x15, (uint8_t)(base_mem >> 0)); + cmos_outb(0x16, (uint8_t)(base_mem >> 8)); + + /* All BIOSes: extended memory (1kB chunks above 1MB). */ + cmos_outb(0x17, (uint8_t)( ext_mem >> 0)); + cmos_outb(0x18, (uint8_t)( ext_mem >> 8)); + cmos_outb(0x30, (uint8_t)( ext_mem >> 0)); + cmos_outb(0x31, (uint8_t)( ext_mem >> 8)); + + /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */ + cmos_outb(0x34, (uint8_t)( alt_mem >> 0)); + cmos_outb(0x35, (uint8_t)( alt_mem >> 8)); } int main(void) @@ -365,6 +396,8 @@ int main(void) acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS); ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000); } + + cmos_write_memory_size(); if ( !check_amd() ) { diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/smbios.c Fri Mar 16 23:34:24 2007 +0000 @@ -22,7 +22,6 @@ #include <stdint.h> #include <xen/version.h> -#include <xen/hvm/e820.h> #include "smbios.h" #include "smbios_types.h" #include "util.h" @@ -129,47 +128,32 @@ write_smbios_tables(void *start, return (size_t)((char *)p - (char *)start); } -/* This tries to figure out how much pseudo-physical memory (in MB) - is allocated to the current domU. - - It iterates through the e820 table, adding up the 'usable' and - 'reserved' entries and rounding up to the nearest MB. - - The e820map is not at e820 in hvmloader, so this uses the - E820_MAP_* constants from e820.h to pick it up where libxenguest - left it. - */ +/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */ static uint64_t get_memsize(void) { - struct e820entry *map = NULL; - uint8_t num_entries = 0; + struct e820entry *map = E820_MAP; + uint8_t num_entries = *E820_MAP_NR; uint64_t memsize = 0; - uint8_t i; - - map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET); - num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET)); - - /* walk through e820map, ignoring any entries that aren't marked - as usable or reserved. */ - + int i; + + /* + * Walk through e820map, ignoring any entries that aren't marked + * as usable or reserved. + */ for ( i = 0; i < num_entries; i++ ) { - if (map->type == E820_RAM || map->type == E820_RESERVED) + if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) ) memsize += map->size; map++; } - /* Round up to the nearest MB. The user specifies domU - pseudo-physical memory in megabytes, so not doing this - could easily lead to reporting one less MB than the user - specified. */ - if ( memsize & ((1<<20)-1) ) - memsize = (memsize >> 20) + 1; - else - memsize = (memsize >> 20); - - return memsize; + /* + * Round up to the nearest MB. The user specifies domU pseudo-physical + * memory in megabytes, so not doing this could easily lead to reporting + * one less MB than the user specified. + */ + return (memsize + (1 << 20) - 1) >> 20; } void diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/util.c Fri Mar 16 23:34:24 2007 +0000 @@ -27,17 +27,17 @@ void outb(uint16_t addr, uint8_t val) { - __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outb %%al, %%dx" : : "d" (addr), "a" (val) ); } void outw(uint16_t addr, uint16_t val) { - __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outw %%ax, %%dx" : : "d" (addr), "a" (val) ); } void outl(uint16_t addr, uint32_t val) { - __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) ); + __asm__ __volatile__ ( "outl %%eax, %%dx" : : "d" (addr), "a" (val) ); } uint8_t inb(uint16_t addr) @@ -59,6 +59,18 @@ uint32_t inl(uint16_t addr) uint32_t val; __asm__ __volatile__ ( "inl %%dx,%%eax" : "=a" (val) : "d" (addr) ); return val; +} + +uint8_t cmos_inb(uint8_t idx) +{ + outb(0x70, idx); + return inb(0x71); +} + +void cmos_outb(uint8_t idx, uint8_t val) +{ + outb(0x70, idx); + outb(0x71, val); } char *itoa(char *a, unsigned int i) @@ -280,9 +292,6 @@ uuid_to_string(char *dest, uint8_t *uuid *p = '\0'; } -#include <xen/hvm/e820.h> -#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) -#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask) { uint64_t addr = 0; diff -r 519d32076d48 -r cf32c9e54c8f tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Fri Mar 16 23:33:44 2007 +0000 +++ b/tools/firmware/hvmloader/util.h Fri Mar 16 23:34:24 2007 +0000 @@ -25,6 +25,10 @@ uint8_t inb(uint16_t addr); uint8_t inb(uint16_t addr); uint16_t inw(uint16_t addr); uint32_t inl(uint16_t addr); + +/* CMOS access */ +uint8_t cmos_inb(uint8_t idx); +void cmos_outb(uint8_t idx, uint8_t val); /* APIC access */ uint32_t ioapic_read(uint32_t reg); @@ -78,9 +82,13 @@ int vprintf(const char *fmt, va_list ap) /* Allocate region of specified type in the e820 table. */ uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); +/* General e820 access. */ +#include <xen/hvm/e820.h> +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) +#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) + /* Prepare the 32bit BIOS */ int highbios_setup(void); - #define isdigit(c) ((c) >= '0' && (c) <= '9') _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |