ia64/xen-unstable

changeset 15148:409f9849fa68

[IA64] vcpu_set_psr added and used by vcpu_rfi.

Signed-off-by: Tristan Gingold <tgingold@free.fr>
author Alex Williamson <alex.williamson@hp.com>
date Thu May 31 11:05:33 2007 -0600 (2007-05-31)
parents b4cc3fbcdf25
children c0afc89cda75
files xen/arch/ia64/xen/vcpu.c
line diff
     1.1 --- a/xen/arch/ia64/xen/vcpu.c	Thu May 31 10:48:48 2007 -0600
     1.2 +++ b/xen/arch/ia64/xen/vcpu.c	Thu May 31 11:05:33 2007 -0600
     1.3 @@ -448,6 +448,67 @@ IA64FAULT vcpu_set_psr_l(VCPU * vcpu, u6
     1.4  	return IA64_NO_FAULT;
     1.5  }
     1.6  
     1.7 +IA64FAULT vcpu_set_psr(VCPU * vcpu, u64 val)
     1.8 +{
     1.9 +	IA64_PSR newpsr, vpsr;
    1.10 +	REGS *regs = vcpu_regs(vcpu);
    1.11 +	u64 enabling_interrupts = 0;
    1.12 +
    1.13 +	/* Copy non-virtualized bits.  */
    1.14 +	newpsr.val = val & (IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC |
    1.15 +			    IA64_PSR_MFL| IA64_PSR_MFH| IA64_PSR_PK |
    1.16 +			    IA64_PSR_DFL| IA64_PSR_SP | IA64_PSR_DB |
    1.17 +			    IA64_PSR_LP | IA64_PSR_TB | IA64_PSR_ID |
    1.18 +			    IA64_PSR_DA | IA64_PSR_DD | IA64_PSR_SS |
    1.19 +			    IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA);
    1.20 +
    1.21 +	/* Bits forced to 1 (psr.si, psr.is and psr.mc are forced to 0)  */
    1.22 +	newpsr.val |= IA64_PSR_DI;
    1.23 +
    1.24 +	newpsr.val |= IA64_PSR_I  | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT |
    1.25 +		      IA64_PSR_IT | IA64_PSR_BN | IA64_PSR_DI | IA64_PSR_PP;
    1.26 +
    1.27 +	vpsr.val = val;
    1.28 +
    1.29 +	if (val & IA64_PSR_DFH) {
    1.30 +		newpsr.dfh = 1;
    1.31 +		PSCB(vcpu, vpsr_dfh) = 1;
    1.32 +	} else {
    1.33 +		newpsr.dfh = PSCB(vcpu, hpsr_dfh);
    1.34 +		PSCB(vcpu, vpsr_dfh) = 0;
    1.35 +	}
    1.36 +
    1.37 +	PSCB(vcpu, vpsr_pp) = vpsr.pp;
    1.38 +
    1.39 +	if (vpsr.i) {
    1.40 +		if (vcpu->vcpu_info->evtchn_upcall_mask)
    1.41 +			enabling_interrupts = 1;
    1.42 +
    1.43 +		vcpu->vcpu_info->evtchn_upcall_mask = 0;
    1.44 +
    1.45 +		if (enabling_interrupts &&
    1.46 +		    vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
    1.47 +			PSCB(vcpu, pending_interruption) = 1;
    1.48 +	} else
    1.49 +		vcpu->vcpu_info->evtchn_upcall_mask = 1;
    1.50 +
    1.51 +	PSCB(vcpu, interrupt_collection_enabled) = vpsr.ic;
    1.52 +	vcpu_set_metaphysical_mode(vcpu, !(vpsr.dt && vpsr.rt && vpsr.it));
    1.53 +
    1.54 +	newpsr.cpl |= vpsr.cpl | 2;
    1.55 +
    1.56 +	if (PSCB(vcpu, banknum)	!= vpsr.bn) {
    1.57 +		if (vpsr.bn)
    1.58 +			vcpu_bsw1(vcpu);
    1.59 +		else
    1.60 +			vcpu_bsw0(vcpu);
    1.61 +	}
    1.62 +
    1.63 +	regs->cr_ipsr = newpsr.val;
    1.64 +
    1.65 +	return IA64_NO_FAULT;
    1.66 +}
    1.67 +
    1.68  u64 vcpu_get_psr(VCPU * vcpu)
    1.69  {
    1.70   	REGS *regs = vcpu_regs(vcpu);
    1.71 @@ -473,12 +534,14 @@ u64 vcpu_get_psr(VCPU * vcpu)
    1.72  
    1.73  	if (!PSCB(vcpu, metaphysical_mode))
    1.74  		newpsr.i64 |= IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_IT;
    1.75 +
    1.76  	newpsr.ia64_psr.dfh = PSCB(vcpu, vpsr_dfh);
    1.77  	newpsr.ia64_psr.pp = PSCB(vcpu, vpsr_pp);
    1.78  
    1.79  	/* Fool cpl.  */
    1.80  	if (ipsr.ia64_psr.cpl < 3)
    1.81  		newpsr.ia64_psr.cpl = 0;
    1.82 +
    1.83  	newpsr.ia64_psr.bn = PSCB(vcpu, banknum);
    1.84  	
    1.85  	return newpsr.i64;
    1.86 @@ -1347,44 +1410,17 @@ IA64FAULT vcpu_force_data_miss(VCPU * vc
    1.87  
    1.88  IA64FAULT vcpu_rfi(VCPU * vcpu)
    1.89  {
    1.90 -	// TODO: Only allowed for current vcpu
    1.91 -	PSR psr;
    1.92 -	u64 int_enable, ifs;
    1.93 +	u64 ifs;
    1.94  	REGS *regs = vcpu_regs(vcpu);
    1.95 -
    1.96 -	psr.i64 = PSCB(vcpu, ipsr);
    1.97 -	if (psr.ia64_psr.cpl < 3)
    1.98 -		psr.ia64_psr.cpl = 2;
    1.99 -	int_enable = psr.ia64_psr.i;
   1.100 -	if (psr.ia64_psr.dfh) {
   1.101 -		PSCB(vcpu, vpsr_dfh) = 1;
   1.102 -	} else {
   1.103 -		psr.ia64_psr.dfh = PSCB(vcpu, hpsr_dfh);
   1.104 -		PSCB(vcpu, vpsr_dfh) = 0;
   1.105 -	}
   1.106 -	if (psr.ia64_psr.ic)
   1.107 -		PSCB(vcpu, interrupt_collection_enabled) = 1;
   1.108 -	if (psr.ia64_psr.dt && psr.ia64_psr.rt && psr.ia64_psr.it)
   1.109 -		vcpu_set_metaphysical_mode(vcpu, FALSE);
   1.110 -	else
   1.111 -		vcpu_set_metaphysical_mode(vcpu, TRUE);
   1.112 -	psr.ia64_psr.ic = 1;
   1.113 -	psr.ia64_psr.i = 1;
   1.114 -	psr.ia64_psr.dt = 1;
   1.115 -	psr.ia64_psr.rt = 1;
   1.116 -	psr.ia64_psr.it = 1;
   1.117 -	psr.ia64_psr.bn = 1;
   1.118 -	//psr.pk = 1;  // checking pkeys shouldn't be a problem but seems broken
   1.119 +	
   1.120 +	vcpu_set_psr(vcpu, PSCB(vcpu, ipsr));
   1.121  
   1.122  	ifs = PSCB(vcpu, ifs);
   1.123  	if (ifs & 0x8000000000000000UL) 
   1.124  		regs->cr_ifs = ifs;
   1.125  
   1.126 -	regs->cr_ipsr = psr.i64;
   1.127  	regs->cr_iip = PSCB(vcpu, iip);
   1.128 -	PSCB(vcpu, interrupt_collection_enabled) = 1;
   1.129 -	vcpu_bsw1(vcpu);
   1.130 -	vcpu->vcpu_info->evtchn_upcall_mask = !int_enable;
   1.131 +
   1.132  	return IA64_NO_FAULT;
   1.133  }
   1.134