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

[Xen-changelog] [IA64] SetVirtualAddressMap emulation support



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 9de9ad0685bf8b4f0ba6d3997cfcb362f98a6afd
# Parent  e2fba672928171f3718f45d3487887257b195ee5
[IA64] SetVirtualAddressMap emulation support

Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S |    2 
 xen/arch/ia64/xen/Makefile                     |    1 
 xen/arch/ia64/xen/dom_fw.c                     |    9 -
 xen/arch/ia64/xen/efi_emul.c                   |  180 +++++++++++++++++++++++++
 xen/arch/ia64/xen/hypercall.c                  |   61 ++------
 xen/arch/ia64/xen/process.c                    |   12 -
 xen/include/asm-ia64/dom_fw.h                  |   14 +
 xen/include/asm-ia64/domain.h                  |    2 
 8 files changed, 224 insertions(+), 57 deletions(-)

diff -r e2fba6729281 -r 9de9ad0685bf 
linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Tue May 09 16:56:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S    Wed May 10 15:29:48 
2006 -0600
@@ -345,7 +345,7 @@ GLOBAL_ENTRY(xen_send_ipi)
 GLOBAL_ENTRY(xen_send_ipi)
         mov r14=r32
         mov r15=r33
-        mov r2=0x380
+        mov r2=0x400
         break 0x1000
         ;;
         br.ret.sptk.many rp
diff -r e2fba6729281 -r 9de9ad0685bf xen/arch/ia64/xen/Makefile
--- a/xen/arch/ia64/xen/Makefile        Tue May 09 16:56:45 2006 -0600
+++ b/xen/arch/ia64/xen/Makefile        Wed May 10 15:29:48 2006 -0600
@@ -2,6 +2,7 @@ obj-y += dom0_ops.o
 obj-y += dom0_ops.o
 obj-y += domain.o
 obj-y += dom_fw.o
+obj-y += efi_emul.o
 obj-y += hpsimserial.o
 obj-y += hypercall.o
 obj-y += hyperprivop.o
diff -r e2fba6729281 -r 9de9ad0685bf xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Tue May 09 16:56:45 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c        Wed May 10 15:29:48 2006 -0600
@@ -798,6 +798,9 @@ dom_fw_init (struct domain *d, const cha
        pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
        cmd_line    = (void *) cp;
 
+       /* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
+       d->arch.efi_runtime = efi_runtime;
+
        if (args) {
                if (arglen >= 1024)
                        arglen = 1023;
@@ -959,7 +962,7 @@ dom_fw_init (struct domain *d, const cha
                MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);//XXX
 #endif
                /* hypercall patches live here, masquerade as reserved PAL 
memory */
-               
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB,HYPERCALL_START,HYPERCALL_END, 0);
+               
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
 0);
                
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem-IA64_GRANULE_SIZE,
 0);//XXX make sure this doesn't overlap on i/o, runtime area.
 #ifndef CONFIG_XEN_IA64_DOM0_VP
 /* hack */     
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,last_start,last_end,1);
@@ -993,7 +996,7 @@ dom_fw_init (struct domain *d, const cha
                MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1);
 #endif
                /* hypercall patches live here, masquerade as reserved PAL 
memory */
-               
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB,HYPERCALL_START,HYPERCALL_END, 1);
+               
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
 1);
                
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
                /* Create a dummy entry for IO ports, so that IO accesses are
                   trapped by Xen.  */
@@ -1009,7 +1012,7 @@ dom_fw_init (struct domain *d, const cha
        BUG_ON(i > NUM_MEM_DESCS);
        bp->efi_memmap_size = i * sizeof(efi_memory_desc_t);
        bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
-       bp->efi_memdesc_version = 1;
+       bp->efi_memdesc_version = EFI_MEMDESC_VERSION;
        bp->command_line = dom_pa((unsigned long) cmd_line);
        bp->console_info.num_cols = 80;
        bp->console_info.num_rows = 25;
diff -r e2fba6729281 -r 9de9ad0685bf xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Tue May 09 16:56:45 2006 -0600
+++ b/xen/arch/ia64/xen/hypercall.c     Wed May 10 15:29:48 2006 -0600
@@ -26,7 +26,6 @@
 #include <public/physdev.h>
 #include <xen/domain.h>
 
-extern unsigned long translate_domain_mpaddr(unsigned long);
 static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
 static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
 /* FIXME: where these declarations should be there ? */
@@ -103,7 +102,7 @@ uint32_t nr_hypercalls =
 uint32_t nr_hypercalls =
        sizeof(ia64_hypercall_table) / sizeof(hypercall_t);
 
-static int
+static IA64FAULT
 xen_hypercall (struct pt_regs *regs)
 {
        uint32_t cmd = (uint32_t)regs->r2;
@@ -119,7 +118,7 @@ xen_hypercall (struct pt_regs *regs)
        else
                regs->r8 = -ENOSYS;
 
-       return 1;
+       return IA64_NO_FAULT;
 }
 
 
@@ -182,14 +181,16 @@ fw_hypercall_ipi (struct pt_regs *regs)
        return;
 }
 
-static int
+static IA64FAULT
 fw_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = current;
        struct sal_ret_values x;
-       unsigned long *tv, *tc;
-
-       switch (regs->r2) {
+       efi_status_t efi_ret_value;
+       IA64FAULT fault; 
+       unsigned long index = regs->r2 & FW_HYPERCALL_NUM_MASK_HIGH;
+
+       switch (index) {
            case FW_HYPERCALL_PAL_CALL:
                //printf("*** PAL hypercall: index=%d\n",regs->r28);
                //FIXME: This should call a C routine
@@ -247,40 +248,10 @@ fw_hypercall (struct pt_regs *regs)
                regs->r8 = x.r8; regs->r9 = x.r9;
                regs->r10 = x.r10; regs->r11 = x.r11;
                break;
-           case FW_HYPERCALL_EFI_RESET_SYSTEM:
-               printf("efi.reset_system called ");
-               if (current->domain == dom0) {
-                       printf("(by dom0)\n ");
-                       (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
-               }
-               else
-                       domain_shutdown (current->domain, SHUTDOWN_reboot);
-               regs->r8 = EFI_UNSUPPORTED;
-               break;
-           case FW_HYPERCALL_EFI_GET_TIME:
-               tv = (unsigned long *) vcpu_get_gr(v,32);
-               tc = (unsigned long *) vcpu_get_gr(v,33);
-               //printf("efi_get_time(%p,%p) called...",tv,tc);
-               tv = (unsigned long *) __va(translate_domain_mpaddr((unsigned 
long) tv));
-               if (tc) tc = (unsigned long *) 
__va(translate_domain_mpaddr((unsigned long) tc));
-               regs->r8 = (*efi.get_time)((efi_time_t *) tv, (efi_time_cap_t 
*) tc);
-               //printf("and returns %lx\n",regs->r8);
-               break;
-           case FW_HYPERCALL_EFI_SET_TIME:
-           case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
-           case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
-               // FIXME: need fixes in efi.h from 2.6.9
-           case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
-               // FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
-               // SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS 
-               // POINTER ARGUMENTS WILL BE VIRTUAL!!
-           case FW_HYPERCALL_EFI_GET_VARIABLE:
-               // FIXME: need fixes in efi.h from 2.6.9
-           case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
-           case FW_HYPERCALL_EFI_SET_VARIABLE:
-           case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
-               // FIXME: need fixes in efi.h from 2.6.9
-               regs->r8 = EFI_UNSUPPORTED;
+           case FW_HYPERCALL_EFI_CALL:
+               efi_ret_value = efi_emulator (regs, &fault);
+               if (fault != IA64_NO_FAULT) return fault;
+               regs->r8 = efi_ret_value;
                break;
            case FW_HYPERCALL_IPI:
                fw_hypercall_ipi (regs);
@@ -289,7 +260,7 @@ fw_hypercall (struct pt_regs *regs)
                printf("unknown ia64 fw hypercall %lx\n", regs->r2);
                regs->r8 = do_ni_hypercall();
        }
-       return 1;
+       return IA64_NO_FAULT;
 }
 
 /* opt_unsafe_hypercall: If true, unsafe debugging hypercalls are allowed.
@@ -297,7 +268,7 @@ static int opt_unsafe_hypercall = 0;
 static int opt_unsafe_hypercall = 0;
 boolean_param("unsafe_hypercall", opt_unsafe_hypercall);
 
-int
+IA64FAULT
 ia64_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = current;
@@ -327,7 +298,7 @@ ia64_hypercall (struct pt_regs *regs)
                        printf("unknown user xen/ia64 hypercall %lx\n", index);
                        regs->r8 = do_ni_hypercall();
            }
-           return 1;
+           return IA64_NO_FAULT;
        }
 
        /* Hypercalls are only allowed by kernel.
@@ -336,7 +307,7 @@ ia64_hypercall (struct pt_regs *regs)
            /* FIXME: Return a better error value ?
               Reflection ? Illegal operation ?  */
            regs->r8 = -1;
-           return 1;
+           return IA64_NO_FAULT;
        }
 
        if (index >= FW_HYPERCALL_FIRST_ARCH)
diff -r e2fba6729281 -r 9de9ad0685bf xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Tue May 09 16:56:45 2006 -0600
+++ b/xen/arch/ia64/xen/process.c       Wed May 10 15:29:48 2006 -0600
@@ -15,7 +15,6 @@
 #include <asm/ptrace.h>
 #include <xen/delay.h>
 
-#include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */
 #include <asm/sal.h>   /* FOR struct ia64_sal_retval */
 
 #include <asm/system.h>
@@ -40,7 +39,7 @@ extern void panic_domain(struct pt_regs 
 extern void panic_domain(struct pt_regs *, const char *, ...);
 extern long platform_is_hp_ski(void);
 extern int ia64_hyperprivop(unsigned long, REGS *);
-extern int ia64_hypercall(struct pt_regs *regs);
+extern IA64FAULT ia64_hypercall(struct pt_regs *regs);
 extern void vmx_do_launch(struct vcpu *);
 extern unsigned long lookup_domain_mpa(struct domain *,unsigned long);
 
@@ -680,6 +679,7 @@ ia64_handle_break (unsigned long ifa, st
 {
        struct domain *d = current->domain;
        struct vcpu *v = current;
+       IA64FAULT vector;
 
        if (first_break) {
                if (platform_is_hp_ski()) running_on_sim = 1;
@@ -700,9 +700,11 @@ ia64_handle_break (unsigned long ifa, st
                /* by default, do not continue */
                v->arch.hypercall_continuation = 0;
 
-               if (ia64_hypercall(regs) &&
-                   !PSCBX(v, hypercall_continuation))
-                       vcpu_increment_iip(current);
+               if ((vector = ia64_hypercall(regs)) == IA64_NO_FAULT) {
+                       if (!PSCBX(v, hypercall_continuation))
+                               vcpu_increment_iip(current);
+               }
+               else reflect_interruption(isr, regs, vector);
        }
        else if (!PSCB(v,interrupt_collection_enabled)) {
                if (ia64_hyperprivop(iim,regs))
diff -r e2fba6729281 -r 9de9ad0685bf xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Tue May 09 16:56:45 2006 -0600
+++ b/xen/include/asm-ia64/dom_fw.h     Wed May 10 15:29:48 2006 -0600
@@ -5,7 +5,7 @@
  *     Dan Magenheimer (dan.magenheimer@xxxxxx)
  */
 
-extern unsigned long dom_fw_setup(struct domain *, const char *, int);
+#include <linux/efi.h>
 
 #ifndef MB
 #define MB (1024*1024)
@@ -55,7 +55,7 @@ extern unsigned long dom_fw_setup(struct
 
 #define FW_HYPERCALL_SAL_CALL_INDEX    0x82UL
 #define FW_HYPERCALL_SAL_CALL_PADDR    
FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_CALL_INDEX)
-#define FW_HYPERCALL_SAL_CALL          0x1001UL
+#define FW_HYPERCALL_SAL_CALL          0x1100UL
 
 /*
  * EFI is accessed via the EFI system table, which contains:
@@ -94,6 +94,7 @@ extern unsigned long dom_fw_setup(struct
 #define FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX            9UL
 
 /* these are hypercall numbers */
+#define FW_HYPERCALL_EFI_CALL                          0x300UL
 #define FW_HYPERCALL_EFI_GET_TIME                      0x300UL
 #define FW_HYPERCALL_EFI_SET_TIME                      0x301UL
 #define FW_HYPERCALL_EFI_GET_WAKEUP_TIME               0x302UL
@@ -125,7 +126,7 @@ extern unsigned long dom_fw_setup(struct
 */
 #define FW_HYPERCALL_FIRST_ARCH                0x300UL
 
-#define FW_HYPERCALL_IPI               0x380UL
+#define FW_HYPERCALL_IPI               0x400UL
 
 /* Xen/ia64 user hypercalls.  Only used for debugging.  */
 #define FW_HYPERCALL_FIRST_USER                0xff00UL
@@ -133,9 +134,16 @@ extern unsigned long dom_fw_setup(struct
 /* Interrupt vector used for os boot rendez vous.  */
 #define XEN_SAL_BOOT_RENDEZ_VEC        0xF3
 
+#define FW_HYPERCALL_NUM_MASK_HIGH     ~0xffUL
+#define FW_HYPERCALL_NUM_MASK_LOW       0xffUL
+
+#define EFI_MEMDESC_VERSION            1
+
 extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
 extern struct sal_ret_values sal_emulator (long index, unsigned long in1, 
unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, 
unsigned long in6, unsigned long in7);
 extern struct ia64_pal_retval pal_emulator_static (unsigned long);
+extern unsigned long dom_fw_setup (struct domain *, const char *, int);
+extern efi_status_t efi_emulator (struct pt_regs *regs, unsigned long *fault);
 
 extern void build_pal_hypercall_bundles(unsigned long *imva, unsigned long 
brkimm, unsigned long hypnum);
 extern void build_hypercall_bundle(UINT64 *imva, UINT64 brkimm, UINT64 hypnum, 
UINT64 ret);
diff -r e2fba6729281 -r 9de9ad0685bf xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Tue May 09 16:56:45 2006 -0600
+++ b/xen/include/asm-ia64/domain.h     Wed May 10 15:29:48 2006 -0600
@@ -54,6 +54,8 @@ struct arch_domain {
     unsigned long initrd_start;
     unsigned long initrd_len;
     char *cmdline;
+    int efi_virt_mode;         /* phys : 0 , virt : 1 */
+    void *efi_runtime;
 };
 #define xen_vastart arch.xen_vastart
 #define xen_vaend arch.xen_vaend
diff -r e2fba6729281 -r 9de9ad0685bf xen/arch/ia64/xen/efi_emul.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/xen/efi_emul.c      Wed May 10 15:29:48 2006 -0600
@@ -0,0 +1,180 @@
+/*
+ * efi_emul.c:
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/compile.h>
+#include <asm/pgalloc.h>
+#include <asm/vcpu.h>
+#include <asm/dom_fw.h>
+#include <public/sched.h>
+
+extern unsigned long translate_domain_mpaddr(unsigned long);
+extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
+
+// given a current domain (virtual or metaphysical) address, return the 
virtual address
+static unsigned long
+efi_translate_domain_addr(unsigned long domain_addr, IA64FAULT *fault)
+{
+       struct vcpu *v = current;
+       unsigned long mpaddr = domain_addr;
+       *fault = IA64_NO_FAULT;
+
+       if (v->domain->arch.efi_virt_mode) {
+               *fault = vcpu_tpa(v, domain_addr, &mpaddr);
+               if (*fault != IA64_NO_FAULT) return 0;
+       }
+
+       return ((unsigned long) __va(translate_domain_mpaddr(mpaddr)));
+}
+
+static efi_status_t
+efi_emulate_get_time(
+       unsigned long tv_addr, unsigned long tc_addr,
+       IA64FAULT *fault)
+{
+       unsigned long tv = 0, tc = 0;
+       efi_status_t status;
+
+       //printf("efi_get_time(%016lx,%016lx) called\n", tv_addr, tc_addr);
+       tv = efi_translate_domain_addr(tv_addr, fault);
+       if (*fault != IA64_NO_FAULT) return 0;
+       if (tc_addr) {
+               tc = efi_translate_domain_addr(tc_addr, fault);
+               if (*fault != IA64_NO_FAULT) return 0;
+       }
+       //printf("efi_get_time(%016lx,%016lx) translated to xen virtual 
address\n", tv, tc);
+       status = (*efi.get_time)((efi_time_t *) tv, (efi_time_cap_t *) tc);
+       //printf("efi_get_time returns %lx\n", status);
+       return status;
+}
+
+static efi_status_t
+efi_emulate_set_virtual_address_map(
+       unsigned long memory_map_size, unsigned long descriptor_size,
+       u32 descriptor_version, efi_memory_desc_t *virtual_map)
+{
+       void *efi_map_start, *efi_map_end, *p;
+       efi_memory_desc_t entry, *md = &entry;
+       u64 efi_desc_size;
+
+       unsigned long *vfn;
+       struct domain *d = current->domain;
+       efi_runtime_services_t *efi_runtime = d->arch.efi_runtime;
+
+       if (descriptor_version != EFI_MEMDESC_VERSION) {
+               printf ("efi_emulate_set_virtual_address_map: memory descriptor 
version unmatched\n");
+               return EFI_INVALID_PARAMETER;
+       }
+
+       if (descriptor_size != sizeof(efi_memory_desc_t)) {
+               printf ("efi_emulate_set_virtual_address_map: memory descriptor 
size unmatched\n");
+               return EFI_INVALID_PARAMETER;
+       }
+
+       if (d->arch.efi_virt_mode) return EFI_UNSUPPORTED;
+
+       efi_map_start = virtual_map;
+       efi_map_end   = efi_map_start + memory_map_size;
+       efi_desc_size = sizeof(efi_memory_desc_t);
+
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) {
+                       printf ("efi_emulate_set_virtual_address_map: 
copy_from_user() fault. addr=0x%p\n", p);
+                       return EFI_UNSUPPORTED;
+               }
+
+               /* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is 
included in PAL_CODE. */
+                if (md->type != EFI_PAL_CODE)
+                        continue;
+
+#define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \
+       do { \
+               vfn = (unsigned long *) domain_mpa_to_imva(d, tgt); \
+               *vfn++ = FW_HYPERCALL_##call##_INDEX * 16UL + md->virt_addr; \
+               *vfn++ = 0; \
+       } while (0)
+
+               EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_time,EFI_GET_TIME);
+               EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_time,EFI_SET_TIME);
+               
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
+               
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
+               
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
+               
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_variable,EFI_GET_VARIABLE);
+               
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
+               
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);
+       }
+
+       /* The virtual address map has been applied. */
+       d->arch.efi_virt_mode = 1;
+
+       return EFI_SUCCESS;
+}
+
+efi_status_t
+efi_emulator (struct pt_regs *regs, IA64FAULT *fault)
+{
+       struct vcpu *v = current;
+       efi_status_t status;
+
+       *fault = IA64_NO_FAULT;
+
+       switch (regs->r2) {
+           case FW_HYPERCALL_EFI_RESET_SYSTEM:
+               printf("efi.reset_system called ");
+               if (current->domain == dom0) {
+                       printf("(by dom0)\n ");
+                       (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
+               }
+               else
+                       domain_shutdown (current->domain, SHUTDOWN_reboot);
+               status = EFI_UNSUPPORTED;
+               break;
+           case FW_HYPERCALL_EFI_GET_TIME:
+               status = efi_emulate_get_time (
+                               vcpu_get_gr(v,32),
+                               vcpu_get_gr(v,33),
+                               fault);
+               break;
+           case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
+               status = efi_emulate_set_virtual_address_map (
+                               vcpu_get_gr(v,32),
+                               vcpu_get_gr(v,33),
+                               (u32) vcpu_get_gr(v,34),
+                               (efi_memory_desc_t *) vcpu_get_gr(v,35));
+               break;
+           case FW_HYPERCALL_EFI_SET_TIME:
+           case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
+           case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
+               // FIXME: need fixes in efi.h from 2.6.9
+           case FW_HYPERCALL_EFI_GET_VARIABLE:
+               // FIXME: need fixes in efi.h from 2.6.9
+           case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
+           case FW_HYPERCALL_EFI_SET_VARIABLE:
+           case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
+               // FIXME: need fixes in efi.h from 2.6.9
+               status = EFI_UNSUPPORTED;
+               break;
+           default:
+               printf("unknown ia64 fw hypercall %lx\n", regs->r2);
+               status = EFI_UNSUPPORTED;
+       }
+
+       return status;
+}

_______________________________________________
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®.