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>
- 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 + /* convert xen pointer shared_info into guest physical */ 1.56 + shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page); 1.57 1.58 - /* Put stack below everything. */ 1.59 - v->arch.ctxt.gprs[1] = dst - STACK_FRAME_OVERHEAD; 1.60 - 1.61 - /* copy relative to Xen */ 1.62 - dst += rma; 1.63 + /* start loading stuff */ 1.64 + rc = elf_init(&elf, (void *)image_start, image_len); 1.65 + if (rc) 1.66 + return rc; 1.67 +#ifdef VERBOSE 1.68 + elf_set_verbose(&elf); 1.69 +#endif 1.70 + elf_parse_binary(&elf); 1.71 + if (0 != (elf_xen_parse(&elf, &parms))) 1.72 + return rc; 1.73 1.74 - ASSERT((dst - rma) + (ulong)firmware_image_size < eomem); 1.75 - printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma); 1.76 - memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size); 1.77 - 1.78 - v->arch.ctxt.gprs[5] = (dst - rma); 1.79 - ofh_tree = (u64 *)(dst + 0x10); 1.80 - ASSERT(*ofh_tree == 0xdeadbeef00000000); 1.81 + printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", 1.82 + elf_64bit(&elf) ? "64-bit" : "32-bit", 1.83 + elf.pstart, elf.pend); 1.84 1.85 - /* accomodate for a modest bss section */ 1.86 - dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE); 1.87 - ASSERT((dst - rma) + oftree_len < eomem); 1.88 + /* elf contains virtual addresses that can have the upper bits 1.89 + * masked while running in real mode, so we do the masking as well 1.90 + * as well */ 1.91 + parms.virt_kend = RM_MASK(parms.virt_kend, 42); 1.92 + parms.virt_entry = RM_MASK(parms.virt_entry, 42); 1.93 1.94 - *ofh_tree = dst - rma; 1.95 - printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma, 1.96 - oftree_len); 1.97 - memcpy((void *)dst, (void *)oftree, oftree_len); 1.98 - dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE); 1.99 + /* set the MSR bit correctly */ 1.100 + if (elf_64bit(&elf)) 1.101 + v->arch.ctxt.msr = MSR_SF; 1.102 + else 1.103 + v->arch.ctxt.msr = 0; 1.104 1.105 /* Load the dom0 kernel. */ 1.106 - elf.dest = (void *)dst; 1.107 + elf.dest = (void *)(parms.virt_kstart + rma); 1.108 + 1.109 elf_load_binary(&elf); 1.110 - v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart); 1.111 - dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE); 1.112 + v->arch.ctxt.pc = parms.virt_entry; 1.113 + 1.114 + dst = ALIGN_UP(parms.virt_kend + rma, PAGE_SIZE); 1.115 1.116 /* Load the initrd. */ 1.117 if (initrd_len > 0) { 1.118 @@ -247,15 +231,46 @@ int construct_dom0(struct domain *d, 1.119 printk("no initrd\n"); 1.120 } 1.121 1.122 - if (elf_64bit(&elf)) { 1.123 - v->arch.ctxt.msr = MSR_SF; 1.124 - } else { 1.125 - v->arch.ctxt.msr = 0; 1.126 - } 1.127 - v->arch.ctxt.gprs[2] = 0; 1.128 v->arch.ctxt.gprs[3] = mod_start; 1.129 v->arch.ctxt.gprs[4] = mod_len; 1.130 1.131 + /* OF usually sits here: 1.132 + * - Linux needs it to be loaded before the vmlinux or initrd 1.133 + * - AIX demands it to be @ 32M. 1.134 + */ 1.135 + firmware_base = (32 << 20); 1.136 + if (dst - rma > firmware_base) 1.137 + panic("Firmware [0x%lx] will over-write images ending: 0x%lx\n", 1.138 + firmware_base, dst - rma); 1.139 + dst = firmware_base + rma; 1.140 + 1.141 + /* Put stack below firmware. */ 1.142 + v->arch.ctxt.gprs[1] = dst - rma - STACK_FRAME_OVERHEAD; 1.143 + v->arch.ctxt.gprs[2] = 0; 1.144 + 1.145 + ASSERT((dst - rma) + (ulong)firmware_image_size < eomem); 1.146 + printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma); 1.147 + memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size); 1.148 + 1.149 + v->arch.ctxt.gprs[5] = (dst - rma); 1.150 + ofh_tree = (u64 *)(dst + 0x10); 1.151 + ASSERT(*ofh_tree == 0xdeadbeef00000000); 1.152 + 1.153 + /* accomodate for a modest bss section */ 1.154 + dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE); 1.155 + 1.156 + ASSERT((dst - rma) + oftree_len < eomem); 1.157 + 1.158 + *ofh_tree = dst - rma; 1.159 + printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma, 1.160 + oftree_len); 1.161 + memcpy((void *)dst, (void *)oftree, oftree_len); 1.162 + 1.163 + /* fixup and add stuff for dom0 */ 1.164 + sz = ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); 1.165 + printk("modified OFD size: 0x%lx\n", sz); 1.166 + dst = ALIGN_UP(dst + sz + PAGE_SIZE, PAGE_SIZE); 1.167 + 1.168 printk("dom0 initial register state:\n" 1.169 " pc %016lx msr %016lx\n" 1.170 " r1 %016lx r2 %016lx r3 %016lx\n" 1.171 @@ -268,11 +283,6 @@ int construct_dom0(struct domain *d, 1.172 v->arch.ctxt.gprs[4], 1.173 v->arch.ctxt.gprs[5]); 1.174 1.175 - /* convert xen pointer shared_info into guest physical */ 1.176 - shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page); 1.177 - 1.178 - ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); 1.179 - 1.180 v->is_initialised = 1; 1.181 clear_bit(_VPF_down, &v->pause_flags); 1.182