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

[Xen-changelog] [xen-unstable] [IA64] merge efi_emul.c into fw_emul.c and clean up



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 4e78528e34806bd1de06e8f14638dded2b694a7e
# Parent  6a49e02dc169540992956eb35b7736ee698a2029
[IA64] merge efi_emul.c into fw_emul.c and clean up

Merge efi_emul.c into fw_emul.c
Clean up: replace some goto with return.
Declare translate_mpa_to_imva in mm.h and as void *.

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
 xen/arch/ia64/xen/efi_emul.c      |  189 --------------------------------------
 xen/arch/ia64/vmx/vmx_hypercall.c |    1 
 xen/arch/ia64/xen/Makefile        |    1 
 xen/arch/ia64/xen/dom_fw.c        |   13 +-
 xen/arch/ia64/xen/fw_emul.c       |  178 +++++++++++++++++++++++++++++++++++
 xen/arch/ia64/xen/mm.c            |   54 ++--------
 xen/include/asm-ia64/mm.h         |    1 
 7 files changed, 199 insertions(+), 238 deletions(-)

diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Tue Jun 06 09:11:25 2006 -0600
@@ -36,7 +36,6 @@
 #include <xen/domain.h>
 
 extern long do_sched_op_compat(int cmd, unsigned long arg);
-extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
 
 void hyper_not_support(void)
 {
diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/xen/Makefile
--- a/xen/arch/ia64/xen/Makefile        Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/arch/ia64/xen/Makefile        Tue Jun 06 09:11:25 2006 -0600
@@ -2,7 +2,6 @@ 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 += fw_emul.o
 obj-y += hpsimserial.o
 obj-y += hypercall.o
diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c        Tue Jun 06 09:11:25 2006 -0600
@@ -25,7 +25,6 @@
 #include <asm/dom_fw.h>
 
 static struct ia64_boot_param *dom_fw_init(struct domain *, const char 
*,int,char *,int);
-extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
 extern struct domain *dom0;
 extern unsigned long dom0_start;
 
@@ -77,8 +76,8 @@ static void dom_fpswa_hypercall_patch(st
 #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 = domain_mpa_to_imva(d, entry_paddr);
+       patch_imva = domain_mpa_to_imva(d, patch_paddr);
 
        *entry_imva++ = patch_paddr;
        *entry_imva   = 0;
@@ -94,7 +93,7 @@ static void dom_efi_hypercall_patch(stru
        if (d == dom0) paddr += dom0_start;
 #endif
        ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = (unsigned long *) domain_mpa_to_imva(d, paddr);
+       imva = domain_mpa_to_imva(d, paddr);
        build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
 }
 
@@ -104,7 +103,7 @@ static void dom_fw_hypercall_patch(struc
        unsigned long *imva;
 
        ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = (unsigned long *) domain_mpa_to_imva(d, paddr);
+       imva = domain_mpa_to_imva(d, paddr);
        build_hypercall_bundle(imva, d->arch.breakimm, hypercall, ret);
 }
 
@@ -113,7 +112,7 @@ static void dom_fw_pal_hypercall_patch(s
        unsigned long *imva;
 
        ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = (unsigned long *) domain_mpa_to_imva(d, paddr);
+       imva = domain_mpa_to_imva(d, paddr);
        build_pal_hypercall_bundles(imva, d->arch.breakimm, 
FW_HYPERCALL_PAL_CALL);
 }
 
@@ -130,7 +129,7 @@ unsigned long dom_fw_setup(struct domain
        if (d == dom0) dom_fw_base_mpa += dom0_start;
 #endif
        ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, dom_fw_base_mpa);
-       imva_fw_base = domain_mpa_to_imva(d, dom_fw_base_mpa);
+       imva_fw_base = (unsigned long) domain_mpa_to_imva(d, dom_fw_base_mpa);
        bp = dom_fw_init(d, args, arglen, (char *) imva_fw_base, PAGE_SIZE);
        return dom_pa((unsigned long) bp);
 }
diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c       Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/arch/ia64/xen/fw_emul.c       Tue Jun 06 09:11:25 2006 -0600
@@ -1,3 +1,20 @@
+/*
+ * fw_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 <asm/system.h>
 #include <asm/pgalloc.h>
@@ -338,6 +355,167 @@ xen_pal_emulator(unsigned long index, u6
                break;
        }
        return ((struct ia64_pal_retval) {status, r9, r10, r11});
+}
+
+// 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;
+       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");
+               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);
+
+               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. */
+       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 {
+                       printf("\n");
+                       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;
 }
 
 void
diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/arch/ia64/xen/mm.c    Tue Jun 06 09:11:25 2006 -0600
@@ -296,7 +296,6 @@ u64 translate_domain_pte(u64 pteval, u64
                        printk("translate_domain_pte: out-of-bounds dom0 mpaddr 
0x%lx! itc=%lx...\n",
                                mpaddr, ia64_get_itc());
                        */
-                       tdpfoo();
                }
        }
        else if ((mpaddr >> PAGE_SHIFT) > d->max_pages) {
@@ -310,7 +309,6 @@ u64 translate_domain_pte(u64 pteval, u64
                               "vadr=0x%lx,pteval=0x%lx,itir=0x%lx\n",
                               mpaddr, (unsigned long)d->max_pages<<PAGE_SHIFT,
                               address, pteval, itir.itir);
-               tdpfoo();
        }
 #endif
        pteval2 = lookup_domain_mpa(d,mpaddr);
@@ -345,7 +343,6 @@ unsigned long translate_domain_mpaddr(un
                if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
                        printk("translate_domain_mpaddr: out-of-bounds dom0 
mpaddr 0x%lx! continuing...\n",
                                mpaddr);
-                       tdpfoo();
                }
        }
 #endif
@@ -393,20 +390,17 @@ lookup_noalloc_domain_pte(struct domain*
     BUG_ON(mm->pgd == NULL);
     pgd = pgd_offset(mm, mpaddr);
     if (!pgd_present(*pgd))
-        goto not_present;
+        return NULL;
 
     pud = pud_offset(pgd, mpaddr);
     if (!pud_present(*pud))
-        goto not_present;
+        return NULL;
 
     pmd = pmd_offset(pud, mpaddr);
     if (!pmd_present(*pmd))
-        goto not_present;
+        return NULL;
 
     return pte_offset_map(pmd, mpaddr);
-
-not_present:
-    return NULL;
 }
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
@@ -421,20 +415,17 @@ lookup_noalloc_domain_pte_none(struct do
     BUG_ON(mm->pgd == NULL);
     pgd = pgd_offset(mm, mpaddr);
     if (pgd_none(*pgd))
-        goto not_present;
+        return NULL;
 
     pud = pud_offset(pgd, mpaddr);
     if (pud_none(*pud))
-        goto not_present;
+        return NULL;
 
     pmd = pmd_offset(pud, mpaddr);
     if (pmd_none(*pmd))
-        goto not_present;
+        return NULL;
 
     return pte_offset_map(pmd, mpaddr);
-
-not_present:
-    return NULL;
 }
 
 unsigned long
@@ -444,14 +435,12 @@ ____lookup_domain_mpa(struct domain *d, 
 
     pte = lookup_noalloc_domain_pte(d, mpaddr);
     if (pte == NULL)
-        goto not_present;
+        return INVALID_MFN;
 
     if (pte_present(*pte))
         return (pte->pte & _PFN_MASK);
     else if (VMX_DOMAIN(d->vcpu[0]))
         return GPFN_INV_MASK;
-
-not_present:
     return INVALID_MFN;
 }
 
@@ -469,13 +458,6 @@ __lookup_domain_mpa(struct domain *d, un
     return INVALID_MFN;
 }
 #endif
-
-void mpafoo(unsigned long mpaddr)
-{
-    extern unsigned long privop_trace;
-    if (mpaddr == 0x3800)
-        privop_trace = 1;
-}
 
 unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr)
 {
@@ -487,7 +469,6 @@ unsigned long lookup_domain_mpa(struct d
         if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
             //printk("lookup_domain_mpa: bad dom0 mpaddr 0x%lx!\n",mpaddr);
             //printk("lookup_domain_mpa: 
start=0x%lx,end=0x%lx!\n",dom0_start,dom0_start+dom0_size);
-            mpafoo(mpaddr);
         }
         pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
             __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
@@ -511,7 +492,6 @@ unsigned long lookup_domain_mpa(struct d
     else
         printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__,
                mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT);
-    mpafoo(mpaddr);
 
     //XXX This is a work around until the emulation memory access to a region
     //    where memory or device are attached is implemented.
@@ -520,7 +500,7 @@ unsigned long lookup_domain_mpa(struct d
 
 // FIXME: ONLY USE FOR DOMAIN PAGE_SIZE == PAGE_SIZE
 #if 1
-unsigned long domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
+void *domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
 {
     unsigned long pte = lookup_domain_mpa(d,mpaddr);
     unsigned long imva;
@@ -528,14 +508,14 @@ unsigned long domain_mpa_to_imva(struct 
     pte &= _PAGE_PPN_MASK;
     imva = (unsigned long) __va(pte);
     imva |= mpaddr & ~PAGE_MASK;
-    return(imva);
+    return (void*)imva;
 }
 #else
-unsigned long domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
+void *domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
 {
     unsigned long imva = __gpa_to_mpa(d, mpaddr);
 
-    return __va(imva);
+    return (void *)__va(imva);
 }
 #endif
 
@@ -842,17 +822,13 @@ dom0vp_zap_physmap(struct domain *d, uns
 dom0vp_zap_physmap(struct domain *d, unsigned long gpfn,
                    unsigned int extent_order)
 {
-    unsigned long ret = 0;
     if (extent_order != 0) {
         //XXX
-        ret = -ENOSYS;
-        goto out;
+        return -ENOSYS;
     }
 
     zap_domain_page_one(d, gpfn << PAGE_SHIFT, 1);
-
-out:
-    return ret;
+    return 0;
 }
 
 unsigned long
@@ -875,8 +851,7 @@ dom0vp_add_physmap(struct domain* d, uns
             DPRINTK("d 0x%p domid %d "
                     "pgfn 0x%lx mfn 0x%lx flags 0x%lx domid %d\n",
                     d, d->domain_id, gpfn, mfn, flags, domid);
-            error = -ESRCH;
-            goto out0;
+            return -ESRCH;
         }
         BUG_ON(rd == NULL);
         get_knownalive_domain(rd);
@@ -895,7 +870,6 @@ dom0vp_add_physmap(struct domain* d, uns
     //don't update p2m table because this page belongs to rd, not d.
 out1:
     put_domain(rd);
-out0:
     return error;
 }
 
diff -r 6a49e02dc169 -r 4e78528e3480 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Tue Jun 06 09:06:19 2006 -0600
+++ b/xen/include/asm-ia64/mm.h Tue Jun 06 09:11:25 2006 -0600
@@ -429,6 +429,7 @@ extern void assign_domain_page(struct do
 extern void assign_domain_page(struct domain *d, unsigned long mpaddr, 
unsigned long physaddr);
 extern void assign_domain_io_page(struct domain *d, unsigned long mpaddr, 
unsigned long flags);
 extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr);
+extern void *domain_mpa_to_imva(struct domain *d, unsigned long mpaddr);
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 extern unsigned long assign_domain_mmio_page(struct domain *d, unsigned long 
mpaddr, unsigned long size);
diff -r 6a49e02dc169 -r 4e78528e3480 xen/arch/ia64/xen/efi_emul.c
--- a/xen/arch/ia64/xen/efi_emul.c      Tue Jun 06 09:06:19 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * 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 <asm/fpswa.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;
-       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");
-               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);
-
-               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. */
-       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 {
-                       printf("\n");
-                       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®.