[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [IA64] support FPSWA hypercall



# 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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.