debuggers.hg
changeset 11046:b2fc8357b8ff
[LIBXC] move xc_ppc_linux_build.c into a powerpc64 directory
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author | Hollis Blanchard <hollisb@us.ibm.com> |
---|---|
date | Tue Aug 08 15:11:25 2006 -0500 (2006-08-08) |
parents | 00a41d1daf89 |
children | d161ee2ade7e |
files | tools/libxc/powerpc64/Makefile tools/libxc/powerpc64/xc_linux_build.c tools/libxc/xc_ppc_linux_build.c |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/libxc/powerpc64/Makefile Tue Aug 08 15:11:25 2006 -0500 1.3 @@ -0,0 +1,1 @@ 1.4 +CTRL_SRCS-y += powerpc64/xc_linux_build.c
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/libxc/powerpc64/xc_linux_build.c Tue Aug 08 15:11:25 2006 -0500 2.3 @@ -0,0 +1,408 @@ 2.4 +/* 2.5 + * This program is free software; you can redistribute it and/or modify 2.6 + * it under the terms of the GNU General Public License as published by 2.7 + * the Free Software Foundation; either version 2 of the License, or 2.8 + * (at your option) any later version. 2.9 + * 2.10 + * This program is distributed in the hope that it will be useful, 2.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 2.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.13 + * GNU General Public License for more details. 2.14 + * 2.15 + * You should have received a copy of the GNU General Public License 2.16 + * along with this program; if not, write to the Free Software 2.17 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2.18 + * 2.19 + * Copyright (C) IBM Corporation 2006 2.20 + * 2.21 + * Authors: Hollis Blanchard <hollisb@us.ibm.com> 2.22 + */ 2.23 + 2.24 +#include <stdio.h> 2.25 +#include <stdint.h> 2.26 +#include <stdlib.h> 2.27 +#include <string.h> 2.28 +#include <unistd.h> 2.29 +#include <fcntl.h> 2.30 +#include <sys/types.h> 2.31 +#include <inttypes.h> 2.32 + 2.33 +#include <xen/dom0_ops.h> 2.34 +#include <xen/memory.h> 2.35 +#include <xc_private.h> 2.36 +#include <xg_private.h> 2.37 +#include <xenctrl.h> 2.38 + 2.39 +/* XXX 64M hack */ 2.40 +#define MEMSIZE (64UL << 20) 2.41 +#define INITRD_ADDR (24UL << 20) 2.42 + 2.43 +#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) 2.44 + 2.45 +#define max(x,y) ({ \ 2.46 + const typeof(x) _x = (x); \ 2.47 + const typeof(y) _y = (y); \ 2.48 + (void) (&_x == &_y); \ 2.49 + _x > _y ? _x : _y; }) 2.50 + 2.51 +static void *load_file(const char *path, unsigned long *filesize) 2.52 +{ 2.53 + void *img; 2.54 + ssize_t size; 2.55 + int fd; 2.56 + 2.57 + DPRINTF("load_file(%s)\n", path); 2.58 + 2.59 + fd = open(path, O_RDONLY); 2.60 + if (fd < 0) { 2.61 + perror(path); 2.62 + return NULL; 2.63 + } 2.64 + 2.65 + size = lseek(fd, 0, SEEK_END); 2.66 + if (size < 0) { 2.67 + perror(path); 2.68 + close(fd); 2.69 + return NULL; 2.70 + } 2.71 + lseek(fd, 0, SEEK_SET); 2.72 + 2.73 + img = malloc(size); 2.74 + if (img == NULL) { 2.75 + perror(path); 2.76 + close(fd); 2.77 + return NULL; 2.78 + } 2.79 + 2.80 + size = read(fd, img, size); 2.81 + if (size <= 0) { 2.82 + perror(path); 2.83 + close(fd); 2.84 + free(img); 2.85 + return NULL; 2.86 + } 2.87 + 2.88 + if (filesize) 2.89 + *filesize = size; 2.90 + close(fd); 2.91 + return img; 2.92 +} 2.93 + 2.94 +static int init_boot_vcpu( 2.95 + int xc_handle, 2.96 + int domid, 2.97 + struct domain_setup_info *dsi, 2.98 + unsigned long dtb, 2.99 + unsigned long kaddr) 2.100 +{ 2.101 + vcpu_guest_context_t ctxt; 2.102 + int rc; 2.103 + 2.104 + memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs)); 2.105 + ctxt.user_regs.pc = dsi->v_kernentry; 2.106 + ctxt.user_regs.msr = 0; 2.107 + ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */ 2.108 + ctxt.user_regs.gprs[3] = dtb; 2.109 + ctxt.user_regs.gprs[4] = kaddr; 2.110 + ctxt.user_regs.gprs[5] = 0; 2.111 + /* There is a buggy kernel that does not zero the "local_paca", so 2.112 + * we must make sure this register is 0 */ 2.113 + ctxt.user_regs.gprs[13] = 0; 2.114 + 2.115 + DPRINTF("xc_vcpu_setvcpucontext:\n" 2.116 + " pc 0x%"PRIx64", msr 0x016%"PRIx64"\n" 2.117 + " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64 2.118 + " %016"PRIx64"\n", 2.119 + ctxt.user_regs.pc, ctxt.user_regs.msr, 2.120 + ctxt.user_regs.gprs[1], 2.121 + ctxt.user_regs.gprs[2], 2.122 + ctxt.user_regs.gprs[3], 2.123 + ctxt.user_regs.gprs[4], 2.124 + ctxt.user_regs.gprs[5]); 2.125 + rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt); 2.126 + if (rc < 0) 2.127 + perror("setdomaininfo"); 2.128 + 2.129 + return rc; 2.130 +} 2.131 + 2.132 +static int install_image( 2.133 + int xc_handle, 2.134 + int domid, 2.135 + xen_pfn_t *page_array, 2.136 + void *image, 2.137 + unsigned long paddr, 2.138 + unsigned long size) 2.139 +{ 2.140 + uint8_t *img = image; 2.141 + int i; 2.142 + int rc = 0; 2.143 + 2.144 + if (paddr & ~PAGE_MASK) { 2.145 + printf("*** unaligned address\n"); 2.146 + return -1; 2.147 + } 2.148 + 2.149 + for (i = 0; i < size; i += PAGE_SIZE) { 2.150 + void *page = img + i; 2.151 + xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT; 2.152 + xen_pfn_t mfn = page_array[pfn]; 2.153 + 2.154 + rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page); 2.155 + if (rc < 0) { 2.156 + perror("xc_copy_to_domain_page"); 2.157 + break; 2.158 + } 2.159 + } 2.160 + return rc; 2.161 +} 2.162 + 2.163 +/* XXX be more flexible about placement in memory */ 2.164 +static int load_dtb( 2.165 + int xc_handle, 2.166 + int domid, 2.167 + const char *dtb_path, 2.168 + unsigned long dtb_addr, 2.169 + struct domain_setup_info *dsi, 2.170 + xen_pfn_t *page_array) 2.171 +{ 2.172 + uint8_t *img; 2.173 + unsigned long dtb_size; 2.174 + int rc = 0; 2.175 + 2.176 + img = load_file(dtb_path, &dtb_size); 2.177 + if (img == NULL) { 2.178 + rc = -1; 2.179 + goto out; 2.180 + } 2.181 + 2.182 + DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size); 2.183 + rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size); 2.184 + 2.185 +out: 2.186 + free(img); 2.187 + return rc; 2.188 +} 2.189 + 2.190 +unsigned long spin_list[] = { 2.191 +#if 0 2.192 + 0x100, 2.193 + 0x200, 2.194 + 0x300, 2.195 + 0x380, 2.196 + 0x400, 2.197 + 0x480, 2.198 + 0x500, 2.199 + 0x700, 2.200 + 0x900, 2.201 + 0xc00, 2.202 +#endif 2.203 + 0 2.204 +}; 2.205 + 2.206 +/* XXX yes, this is a hack */ 2.207 +static void hack_kernel_img(char *img) 2.208 +{ 2.209 + const off_t file_offset = 0x10000; 2.210 + unsigned long *addr = spin_list; 2.211 + 2.212 + while (*addr) { 2.213 + uint32_t *instruction = (uint32_t *)(img + *addr + file_offset); 2.214 + printf("installing spin loop at %lx (%x)\n", *addr, *instruction); 2.215 + *instruction = 0x48000000; 2.216 + addr++; 2.217 + } 2.218 +} 2.219 + 2.220 +static int load_kernel( 2.221 + int xc_handle, 2.222 + int domid, 2.223 + const char *kernel_path, 2.224 + struct domain_setup_info *dsi, 2.225 + xen_pfn_t *page_array) 2.226 +{ 2.227 + struct load_funcs load_funcs; 2.228 + char *kernel_img; 2.229 + unsigned long kernel_size; 2.230 + int rc; 2.231 + 2.232 + /* load the kernel ELF file */ 2.233 + kernel_img = load_file(kernel_path, &kernel_size); 2.234 + if (kernel_img == NULL) { 2.235 + rc = -1; 2.236 + goto out; 2.237 + } 2.238 + 2.239 + hack_kernel_img(kernel_img); 2.240 + 2.241 + DPRINTF("probe_elf\n"); 2.242 + rc = probe_elf(kernel_img, kernel_size, &load_funcs); 2.243 + if (rc < 0) { 2.244 + rc = -1; 2.245 + printf("%s is not an ELF file\n", kernel_path); 2.246 + goto out; 2.247 + } 2.248 + 2.249 + DPRINTF("parseimage\n"); 2.250 + rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi); 2.251 + if (rc < 0) { 2.252 + rc = -1; 2.253 + goto out; 2.254 + } 2.255 + 2.256 + DPRINTF("loadimage\n"); 2.257 + (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid, 2.258 + page_array, dsi); 2.259 + 2.260 + DPRINTF(" v_start %016"PRIx64"\n", dsi->v_start); 2.261 + DPRINTF(" v_end %016"PRIx64"\n", dsi->v_end); 2.262 + DPRINTF(" v_kernstart %016"PRIx64"\n", dsi->v_kernstart); 2.263 + DPRINTF(" v_kernend %016"PRIx64"\n", dsi->v_kernend); 2.264 + DPRINTF(" v_kernentry %016"PRIx64"\n", dsi->v_kernentry); 2.265 + 2.266 +out: 2.267 + free(kernel_img); 2.268 + return rc; 2.269 +} 2.270 + 2.271 +static int load_initrd( 2.272 + int xc_handle, 2.273 + int domid, 2.274 + xen_pfn_t *page_array, 2.275 + const char *initrd_path, 2.276 + unsigned long *base, 2.277 + unsigned long *len) 2.278 +{ 2.279 + uint8_t *initrd_img; 2.280 + int rc = -1; 2.281 + 2.282 + /* load the initrd file */ 2.283 + initrd_img = load_file(initrd_path, len); 2.284 + if (initrd_img == NULL) 2.285 + return -1; 2.286 + 2.287 + DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len); 2.288 + if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR, 2.289 + *len)) 2.290 + goto out; 2.291 + 2.292 + *base = INITRD_ADDR; 2.293 + rc = 0; 2.294 + 2.295 +out: 2.296 + free(initrd_img); 2.297 + return rc; 2.298 +} 2.299 + 2.300 +static unsigned long create_start_info(start_info_t *si, 2.301 + unsigned int console_evtchn, unsigned int store_evtchn) 2.302 +{ 2.303 + unsigned long eomem; 2.304 + unsigned long si_addr; 2.305 + 2.306 + memset(si, 0, sizeof(*si)); 2.307 + snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); 2.308 + 2.309 + eomem = MEMSIZE; 2.310 + si->nr_pages = eomem >> PAGE_SHIFT; 2.311 + si->shared_info = eomem - (PAGE_SIZE * 1); 2.312 + si->store_mfn = si->nr_pages - 2; 2.313 + si->store_evtchn = store_evtchn; 2.314 + si->console_mfn = si->nr_pages - 3; 2.315 + si->console_evtchn = console_evtchn; 2.316 + si_addr = eomem - (PAGE_SIZE * 4); 2.317 + 2.318 + return si_addr; 2.319 +} 2.320 + 2.321 +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array) 2.322 +{ 2.323 + int nr_pages; 2.324 + int rc; 2.325 + 2.326 + DPRINTF("xc_get_tot_pages\n"); 2.327 + nr_pages = xc_get_tot_pages(xc_handle, domid); 2.328 + DPRINTF(" 0x%x\n", nr_pages); 2.329 + 2.330 + *page_array = malloc(nr_pages * sizeof(xen_pfn_t)); 2.331 + if (*page_array == NULL) { 2.332 + perror("malloc"); 2.333 + return -1; 2.334 + } 2.335 + 2.336 + DPRINTF("xc_get_pfn_list\n"); 2.337 + rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages); 2.338 + if (rc != nr_pages) { 2.339 + perror("Could not get the page frame list"); 2.340 + return -1; 2.341 + } 2.342 + 2.343 + return 0; 2.344 +} 2.345 + 2.346 + 2.347 + 2.348 +int xc_linux_build(int xc_handle, 2.349 + uint32_t domid, 2.350 + const char *image_name, 2.351 + const char *initrd_name, 2.352 + const char *cmdline, 2.353 + const char *features, 2.354 + unsigned long flags, 2.355 + unsigned int store_evtchn, 2.356 + unsigned long *store_mfn, 2.357 + unsigned int console_evtchn, 2.358 + unsigned long *console_mfn) 2.359 +{ 2.360 + struct domain_setup_info dsi; 2.361 + xen_pfn_t *page_array = NULL; 2.362 + unsigned long kern_addr; 2.363 + unsigned long dtb_addr; 2.364 + unsigned long si_addr; 2.365 + unsigned long initrd_base = 0; 2.366 + unsigned long initrd_len = 0; 2.367 + start_info_t si; 2.368 + int rc = 0; 2.369 + 2.370 + if (get_page_array(xc_handle, domid, &page_array)) { 2.371 + rc = -1; 2.372 + goto out; 2.373 + } 2.374 + 2.375 + if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) { 2.376 + rc = -1; 2.377 + goto out; 2.378 + } 2.379 + kern_addr = 0; 2.380 + 2.381 + if (initrd_name && initrd_name[0] != '\0' && 2.382 + load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base, 2.383 + &initrd_len)) { 2.384 + rc = -1; 2.385 + goto out; 2.386 + } 2.387 + /* XXX install initrd addr/len into device tree */ 2.388 + 2.389 + dtb_addr = (16 << 20); 2.390 + if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) { 2.391 + dtb_addr = 0; 2.392 + } 2.393 + 2.394 + si_addr = create_start_info(&si, console_evtchn, store_evtchn); 2.395 + *console_mfn = page_array[si.console_mfn]; 2.396 + *store_mfn = page_array[si.store_mfn]; 2.397 + 2.398 + if (install_image(xc_handle, domid, page_array, &si, si_addr, 2.399 + sizeof(start_info_t))) { 2.400 + rc = -1; 2.401 + goto out; 2.402 + } 2.403 + 2.404 + if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) { 2.405 + rc = -1; 2.406 + goto out; 2.407 + } 2.408 + 2.409 +out: 2.410 + return rc; 2.411 +}
3.1 --- a/tools/libxc/xc_ppc_linux_build.c Mon Aug 07 17:16:18 2006 -0500 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,408 +0,0 @@ 3.4 -/* 3.5 - * This program is free software; you can redistribute it and/or modify 3.6 - * it under the terms of the GNU General Public License as published by 3.7 - * the Free Software Foundation; either version 2 of the License, or 3.8 - * (at your option) any later version. 3.9 - * 3.10 - * This program is distributed in the hope that it will be useful, 3.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.13 - * GNU General Public License for more details. 3.14 - * 3.15 - * You should have received a copy of the GNU General Public License 3.16 - * along with this program; if not, write to the Free Software 3.17 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 3.18 - * 3.19 - * Copyright (C) IBM Corporation 2006 3.20 - * 3.21 - * Authors: Hollis Blanchard <hollisb@us.ibm.com> 3.22 - */ 3.23 - 3.24 -#include <stdio.h> 3.25 -#include <stdint.h> 3.26 -#include <stdlib.h> 3.27 -#include <string.h> 3.28 -#include <unistd.h> 3.29 -#include <fcntl.h> 3.30 -#include <sys/types.h> 3.31 -#include <inttypes.h> 3.32 - 3.33 -#include <xen/dom0_ops.h> 3.34 -#include <xen/memory.h> 3.35 -#include <xc_private.h> 3.36 -#include <xg_private.h> 3.37 -#include <xenctrl.h> 3.38 - 3.39 -/* XXX 64M hack */ 3.40 -#define MEMSIZE (64UL << 20) 3.41 -#define INITRD_ADDR (24UL << 20) 3.42 - 3.43 -#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) 3.44 - 3.45 -#define max(x,y) ({ \ 3.46 - const typeof(x) _x = (x); \ 3.47 - const typeof(y) _y = (y); \ 3.48 - (void) (&_x == &_y); \ 3.49 - _x > _y ? _x : _y; }) 3.50 - 3.51 -static void *load_file(const char *path, unsigned long *filesize) 3.52 -{ 3.53 - void *img; 3.54 - ssize_t size; 3.55 - int fd; 3.56 - 3.57 - DPRINTF("load_file(%s)\n", path); 3.58 - 3.59 - fd = open(path, O_RDONLY); 3.60 - if (fd < 0) { 3.61 - perror(path); 3.62 - return NULL; 3.63 - } 3.64 - 3.65 - size = lseek(fd, 0, SEEK_END); 3.66 - if (size < 0) { 3.67 - perror(path); 3.68 - close(fd); 3.69 - return NULL; 3.70 - } 3.71 - lseek(fd, 0, SEEK_SET); 3.72 - 3.73 - img = malloc(size); 3.74 - if (img == NULL) { 3.75 - perror(path); 3.76 - close(fd); 3.77 - return NULL; 3.78 - } 3.79 - 3.80 - size = read(fd, img, size); 3.81 - if (size <= 0) { 3.82 - perror(path); 3.83 - close(fd); 3.84 - free(img); 3.85 - return NULL; 3.86 - } 3.87 - 3.88 - if (filesize) 3.89 - *filesize = size; 3.90 - close(fd); 3.91 - return img; 3.92 -} 3.93 - 3.94 -static int init_boot_vcpu( 3.95 - int xc_handle, 3.96 - int domid, 3.97 - struct domain_setup_info *dsi, 3.98 - unsigned long dtb, 3.99 - unsigned long kaddr) 3.100 -{ 3.101 - vcpu_guest_context_t ctxt; 3.102 - int rc; 3.103 - 3.104 - memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs)); 3.105 - ctxt.user_regs.pc = dsi->v_kernentry; 3.106 - ctxt.user_regs.msr = 0; 3.107 - ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */ 3.108 - ctxt.user_regs.gprs[3] = dtb; 3.109 - ctxt.user_regs.gprs[4] = kaddr; 3.110 - ctxt.user_regs.gprs[5] = 0; 3.111 - /* There is a buggy kernel that does not zero the "local_paca", so 3.112 - * we must make sure this register is 0 */ 3.113 - ctxt.user_regs.gprs[13] = 0; 3.114 - 3.115 - DPRINTF("xc_vcpu_setvcpucontext:\n" 3.116 - " pc 0x%"PRIx64", msr 0x016%"PRIx64"\n" 3.117 - " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64 3.118 - " %016"PRIx64"\n", 3.119 - ctxt.user_regs.pc, ctxt.user_regs.msr, 3.120 - ctxt.user_regs.gprs[1], 3.121 - ctxt.user_regs.gprs[2], 3.122 - ctxt.user_regs.gprs[3], 3.123 - ctxt.user_regs.gprs[4], 3.124 - ctxt.user_regs.gprs[5]); 3.125 - rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt); 3.126 - if (rc < 0) 3.127 - perror("setdomaininfo"); 3.128 - 3.129 - return rc; 3.130 -} 3.131 - 3.132 -static int install_image( 3.133 - int xc_handle, 3.134 - int domid, 3.135 - xen_pfn_t *page_array, 3.136 - void *image, 3.137 - unsigned long paddr, 3.138 - unsigned long size) 3.139 -{ 3.140 - uint8_t *img = image; 3.141 - int i; 3.142 - int rc = 0; 3.143 - 3.144 - if (paddr & ~PAGE_MASK) { 3.145 - printf("*** unaligned address\n"); 3.146 - return -1; 3.147 - } 3.148 - 3.149 - for (i = 0; i < size; i += PAGE_SIZE) { 3.150 - void *page = img + i; 3.151 - xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT; 3.152 - xen_pfn_t mfn = page_array[pfn]; 3.153 - 3.154 - rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page); 3.155 - if (rc < 0) { 3.156 - perror("xc_copy_to_domain_page"); 3.157 - break; 3.158 - } 3.159 - } 3.160 - return rc; 3.161 -} 3.162 - 3.163 -/* XXX be more flexible about placement in memory */ 3.164 -static int load_dtb( 3.165 - int xc_handle, 3.166 - int domid, 3.167 - const char *dtb_path, 3.168 - unsigned long dtb_addr, 3.169 - struct domain_setup_info *dsi, 3.170 - xen_pfn_t *page_array) 3.171 -{ 3.172 - uint8_t *img; 3.173 - unsigned long dtb_size; 3.174 - int rc = 0; 3.175 - 3.176 - img = load_file(dtb_path, &dtb_size); 3.177 - if (img == NULL) { 3.178 - rc = -1; 3.179 - goto out; 3.180 - } 3.181 - 3.182 - DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size); 3.183 - rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size); 3.184 - 3.185 -out: 3.186 - free(img); 3.187 - return rc; 3.188 -} 3.189 - 3.190 -unsigned long spin_list[] = { 3.191 -#if 0 3.192 - 0x100, 3.193 - 0x200, 3.194 - 0x300, 3.195 - 0x380, 3.196 - 0x400, 3.197 - 0x480, 3.198 - 0x500, 3.199 - 0x700, 3.200 - 0x900, 3.201 - 0xc00, 3.202 -#endif 3.203 - 0 3.204 -}; 3.205 - 3.206 -/* XXX yes, this is a hack */ 3.207 -static void hack_kernel_img(char *img) 3.208 -{ 3.209 - const off_t file_offset = 0x10000; 3.210 - unsigned long *addr = spin_list; 3.211 - 3.212 - while (*addr) { 3.213 - uint32_t *instruction = (uint32_t *)(img + *addr + file_offset); 3.214 - printf("installing spin loop at %lx (%x)\n", *addr, *instruction); 3.215 - *instruction = 0x48000000; 3.216 - addr++; 3.217 - } 3.218 -} 3.219 - 3.220 -static int load_kernel( 3.221 - int xc_handle, 3.222 - int domid, 3.223 - const char *kernel_path, 3.224 - struct domain_setup_info *dsi, 3.225 - xen_pfn_t *page_array) 3.226 -{ 3.227 - struct load_funcs load_funcs; 3.228 - char *kernel_img; 3.229 - unsigned long kernel_size; 3.230 - int rc; 3.231 - 3.232 - /* load the kernel ELF file */ 3.233 - kernel_img = load_file(kernel_path, &kernel_size); 3.234 - if (kernel_img == NULL) { 3.235 - rc = -1; 3.236 - goto out; 3.237 - } 3.238 - 3.239 - hack_kernel_img(kernel_img); 3.240 - 3.241 - DPRINTF("probe_elf\n"); 3.242 - rc = probe_elf(kernel_img, kernel_size, &load_funcs); 3.243 - if (rc < 0) { 3.244 - rc = -1; 3.245 - printf("%s is not an ELF file\n", kernel_path); 3.246 - goto out; 3.247 - } 3.248 - 3.249 - DPRINTF("parseimage\n"); 3.250 - rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi); 3.251 - if (rc < 0) { 3.252 - rc = -1; 3.253 - goto out; 3.254 - } 3.255 - 3.256 - DPRINTF("loadimage\n"); 3.257 - (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid, 3.258 - page_array, dsi); 3.259 - 3.260 - DPRINTF(" v_start %016"PRIx64"\n", dsi->v_start); 3.261 - DPRINTF(" v_end %016"PRIx64"\n", dsi->v_end); 3.262 - DPRINTF(" v_kernstart %016"PRIx64"\n", dsi->v_kernstart); 3.263 - DPRINTF(" v_kernend %016"PRIx64"\n", dsi->v_kernend); 3.264 - DPRINTF(" v_kernentry %016"PRIx64"\n", dsi->v_kernentry); 3.265 - 3.266 -out: 3.267 - free(kernel_img); 3.268 - return rc; 3.269 -} 3.270 - 3.271 -static int load_initrd( 3.272 - int xc_handle, 3.273 - int domid, 3.274 - xen_pfn_t *page_array, 3.275 - const char *initrd_path, 3.276 - unsigned long *base, 3.277 - unsigned long *len) 3.278 -{ 3.279 - uint8_t *initrd_img; 3.280 - int rc = -1; 3.281 - 3.282 - /* load the initrd file */ 3.283 - initrd_img = load_file(initrd_path, len); 3.284 - if (initrd_img == NULL) 3.285 - return -1; 3.286 - 3.287 - DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len); 3.288 - if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR, 3.289 - *len)) 3.290 - goto out; 3.291 - 3.292 - *base = INITRD_ADDR; 3.293 - rc = 0; 3.294 - 3.295 -out: 3.296 - free(initrd_img); 3.297 - return rc; 3.298 -} 3.299 - 3.300 -static unsigned long create_start_info(start_info_t *si, 3.301 - unsigned int console_evtchn, unsigned int store_evtchn) 3.302 -{ 3.303 - unsigned long eomem; 3.304 - unsigned long si_addr; 3.305 - 3.306 - memset(si, 0, sizeof(*si)); 3.307 - snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); 3.308 - 3.309 - eomem = MEMSIZE; 3.310 - si->nr_pages = eomem >> PAGE_SHIFT; 3.311 - si->shared_info = eomem - (PAGE_SIZE * 1); 3.312 - si->store_mfn = si->nr_pages - 2; 3.313 - si->store_evtchn = store_evtchn; 3.314 - si->console_mfn = si->nr_pages - 3; 3.315 - si->console_evtchn = console_evtchn; 3.316 - si_addr = eomem - (PAGE_SIZE * 4); 3.317 - 3.318 - return si_addr; 3.319 -} 3.320 - 3.321 -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array) 3.322 -{ 3.323 - int nr_pages; 3.324 - int rc; 3.325 - 3.326 - DPRINTF("xc_get_tot_pages\n"); 3.327 - nr_pages = xc_get_tot_pages(xc_handle, domid); 3.328 - DPRINTF(" 0x%x\n", nr_pages); 3.329 - 3.330 - *page_array = malloc(nr_pages * sizeof(xen_pfn_t)); 3.331 - if (*page_array == NULL) { 3.332 - perror("malloc"); 3.333 - return -1; 3.334 - } 3.335 - 3.336 - DPRINTF("xc_get_pfn_list\n"); 3.337 - rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages); 3.338 - if (rc != nr_pages) { 3.339 - perror("Could not get the page frame list"); 3.340 - return -1; 3.341 - } 3.342 - 3.343 - return 0; 3.344 -} 3.345 - 3.346 - 3.347 - 3.348 -int xc_linux_build(int xc_handle, 3.349 - uint32_t domid, 3.350 - const char *image_name, 3.351 - const char *initrd_name, 3.352 - const char *cmdline, 3.353 - const char *features, 3.354 - unsigned long flags, 3.355 - unsigned int store_evtchn, 3.356 - unsigned long *store_mfn, 3.357 - unsigned int console_evtchn, 3.358 - unsigned long *console_mfn) 3.359 -{ 3.360 - struct domain_setup_info dsi; 3.361 - xen_pfn_t *page_array = NULL; 3.362 - unsigned long kern_addr; 3.363 - unsigned long dtb_addr; 3.364 - unsigned long si_addr; 3.365 - unsigned long initrd_base = 0; 3.366 - unsigned long initrd_len = 0; 3.367 - start_info_t si; 3.368 - int rc = 0; 3.369 - 3.370 - if (get_page_array(xc_handle, domid, &page_array)) { 3.371 - rc = -1; 3.372 - goto out; 3.373 - } 3.374 - 3.375 - if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) { 3.376 - rc = -1; 3.377 - goto out; 3.378 - } 3.379 - kern_addr = 0; 3.380 - 3.381 - if (initrd_name && initrd_name[0] != '\0' && 3.382 - load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base, 3.383 - &initrd_len)) { 3.384 - rc = -1; 3.385 - goto out; 3.386 - } 3.387 - /* XXX install initrd addr/len into device tree */ 3.388 - 3.389 - dtb_addr = (16 << 20); 3.390 - if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) { 3.391 - dtb_addr = 0; 3.392 - } 3.393 - 3.394 - si_addr = create_start_info(&si, console_evtchn, store_evtchn); 3.395 - *console_mfn = page_array[si.console_mfn]; 3.396 - *store_mfn = page_array[si.store_mfn]; 3.397 - 3.398 - if (install_image(xc_handle, domid, page_array, &si, si_addr, 3.399 - sizeof(start_info_t))) { 3.400 - rc = -1; 3.401 - goto out; 3.402 - } 3.403 - 3.404 - if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) { 3.405 - rc = -1; 3.406 - goto out; 3.407 - } 3.408 - 3.409 -out: 3.410 - return rc; 3.411 -}