WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] General hvmloader cleanups and write memo

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] General hvmloader cleanups and write memory fields of CMOS with
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 17 Mar 2007 10:00:17 -0700
Delivery-date: Sat, 17 Mar 2007 09:59:12 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] General hvmloader cleanups and write memory fields of CMOS with, Xen patchbot-unstable <=