ia64/xen-unstable

changeset 13955:aea80dbf6d96

[POWERPC][XEN] Use libelf for dom0 construction.
- Remove old 32-bit ELF loader hack.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Hollis Blanchard <hollisb@us.ibm.com>
date Fri Feb 09 14:43:22 2007 -0600 (2007-02-09)
parents 632d8e576900
children 9af0c7e4ff51
files xen/arch/powerpc/Makefile xen/arch/powerpc/domain_build.c xen/arch/powerpc/elf32.c
line diff
     1.1 --- a/xen/arch/powerpc/Makefile	Fri Feb 09 14:43:22 2007 -0600
     1.2 +++ b/xen/arch/powerpc/Makefile	Fri Feb 09 14:43:22 2007 -0600
     1.3 @@ -51,8 +51,6 @@ obj-$(builtin_dom0) += dom0.o
     1.4  
     1.5  obj-y += firmware_image.o
     1.6  
     1.7 -obj-y += elf32.o
     1.8 -
     1.9  # These are extra warnings like for the arch/ppc directory but may not
    1.10  # allow the rest of the tree to build.
    1.11  PPC_C_WARNINGS += -Wundef -Wmissing-prototypes -Wmissing-declarations
     2.1 --- a/xen/arch/powerpc/domain_build.c	Fri Feb 09 14:43:22 2007 -0600
     2.2 +++ b/xen/arch/powerpc/domain_build.c	Fri Feb 09 14:43:22 2007 -0600
     2.3 @@ -20,7 +20,6 @@
     2.4  
     2.5  #include <xen/config.h>
     2.6  #include <xen/lib.h>
     2.7 -#include <xen/elf.h>
     2.8  #include <xen/sched.h>
     2.9  #include <xen/init.h>
    2.10  #include <xen/ctype.h>
    2.11 @@ -31,11 +30,9 @@
    2.12  #include <asm/processor.h>
    2.13  #include <asm/papr.h>
    2.14  #include <public/arch-powerpc.h>
    2.15 +#include <public/libelf.h>
    2.16  #include "oftree.h"
    2.17  
    2.18 -extern int parseelfimage_32(struct domain_setup_info *dsi);
    2.19 -extern int loadelfimage_32(struct domain_setup_info *dsi);
    2.20 -
    2.21  /* opt_dom0_mem: memory allocated to domain 0. */
    2.22  static unsigned int dom0_nrpages;
    2.23  static void parse_dom0_mem(char *s)
    2.24 @@ -53,63 +50,18 @@ integer_param("dom0_max_vcpus", opt_dom0
    2.25  static unsigned int opt_dom0_shadow;
    2.26  boolean_param("dom0_shadow", opt_dom0_shadow);
    2.27  
    2.28 -int elf_sanity_check(const Elf_Ehdr *ehdr)
    2.29 -{
    2.30 -    if (IS_ELF(*ehdr))
    2.31 -        /* we are happy with either */
    2.32 -        if ((ehdr->e_ident[EI_CLASS] == ELFCLASS32
    2.33 -             && ehdr->e_machine == EM_PPC)
    2.34 -            || (ehdr->e_ident[EI_CLASS] == ELFCLASS64
    2.35 -                && ehdr->e_machine == EM_PPC64)) {
    2.36 -            if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB
    2.37 -                && ehdr->e_type == ET_EXEC)
    2.38 -                return 1;
    2.39 -        }
    2.40 -    printk("DOM0 image is not a Xen-compatible Elf image.\n");
    2.41 -    return 0;
    2.42 -}
    2.43 -
    2.44  /* adapted from common/elf.c */
    2.45  #define RM_MASK(a,l) ((a) & ((1UL << (l)) - 1))
    2.46  
    2.47 -static int rm_loadelfimage_64(struct domain_setup_info *dsi, ulong rma)
    2.48 -{
    2.49 -    char *elfbase = (char *)dsi->image_addr;
    2.50 -    Elf64_Ehdr *ehdr = (Elf64_Ehdr *)dsi->image_addr;
    2.51 -    Elf64_Phdr *phdr;
    2.52 -    int h;
    2.53 -  
    2.54 -    for (h = 0; h < ehdr->e_phnum; h++ ) 
    2.55 -    {
    2.56 -        phdr = (Elf64_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
    2.57 -        if (!((phdr->p_type == PT_LOAD) &&
    2.58 -             ((phdr->p_flags & (PF_W|PF_X)) != 0)))
    2.59 -            continue;
    2.60 -
    2.61 -        if (phdr->p_filesz != 0)
    2.62 -            memcpy((char *)(rma + RM_MASK(phdr->p_paddr, 42)),
    2.63 -                   elfbase + phdr->p_offset, 
    2.64 -                   phdr->p_filesz);
    2.65 -        if (phdr->p_memsz > phdr->p_filesz)
    2.66 -            memset((char *)(rma + RM_MASK(phdr->p_paddr, 42) + phdr->p_filesz),
    2.67 -                   0, phdr->p_memsz - phdr->p_filesz);
    2.68 -    }
    2.69 -
    2.70 -#ifdef NOT_YET
    2.71 -    loadelfsymtab(dsi, 1);
    2.72 -#endif
    2.73 -
    2.74 -    return 0;
    2.75 -}
    2.76 -
    2.77  int construct_dom0(struct domain *d,
    2.78                     unsigned long image_start, unsigned long image_len, 
    2.79                     unsigned long initrd_start, unsigned long initrd_len,
    2.80                     char *cmdline)
    2.81  {
    2.82 +    struct elf_binary elf;
    2.83 +    struct elf_dom_parms parms;
    2.84      int rc;
    2.85      struct vcpu *v = d->vcpu[0];
    2.86 -    struct domain_setup_info dsi;
    2.87      ulong dst;
    2.88      u64 *ofh_tree;
    2.89      uint rma_nrpages = 1 << d->arch.rma_order;
    2.90 @@ -117,11 +69,7 @@ int construct_dom0(struct domain *d,
    2.91      ulong rma = page_to_maddr(d->arch.rma_page);
    2.92      start_info_t *si;
    2.93      ulong eomem;
    2.94 -    int am64 = 1;
    2.95      int preempt = 0;
    2.96 -    ulong msr;
    2.97 -    ulong pc;
    2.98 -    ulong r2;
    2.99      int vcpu;
   2.100  
   2.101      /* Sanity! */
   2.102 @@ -133,26 +81,27 @@ int construct_dom0(struct domain *d,
   2.103  
   2.104      cpu_init_vcpu(v);
   2.105  
   2.106 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
   2.107 -    dsi.image_addr = image_start;
   2.108 -    dsi.image_len  = image_len;
   2.109 +    printk("*** LOADING DOMAIN 0 ***\n");
   2.110  
   2.111 -    printk("Trying Dom0 as 64bit ELF\n");
   2.112 -    if ((rc = parseelfimage(&dsi)) != 0) {
   2.113 -        printk("Trying Dom0 as 32bit ELF\n");
   2.114 -        if ((rc = parseelfimage_32(&dsi)) != 0)
   2.115 -            return rc;
   2.116 -        am64 = 0;
   2.117 -    }
   2.118 +    rc = elf_init(&elf, (void *)image_start, image_len);
   2.119 +    if (rc)
   2.120 +        return rc;
   2.121 +#ifdef VERBOSE
   2.122 +    elf_set_verbose(&elf);
   2.123 +#endif
   2.124 +    elf_parse_binary(&elf);
   2.125 +    if (0 != (elf_xen_parse(&elf, &parms)))
   2.126 +        return rc;
   2.127 +
   2.128 +    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
   2.129 +            elf_64bit(&elf) ? "64-bit" : "32-bit",
   2.130 +            elf.pstart, elf.pend);
   2.131  
   2.132      /* elf contains virtual addresses that can have the upper bits
   2.133       * masked while running in real mode, so we do the masking as well
   2.134       * as well */
   2.135 -    dsi.v_kernstart = RM_MASK(dsi.v_kernstart, 42);
   2.136 -    dsi.v_kernend = RM_MASK(dsi.v_kernend, 42);
   2.137 -    dsi.v_kernentry = RM_MASK(dsi.v_kernentry, 42);
   2.138 -
   2.139 -    printk("*** LOADING DOMAIN 0 ***\n");
   2.140 +    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
   2.141 +    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
   2.142  
   2.143      /* By default DOM0 is allocated all available memory. */
   2.144      d->max_pages = ~0U;
   2.145 @@ -253,75 +202,56 @@ int construct_dom0(struct domain *d,
   2.146      printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
   2.147             oftree_len);
   2.148      memcpy((void *)dst, (void *)oftree, oftree_len);
   2.149 -
   2.150      dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE);
   2.151  
   2.152 -    if (am64) {
   2.153 -        ulong kbase;
   2.154 -        ulong *fdesc;
   2.155 -
   2.156 -        printk("loading 64-bit Dom0: 0x%lx, in RMA:0x%lx\n", dst, dst - rma);
   2.157 -        rm_loadelfimage_64(&dsi, dst);
   2.158 +    /* Load the dom0 kernel. */
   2.159 +    elf.dest = (void *)dst;
   2.160 +    elf_load_binary(&elf);
   2.161 +    v->arch.ctxt.pc = dst - rma;
   2.162 +    dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
   2.163  
   2.164 -        kbase = dst;
   2.165 -        /* move dst to end of bss */
   2.166 -        dst = ALIGN_UP(dsi.v_kernend + dst, PAGE_SIZE);
   2.167 -
   2.168 -        if ( initrd_len > 0 ) {
   2.169 -            ASSERT( (dst - rma) + image_len < eomem );
   2.170 -
   2.171 -            printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
   2.172 -            memcpy((void *)dst, (void *)initrd_start, initrd_len);
   2.173 -
   2.174 -            si->mod_start = dst - rma;
   2.175 -            si->mod_len = image_len;
   2.176 +    /* Load the initrd. */
   2.177 +    if (initrd_len > 0) {
   2.178 +        ASSERT((dst - rma) + image_len < eomem);
   2.179  
   2.180 -            dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
   2.181 -        } else {
   2.182 -            printk("no initrd\n");
   2.183 -            si->mod_start = 0;
   2.184 -            si->mod_len = 0;
   2.185 -        }
   2.186 -        /* it may be a function descriptor */
   2.187 -        fdesc = (ulong *)(dsi.v_kernstart + dsi.v_kernentry + kbase);
   2.188 +        printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
   2.189 +        memcpy((void *)dst, (void *)initrd_start, initrd_len);
   2.190 +
   2.191 +        si->mod_start = dst - rma;
   2.192 +        si->mod_len = image_len;
   2.193  
   2.194 -        if (fdesc[2] == 0
   2.195 -            && ((fdesc[0] >= dsi.v_kernstart)
   2.196 -                && (fdesc[0] < dsi.v_kernend)) /* text entry is in range */
   2.197 -            && ((fdesc[1] >= dsi.v_kernstart)  /* toc can be > image */
   2.198 -                && (fdesc[1] < (dsi.v_kernend + (0x7fff * sizeof (ulong)))))) {
   2.199 -            /* it is almost certainly a function descriptor */
   2.200 -            pc = RM_MASK(fdesc[0], 42) + kbase - rma;
   2.201 -            r2 = RM_MASK(fdesc[1], 42) + kbase - rma;
   2.202 -        } else {
   2.203 -            pc = ((ulong)fdesc) - rma;
   2.204 -            r2 = 0;
   2.205 -        }
   2.206 -        msr = MSR_SF;
   2.207 +        dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
   2.208      } else {
   2.209 -        printk("loading 32-bit Dom0: 0x%lx, in RMA:0x%lx\n",
   2.210 -               dsi.v_kernstart + rma, dsi.v_kernstart);
   2.211 -        dsi.v_start = rma;
   2.212 -        loadelfimage_32(&dsi);
   2.213 -
   2.214 -        pc = dsi.v_kernentry;
   2.215 -        r2 = 0;
   2.216 -        msr = 0;
   2.217 +        printk("no initrd\n");
   2.218 +        si->mod_start = 0;
   2.219 +        si->mod_len = 0;
   2.220      }
   2.221  
   2.222 +    if (elf_64bit(&elf)) {
   2.223 +        v->arch.ctxt.msr = MSR_SF;
   2.224 +    } else {
   2.225 +        v->arch.ctxt.msr = 0;
   2.226 +    }
   2.227 +    v->arch.ctxt.gprs[2] = 0;
   2.228      v->arch.ctxt.gprs[3] = si->mod_start;
   2.229      v->arch.ctxt.gprs[4] = si->mod_len;
   2.230  
   2.231 +	printk("dom0 initial register state:\n"
   2.232 +			"    pc %016lx msr %016lx\n"
   2.233 +			"    r1 %016lx r2 %016lx r3 %016lx\n"
   2.234 +			"    r4 %016lx r5 %016lx\n",
   2.235 +			v->arch.ctxt.pc,
   2.236 +			v->arch.ctxt.msr,
   2.237 +			v->arch.ctxt.gprs[1],
   2.238 +			v->arch.ctxt.gprs[2],
   2.239 +			v->arch.ctxt.gprs[3],
   2.240 +			v->arch.ctxt.gprs[4],
   2.241 +			v->arch.ctxt.gprs[5]);
   2.242 +
   2.243      memset(si->cmd_line, 0, sizeof(si->cmd_line));
   2.244      if ( cmdline != NULL )
   2.245          strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line));
   2.246  
   2.247 -    v->arch.ctxt.msr = msr;
   2.248 -    v->arch.ctxt.pc = pc;
   2.249 -    v->arch.ctxt.gprs[2] = r2;
   2.250 -
   2.251 -    printk("DOM: pc = 0x%lx, r2 = 0x%lx\n", pc, r2);
   2.252 -
   2.253      ofd_dom0_fixup(d, *ofh_tree + rma, si);
   2.254  
   2.255      set_bit(_VCPUF_initialised, &v->vcpu_flags);
     3.1 --- a/xen/arch/powerpc/elf32.c	Fri Feb 09 14:43:22 2007 -0600
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,7 +0,0 @@
     3.4 -#define parseelfimage parseelfimage_32
     3.5 -#define loadelfimage loadelfimage_32
     3.6 -#define xen_elfnote_string xen_elfnote_string32
     3.7 -#define xen_elfnote_numeric xen_elfnote_numeric32
     3.8 -#define ELFSIZE 32
     3.9 -#include "../../common/elf.c"
    3.10 -