[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XenPPC] [xenppc-unstable] [ppc] implement "xc_linux_build" (untested, but based on tools/domctrl/create.c)



# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Node ID 5c726b5ab92b24011c2f982b620ebe884e568f5e
# Parent  81281ae027e1844ef8475cf5eeaffe43a1413752
[ppc] implement "xc_linux_build" (untested, but based on tools/domctrl/create.c)
Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 tools/domctrl/create.c           |    6 
 tools/libxc/Makefile             |    5 
 tools/libxc/xc_ppc_linux_build.c |  388 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 395 insertions(+), 4 deletions(-)

diff -r 81281ae027e1 -r 5c726b5ab92b tools/domctrl/create.c
--- a/tools/domctrl/create.c    Tue Jun 06 15:03:45 2006 -0500
+++ b/tools/domctrl/create.c    Tue Jun 06 15:30:06 2006 -0500
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <sys/types.h>
 
 #include <xen/dom0_ops.h>
@@ -124,8 +125,9 @@ static int init_boot_vcpu(
        ctxt.user_regs.gprs[5] = 0;
 
        DEBUG(printf("xc_vcpu_setvcpucontext:\n"
-                 "  pc 0x%lx, msr 0x016%lx\n"
-                 "  r1-5 %016lx %016lx %016lx %016lx %016lx\n",
+                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
+                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64
+                 " %016"PRIx64" %016"PRIx64"\n",
                  ctxt.user_regs.pc, ctxt.user_regs.msr,
                  ctxt.user_regs.gprs[1],
                  ctxt.user_regs.gprs[2],
diff -r 81281ae027e1 -r 5c726b5ab92b tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Jun 06 15:03:45 2006 -0500
+++ b/tools/libxc/Makefile      Tue Jun 06 15:30:06 2006 -0500
@@ -26,11 +26,12 @@ CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
 CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
 
 GUEST_SRCS-y :=
-GUEST_SRCS-y += xc_linux_build.c
 GUEST_SRCS-y += xc_load_bin.c
 GUEST_SRCS-y += xc_load_elf.c
 GUEST_SRCS-y += xg_private.c
-GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
+GUEST_SRCS-$(CONFIG_POWERPC) += xc_ppc_linux_build.c
+GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
+GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c xc_linux_build.c
 GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
diff -r 81281ae027e1 -r 5c726b5ab92b tools/libxc/xc_ppc_linux_build.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_ppc_linux_build.c  Tue Jun 06 15:30:06 2006 -0500
@@ -0,0 +1,388 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <xen/dom0_ops.h>
+#include <xen/memory.h>
+#include <xc_private.h>
+#include <xg_private.h>
+#include <xenctrl.h>
+
+/* XXX 64M hack */
+#define MEMSIZE (64UL << 20)
+#define INITRD_ADDR (24UL << 20)
+
+int verbose;
+#define VERBOSE(stuff, ...) \
+    if (verbose) \
+        stuff __VA_ARGS__;
+
+#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+
+#define max(x,y) ({ \
+        const typeof(x) _x = (x);       \
+        const typeof(y) _y = (y);       \
+        (void) (&_x == &_y);            \
+        _x > _y ? _x : _y; })
+
+static void *load_file(const char *path, unsigned long *filesize)
+{
+    void *img;
+    ssize_t size;
+    int fd;
+
+    VERBOSE(printf("load_file(%s)\n", path));
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        perror(path);
+        return NULL;
+    }
+
+    size = lseek(fd, 0, SEEK_END);
+    if (size < 0) {
+        perror(path);
+        close(fd);
+        return NULL;
+    }
+    lseek(fd, 0, SEEK_SET);
+
+    img = malloc(size);
+    if (img == NULL) {
+        perror(path);
+        close(fd);
+        return NULL;
+    }
+
+    size = read(fd, img, size);
+    if (size <= 0) {
+        perror(path);
+        close(fd);
+        free(img);
+        return NULL;
+    }
+
+    if (filesize)
+        *filesize = size;
+    close(fd);
+    return img;
+}
+
+static int init_boot_vcpu(
+    int xc_handle,
+    int domid,
+    struct domain_setup_info *dsi,
+    unsigned long dtb,
+    unsigned long kaddr)
+{
+    vcpu_guest_context_t ctxt;
+    int rc;
+
+    memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
+    ctxt.user_regs.pc = dsi->v_kernentry;
+    ctxt.user_regs.msr = 0;
+    ctxt.user_regs.gprs[1] = 32<<20; /* XXX arbitrary stack address */
+    ctxt.user_regs.gprs[3] = dtb;
+    ctxt.user_regs.gprs[4] = kaddr;
+    ctxt.user_regs.gprs[5] = 0;
+
+    VERBOSE(printf("xc_vcpu_setvcpucontext:\n"
+                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
+                 "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
+                 " %016"PRIx64"\n",
+                 ctxt.user_regs.pc, ctxt.user_regs.msr,
+                 ctxt.user_regs.gprs[1],
+                 ctxt.user_regs.gprs[2],
+                 ctxt.user_regs.gprs[3],
+                 ctxt.user_regs.gprs[4],
+                 ctxt.user_regs.gprs[5]));
+    rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
+    if (rc < 0)
+        perror("setdomaininfo");
+
+    return rc;
+}
+
+static int install_image(
+        int xc_handle,
+        int domid,
+        xen_pfn_t *page_array,
+        void *image,
+        unsigned long paddr,
+        unsigned long size)
+{
+    uint8_t *img = image;
+    int i;
+    int rc = 0;
+
+    if (paddr & ~PAGE_MASK) {
+        printf("*** unaligned address\n");
+        return -1;
+    }
+
+    for (i = 0; i < size; i += PAGE_SIZE) {
+        void *page = img + i;
+        xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
+        xen_pfn_t mfn = page_array[pfn];
+
+        rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
+        if (rc < 0) {
+            perror("xc_copy_to_domain_page");
+            break;
+        }
+    }
+    return rc;
+}
+
+/* XXX be more flexible about placement in memory */
+static int load_dtb(
+    int xc_handle,
+    int domid,
+    const char *dtb_path,
+    unsigned long dtb_addr,
+    struct domain_setup_info *dsi,
+    xen_pfn_t *page_array)
+{
+    uint8_t *img;
+    unsigned long dtb_size;
+    int rc = 0;
+
+    img = load_file(dtb_path, &dtb_size);
+    if (img == NULL) {
+        rc = -1;
+        goto out;
+    }
+
+    VERBOSE(printf("copying device tree to 0x%lx[0x%lx]\n",
+            dtb_addr, dtb_size));
+    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
+
+out:
+    free(img);
+    return rc;
+}
+
+unsigned long spin_list[] = {
+#if 0
+    0x100,
+    0x200,
+    0x300,
+    0x380,
+    0x400,
+    0x480,
+    0x500,
+    0x700,
+    0x900,
+    0xc00,
+#endif
+    0
+};
+
+/* XXX yes, this is a hack */
+static void hack_kernel_img(uint8_t *img)
+{
+    const off_t file_offset = 0x10000;
+    unsigned long *addr = spin_list;
+
+    while (*addr) {
+        uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
+        printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
+        *instruction = 0x48000000;
+        addr++;
+    }
+}
+
+static int load_kernel(
+    int xc_handle,
+    int domid,
+    const char *kernel_path,
+    struct domain_setup_info *dsi,
+    xen_pfn_t *page_array)
+{
+    struct load_funcs load_funcs;
+    uint8_t *kernel_img;
+    unsigned long kernel_size;
+    int rc;
+
+    /* load the kernel ELF file */
+    kernel_img = load_file(kernel_path, &kernel_size);
+    if (kernel_img == NULL) {
+        rc = -1;
+        goto out;
+    }
+
+    hack_kernel_img(kernel_img);
+
+    VERBOSE(printf("probe_elf\n"));
+    rc = probe_elf(kernel_img, kernel_size, &load_funcs);
+    if (rc < 0) {
+        rc = -1;
+        printf("%s is not an ELF file\n", kernel_path);
+        goto out;
+    }
+
+    VERBOSE(printf("parseimage\n"));
+    rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
+    if (rc < 0) {
+        rc = -1;
+        goto out;
+    }
+
+    VERBOSE(printf("loadimage\n"));
+    (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
+            page_array, dsi);
+
+    VERBOSE(printf("  v_start     %lx\n", dsi->v_start));
+    VERBOSE(printf("  v_end       %lx\n", dsi->v_end));
+    VERBOSE(printf("  v_kernstart %lx\n", dsi->v_kernstart));
+    VERBOSE(printf("  v_kernend   %lx\n", dsi->v_kernend));
+    VERBOSE(printf("  v_kernentry %lx\n", dsi->v_kernentry));
+
+out:
+    free(kernel_img);
+    return rc;
+}
+
+static int load_initrd(
+    int xc_handle,
+    int domid,
+    xen_pfn_t *page_array,
+    const char *initrd_path,
+    unsigned long *base,
+    unsigned long *len)
+{
+    uint8_t *initrd_img;
+    int rc = -1;
+
+    /* load the initrd file */
+    initrd_img = load_file(initrd_path, len);
+    if (initrd_img == NULL)
+        return -1;
+
+    VERBOSE(printf("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len));
+    if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
+                *len))
+        goto out;
+
+    *base = INITRD_ADDR;
+    rc = 0;
+
+out:
+    free(initrd_img);
+    return rc;
+}
+
+static unsigned long create_start_info(start_info_t *si,
+        unsigned int console_evtchn, unsigned int store_evtchn)
+{
+    unsigned long eomem;
+    unsigned long si_addr;
+
+    memset(si, 0, sizeof(*si));
+    snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
+
+    eomem = MEMSIZE;
+    si->nr_pages = eomem >> PAGE_SHIFT;
+    si->shared_info = eomem - (PAGE_SIZE * 1);
+    si->store_mfn = si->nr_pages - 2;
+    si->store_evtchn = store_evtchn;
+    si->console_mfn = si->nr_pages - 3;
+    si->console_evtchn = console_evtchn;
+    si_addr = eomem - (PAGE_SIZE * 4);
+
+    return si_addr;
+}
+
+static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
+{
+    int nr_pages;
+    int rc;
+
+    VERBOSE(printf("xc_get_tot_pages\n"));
+    nr_pages = xc_get_tot_pages(xc_handle, domid);
+    VERBOSE(printf("  0x%x\n", nr_pages));
+
+    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
+    if (*page_array == NULL) {
+        perror("malloc");
+        return -1;
+    }
+
+    VERBOSE(printf("xc_get_pfn_list\n"));
+    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
+    if (rc != nr_pages) {
+        perror("Could not get the page frame list");
+        return -1;
+    }
+
+    return 0;
+}
+
+int xc_linux_build(int xc_handle,
+                   uint32_t domid,
+                   const char *image_name,
+                   const char *initrd_name,
+                   const char *cmdline,
+                   const char *features,
+                   unsigned long flags,
+                   unsigned int store_evtchn,
+                   unsigned long *store_mfn,
+                   unsigned int console_evtchn,
+                   unsigned long *console_mfn)
+{
+    struct domain_setup_info dsi;
+    xen_pfn_t *page_array = NULL;
+    unsigned long kern_addr;
+    unsigned long dtb_addr;
+    unsigned long si_addr;
+    unsigned long initrd_base = 0;
+    unsigned long initrd_len = 0;
+    start_info_t si;
+    int rc = 0;
+
+    if (get_page_array(xc_handle, domid, &page_array)) {
+        rc = -1;
+        goto out;
+    }
+
+    if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
+        rc = -1;
+        goto out;
+    }
+    kern_addr = 0;
+
+    if (load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
+                &initrd_len)) {
+        rc = -1;
+        goto out;
+    }
+    /* XXX install initrd addr/len into device tree */
+
+    dtb_addr = (16 << 20);
+    if (load_dtb(xc_handle, domid, "DomU.dtb", dtb_addr, &dsi, page_array)) {
+        rc = -1;
+        goto out;
+    }
+
+    si_addr = create_start_info(&si, store_evtchn, console_evtchn);
+    *console_mfn = si.console_mfn;
+    *store_mfn = si.store_mfn;
+    if (install_image(xc_handle, domid, page_array, &si, si_addr,
+                sizeof(start_info_t))) {
+        rc = -1;
+        goto out;
+    }
+
+    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
+        rc = -1;
+        goto out;
+    }
+
+out:
+    return rc;
+}

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.