aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_dom_ia64.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libxc/xc_dom_ia64.c')
-rw-r--r--tools/libxc/xc_dom_ia64.c106
1 files changed, 102 insertions, 4 deletions
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
index a6d77c5a55..dfe27e6917 100644
--- a/tools/libxc/xc_dom_ia64.c
+++ b/tools/libxc/xc_dom_ia64.c
@@ -12,14 +12,20 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <assert.h>
+#include <asm/kregs.h>
#include <xen/xen.h>
#include <xen/foreign/ia64.h>
+#include <xen/io/protocols.h>
#include "xg_private.h"
#include "xc_dom.h"
#include "xenctrl.h"
+#include <asm/dom_fw_common.h>
+#include "ia64/xc_dom_ia64_util.h"
+
/* ------------------------------------------------------------------------ */
static int alloc_magic_pages(struct xc_dom_image *dom)
@@ -49,6 +55,13 @@ static int start_info_ia64(struct xc_dom_image *dom)
start_info->console.domU.mfn = dom->console_pfn;
start_info->console.domU.evtchn = dom->console_evtchn;
+ /*
+ * domain_start and domain_size are abused for arch_setup hypercall
+ * so that we need to clear them here.
+ */
+ XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = 0;
+ XEN_IA64_MEMMAP_INFO_PFN(bp) = 0;
+
if ( dom->ramdisk_blob )
{
start_info->mod_start = dom->ramdisk_seg.vstart;
@@ -77,6 +90,8 @@ static int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
for (i = 0; i < MAX_VIRT_CPUS; i++)
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
shared_info->arch.start_info_pfn = dom->start_info_pfn;
+ shared_info->arch.memmap_info_num_pages = 1; //XXX
+ shared_info->arch.memmap_info_pfn = dom->start_info_pfn - 1;
return 0;
}
@@ -92,9 +107,10 @@ static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
memset(ctxt, 0, sizeof(*ctxt));
ctxt->flags = 0;
- ctxt->regs.psr = 0; /* all necessary bits filled by hypervisor */
+ /* PSR is set according to SAL 3.2.4: AC, IC and BN are set. */
+ ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_IC | IA64_PSR_BN;
ctxt->regs.ip = dom->parms.virt_entry;
- ctxt->regs.cfm = (uint64_t) 1 << 63;
+ ctxt->regs.cfm = 1UL << 63;
#ifdef __ia64__ /* FIXME */
ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();
#endif
@@ -107,6 +123,7 @@ static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
static struct xc_dom_arch xc_dom_arch = {
.guest_type = "xen-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,
@@ -116,6 +133,7 @@ static struct xc_dom_arch xc_dom_arch = {
static struct xc_dom_arch xc_dom_arch_ia64be = {
.guest_type = "xen-3.0-ia64be",
+ .native_protocol = XEN_IO_PROTO_ABI_IA64,
.page_shift = PAGE_SHIFT_IA64,
.alloc_magic_pages = alloc_magic_pages,
.start_info = start_info_ia64,
@@ -129,6 +147,8 @@ static void __init register_arch_hooks(void)
xc_dom_register_arch_hooks(&xc_dom_arch_ia64be);
}
+#include "xc_efi.h"
+
int arch_setup_meminit(struct xc_dom_image *dom)
{
xen_pfn_t pfn;
@@ -146,6 +166,67 @@ int arch_setup_meminit(struct xc_dom_image *dom)
return rc;
}
+static int ia64_setup_memmap(struct xc_dom_image *dom)
+{
+ unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
+ unsigned long memmap_info_num_pages;
+ unsigned long memmap_info_pfn;
+ xen_ia64_memmap_info_t* memmap_info;
+ unsigned int num_mds;
+ efi_memory_desc_t *md;
+
+ char* start_info;
+ struct xen_ia64_boot_param* bp;
+
+ /* setup memmap page */
+ memmap_info_num_pages = 1;
+ memmap_info_pfn = dom->start_info_pfn - 1;
+ xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx\n",
+ __FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
+ memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
+ page_size * memmap_info_num_pages,
+ PROT_READ | PROT_WRITE,
+ memmap_info_pfn);
+ if (NULL == memmap_info)
+ return -1;
+ /* [0, total_pages) */
+ memmap_info->efi_memdesc_size = sizeof(md[0]);
+ memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
+ num_mds = 0;
+ md = (efi_memory_desc_t*)&memmap_info->memdesc;
+ md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
+ md[num_mds].pad = 0;
+ md[num_mds].phys_addr = 0;
+ md[num_mds].virt_addr = 0;
+ md[num_mds].num_pages = dom->total_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
+ md[num_mds].attribute = EFI_MEMORY_WB;
+ num_mds++;
+ memmap_info->efi_memmap_size = num_mds * sizeof(md[0]);
+ munmap(memmap_info, page_size * memmap_info_num_pages);
+ assert(num_mds <=
+ (page_size * memmap_info_num_pages -
+ offsetof(typeof(*memmap_info), memdesc))/sizeof(*md));
+
+ /*
+ * kludge: we need to pass memmap_info page's pfn and other magic pages
+ * somehow.
+ * we use xen_ia64_boot_param::efi_memmap::{efi_memmap, efi_memmap_size}
+ * for this purpose
+ */
+ start_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
+ page_size,
+ PROT_READ | PROT_WRITE,
+ dom->start_info_pfn);
+ if (NULL == start_info)
+ return -1;
+ bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t));
+ memset(bp, 0, sizeof(*bp));
+ XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = memmap_info_num_pages;
+ XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn;
+ munmap(start_info, page_size);
+ return 0;
+}
+
int arch_setup_bootearly(struct xc_dom_image *dom)
{
DECLARE_DOMCTL;
@@ -153,6 +234,24 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
xc_dom_printf("%s: setup firmware\n", __FUNCTION__);
+ rc = ia64_setup_memmap(dom);
+ if (rc)
+ return rc;
+
+ memset(&domctl, 0, sizeof(domctl));
+ domctl.cmd = XEN_DOMCTL_arch_setup;
+ domctl.domain = dom->guest_domid;
+ domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;
+ rc = do_domctl(dom->guest_xc, &domctl);
+ if (rc)
+ return rc;
+ rc = xen_ia64_dom_fw_setup(dom, domctl.u.arch_setup.hypercall_imm,
+ (dom->start_info_pfn << PAGE_SHIFT) +
+ sizeof(start_info_t),
+ dom->total_pages << PAGE_SHIFT);
+ if (rc)
+ return rc;
+
memset(&domctl, 0, sizeof(domctl));
domctl.cmd = XEN_DOMCTL_arch_setup;
domctl.domain = dom->guest_domid;
@@ -160,8 +259,7 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
+ sizeof(start_info_t);
- /* 3 = start info page, xenstore page and console page */
- domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT;
+ domctl.u.arch_setup.maxmem = dom->total_pages << PAGE_SHIFT;
rc = do_domctl(dom->guest_xc, &domctl);
return rc;
}