direct-io.hg

changeset 15487:cb40299a0733

[POWERPC][XEN] Simplify Dom0 Loading.

- Load the kernel image before all other images, this allows for
debugging image location to be way easier.
- Simplify libelf usage

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Sun Jun 03 10:15:50 2007 -0400 (2007-06-03)
parents dca7528ef9f1
children 6d2645b78975
files xen/arch/powerpc/domain_build.c
line diff
     1.1 --- a/xen/arch/powerpc/domain_build.c	Sun Jun 03 10:02:25 2007 -0400
     1.2 +++ b/xen/arch/powerpc/domain_build.c	Sun Jun 03 10:15:50 2007 -0400
     1.3 @@ -68,6 +68,7 @@ int construct_dom0(struct domain *d,
     1.4      struct vcpu *v;
     1.5      ulong dst;
     1.6      u64 *ofh_tree;
     1.7 +    ulong firmware_base;
     1.8      uint rma_nrpages = 1 << cpu_default_rma_order_pages();
     1.9      ulong rma_sz;
    1.10      ulong rma;
    1.11 @@ -78,6 +79,7 @@ int construct_dom0(struct domain *d,
    1.12      ulong mod_len = 0;
    1.13      ulong shared_info_addr;
    1.14      uint extent_size = 1 << cpu_extent_order();
    1.15 +    ulong sz;
    1.16  
    1.17      /* Sanity! */
    1.18      BUG_ON(d->domain_id != 0);
    1.19 @@ -87,26 +89,6 @@ int construct_dom0(struct domain *d,
    1.20  
    1.21      printk("*** LOADING DOMAIN 0 ***\n");
    1.22  
    1.23 -    rc = elf_init(&elf, (void *)image_start, image_len);
    1.24 -    if (rc)
    1.25 -        return rc;
    1.26 -#ifdef VERBOSE
    1.27 -    elf_set_verbose(&elf);
    1.28 -#endif
    1.29 -    elf_parse_binary(&elf);
    1.30 -    if (0 != (elf_xen_parse(&elf, &parms)))
    1.31 -        return rc;
    1.32 -
    1.33 -    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
    1.34 -            elf_64bit(&elf) ? "64-bit" : "32-bit",
    1.35 -            elf.pstart, elf.pend);
    1.36 -
    1.37 -    /* elf contains virtual addresses that can have the upper bits
    1.38 -     * masked while running in real mode, so we do the masking as well
    1.39 -     * as well */
    1.40 -    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
    1.41 -    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
    1.42 -
    1.43      /* default is the max(1/16th of memory, CONFIG_MIN_DOM0_PAGES) */
    1.44      if (dom0_nrpages == 0) {
    1.45          dom0_nrpages = total_pages >> 4;
    1.46 @@ -196,41 +178,43 @@ int construct_dom0(struct domain *d,
    1.47      v = d->vcpu[0];
    1.48      cpu_init_vcpu(v);
    1.49  
    1.50 -    /* OF usually sits here:
    1.51 -     *   - Linux needs it to be loaded before the vmlinux or initrd
    1.52 -     *   - AIX demands it to be @ 32M.
    1.53 -     */
    1.54 -    dst = (32 << 20);
    1.55 -
    1.56 -    /* Put stack below everything. */
    1.57 -    v->arch.ctxt.gprs[1] = dst - STACK_FRAME_OVERHEAD;
    1.58 -
    1.59 -    /* copy relative to Xen */
    1.60 -    dst += rma;
    1.61 +    /* convert xen pointer shared_info into guest physical */
    1.62 +    shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page);
    1.63  
    1.64 -    ASSERT((dst - rma) + (ulong)firmware_image_size < eomem);
    1.65 -    printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma);
    1.66 -    memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size);
    1.67 -
    1.68 -    v->arch.ctxt.gprs[5] = (dst - rma);
    1.69 -    ofh_tree = (u64 *)(dst + 0x10);
    1.70 -    ASSERT(*ofh_tree == 0xdeadbeef00000000);
    1.71 +    /* start loading stuff */
    1.72 +    rc = elf_init(&elf, (void *)image_start, image_len);
    1.73 +    if (rc)
    1.74 +        return rc;
    1.75 +#ifdef VERBOSE
    1.76 +    elf_set_verbose(&elf);
    1.77 +#endif
    1.78 +    elf_parse_binary(&elf);
    1.79 +    if (0 != (elf_xen_parse(&elf, &parms)))
    1.80 +        return rc;
    1.81  
    1.82 -    /* accomodate for a modest bss section */
    1.83 -    dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE);
    1.84 -    ASSERT((dst - rma) + oftree_len < eomem);
    1.85 +    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
    1.86 +            elf_64bit(&elf) ? "64-bit" : "32-bit",
    1.87 +            elf.pstart, elf.pend);
    1.88  
    1.89 -    *ofh_tree = dst - rma;
    1.90 -    printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
    1.91 -           oftree_len);
    1.92 -    memcpy((void *)dst, (void *)oftree, oftree_len);
    1.93 -    dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE);
    1.94 +    /* elf contains virtual addresses that can have the upper bits
    1.95 +     * masked while running in real mode, so we do the masking as well
    1.96 +     * as well */
    1.97 +    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
    1.98 +    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
    1.99 +
   1.100 +    /* set the MSR bit correctly */
   1.101 +    if (elf_64bit(&elf))
   1.102 +        v->arch.ctxt.msr = MSR_SF;
   1.103 +    else
   1.104 +        v->arch.ctxt.msr = 0;
   1.105  
   1.106      /* Load the dom0 kernel. */
   1.107 -    elf.dest = (void *)dst;
   1.108 +    elf.dest = (void *)(parms.virt_kstart + rma);
   1.109 +
   1.110      elf_load_binary(&elf);
   1.111 -    v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart);
   1.112 -    dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
   1.113 +    v->arch.ctxt.pc = parms.virt_entry;
   1.114 +
   1.115 +    dst = ALIGN_UP(parms.virt_kend + rma, PAGE_SIZE);
   1.116  
   1.117      /* Load the initrd. */
   1.118      if (initrd_len > 0) {
   1.119 @@ -247,15 +231,46 @@ int construct_dom0(struct domain *d,
   1.120          printk("no initrd\n");
   1.121      }
   1.122  
   1.123 -    if (elf_64bit(&elf)) {
   1.124 -        v->arch.ctxt.msr = MSR_SF;
   1.125 -    } else {
   1.126 -        v->arch.ctxt.msr = 0;
   1.127 -    }
   1.128 -    v->arch.ctxt.gprs[2] = 0;
   1.129      v->arch.ctxt.gprs[3] = mod_start;
   1.130      v->arch.ctxt.gprs[4] = mod_len;
   1.131  
   1.132 +    /* OF usually sits here:
   1.133 +     *   - Linux needs it to be loaded before the vmlinux or initrd
   1.134 +     *   - AIX demands it to be @ 32M.
   1.135 +     */
   1.136 +    firmware_base = (32 << 20);
   1.137 +    if (dst - rma > firmware_base)
   1.138 +    panic("Firmware [0x%lx] will over-write images ending: 0x%lx\n",
   1.139 +          firmware_base, dst - rma);
   1.140 +    dst = firmware_base + rma;
   1.141 +
   1.142 +    /* Put stack below firmware. */
   1.143 +    v->arch.ctxt.gprs[1] = dst - rma - STACK_FRAME_OVERHEAD;
   1.144 +    v->arch.ctxt.gprs[2] = 0;
   1.145 +
   1.146 +    ASSERT((dst - rma) + (ulong)firmware_image_size < eomem);
   1.147 +    printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma);
   1.148 +    memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size);
   1.149 +
   1.150 +    v->arch.ctxt.gprs[5] = (dst - rma);
   1.151 +    ofh_tree = (u64 *)(dst + 0x10);
   1.152 +    ASSERT(*ofh_tree == 0xdeadbeef00000000);
   1.153 +
   1.154 +    /* accomodate for a modest bss section */
   1.155 +    dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE);
   1.156 +
   1.157 +    ASSERT((dst - rma) + oftree_len < eomem);
   1.158 +
   1.159 +    *ofh_tree = dst - rma;
   1.160 +    printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
   1.161 +           oftree_len);
   1.162 +    memcpy((void *)dst, (void *)oftree, oftree_len);
   1.163 +
   1.164 +    /* fixup and add stuff for dom0 */
   1.165 +    sz = ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
   1.166 +    printk("modified OFD size: 0x%lx\n", sz);
   1.167 +    dst = ALIGN_UP(dst + sz + PAGE_SIZE, PAGE_SIZE);
   1.168 +
   1.169  	printk("dom0 initial register state:\n"
   1.170  			"    pc %016lx msr %016lx\n"
   1.171  			"    r1 %016lx r2 %016lx r3 %016lx\n"
   1.172 @@ -268,11 +283,6 @@ int construct_dom0(struct domain *d,
   1.173  			v->arch.ctxt.gprs[4],
   1.174  			v->arch.ctxt.gprs[5]);
   1.175  
   1.176 -    /* convert xen pointer shared_info into guest physical */
   1.177 -    shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page);
   1.178 -
   1.179 -    ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
   1.180 -
   1.181      v->is_initialised = 1;
   1.182      clear_bit(_VPF_down, &v->pause_flags);
   1.183