# HG changeset patch # User Tristan Gingold # Date 1202795767 -3600 # Node ID 48046defcfb3f2224fb8ca8cc14bc752c82a8cb5 # Parent 6ba0c3a71fe1e3579e4d07bfa54a26fd8648a7ad Implements Self-IOEMUlator - loader Signed-off-by: Tristan Gingold diff -r 6ba0c3a71fe1 -r 48046defcfb3 tools/libxc/ia64/Makefile --- a/tools/libxc/ia64/Makefile Tue Feb 12 06:55:31 2008 +0100 +++ b/tools/libxc/ia64/Makefile Tue Feb 12 06:56:07 2008 +0100 @@ -6,6 +6,8 @@ GUEST_SRCS-y += ia64/xc_ia64_linux_resto GUEST_SRCS-y += ia64/xc_dom_ia64_util.c GUEST_SRCS-y += ia64/dom_fw_acpi.c + +GUEST_SRCS-y += ia64/xc_ia64_dom_fwloader.c DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE)) diff -r 6ba0c3a71fe1 -r 48046defcfb3 tools/libxc/ia64/xc_dom_ia64_util.h --- a/tools/libxc/ia64/xc_dom_ia64_util.h Tue Feb 12 06:55:31 2008 +0100 +++ b/tools/libxc/ia64/xc_dom_ia64_util.h Tue Feb 12 06:56:07 2008 +0100 @@ -16,4 +16,11 @@ xen_ia64_dom_fw_setup(struct xc_dom_imag #define efi_systable_init_dom0(tables) assert(0) #define complete_dom0_memmap(d, tables) ({assert(0);0;}) +/* Defined in xc_dom_ia64.c */ +extern int start_info_ia64(struct xc_dom_image *dom); +extern int shared_info_ia64(struct xc_dom_image *dom, void *ptr); + +#define FW_MEM_BASE 0xff000000UL +#define FW_MEM_SIZE 0x01000000UL + #endif /* XC_IA64_DOM_IA64_UTIL_H */ diff -r 6ba0c3a71fe1 -r 48046defcfb3 tools/libxc/ia64/xc_ia64_dom_fwloader.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_ia64_dom_fwloader.c Tue Feb 12 06:56:07 2008 +0100 @@ -0,0 +1,124 @@ +#include +#include +#include + +#include +#include +#include + +#include "xg_private.h" +#include "xc_dom.h" + +#include "ia64/xc_dom_ia64_util.h" + +static const char fw_magic[16] = {'X', 'e', 'n', '-', + 'i', 'a', '6', '4', + '-', 'f', 'w', 0, + 0, 0, 0, 0}; +#define FW_LOAD 0xff800000UL +#define FW_SIZE (8 * 1024 * 1024) + +static int xc_dom_probe_fw_kernel(struct xc_dom_image *dom) +{ + if (dom->kernel_size != FW_SIZE) + return -EINVAL; + if (memcmp (dom->kernel_blob, fw_magic, sizeof (fw_magic))) + return -EINVAL; + return 0; +} + +static int xc_dom_parse_fw_kernel(struct xc_dom_image *dom) +{ + dom->kernel_seg.vstart = FW_LOAD; + dom->kernel_seg.vend = FW_LOAD + FW_SIZE; + dom->parms.virt_base = FW_MEM_BASE; + dom->parms.virt_entry = FW_LOAD + sizeof (fw_magic); + dom->ramdisk_blob = NULL; /* No ramdisk yet. */ + dom->guest_type = "hvm-3.0-ia64"; + return 0; +} + +static int xc_dom_load_fw_kernel(struct xc_dom_image *dom) +{ + char *dest; + unsigned long i; + + dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart); + memcpy(dest, dom->kernel_blob, FW_SIZE); + + /* Synchronize cache. */ + for (i = 0; i < FW_SIZE; i += 32) + asm volatile ("fc.i %0" :: "r"(dest + i) : "memory"); + + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int alloc_magic_pages(struct xc_dom_image *dom) +{ + /* allocate special pages */ + dom->console_pfn = 0; + dom->xenstore_pfn = 1; + dom->start_info_pfn = 2; + return 0; +} + +extern unsigned long xc_ia64_fpsr_default(void); + +static int vcpu_ia64(struct xc_dom_image *dom, void *ptr) +{ + vcpu_guest_context_ia64_t *ctxt = ptr; + + xc_dom_printf("%s: called\n", __FUNCTION__); + + /* clear everything */ + memset(ctxt, 0, sizeof(*ctxt)); + + ctxt->flags = 0; + ctxt->regs.ip = dom->parms.virt_entry; +#ifdef __ia64__ /* FIXME */ + ctxt->regs.ar.fpsr = xc_ia64_fpsr_default(); +#endif + ctxt->regs.cr.isr = 1UL << 63; + ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_BN; + ctxt->regs.cr.dcr = 0; + ctxt->regs.cr.pta = 15 << 2; + + return 0; +} + +static struct xc_dom_arch xc_dom_arch_ia64_fw = { + .guest_type = "hvm-3.0-ia64", + .native_protocol = XEN_IO_PROTO_ABI_IA64, + .page_shift = PAGE_SHIFT_IA64, + .alloc_magic_pages = alloc_magic_pages, + .start_info = start_info_ia64, + .shared_info = shared_info_ia64, + .vcpu = vcpu_ia64, +}; + +/* ------------------------------------------------------------------------ */ + +static struct xc_dom_loader fw_loader = { + .name = "xen-ia64-fw", + .probe = xc_dom_probe_fw_kernel, + .parser = xc_dom_parse_fw_kernel, + .loader = xc_dom_load_fw_kernel, +}; + +static void __init register_fwloader(void) +{ + xc_dom_register_arch_hooks(&xc_dom_arch_ia64_fw); + xc_dom_register_loader(&fw_loader); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 6ba0c3a71fe1 -r 48046defcfb3 tools/libxc/xc_dom_ia64.c --- a/tools/libxc/xc_dom_ia64.c Tue Feb 12 06:55:31 2008 +0100 +++ b/tools/libxc/xc_dom_ia64.c Tue Feb 12 06:56:07 2008 +0100 @@ -37,7 +37,7 @@ static int alloc_magic_pages(struct xc_d return 0; } -static int start_info_ia64(struct xc_dom_image *dom) +int start_info_ia64(struct xc_dom_image *dom) { start_info_ia64_t *start_info = xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); @@ -79,7 +79,7 @@ static int start_info_ia64(struct xc_dom return 0; } -static int shared_info_ia64(struct xc_dom_image *dom, void *ptr) +int shared_info_ia64(struct xc_dom_image *dom, void *ptr) { shared_info_ia64_t *shared_info = ptr; int i; @@ -153,15 +153,27 @@ int arch_setup_meminit(struct xc_dom_ima { xen_pfn_t pfn; int rc; + unsigned long start; + unsigned long nbr; /* setup initial p2m */ - dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); - for ( pfn = 0; pfn < dom->total_pages; pfn++ ) - dom->p2m_host[pfn] = pfn; + if (dom->guest_type && strcmp (dom->guest_type, "hvm-3.0-ia64") == 0) { + start = FW_MEM_BASE >> PAGE_SHIFT_IA64; + nbr = FW_MEM_SIZE >> PAGE_SHIFT_IA64; + } + else { + start = 0; + nbr = dom->total_pages; + } + + /* setup initial p2m */ + dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr); + for ( pfn = 0; pfn < nbr; pfn++ ) + dom->p2m_host[pfn] = start + pfn; /* allocate guest memory */ rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, - dom->total_pages, 0, 0, + nbr, 0, 0, dom->p2m_host); return rc; } @@ -232,7 +244,19 @@ int arch_setup_bootearly(struct xc_dom_i DECLARE_DOMCTL; int rc; - xc_dom_printf("%s: setup firmware\n", __FUNCTION__); + xc_dom_printf("%s: setup firmware for %s\n", __FUNCTION__, dom->guest_type); + + if (dom->guest_type && strcmp (dom->guest_type, "hvm-3.0-ia64") == 0) { + memset(&domctl, 0, sizeof(domctl)); + domctl.u.arch_setup.flags = XEN_DOMAINSETUP_hvmstub_guest; + domctl.u.arch_setup.bp = 0; + domctl.u.arch_setup.maxmem = 0; + domctl.cmd = XEN_DOMCTL_arch_setup; + domctl.domain = dom->guest_domid; + rc = xc_domctl(dom->guest_xc, &domctl); + xc_dom_printf("%s: hvm-3.0-ia64: %d\n", __FUNCTION__, rc); + return rc; + } rc = ia64_setup_memmap(dom); if (rc)