# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 9d52a66c74996a66adf5ee71a0d7f91bb880f7fb
# Parent faae893d428e989148743bb92bce234dfead281c
[IA64] support FPSWA hypercall
Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
---
xen/arch/ia64/xen/dom_fw.c | 35 +++++++++++++++++++++++++++++++++--
xen/arch/ia64/xen/efi_emul.c | 8 ++++++++
xen/arch/ia64/xen/hypercall.c | 15 +++++++++++++++
xen/include/asm-ia64/dom_fw.h | 19 +++++++++++++++++--
xen/include/asm-ia64/domain.h | 6 ++++++
5 files changed, 79 insertions(+), 4 deletions(-)
diff -r faae893d428e -r 9d52a66c7499 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c Thu May 25 15:47:33 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c Thu May 25 15:59:18 2006 -0600
@@ -15,6 +15,7 @@
#include <asm/pal.h>
#include <asm/sal.h>
#include <asm/meminit.h>
+#include <asm/fpswa.h>
#include <xen/compile.h>
#include <xen/acpi.h>
@@ -60,6 +61,29 @@ dom_pa(unsigned long imva)
} while (0)
// builds a hypercall bundle at domain physical address
+static void dom_fpswa_hypercall_patch(struct domain *d)
+{
+ unsigned long *entry_imva, *patch_imva;
+ unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
+ unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
+
+#ifndef CONFIG_XEN_IA64_DOM0_VP
+ if (d == dom0) {
+ entry_paddr += dom0_start;
+ patch_paddr += dom0_start;
+ }
+#endif
+ ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
+ ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
+ entry_imva = (unsigned long *) domain_mpa_to_imva(d, entry_paddr);
+ patch_imva = (unsigned long *) domain_mpa_to_imva(d, patch_paddr);
+
+ *entry_imva++ = patch_paddr;
+ *entry_imva = 0;
+ build_hypercall_bundle(patch_imva, d->arch.breakimm,
FW_HYPERCALL_FPSWA, 1);
+}
+
+// builds a hypercall bundle at domain physical address
static void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr,
unsigned long hypercall)
{
unsigned long *imva;
@@ -71,7 +95,6 @@ static void dom_efi_hypercall_patch(stru
imva = (unsigned long *) domain_mpa_to_imva(d, paddr);
build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
}
-
// builds a hypercall bundle at domain physical address
static void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr,
unsigned long hypercall,unsigned long ret)
@@ -771,6 +794,7 @@ dom_fw_init (struct domain *d, const cha
struct ia64_sal_systab *sal_systab;
struct ia64_sal_desc_entry_point *sal_ed;
struct ia64_sal_desc_ap_wakeup *sal_wakeup;
+ fpswa_interface_t *fpswa_inf;
efi_memory_desc_t *efi_memmap, *md;
struct ia64_boot_param *bp;
unsigned long *pfn;
@@ -812,6 +836,7 @@ dom_fw_init (struct domain *d, const cha
sal_systab = (void *) cp; cp += sizeof(*sal_systab);
sal_ed = (void *) cp; cp += sizeof(*sal_ed);
sal_wakeup = (void *) cp; cp += sizeof(*sal_wakeup);
+ fpswa_inf = (void *) cp; cp += sizeof(*fpswa_inf);
efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
bp = (void *) cp; cp += sizeof(*bp);
pfn = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
@@ -819,6 +844,7 @@ dom_fw_init (struct domain *d, const cha
/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
d->arch.efi_runtime = efi_runtime;
+ d->arch.fpswa_inf = fpswa_inf;
if (args) {
if (arglen >= 1024)
@@ -961,6 +987,11 @@ dom_fw_init (struct domain *d, const cha
checksum += *cp;
sal_systab->checksum = -checksum;
+
+ /* Fill in the FPSWA interface: */
+ fpswa_inf->revision = fpswa_interface->revision;
+ dom_fpswa_hypercall_patch(d);
+ fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR +
start_mpaddr;
i = 0;
if (d == dom0) {
@@ -1045,7 +1076,7 @@ dom_fw_init (struct domain *d, const cha
bp->console_info.num_rows = 25;
bp->console_info.orig_x = 0;
bp->console_info.orig_y = 24;
- bp->fpswa = 0;
+ bp->fpswa = dom_pa((unsigned long) fpswa_inf);
if (d == dom0) {
// XXX CONFIG_XEN_IA64_DOM0_VP
// initrd_start address is hard coded in start_kernel()
diff -r faae893d428e -r 9d52a66c7499 xen/arch/ia64/xen/efi_emul.c
--- a/xen/arch/ia64/xen/efi_emul.c Thu May 25 15:47:33 2006 -0600
+++ b/xen/arch/ia64/xen/efi_emul.c Thu May 25 15:59:18 2006 -0600
@@ -21,6 +21,7 @@
#include <asm/pgalloc.h>
#include <asm/vcpu.h>
#include <asm/dom_fw.h>
+#include <asm/fpswa.h>
#include <public/sched.h>
extern unsigned long translate_domain_mpaddr(unsigned long);
@@ -75,6 +76,7 @@ efi_emulate_set_virtual_address_map(
unsigned long *vfn;
struct domain *d = current->domain;
efi_runtime_services_t *efi_runtime = d->arch.efi_runtime;
+ fpswa_interface_t *fpswa_inf = d->arch.fpswa_inf;
if (descriptor_version != EFI_MEMDESC_VERSION) {
printf ("efi_emulate_set_virtual_address_map: memory descriptor
version unmatched\n");
@@ -119,6 +121,12 @@ efi_emulate_set_virtual_address_map(
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_variable,EFI_SET_VARIABLE);
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->reset_system,EFI_RESET_SYSTEM);
+
+ vfn = (unsigned long *) domain_mpa_to_imva(d, (unsigned long)
fpswa_inf->fpswa);
+ *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
+ *vfn = 0;
+ fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX *
16UL + md->virt_addr);
+ break;
}
/* The virtual address map has been applied. */
diff -r faae893d428e -r 9d52a66c7499 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c Thu May 25 15:47:33 2006 -0600
+++ b/xen/arch/ia64/xen/hypercall.c Thu May 25 15:59:18 2006 -0600
@@ -14,6 +14,7 @@
#include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */
#include <asm/sal.h> /* FOR struct ia64_sal_retval */
+#include <asm/fpswa.h> /* FOR struct fpswa_ret_t */
#include <asm/vcpu.h>
#include <asm/dom_fw.h>
@@ -181,12 +182,19 @@ fw_hypercall_ipi (struct pt_regs *regs)
return;
}
+static fpswa_ret_t
+fw_hypercall_fpswa (struct vcpu *v)
+{
+ return PSCBX(v, fpswa_ret);
+}
+
static IA64FAULT
fw_hypercall (struct pt_regs *regs)
{
struct vcpu *v = current;
struct sal_ret_values x;
efi_status_t efi_ret_value;
+ fpswa_ret_t fpswa_ret;
IA64FAULT fault;
unsigned long index = regs->r2 & FW_HYPERCALL_NUM_MASK_HIGH;
@@ -253,6 +261,13 @@ fw_hypercall (struct pt_regs *regs)
case FW_HYPERCALL_IPI:
fw_hypercall_ipi (regs);
break;
+ case FW_HYPERCALL_FPSWA:
+ fpswa_ret = fw_hypercall_fpswa (v);
+ regs->r8 = fpswa_ret.status;
+ regs->r9 = fpswa_ret.err0;
+ regs->r10 = fpswa_ret.err1;
+ regs->r11 = fpswa_ret.err2;
+ break;
default:
printf("unknown ia64 fw hypercall %lx\n", regs->r2);
regs->r8 = do_ni_hypercall();
diff -r faae893d428e -r 9d52a66c7499 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h Thu May 25 15:47:33 2006 -0600
+++ b/xen/include/asm-ia64/dom_fw.h Thu May 25 15:59:18 2006 -0600
@@ -119,14 +119,29 @@
#define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_PADDR
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX)
#define FW_HYPERCALL_EFI_RESET_SYSTEM_PADDR
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX)
+/*
+ * This is a hypercall number for IPI.
+ * A pseudo-entry-point is not presented to IPI hypercall. This hypercall
number
+ * is used in xen_send_ipi of linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S.
+ */
+#define FW_HYPERCALL_IPI 0x400UL
+
+/*
+ * This is a hypercall number for FPSWA.
+ * FPSWA hypercall uses 2 bundles for a pseudo-entry-point and a
hypercall-patch.
+ */
+#define FW_HYPERCALL_FPSWA_ENTRY_INDEX 0x83UL
+#define FW_HYPERCALL_FPSWA_PATCH_INDEX 0x84UL
+#define FW_HYPERCALL_FPSWA_ENTRY_PADDR
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
+#define FW_HYPERCALL_FPSWA_PATCH_PADDR
FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
+#define FW_HYPERCALL_FPSWA 0x500UL
+
/* Hypercalls index bellow _FIRST_ARCH are reserved by Xen, while those above
are for the architecture.
Note: this limit was defined by Xen/ia64 (and not by Xen).²
This can be renumbered safely.
*/
#define FW_HYPERCALL_FIRST_ARCH 0x300UL
-
-#define FW_HYPERCALL_IPI 0x400UL
/* Xen/ia64 user hypercalls. Only used for debugging. */
#define FW_HYPERCALL_FIRST_USER 0xff00UL
diff -r faae893d428e -r 9d52a66c7499 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h Thu May 25 15:47:33 2006 -0600
+++ b/xen/include/asm-ia64/domain.h Thu May 25 15:59:18 2006 -0600
@@ -10,6 +10,7 @@
#include <asm/vmx_platform.h>
#include <xen/list.h>
#include <xen/cpumask.h>
+#include <asm/fpswa.h>
extern void domain_relinquish_resources(struct domain *);
@@ -59,8 +60,12 @@ struct arch_domain {
unsigned long initrd_start;
unsigned long initrd_len;
char *cmdline;
+ /* There are these for EFI_SET_VIRTUAL_ADDRESS_MAP emulation. */
int efi_virt_mode; /* phys : 0 , virt : 1 */
+ /* Metaphysical address to efi_runtime_services_t in domain firmware
memory is set. */
void *efi_runtime;
+ /* Metaphysical address to fpswa_interface_t in domain firmware memory is
set. */
+ void *fpswa_inf;
};
#define xen_vastart arch.xen_vastart
#define xen_vaend arch.xen_vaend
@@ -109,6 +114,7 @@ struct arch_vcpu {
//for phycial emulation
unsigned long old_rsc;
int mode_flags;
+ fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */
struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
};
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|