direct-io.hg

changeset 14418:cf32c9e54c8f

General hvmloader cleanups and write memory fields of CMOS with
correct values.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Fri Mar 16 23:34:24 2007 +0000 (2007-03-16)
parents 519d32076d48
children 5a198ae89051
files tools/firmware/hvmloader/32bitbios_support.c tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/smbios.c tools/firmware/hvmloader/util.c tools/firmware/hvmloader/util.h
line diff
     1.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Fri Mar 16 23:33:44 2007 +0000
     1.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Fri Mar 16 23:34:24 2007 +0000
     1.3 @@ -17,58 +17,64 @@
     1.4   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
     1.5   * Place - Suite 330, Boston, MA 02111-1307 USA.
     1.6   */
     1.7 +
     1.8  #include <inttypes.h>
     1.9  #include <elf.h>
    1.10  #ifdef __sun__
    1.11  #include <sys/machelf.h>
    1.12  #endif
    1.13  
    1.14 -#include <xen/hvm/e820.h>
    1.15  #include "util.h"
    1.16  #include "config.h"
    1.17  
    1.18  #include "../rombios/32bit/32bitbios_flat.h"
    1.19  #include "../rombios/32bit/jumptable.h"
    1.20  
    1.21 -
    1.22 -/*
    1.23 - * relocate ELF file of type ET_REL
    1.24 - */
    1.25 -static int relocate_elf(unsigned char *elfarray) {
    1.26 +/* Relocate ELF file of type ET_REL */
    1.27 +static int relocate_elf(char *elfarray)
    1.28 +{
    1.29      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
    1.30      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
    1.31      int i;
    1.32  
    1.33 -    if (ehdr->e_type != ET_REL) {
    1.34 +    if ( ehdr->e_type != ET_REL )
    1.35 +    {
    1.36          printf("Not a relocatable BIOS object file. Has type %d, need %d\n",
    1.37                 ehdr->e_type, ET_REL);
    1.38          return -1;
    1.39      }
    1.40  
    1.41 -    for (i = 0; i < ehdr->e_shnum; i++)
    1.42 +    for ( i = 0; i < ehdr->e_shnum; i++ )
    1.43          shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
    1.44  
    1.45 -    for (i = 0; i < ehdr->e_shnum; i++) {
    1.46 -        if (shdr[i].sh_type == SHT_REL) {
    1.47 +    for ( i = 0; i < ehdr->e_shnum; i++ )
    1.48 +    {
    1.49 +        if ( shdr[i].sh_type == SHT_RELA )
    1.50 +            return -2;
    1.51 +
    1.52 +        if ( shdr[i].sh_type == SHT_REL )
    1.53 +        {
    1.54              Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]);
    1.55              Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]);
    1.56              Elf32_Sym  *syms      = (Elf32_Sym *)symtabsec->sh_addr;
    1.57              Elf32_Rel  *rels      = (Elf32_Rel *)shdr[i].sh_addr;
    1.58 -            unsigned char *code   = (unsigned char *)targetsec->sh_addr;
    1.59 +            char *code            = (char *)targetsec->sh_addr;
    1.60              int j;
    1.61  
    1.62              /* must not have been stripped */
    1.63 -            if (shdr[i].sh_size == 0)
    1.64 +            if ( shdr[i].sh_size == 0 )
    1.65                  return -6;
    1.66  
    1.67 -            for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) {
    1.68 +            for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
    1.69 +            {
    1.70                  int idx           = ELF32_R_SYM(rels[j].r_info);
    1.71                  Elf32_Sym *symbol = &syms[idx];
    1.72                  uint32_t *loc     = (uint32_t *)&code[rels[j].r_offset];
    1.73                  uint32_t fix      = shdr[symbol->st_shndx].sh_addr +
    1.74                                      symbol->st_value;
    1.75  
    1.76 -                switch (ELF32_R_TYPE(rels[j].r_info)) {
    1.77 +                switch ( ELF32_R_TYPE(rels[j].r_info) )
    1.78 +                {
    1.79                      case R_386_PC32:
    1.80                          *loc += (fix - (uint32_t)loc);
    1.81                      break;
    1.82 @@ -78,96 +84,80 @@ static int relocate_elf(unsigned char *e
    1.83                      break;
    1.84                  }
    1.85              }
    1.86 -        } else if (shdr[i].sh_type == SHT_RELA) {
    1.87 -            return -2;
    1.88          }
    1.89      }
    1.90      return 0;
    1.91  }
    1.92  
    1.93 -/* scan the rombios for the destination of the jumptable */
    1.94 -static char* get_jump_table_start(void)
    1.95 +/* Scan the rombios for the destination of the jump table. */
    1.96 +static char *get_jump_table_start(void)
    1.97  {
    1.98      char *bios_mem;
    1.99  
   1.100      for ( bios_mem = (char *)ROMBIOS_BEGIN;
   1.101            bios_mem != (char *)ROMBIOS_END;
   1.102 -          bios_mem++ ) {
   1.103 -        if (strncmp(bios_mem, "___JMPT", 7) == 0)
   1.104 +          bios_mem++ )
   1.105 +    {
   1.106 +        if ( strncmp(bios_mem, "___JMPT", 7) == 0 )
   1.107              return bios_mem;
   1.108      }
   1.109  
   1.110      return NULL;
   1.111  }
   1.112  
   1.113 -/* copy relocated jumptable into the rombios */
   1.114 -static int copy_jumptable(unsigned char *elfarray)
   1.115 +/* Copy relocated jumptable into the rombios. */
   1.116 +static int copy_jumptable(char *elfarray)
   1.117  {
   1.118 -    int rc = 0;
   1.119      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
   1.120      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
   1.121      Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx];
   1.122      char *secstrings = (char *)&elfarray[shdr_strings->sh_offset];
   1.123      uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start();
   1.124 -    uint32_t *biosjumptable    = NULL;
   1.125      int i;
   1.126  
   1.127 -    if (rombiosjumptable == NULL) {
   1.128 +    if ( rombiosjumptable == NULL )
   1.129          return -3;
   1.130 +
   1.131 +    /* Find the section with the jump table and copy to lower BIOS memory. */
   1.132 +    for ( i = 0; i < ehdr->e_shnum; i++ )
   1.133 +        if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) )
   1.134 +            break;
   1.135 +
   1.136 +    if ( i == ehdr->e_shnum )
   1.137 +    {
   1.138 +        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
   1.139 +        return -4;
   1.140      }
   1.141  
   1.142 -     /* find the section with the jump table  and copy to lower BIOS memory */
   1.143 -    for (i = 0; i < ehdr->e_shnum; i++) {
   1.144 -        if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) {
   1.145 -            uint32_t biosjumptableentries;
   1.146 -            biosjumptable        = (uint32_t *)shdr[i].sh_addr;
   1.147 -            biosjumptableentries = shdr[i].sh_size / 4;
   1.148 -            for (int j = 0; j < biosjumptableentries; j++) {
   1.149 -                rombiosjumptable[j] = biosjumptable[j];
   1.150 -                if (biosjumptable[j] == 0 &&
   1.151 -                    j < (biosjumptableentries - 1)) {
   1.152 -                    printf("WARNING: jumptable entry %d is NULL!\n",j);
   1.153 -                }
   1.154 -            }
   1.155 -            break;
   1.156 -        }
   1.157 -    }
   1.158 -
   1.159 -    if (biosjumptable == NULL) {
   1.160 -        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
   1.161 -        rc = -4;
   1.162 -    }
   1.163 +    memcpy(rombiosjumptable, (uint32_t *)shdr[i].sh_addr, shdr[i].sh_size);
   1.164  
   1.165      return 0;
   1.166  }
   1.167  
   1.168 -static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize)
   1.169 +static int relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
   1.170  {
   1.171 -    int rc = 0;
   1.172      uint32_t mask = (64 * 1024) - 1;
   1.173 -    uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */
   1.174 -    unsigned char *highbiosarea;
   1.175 +    char *highbiosarea;
   1.176 +    int rc;
   1.177  
   1.178 -    highbiosarea = (unsigned char *)(long)
   1.179 -                           e820_malloc((uint64_t)to_malloc,
   1.180 -                                       E820_RESERVED,
   1.181 -                                       (uint64_t)0xffffffff);
   1.182 +    highbiosarea = (char *)(long)
   1.183 +        e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */
   1.184 +                    E820_RESERVED,
   1.185 +                    (uint64_t)0xffffffff);
   1.186  
   1.187 -    if (highbiosarea != 0) {
   1.188 -        memcpy(highbiosarea, elfarray, elfarraysize);
   1.189 -        rc = relocate_elf(highbiosarea);
   1.190 -        if (rc == 0) {
   1.191 -            rc = copy_jumptable(highbiosarea);
   1.192 -        }
   1.193 -    } else {
   1.194 -        rc = -5;
   1.195 -    }
   1.196 +    if ( highbiosarea == NULL )
   1.197 +        return -5;
   1.198 +
   1.199 +    memcpy(highbiosarea, elfarray, elfarraysize);
   1.200 +    rc = relocate_elf(highbiosarea);
   1.201 +    if ( rc == 0 )
   1.202 +        rc = copy_jumptable(highbiosarea);
   1.203  
   1.204      return rc;
   1.205  }
   1.206  
   1.207  int highbios_setup(void)
   1.208  {
   1.209 -    return relocate_32bitbios((unsigned char *)highbios_array,
   1.210 +    return relocate_32bitbios((char *)highbios_array,
   1.211                                sizeof(highbios_array));
   1.212  }
     2.1 --- a/tools/firmware/hvmloader/acpi/build.c	Fri Mar 16 23:33:44 2007 +0000
     2.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Fri Mar 16 23:34:24 2007 +0000
     2.3 @@ -20,7 +20,6 @@
     2.4  #include "ssdt_tpm.h"
     2.5  #include "../config.h"
     2.6  #include "../util.h"
     2.7 -#include <xen/hvm/e820.h>
     2.8  
     2.9  #define align16(sz)        (((sz) + 15) & ~15)
    2.10  #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
     3.1 --- a/tools/firmware/hvmloader/hvmloader.c	Fri Mar 16 23:33:44 2007 +0000
     3.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Fri Mar 16 23:34:24 2007 +0000
     3.3 @@ -29,7 +29,6 @@
     3.4  #include "pci_regs.h"
     3.5  #include <xen/version.h>
     3.6  #include <xen/hvm/params.h>
     3.7 -#include <xen/hvm/e820.h>
     3.8  
     3.9  /* memory map */
    3.10  #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
    3.11 @@ -297,25 +296,57 @@ static void pci_setup(void)
    3.12      }
    3.13  }
    3.14  
    3.15 -static 
    3.16 -int must_load_nic(void) 
    3.17 +/*
    3.18 + * If the network card is in the boot order, load the Etherboot option ROM.
    3.19 + * Read the boot order bytes from CMOS and check if any of them are 0x4.
    3.20 + */
    3.21 +static int must_load_nic(void) 
    3.22  {
    3.23 -    /* If the network card is in the boot order, load the Etherboot 
    3.24 -     * option ROM.  Read the boot order bytes from CMOS and check 
    3.25 -     * if any of them are 0x4. */
    3.26      uint8_t boot_order;
    3.27  
    3.28 -    /* Read CMOS register 0x3d (boot choices 0 and 1) */
    3.29 -    outb(0x70, 0x3d);
    3.30 -    boot_order = inb(0x71);
    3.31 -    if ( (boot_order & 0xf) == 0x4 || (boot_order & 0xf0) == 0x40 ) 
    3.32 +    /* Read CMOS register 0x3d (boot choices 0 and 1). */
    3.33 +    boot_order = cmos_inb(0x3d);
    3.34 +    if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) ) 
    3.35          return 1;
    3.36 -    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag) */
    3.37 -    outb(0x70, 0x38);
    3.38 -    boot_order = inb(0x71);
    3.39 -    if ( (boot_order & 0xf0) == 0x40 ) 
    3.40 -        return 1;
    3.41 -    return 0;
    3.42 +
    3.43 +    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */
    3.44 +    boot_order = cmos_inb(0x38);
    3.45 +    return ((boot_order & 0xf0) == 0x40);
    3.46 +}
    3.47 +
    3.48 +/* Replace possibly erroneous memory-size CMOS fields with correct values. */
    3.49 +static void cmos_write_memory_size(void)
    3.50 +{
    3.51 +    struct e820entry *map = E820_MAP;
    3.52 +    int i, nr = *E820_MAP_NR;
    3.53 +    uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
    3.54 +
    3.55 +    for ( i = 0; i < nr; i++ )
    3.56 +        if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) )
    3.57 +            break;
    3.58 +
    3.59 +    if ( i != nr )
    3.60 +    {
    3.61 +        alt_mem = ext_mem = map[i].addr + map[i].size;
    3.62 +        ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
    3.63 +        if ( ext_mem > 0xffff )
    3.64 +            ext_mem = 0xffff;
    3.65 +        alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
    3.66 +    }
    3.67 +
    3.68 +    /* All BIOSes: conventional memory (640kB). */
    3.69 +    cmos_outb(0x15, (uint8_t)(base_mem >> 0));
    3.70 +    cmos_outb(0x16, (uint8_t)(base_mem >> 8));
    3.71 +
    3.72 +    /* All BIOSes: extended memory (1kB chunks above 1MB). */
    3.73 +    cmos_outb(0x17, (uint8_t)( ext_mem >> 0));
    3.74 +    cmos_outb(0x18, (uint8_t)( ext_mem >> 8));
    3.75 +    cmos_outb(0x30, (uint8_t)( ext_mem >> 0));
    3.76 +    cmos_outb(0x31, (uint8_t)( ext_mem >> 8));
    3.77 +
    3.78 +    /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
    3.79 +    cmos_outb(0x34, (uint8_t)( alt_mem >> 0));
    3.80 +    cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
    3.81  }
    3.82  
    3.83  int main(void)
    3.84 @@ -366,6 +397,8 @@ int main(void)
    3.85          ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
    3.86      }
    3.87  
    3.88 +    cmos_write_memory_size();
    3.89 +
    3.90      if ( !check_amd() )
    3.91      {
    3.92          printf("Loading VMXAssist ...\n");
     4.1 --- a/tools/firmware/hvmloader/smbios.c	Fri Mar 16 23:33:44 2007 +0000
     4.2 +++ b/tools/firmware/hvmloader/smbios.c	Fri Mar 16 23:34:24 2007 +0000
     4.3 @@ -22,7 +22,6 @@
     4.4  
     4.5  #include <stdint.h>
     4.6  #include <xen/version.h>
     4.7 -#include <xen/hvm/e820.h>
     4.8  #include "smbios.h"
     4.9  #include "smbios_types.h"
    4.10  #include "util.h"
    4.11 @@ -129,47 +128,32 @@ write_smbios_tables(void *start,
    4.12      return (size_t)((char *)p - (char *)start);
    4.13  }
    4.14  
    4.15 -/* This tries to figure out how much pseudo-physical memory (in MB)
    4.16 -   is allocated to the current domU.
    4.17 -
    4.18 -   It iterates through the e820 table, adding up the 'usable' and
    4.19 -   'reserved' entries and rounding up to the nearest MB.
    4.20 -
    4.21 -   The e820map is not at e820 in hvmloader, so this uses the
    4.22 -   E820_MAP_* constants from e820.h to pick it up where libxenguest
    4.23 -   left it.
    4.24 - */
    4.25 +/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */
    4.26  static uint64_t
    4.27  get_memsize(void)
    4.28  {
    4.29 -    struct e820entry *map = NULL;
    4.30 -    uint8_t num_entries = 0;
    4.31 +    struct e820entry *map = E820_MAP;
    4.32 +    uint8_t num_entries = *E820_MAP_NR;
    4.33      uint64_t memsize = 0;
    4.34 -    uint8_t i;
    4.35 +    int i;
    4.36  
    4.37 -    map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET);
    4.38 -    num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET));
    4.39 -
    4.40 -    /* walk through e820map, ignoring any entries that aren't marked
    4.41 -       as usable or reserved. */
    4.42 -
    4.43 +    /*
    4.44 +     * Walk through e820map, ignoring any entries that aren't marked
    4.45 +     * as usable or reserved.
    4.46 +     */
    4.47      for ( i = 0; i < num_entries; i++ )
    4.48      {
    4.49 -        if (map->type == E820_RAM || map->type == E820_RESERVED)
    4.50 +        if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) )
    4.51              memsize += map->size;
    4.52          map++;
    4.53      }
    4.54  
    4.55 -    /* Round up to the nearest MB.  The user specifies domU
    4.56 -       pseudo-physical memory in megabytes, so not doing this
    4.57 -       could easily lead to reporting one less MB than the user
    4.58 -       specified. */
    4.59 -    if ( memsize & ((1<<20)-1) )
    4.60 -        memsize = (memsize >> 20) + 1;
    4.61 -    else
    4.62 -        memsize = (memsize >> 20);
    4.63 -
    4.64 -    return memsize;
    4.65 +    /*
    4.66 +     * Round up to the nearest MB.  The user specifies domU pseudo-physical 
    4.67 +     * memory in megabytes, so not doing this could easily lead to reporting 
    4.68 +     * one less MB than the user specified.
    4.69 +     */
    4.70 +    return (memsize + (1 << 20) - 1) >> 20;
    4.71  }
    4.72  
    4.73  void
     5.1 --- a/tools/firmware/hvmloader/util.c	Fri Mar 16 23:33:44 2007 +0000
     5.2 +++ b/tools/firmware/hvmloader/util.c	Fri Mar 16 23:34:24 2007 +0000
     5.3 @@ -27,17 +27,17 @@
     5.4  
     5.5  void outb(uint16_t addr, uint8_t val)
     5.6  {
     5.7 -    __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) );
     5.8 +    __asm__ __volatile__ ( "outb %%al, %%dx" : : "d" (addr), "a" (val) );
     5.9  }
    5.10  
    5.11  void outw(uint16_t addr, uint16_t val)
    5.12  {
    5.13 -    __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) );
    5.14 +    __asm__ __volatile__ ( "outw %%ax, %%dx" : : "d" (addr), "a" (val) );
    5.15  }
    5.16  
    5.17  void outl(uint16_t addr, uint32_t val)
    5.18  {
    5.19 -    __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) );
    5.20 +    __asm__ __volatile__ ( "outl %%eax, %%dx" : : "d" (addr), "a" (val) );
    5.21  }
    5.22  
    5.23  uint8_t inb(uint16_t addr)
    5.24 @@ -61,6 +61,18 @@ uint32_t inl(uint16_t addr)
    5.25      return val;
    5.26  }
    5.27  
    5.28 +uint8_t cmos_inb(uint8_t idx)
    5.29 +{
    5.30 +    outb(0x70, idx);
    5.31 +    return inb(0x71);
    5.32 +}
    5.33 +
    5.34 +void cmos_outb(uint8_t idx, uint8_t val)
    5.35 +{
    5.36 +    outb(0x70, idx);
    5.37 +    outb(0x71, val);
    5.38 +}
    5.39 +
    5.40  char *itoa(char *a, unsigned int i)
    5.41  {
    5.42      unsigned int _i = i, x = 0;
    5.43 @@ -280,9 +292,6 @@ uuid_to_string(char *dest, uint8_t *uuid
    5.44      *p = '\0';
    5.45  }
    5.46  
    5.47 -#include <xen/hvm/e820.h>
    5.48 -#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
    5.49 -#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
    5.50  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask)
    5.51  {
    5.52      uint64_t addr = 0;
     6.1 --- a/tools/firmware/hvmloader/util.h	Fri Mar 16 23:33:44 2007 +0000
     6.2 +++ b/tools/firmware/hvmloader/util.h	Fri Mar 16 23:34:24 2007 +0000
     6.3 @@ -26,6 +26,10 @@ uint8_t  inb(uint16_t addr);
     6.4  uint16_t inw(uint16_t addr);
     6.5  uint32_t inl(uint16_t addr);
     6.6  
     6.7 +/* CMOS access */
     6.8 +uint8_t cmos_inb(uint8_t idx);
     6.9 +void cmos_outb(uint8_t idx, uint8_t val);
    6.10 +
    6.11  /* APIC access */
    6.12  uint32_t ioapic_read(uint32_t reg);
    6.13  void ioapic_write(uint32_t reg, uint32_t val);
    6.14 @@ -78,10 +82,14 @@ int vprintf(const char *fmt, va_list ap)
    6.15  /* Allocate region of specified type in the e820 table. */
    6.16  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask);
    6.17  
    6.18 +/* General e820 access. */
    6.19 +#include <xen/hvm/e820.h>
    6.20 +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
    6.21 +#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
    6.22 +
    6.23  /* Prepare the 32bit BIOS */
    6.24  int highbios_setup(void);
    6.25  
    6.26 -
    6.27  #define isdigit(c) ((c) >= '0' && (c) <= '9')
    6.28  
    6.29  #endif /* __HVMLOADER_UTIL_H__ */