ia64/xen-unstable

changeset 14450:5a198ae89051

hvmloader: More simplification of highmem bios relocation code.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Fri Mar 16 23:56:26 2007 +0000 (2007-03-16)
parents cf32c9e54c8f
children 0e0fdba35503
files tools/firmware/hvmloader/32bitbios_support.c tools/firmware/hvmloader/util.h
line diff
     1.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Fri Mar 16 23:34:24 2007 +0000
     1.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Fri Mar 16 23:56:26 2007 +0000
     1.3 @@ -31,18 +31,15 @@
     1.4  #include "../rombios/32bit/jumptable.h"
     1.5  
     1.6  /* Relocate ELF file of type ET_REL */
     1.7 -static int relocate_elf(char *elfarray)
     1.8 +static void relocate_elf(char *elfarray)
     1.9  {
    1.10      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
    1.11      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
    1.12 -    int i;
    1.13 -
    1.14 -    if ( ehdr->e_type != ET_REL )
    1.15 -    {
    1.16 -        printf("Not a relocatable BIOS object file. Has type %d, need %d\n",
    1.17 -               ehdr->e_type, ET_REL);
    1.18 -        return -1;
    1.19 -    }
    1.20 +    Elf32_Sym  *syms, *sym;
    1.21 +    Elf32_Rel  *rels;
    1.22 +    char       *code;
    1.23 +    uint32_t   *loc, fix;
    1.24 +    int i, j;
    1.25  
    1.26      for ( i = 0; i < ehdr->e_shnum; i++ )
    1.27          shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
    1.28 @@ -50,43 +47,33 @@ static int relocate_elf(char *elfarray)
    1.29      for ( i = 0; i < ehdr->e_shnum; i++ )
    1.30      {
    1.31          if ( shdr[i].sh_type == SHT_RELA )
    1.32 -            return -2;
    1.33 +            printf("Unsupported section type SHT_RELA\n");
    1.34 +
    1.35 +        if ( shdr[i].sh_type != SHT_REL )
    1.36 +            continue;
    1.37  
    1.38 -        if ( shdr[i].sh_type == SHT_REL )
    1.39 +        syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr;
    1.40 +        rels = (Elf32_Rel *)shdr[i].sh_addr;
    1.41 +        code = (char      *)shdr[shdr[i].sh_info].sh_addr;
    1.42 +
    1.43 +        for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
    1.44          {
    1.45 -            Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]);
    1.46 -            Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]);
    1.47 -            Elf32_Sym  *syms      = (Elf32_Sym *)symtabsec->sh_addr;
    1.48 -            Elf32_Rel  *rels      = (Elf32_Rel *)shdr[i].sh_addr;
    1.49 -            char *code            = (char *)targetsec->sh_addr;
    1.50 -            int j;
    1.51 +            sym = &syms[ELF32_R_SYM(rels[j].r_info)];
    1.52 +            loc = (uint32_t *)&code[rels[j].r_offset];
    1.53 +            fix = shdr[sym->st_shndx].sh_addr + sym->st_value;
    1.54  
    1.55 -            /* must not have been stripped */
    1.56 -            if ( shdr[i].sh_size == 0 )
    1.57 -                return -6;
    1.58 -
    1.59 -            for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
    1.60 +            switch ( ELF32_R_TYPE(rels[j].r_info) )
    1.61              {
    1.62 -                int idx           = ELF32_R_SYM(rels[j].r_info);
    1.63 -                Elf32_Sym *symbol = &syms[idx];
    1.64 -                uint32_t *loc     = (uint32_t *)&code[rels[j].r_offset];
    1.65 -                uint32_t fix      = shdr[symbol->st_shndx].sh_addr +
    1.66 -                                    symbol->st_value;
    1.67 +            case R_386_PC32:
    1.68 +                *loc += fix - (uint32_t)loc;
    1.69 +                break;
    1.70  
    1.71 -                switch ( ELF32_R_TYPE(rels[j].r_info) )
    1.72 -                {
    1.73 -                    case R_386_PC32:
    1.74 -                        *loc += (fix - (uint32_t)loc);
    1.75 -                    break;
    1.76 -
    1.77 -                    case R_386_32:
    1.78 -                        *loc += fix;
    1.79 -                    break;
    1.80 -                }
    1.81 +            case R_386_32:
    1.82 +                *loc += fix;
    1.83 +                break;
    1.84              }
    1.85          }
    1.86      }
    1.87 -    return 0;
    1.88  }
    1.89  
    1.90  /* Scan the rombios for the destination of the jump table. */
    1.91 @@ -97,27 +84,21 @@ static char *get_jump_table_start(void)
    1.92      for ( bios_mem = (char *)ROMBIOS_BEGIN;
    1.93            bios_mem != (char *)ROMBIOS_END;
    1.94            bios_mem++ )
    1.95 -    {
    1.96 -        if ( strncmp(bios_mem, "___JMPT", 7) == 0 )
    1.97 +        if ( !strncmp(bios_mem, "___JMPT", 7) )
    1.98              return bios_mem;
    1.99 -    }
   1.100  
   1.101      return NULL;
   1.102  }
   1.103  
   1.104  /* Copy relocated jumptable into the rombios. */
   1.105 -static int copy_jumptable(char *elfarray)
   1.106 +static void copy_jumptable(char *elfarray)
   1.107  {
   1.108      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
   1.109      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
   1.110 -    Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx];
   1.111 -    char *secstrings = (char *)&elfarray[shdr_strings->sh_offset];
   1.112 -    uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start();
   1.113 +    char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset];
   1.114 +    char *jump_table = get_jump_table_start();
   1.115      int i;
   1.116  
   1.117 -    if ( rombiosjumptable == NULL )
   1.118 -        return -3;
   1.119 -
   1.120      /* Find the section with the jump table and copy to lower BIOS memory. */
   1.121      for ( i = 0; i < ehdr->e_shnum; i++ )
   1.122          if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) )
   1.123 @@ -126,38 +107,39 @@ static int copy_jumptable(char *elfarray
   1.124      if ( i == ehdr->e_shnum )
   1.125      {
   1.126          printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
   1.127 -        return -4;
   1.128 +        return;
   1.129      }
   1.130  
   1.131 -    memcpy(rombiosjumptable, (uint32_t *)shdr[i].sh_addr, shdr[i].sh_size);
   1.132 +    if ( jump_table == NULL )
   1.133 +    {
   1.134 +        printf("Could not find jump table in file.\n");
   1.135 +        return;
   1.136 +    }
   1.137  
   1.138 -    return 0;
   1.139 +    memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size);
   1.140  }
   1.141  
   1.142 -static int relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
   1.143 +static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
   1.144  {
   1.145      uint32_t mask = (64 * 1024) - 1;
   1.146      char *highbiosarea;
   1.147 -    int rc;
   1.148  
   1.149      highbiosarea = (char *)(long)
   1.150          e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */
   1.151                      E820_RESERVED,
   1.152                      (uint64_t)0xffffffff);
   1.153 -
   1.154      if ( highbiosarea == NULL )
   1.155 -        return -5;
   1.156 +    {
   1.157 +        printf("No available memory for BIOS high memory area\n");
   1.158 +        return;
   1.159 +    }
   1.160  
   1.161      memcpy(highbiosarea, elfarray, elfarraysize);
   1.162 -    rc = relocate_elf(highbiosarea);
   1.163 -    if ( rc == 0 )
   1.164 -        rc = copy_jumptable(highbiosarea);
   1.165 -
   1.166 -    return rc;
   1.167 +    relocate_elf(highbiosarea);
   1.168 +    copy_jumptable(highbiosarea);
   1.169  }
   1.170  
   1.171 -int highbios_setup(void)
   1.172 +void highbios_setup(void)
   1.173  {
   1.174 -    return relocate_32bitbios((char *)highbios_array,
   1.175 -                              sizeof(highbios_array));
   1.176 +    relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));
   1.177  }
     2.1 --- a/tools/firmware/hvmloader/util.h	Fri Mar 16 23:34:24 2007 +0000
     2.2 +++ b/tools/firmware/hvmloader/util.h	Fri Mar 16 23:56:26 2007 +0000
     2.3 @@ -88,7 +88,7 @@ uint64_t e820_malloc(uint64_t size, uint
     2.4  #define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
     2.5  
     2.6  /* Prepare the 32bit BIOS */
     2.7 -int highbios_setup(void);
     2.8 +void highbios_setup(void);
     2.9  
    2.10  #define isdigit(c) ((c) >= '0' && (c) <= '9')
    2.11