# HG changeset patch # User gingold@virtu10 # Node ID e8c5c6b008be6865cea60f2c65f2b28abd81590d # Parent f662f98d594b65e1698c5da241312f1ae136b975 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 diff -r f662f98d594b -r e8c5c6b008be xen/arch/ia64/vmx/vmx_hypercall.c --- a/xen/arch/ia64/vmx/vmx_hypercall.c Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c Tue Jun 06 12:17:04 2006 +0200 @@ -36,7 +36,6 @@ #include 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 f662f98d594b -r e8c5c6b008be xen/arch/ia64/xen/Makefile --- a/xen/arch/ia64/xen/Makefile Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/arch/ia64/xen/Makefile Tue Jun 06 12:17:04 2006 +0200 @@ -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 f662f98d594b -r e8c5c6b008be xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/arch/ia64/xen/dom_fw.c Tue Jun 06 12:17:04 2006 +0200 @@ -25,7 +25,6 @@ #include 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 f662f98d594b -r e8c5c6b008be xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/arch/ia64/xen/fw_emul.c Tue Jun 06 12:17:04 2006 +0200 @@ -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 #include #include @@ -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 f662f98d594b -r e8c5c6b008be xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/arch/ia64/xen/mm.c Tue Jun 06 12:17:04 2006 +0200 @@ -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<= 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 f662f98d594b -r e8c5c6b008be xen/include/asm-ia64/mm.h --- a/xen/include/asm-ia64/mm.h Mon Jun 05 14:28:39 2006 -0600 +++ b/xen/include/asm-ia64/mm.h Tue Jun 06 12:17:04 2006 +0200 @@ -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 f662f98d594b -r e8c5c6b008be xen/arch/ia64/xen/efi_emul.c --- a/xen/arch/ia64/xen/efi_emul.c Mon Jun 05 14:28:39 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 -#include -#include -#include -#include -#include -#include - -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; -}