Files
xen/tools/libxc/ia64/xc_dom_ia64_util.c
T
Ian Campbell 2dee7f052d libxc: convert ia64 dom0vp interface to hypercall buffers
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson.citrix.com>
2010-10-22 15:14:51 +01:00

197 lines
5.5 KiB
C

/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
*/
#include <assert.h>
#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->xch, XENVER_version, NULL);
}
int
xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision)
{
int ret;
DECLARE_HYPERCALL;
DECLARE_HYPERCALL_BOUNCE(revision, sizeof(*revision), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
if (xc_hypercall_bounce_pre(dom->xch, revision) )
{
PERROR("Could not lock memory for xen fpswa hypercall");
return -1;
}
hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
hypercall.arg[0] = IA64_DOM0VP_fpswa_revision;
hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(revision);
ret = do_xen_hypercall(dom->xch, &hypercall);
xc_hypercall_bounce_post(dom->xch, revision);
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->xch, 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;
xc_interface *xch = dom->xch;
rc = xc_vcpu_getinfo(xch, dom->guest_domid,
vcpu, &info);
if (rc == 0)
return 1;
if (errno != 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;
struct fw_tables *fw_tables = 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_MIN - 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. */
fw_tables = (struct fw_tables*)xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR);
if (fw_tables == NULL) {
rc = -errno;
goto out;
}
memset(fw_tables, 0, FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR);
BUILD_BUG_ON(FW_END_PADDR_MIN != FW_TABLES_END_PADDR_MIN);
fw_tables->fw_tables_size = FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR;
fw_tables->fw_end_paddr = FW_END_PADDR_MIN;
fw_tables->fw_tables_end_paddr = FW_TABLES_END_PADDR_MIN;
fw_tables->num_mds = 0;
/* 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, fw_tables,
(unsigned long)imva_hypercall_base, maxmem);
BUG_ON(fw_tables->fw_tables_size < sizeof(*fw_tables) +
sizeof(fw_tables->efi_memmap[0]) * fw_tables->num_mds);
/* clear domain builder internal use member */
fw_tables->fw_tables_size = 0;
fw_tables->fw_end_paddr = 0;
fw_tables->fw_tables_end_paddr = 0;
fw_tables->num_mds = 0;
out:
if (imva_hypercall_base != NULL)
xen_ia64_dom_fw_unmap(d, imva_hypercall_base);
if (fw_tables != NULL)
xen_ia64_dom_fw_unmap(d, fw_tables);
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:
*/