ia64/xen-unstable

changeset 11415:9fed76231248

[IA64] hwclock support

This patch supports the hwclock on Domain-0.
It adds the following EFI runtime service emulations for the
hwclock support.
1. SetTime
2. Get/SetWakeupTime

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Mon Sep 04 14:45:20 2006 -0600 (2006-09-04)
parents 1bab7d65171b
children 685bf9b75eb1
files xen/arch/ia64/xen/fw_emul.c
line diff
     1.1 --- a/xen/arch/ia64/xen/fw_emul.c	Fri Sep 01 13:04:02 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/fw_emul.c	Mon Sep 04 14:45:20 2006 -0600
     1.3 @@ -395,28 +395,124 @@ efi_emulate_get_time(
     1.4  	unsigned long tv_addr, unsigned long tc_addr,
     1.5  	IA64FAULT *fault)
     1.6  {
     1.7 -	unsigned long tv = 0, tc = 0;
     1.8 +	unsigned long tv, tc = 0;
     1.9  	struct page_info *tv_page = NULL;
    1.10  	struct page_info *tc_page = NULL;
    1.11 -	efi_status_t status;
    1.12 +	efi_status_t status = 0;
    1.13  
    1.14  	//printf("efi_get_time(%016lx,%016lx) called\n", tv_addr, tc_addr);
    1.15  	tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
    1.16  	if (*fault != IA64_NO_FAULT)
    1.17 -		return 0;
    1.18 +		goto errout;
    1.19  	if (tc_addr) {
    1.20  		tc = efi_translate_domain_addr(tc_addr, fault, &tc_page);
    1.21 -		if (*fault != IA64_NO_FAULT) {
    1.22 -			put_page(tv_page);
    1.23 -			return 0;
    1.24 -		}
    1.25 +		if (*fault != IA64_NO_FAULT)
    1.26 +			goto errout;
    1.27  	}
    1.28 +
    1.29  	//printf("efi_get_time(%016lx,%016lx) translated to xen virtual address\n", tv, tc);
    1.30  	status = (*efi.get_time)((efi_time_t *) tv, (efi_time_cap_t *) tc);
    1.31  	//printf("efi_get_time returns %lx\n", status);
    1.32 +
    1.33 +errout:
    1.34  	if (tc_page != NULL)
    1.35  		put_page(tc_page);
    1.36 -	put_page(tv_page);
    1.37 +	if (tv_page != NULL)
    1.38 +		put_page(tv_page);
    1.39 +
    1.40 +	return status;
    1.41 +}
    1.42 +
    1.43 +static efi_status_t
    1.44 +efi_emulate_set_time(
    1.45 +	unsigned long tv_addr, IA64FAULT *fault)
    1.46 +{
    1.47 +	unsigned long tv;
    1.48 +	struct page_info *tv_page = NULL;
    1.49 +	efi_status_t status = 0;
    1.50 +
    1.51 +	if (current->domain != dom0)
    1.52 +		return EFI_UNSUPPORTED;
    1.53 +
    1.54 +	tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
    1.55 +	if (*fault != IA64_NO_FAULT)
    1.56 +		goto errout;
    1.57 +
    1.58 +	status = (*efi.set_time)((efi_time_t *)tv);
    1.59 +
    1.60 +errout:
    1.61 +	if (tv_page != NULL)
    1.62 +		put_page(tv_page);
    1.63 +
    1.64 +	return status;
    1.65 +}
    1.66 +
    1.67 +static efi_status_t
    1.68 +efi_emulate_get_wakeup_time(
    1.69 +	unsigned long e_addr, unsigned long p_addr,
    1.70 +	unsigned long tv_addr, IA64FAULT *fault)
    1.71 +{
    1.72 +	unsigned long enabled, pending, tv;
    1.73 +	struct page_info *e_page = NULL, *p_page = NULL,
    1.74 +	                 *tv_page = NULL;
    1.75 +	efi_status_t status = 0;
    1.76 +
    1.77 +	if (current->domain != dom0)
    1.78 +		return EFI_UNSUPPORTED;
    1.79 +
    1.80 +	if (!e_addr || !p_addr || !tv_addr)
    1.81 +		return EFI_INVALID_PARAMETER;
    1.82 +
    1.83 +	enabled = efi_translate_domain_addr(e_addr, fault, &e_page);
    1.84 +	if (*fault != IA64_NO_FAULT)
    1.85 +		goto errout;
    1.86 +	pending = efi_translate_domain_addr(p_addr, fault, &p_page);
    1.87 +	if (*fault != IA64_NO_FAULT)
    1.88 +		goto errout;
    1.89 +	tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
    1.90 +	if (*fault != IA64_NO_FAULT)
    1.91 +		goto errout;
    1.92 +
    1.93 +	status = (*efi.get_wakeup_time)((efi_bool_t *)enabled,
    1.94 +	                                (efi_bool_t *)pending,
    1.95 +	                                (efi_time_t *)tv);
    1.96 +
    1.97 +errout:
    1.98 +	if (e_page != NULL)
    1.99 +		put_page(e_page);
   1.100 +	if (p_page != NULL)
   1.101 +		put_page(p_page);
   1.102 +	if (tv_page != NULL)
   1.103 +		put_page(tv_page);
   1.104 +
   1.105 +	return status;
   1.106 +}
   1.107 +
   1.108 +static efi_status_t
   1.109 +efi_emulate_set_wakeup_time(
   1.110 +	unsigned long enabled, unsigned long tv_addr,
   1.111 +	IA64FAULT *fault)
   1.112 +{
   1.113 +	unsigned long tv = 0;
   1.114 +	struct page_info *tv_page = NULL;
   1.115 +	efi_status_t status = 0;
   1.116 +
   1.117 +	if (current->domain != dom0)
   1.118 +		return EFI_UNSUPPORTED;
   1.119 +
   1.120 +	if (tv_addr) {
   1.121 +		tv = efi_translate_domain_addr(tv_addr, fault, &tv_page);
   1.122 +		if (*fault != IA64_NO_FAULT)
   1.123 +			goto errout;
   1.124 +	}
   1.125 +
   1.126 +	status = (*efi.set_wakeup_time)((efi_bool_t)enabled,
   1.127 +	                                (efi_time_t *)tv);
   1.128 +
   1.129 +errout:
   1.130 +	if (tv_page != NULL)
   1.131 +		put_page(tv_page);
   1.132 +
   1.133  	return status;
   1.134  }
   1.135  
   1.136 @@ -663,6 +759,24 @@ efi_emulator (struct pt_regs *regs, IA64
   1.137  				vcpu_get_gr(v,33),
   1.138  				fault);
   1.139  		break;
   1.140 +	    case FW_HYPERCALL_EFI_SET_TIME:
   1.141 +		status = efi_emulate_set_time (
   1.142 +				vcpu_get_gr(v,32),
   1.143 +				fault);
   1.144 +		break;
   1.145 +	    case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
   1.146 +		status = efi_emulate_get_wakeup_time (
   1.147 +				vcpu_get_gr(v,32),
   1.148 +				vcpu_get_gr(v,33),
   1.149 +				vcpu_get_gr(v,34),
   1.150 +				fault);
   1.151 +		break;
   1.152 +	    case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
   1.153 +		status = efi_emulate_set_wakeup_time (
   1.154 +				vcpu_get_gr(v,32),
   1.155 +				vcpu_get_gr(v,33),
   1.156 +				fault);
   1.157 +		break;
   1.158  	    case FW_HYPERCALL_EFI_GET_VARIABLE:
   1.159  		status = efi_emulate_get_variable (
   1.160  				vcpu_get_gr(v,32),
   1.161 @@ -695,10 +809,6 @@ efi_emulator (struct pt_regs *regs, IA64
   1.162   				(u32) vcpu_get_gr(v,34),
   1.163  				(efi_memory_desc_t *) vcpu_get_gr(v,35));
   1.164  		break;
   1.165 -	    case FW_HYPERCALL_EFI_SET_TIME:
   1.166 -	    case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
   1.167 -	    case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
   1.168 -		// FIXME: need fixes in efi.h from 2.6.9
   1.169  	    case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
   1.170  		// FIXME: need fixes in efi.h from 2.6.9
   1.171  		status = EFI_UNSUPPORTED;