# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1175855567 -32400 # Node ID 0a28a364fd1689b5d7a278932aa9f773fb068724 # Parent 452aa57562d9985a6726750b2ed370c935bee3d7 make libxc domain builder set up firmware instead of xen hyperviser. PATCHNAME: make_libxc_domain_builder_set_up_firmware Signed-off-by: Isaku Yamahata diff -r 452aa57562d9 -r 0a28a364fd16 tools/libxc/ia64/Makefile --- a/tools/libxc/ia64/Makefile Fri Apr 06 19:16:54 2007 +0900 +++ b/tools/libxc/ia64/Makefile Fri Apr 06 19:32:47 2007 +0900 @@ -3,3 +3,46 @@ GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c GUEST_SRCS-y += ia64/xc_ia64_linux_save.c GUEST_SRCS-y += ia64/xc_ia64_linux_restore.c + +GUEST_SRCS-y += ia64/xc_dom_ia64_util.c +DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S +DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE)) +$(DOMFW_SRCS): + ln -sf ../$(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@ + +# XXX kludge: libxc/Makefile doesn't understand .S. +GUEST_SRCS-y += $(patsubst %.S, %.c, $(DOMFW_SRCS)) +%.o: %.S + $(CC) $(CFLAGS) -c $< -o $@ +%.opic: %.S + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + + +CFLAGS += -Iia64 + +DOMFW_ASM_HDRS_BASE := bundle.h dom_fw.h dom_fw_common.h dom_fw_domu.h +DOMFW_ASM_HDRS := $(addprefix ia64/asm/, $(DOMFW_ASM_HDRS_BASE)) +$(DOMFW_ASM_HDRS): ia64/asm + ln -sf ../../$(XEN_ROOT)/xen/include/asm-ia64/$(@F) $@ +build: $(DOMFW_ASM_HDR) + +.PHONY: mk-symlinks-acpi ia64-clean + +IA64_HDR_DIRS := ia64/asm ia64/xen ia64/acpi ia64/acpi/platform +$(IA64_HDR_DIRS): + mkdir -p $@ + +IA64_EMPTY_FILES := ia64/asm/acpi.h ia64/xen/list.h +$(IA64_EMPTY_FILES): $(IA64_HDR_DIRS) + echo "/* automatically created dummy empty header file. */" > $@ + +mk-symlinks-acpi: $(IA64_HDR_DIRS) $(IA64_EMPTY_FILES) $(DOMFW_ASM_HDRS) + ( cd ia64/acpi && ln -sf ../../$(XEN_ROOT)/xen/include/acpi/*.h .) + ( cd ia64/acpi/platform && ln -sf ../../../$(XEN_ROOT)/xen/include/acpi/platform/*.h .) + ( cd ia64/acpi/platform/ && ln -sf ../../aclinux.h .) + ( cd ia64/xen && ln -sf ../../$(XEN_ROOT)/xen/include/xen/acpi.h .) +build: mk-symlinks-acpi + +clean: ia64-clean +ia64-clean: + rm -rf $(DOMFW_SRCS) $(DOMFW_ASM_HDRS) $(IA64_EMPTY_FILES) $(IA64_HDR_DIRS) diff -r 452aa57562d9 -r 0a28a364fd16 tools/libxc/ia64/xc_dom_ia64_util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_dom_ia64_util.c Fri Apr 06 19:32:47 2007 +0900 @@ -0,0 +1,175 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (c) 2007 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + */ + +#include "xg_private.h" +#include "xc_dom.h" +#include "asm/dom_fw.h" +#include "asm/dom_fw_common.h" +#include "ia64/xc_dom_ia64_util.h" + +uint32_t +xen_ia64_version(struct xc_dom_image *dom) +{ + return xc_version(dom->guest_xc, XENVER_version, NULL); +} + +int +xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision) +{ + int ret = -1; + DECLARE_HYPERCALL; + hypercall.op = __HYPERVISOR_ia64_dom0vp_op; + //hypercall.arg[0] = IA64_DOM0VP_get_fpswa_revision;//XXX + hypercall.arg[1] = (unsigned long)revision; + + if (lock_pages(revision, sizeof(*revision)) != 0) { + PERROR("Could not lock memory for xen fpswa hypercall"); + goto out; + } + + //ret = do_xen_hypercall(dom->guest_xc, &hypercall);//XXX + ret = -ENOSYS; + + unlock_pages(revision, sizeof(*revision)); +out: + return ret; +} + +int xen_ia64_is_running_on_sim(struct xc_dom_image *dom) +{ + /* + * This is only used by dom_fw_init() as + * "!xen_ia64_is_dom0() || xen_ia64_is_running_on_sim()". + * So this doesn't affect the result. + */ + return 0; +} + +int +xen_ia64_is_dom0(struct xc_dom_image *unused) +{ + /* libxc is for non-dom0 domain builder */ + return 0; +} + +void* +xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr) +{ + unsigned long page_size = XC_DOM_PAGE_SIZE(dom); + void* ret; + + ret = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, + page_size, PROT_READ | PROT_WRITE, + mpaddr / page_size); + if (ret != NULL) + ret = (void*)((unsigned long)ret | (mpaddr & (page_size - 1))); + return ret; +} + +void +xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *vaddr) +{ + unsigned long page_size = XC_DOM_PAGE_SIZE(dom); + munmap((void*)((unsigned long)vaddr & ~(page_size - 1)), page_size); +} + +int +xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu) +{ + // return d->vcpu[vcpu] != NULL; + + int rc; + xc_vcpuinfo_t info; + + rc = xc_vcpu_getinfo(dom->guest_xc, dom->guest_domid, + vcpu, &info); + if (rc == 0) + return 1; + + if (rc != -ESRCH) + PERROR("Could not get vcpu info"); + return 0; +} + +int +xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm, + unsigned long bp_mpa, unsigned long maxmem) +{ + int rc = 0; + void *imva_hypercall_base = NULL; + void *imva_tables_base = NULL; + struct fake_acpi_tables *imva = NULL; + struct xen_ia64_boot_param *bp = NULL; + + BUILD_BUG_ON(sizeof(struct fw_tables) > + (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR)); + + /* Create page for hypercalls. */ + imva_hypercall_base = xen_ia64_dom_fw_map(d, FW_HYPERCALL_BASE_PADDR); + if (imva_hypercall_base == NULL) { + rc = -errno; + goto out; + } + + /* Create page for FW tables. */ + imva_tables_base = xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR); + if (imva_tables_base == NULL) { + rc = -errno; + goto out; + } + + /* Create page for acpi tables. */ + imva = (struct fake_acpi_tables *) + xen_ia64_dom_fw_map(d, FW_ACPI_BASE_PADDR); + if (imva == NULL) { + rc = -errno; + goto out; + } + dom_fw_fake_acpi(d, imva); + + /* Create page for boot_param. */ + bp = xen_ia64_dom_fw_map(d, bp_mpa); + if (bp == NULL) { + rc = -errno; + goto out; + } + rc = dom_fw_init(d, brkimm, bp, imva_tables_base, + (unsigned long)imva_hypercall_base, maxmem); + out: + if (imva_hypercall_base != NULL) + xen_ia64_dom_fw_unmap(d, imva_hypercall_base); + if (imva_tables_base != NULL) + xen_ia64_dom_fw_unmap(d, imva_tables_base); + if (imva != NULL) + xen_ia64_dom_fw_unmap(d, imva); + if (bp != NULL) + xen_ia64_dom_fw_unmap(d, bp); + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 452aa57562d9 -r 0a28a364fd16 tools/libxc/ia64/xc_dom_ia64_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_dom_ia64_util.h Fri Apr 06 19:32:47 2007 +0900 @@ -0,0 +1,19 @@ +#ifndef XC_IA64_DOM_IA64_UTIL_H +#define XC_IA64_DOM_IA64_UTIL_H + +struct xc_dom_image; +uint32_t xen_ia64_version(struct xc_dom_image *dom); +void* xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr); +void xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *addr); +int xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision); +int xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu); +int xen_ia64_is_running_on_sim(struct xc_dom_image *dom); +int xen_ia64_is_dom0(struct xc_dom_image *dom); + +int +xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm, + unsigned long bp_mpa, unsigned long maxmem); +#define efi_systable_init_dom0(tables) assert(0) +#define complete_dom0_memmap(d, tables, maxmem, num_mds) ({assert(0);0;}) + +#endif /* XC_IA64_DOM_IA64_UTIL_H */ diff -r 452aa57562d9 -r 0a28a364fd16 tools/libxc/xc_dom_ia64.c --- a/tools/libxc/xc_dom_ia64.c Fri Apr 06 19:16:54 2007 +0900 +++ b/tools/libxc/xc_dom_ia64.c Fri Apr 06 19:32:47 2007 +0900 @@ -19,6 +19,9 @@ #include "xg_private.h" #include "xc_dom.h" #include "xenctrl.h" + +#include +#include "ia64/xc_dom_ia64_util.h" /* ------------------------------------------------------------------------ */ @@ -48,6 +51,13 @@ static int start_info_ia64(struct xc_dom start_info->store_evtchn = dom->xenstore_evtchn; 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 ) { @@ -186,8 +196,12 @@ static int ia64_setup_memmap(struct xc_d memmap_info->efi_memmap_size = num_mds * sizeof(md[0]); munmap(memmap_info, page_size); - /* kludge: we need to pass memmap_info page's pfn somehow. - * we use xen_ia64_boot_param::efi_memmap for this purpose */ + /* + * 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, @@ -196,9 +210,8 @@ static int ia64_setup_memmap(struct xc_d return -1; bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t)); memset(bp, 0, sizeof(*bp)); - bp->efi_memmap = memmap_info_pfn; - /* 4 = memmap info page, start info page, xenstore page and console page */ - bp->efi_memmap_size = 4 * PAGE_SIZE; + XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = 1; + XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn; munmap(start_info, page_size); return 0; } @@ -211,6 +224,20 @@ int arch_setup_bootearly(struct xc_dom_i 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;