ia64/xen-unstable

changeset 10158:9d52a66c7499

[IA64] support FPSWA hypercall

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Thu May 25 15:59:18 2006 -0600 (2006-05-25)
parents faae893d428e
children c073ebdbde8c
files xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/efi_emul.c xen/arch/ia64/xen/hypercall.c xen/include/asm-ia64/dom_fw.h xen/include/asm-ia64/domain.h
line diff
     1.1 --- a/xen/arch/ia64/xen/dom_fw.c	Thu May 25 15:47:33 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Thu May 25 15:59:18 2006 -0600
     1.3 @@ -15,6 +15,7 @@
     1.4  #include <asm/pal.h>
     1.5  #include <asm/sal.h>
     1.6  #include <asm/meminit.h>
     1.7 +#include <asm/fpswa.h>
     1.8  #include <xen/compile.h>
     1.9  #include <xen/acpi.h>
    1.10  
    1.11 @@ -60,6 +61,29 @@ dom_pa(unsigned long imva)
    1.12      } while (0)
    1.13  
    1.14  // builds a hypercall bundle at domain physical address
    1.15 +static void dom_fpswa_hypercall_patch(struct domain *d)
    1.16 +{
    1.17 +	unsigned long *entry_imva, *patch_imva;
    1.18 +	unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
    1.19 +	unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
    1.20 +
    1.21 +#ifndef CONFIG_XEN_IA64_DOM0_VP
    1.22 +	if (d == dom0) {
    1.23 +		entry_paddr += dom0_start;
    1.24 +		patch_paddr += dom0_start;
    1.25 +	}
    1.26 +#endif
    1.27 +	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
    1.28 +	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
    1.29 +	entry_imva = (unsigned long *) domain_mpa_to_imva(d, entry_paddr);
    1.30 +	patch_imva = (unsigned long *) domain_mpa_to_imva(d, patch_paddr);
    1.31 +
    1.32 +	*entry_imva++ = patch_paddr;
    1.33 +	*entry_imva   = 0;
    1.34 +	build_hypercall_bundle(patch_imva, d->arch.breakimm, FW_HYPERCALL_FPSWA, 1);
    1.35 +}
    1.36 +
    1.37 +// builds a hypercall bundle at domain physical address
    1.38  static void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall)
    1.39  {
    1.40  	unsigned long *imva;
    1.41 @@ -72,7 +96,6 @@ static void dom_efi_hypercall_patch(stru
    1.42  	build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
    1.43  }
    1.44  
    1.45 -
    1.46  // builds a hypercall bundle at domain physical address
    1.47  static void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall,unsigned long ret)
    1.48  {
    1.49 @@ -771,6 +794,7 @@ dom_fw_init (struct domain *d, const cha
    1.50  	struct ia64_sal_systab *sal_systab;
    1.51  	struct ia64_sal_desc_entry_point *sal_ed;
    1.52  	struct ia64_sal_desc_ap_wakeup *sal_wakeup;
    1.53 +	fpswa_interface_t *fpswa_inf;
    1.54  	efi_memory_desc_t *efi_memmap, *md;
    1.55  	struct ia64_boot_param *bp;
    1.56  	unsigned long *pfn;
    1.57 @@ -812,6 +836,7 @@ dom_fw_init (struct domain *d, const cha
    1.58  	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
    1.59  	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
    1.60  	sal_wakeup  = (void *) cp; cp += sizeof(*sal_wakeup);
    1.61 +	fpswa_inf   = (void *) cp; cp += sizeof(*fpswa_inf);
    1.62  	efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
    1.63  	bp	    = (void *) cp; cp += sizeof(*bp);
    1.64  	pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
    1.65 @@ -819,6 +844,7 @@ dom_fw_init (struct domain *d, const cha
    1.66  
    1.67  	/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
    1.68  	d->arch.efi_runtime = efi_runtime;
    1.69 +	d->arch.fpswa_inf   = fpswa_inf;
    1.70  
    1.71  	if (args) {
    1.72  		if (arglen >= 1024)
    1.73 @@ -962,6 +988,11 @@ dom_fw_init (struct domain *d, const cha
    1.74  
    1.75  	sal_systab->checksum = -checksum;
    1.76  
    1.77 +	/* Fill in the FPSWA interface: */
    1.78 +	fpswa_inf->revision = fpswa_interface->revision;
    1.79 +	dom_fpswa_hypercall_patch(d);
    1.80 +	fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR + start_mpaddr;
    1.81 +
    1.82  	i = 0;
    1.83  	if (d == dom0) {
    1.84  #ifndef CONFIG_XEN_IA64_DOM0_VP
    1.85 @@ -1045,7 +1076,7 @@ dom_fw_init (struct domain *d, const cha
    1.86  	bp->console_info.num_rows = 25;
    1.87  	bp->console_info.orig_x = 0;
    1.88  	bp->console_info.orig_y = 24;
    1.89 -	bp->fpswa = 0;
    1.90 +	bp->fpswa = dom_pa((unsigned long) fpswa_inf);
    1.91  	if (d == dom0) {
    1.92  		// XXX CONFIG_XEN_IA64_DOM0_VP
    1.93  		// initrd_start address is hard coded in start_kernel()
     2.1 --- a/xen/arch/ia64/xen/efi_emul.c	Thu May 25 15:47:33 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/efi_emul.c	Thu May 25 15:59:18 2006 -0600
     2.3 @@ -21,6 +21,7 @@
     2.4  #include <asm/pgalloc.h>
     2.5  #include <asm/vcpu.h>
     2.6  #include <asm/dom_fw.h>
     2.7 +#include <asm/fpswa.h>
     2.8  #include <public/sched.h>
     2.9  
    2.10  extern unsigned long translate_domain_mpaddr(unsigned long);
    2.11 @@ -75,6 +76,7 @@ efi_emulate_set_virtual_address_map(
    2.12  	unsigned long *vfn;
    2.13  	struct domain *d = current->domain;
    2.14  	efi_runtime_services_t *efi_runtime = d->arch.efi_runtime;
    2.15 +	fpswa_interface_t *fpswa_inf = d->arch.fpswa_inf;
    2.16  
    2.17  	if (descriptor_version != EFI_MEMDESC_VERSION) {
    2.18  		printf ("efi_emulate_set_virtual_address_map: memory descriptor version unmatched\n");
    2.19 @@ -119,6 +121,12 @@ efi_emulate_set_virtual_address_map(
    2.20  		EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_variable,EFI_SET_VARIABLE);
    2.21  		EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
    2.22  		EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->reset_system,EFI_RESET_SYSTEM);
    2.23 +
    2.24 +		vfn = (unsigned long *) domain_mpa_to_imva(d, (unsigned long) fpswa_inf->fpswa);
    2.25 +		*vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
    2.26 +		*vfn   = 0;
    2.27 +		fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr);
    2.28 +		break;
    2.29  	}
    2.30  
    2.31  	/* The virtual address map has been applied. */
     3.1 --- a/xen/arch/ia64/xen/hypercall.c	Thu May 25 15:47:33 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/hypercall.c	Thu May 25 15:59:18 2006 -0600
     3.3 @@ -14,6 +14,7 @@
     3.4  
     3.5  #include <linux/efi.h>	/* FOR EFI_UNIMPLEMENTED */
     3.6  #include <asm/sal.h>	/* FOR struct ia64_sal_retval */
     3.7 +#include <asm/fpswa.h>	/* FOR struct fpswa_ret_t */
     3.8  
     3.9  #include <asm/vcpu.h>
    3.10  #include <asm/dom_fw.h>
    3.11 @@ -181,12 +182,19 @@ fw_hypercall_ipi (struct pt_regs *regs)
    3.12  	return;
    3.13  }
    3.14  
    3.15 +static fpswa_ret_t
    3.16 +fw_hypercall_fpswa (struct vcpu *v)
    3.17 +{
    3.18 +	return PSCBX(v, fpswa_ret);
    3.19 +}
    3.20 +
    3.21  static IA64FAULT
    3.22  fw_hypercall (struct pt_regs *regs)
    3.23  {
    3.24  	struct vcpu *v = current;
    3.25  	struct sal_ret_values x;
    3.26  	efi_status_t efi_ret_value;
    3.27 +	fpswa_ret_t fpswa_ret;
    3.28  	IA64FAULT fault; 
    3.29  	unsigned long index = regs->r2 & FW_HYPERCALL_NUM_MASK_HIGH;
    3.30  
    3.31 @@ -253,6 +261,13 @@ fw_hypercall (struct pt_regs *regs)
    3.32  	    case FW_HYPERCALL_IPI:
    3.33  		fw_hypercall_ipi (regs);
    3.34  		break;
    3.35 +	    case FW_HYPERCALL_FPSWA:
    3.36 +		fpswa_ret = fw_hypercall_fpswa (v);
    3.37 +		regs->r8  = fpswa_ret.status;
    3.38 +		regs->r9  = fpswa_ret.err0;
    3.39 +		regs->r10 = fpswa_ret.err1;
    3.40 +		regs->r11 = fpswa_ret.err2;
    3.41 +		break;
    3.42  	    default:
    3.43  		printf("unknown ia64 fw hypercall %lx\n", regs->r2);
    3.44  		regs->r8 = do_ni_hypercall();
     4.1 --- a/xen/include/asm-ia64/dom_fw.h	Thu May 25 15:47:33 2006 -0600
     4.2 +++ b/xen/include/asm-ia64/dom_fw.h	Thu May 25 15:59:18 2006 -0600
     4.3 @@ -119,6 +119,23 @@
     4.4  #define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_PADDR	FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX)
     4.5  #define FW_HYPERCALL_EFI_RESET_SYSTEM_PADDR		FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX)
     4.6  
     4.7 +/*
     4.8 + * This is a hypercall number for IPI.
     4.9 + * A pseudo-entry-point is not presented to IPI hypercall. This hypercall number 
    4.10 + * is used in xen_send_ipi of linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S.
    4.11 + */
    4.12 +#define FW_HYPERCALL_IPI				0x400UL
    4.13 +
    4.14 +/*
    4.15 + * This is a hypercall number for FPSWA.
    4.16 + * FPSWA hypercall uses 2 bundles for a pseudo-entry-point and a hypercall-patch.
    4.17 + */
    4.18 +#define FW_HYPERCALL_FPSWA_ENTRY_INDEX			0x83UL
    4.19 +#define FW_HYPERCALL_FPSWA_PATCH_INDEX			0x84UL
    4.20 +#define FW_HYPERCALL_FPSWA_ENTRY_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX)
    4.21 +#define FW_HYPERCALL_FPSWA_PATCH_PADDR			FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX)
    4.22 +#define FW_HYPERCALL_FPSWA				0x500UL
    4.23 +
    4.24  /* Hypercalls index bellow _FIRST_ARCH are reserved by Xen, while those above
    4.25     are for the architecture.
    4.26     Note: this limit was defined by Xen/ia64 (and not by Xen).²
    4.27 @@ -126,8 +143,6 @@
    4.28  */
    4.29  #define FW_HYPERCALL_FIRST_ARCH		0x300UL
    4.30  
    4.31 -#define FW_HYPERCALL_IPI		0x400UL
    4.32 -
    4.33  /* Xen/ia64 user hypercalls.  Only used for debugging.  */
    4.34  #define FW_HYPERCALL_FIRST_USER		0xff00UL
    4.35  
     5.1 --- a/xen/include/asm-ia64/domain.h	Thu May 25 15:47:33 2006 -0600
     5.2 +++ b/xen/include/asm-ia64/domain.h	Thu May 25 15:59:18 2006 -0600
     5.3 @@ -10,6 +10,7 @@
     5.4  #include <asm/vmx_platform.h>
     5.5  #include <xen/list.h>
     5.6  #include <xen/cpumask.h>
     5.7 +#include <asm/fpswa.h>
     5.8  
     5.9  extern void domain_relinquish_resources(struct domain *);
    5.10  
    5.11 @@ -59,8 +60,12 @@ struct arch_domain {
    5.12      unsigned long initrd_start;
    5.13      unsigned long initrd_len;
    5.14      char *cmdline;
    5.15 +    /* There are these for EFI_SET_VIRTUAL_ADDRESS_MAP emulation. */
    5.16      int efi_virt_mode;		/* phys : 0 , virt : 1 */
    5.17 +    /* Metaphysical address to efi_runtime_services_t in domain firmware memory is set. */
    5.18      void *efi_runtime;
    5.19 +    /* Metaphysical address to fpswa_interface_t in domain firmware memory is set. */
    5.20 +    void *fpswa_inf;
    5.21  };
    5.22  #define xen_vastart arch.xen_vastart
    5.23  #define xen_vaend arch.xen_vaend
    5.24 @@ -109,6 +114,7 @@ struct arch_vcpu {
    5.25      //for phycial  emulation
    5.26      unsigned long old_rsc;
    5.27      int mode_flags;
    5.28 +    fpswa_ret_t fpswa_ret;	/* save return values of FPSWA emulation */
    5.29      struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
    5.30  };
    5.31