@ -1331,9 +1331,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static uint64_t isr_read ( CPUARMState * env , const ARMCPRegInfo * ri )
{
CPUState * cs = ENV_GET_CPU ( env ) ;
uint64_t hcr_el2 = arm_hcr_el2_eff ( env ) ;
uint64_t ret = 0 ;
if ( arm_hcr_el2_imo ( env ) ) {
if ( hcr_el2 & HCR_IMO ) {
if ( cs - > interrupt_request & CPU_INTERRUPT_VIRQ ) {
ret | = CPSR_I ;
}
@ -1343,7 +1344,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
}
}
if ( arm_hcr_el2_fmo ( env ) ) {
if ( hcr_el2 & HCR_FMO ) {
if ( cs - > interrupt_request & CPU_INTERRUPT_VFIQ ) {
ret | = CPSR_F ;
}
@ -4008,6 +4009,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
hcr_write ( env , NULL , value ) ;
}
/*
* Return the effective value of HCR_EL2 .
* Bits that are not included here :
* RW ( read from SCR_EL3 . RW as needed )
*/
uint64_t arm_hcr_el2_eff ( CPUARMState * env )
{
uint64_t ret = env - > cp15 . hcr_el2 ;
if ( arm_is_secure_below_el3 ( env ) ) {
/*
* " This register has no effect if EL2 is not enabled in the
* current Security state " . This is ARMv8.4-SecEL2 speak for
* ! ( SCR_EL3 . NS = = 1 | | SCR_EL3 . EEL2 = = 1 ) .
*
* Prior to that , the language was " In an implementation that
* includes EL3 , when the value of SCR_EL3 . NS is 0 the PE behaves
* as if this field is 0 for all purposes other than a direct
* read or write access of HCR_EL2 " . With lots of enumeration
* on a per - field basis . In current QEMU , this is condition
* is arm_is_secure_below_el3 .
*
* Since the v8 .4 language applies to the entire register , and
* appears to be backward compatible , use that .
*/
ret = 0 ;
} else if ( ret & HCR_TGE ) {
/* These bits are up-to-date as of ARMv8.4. */
if ( ret & HCR_E2H ) {
ret & = ~ ( HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE ) ;
} else {
ret | = HCR_FMO | HCR_IMO | HCR_AMO ;
}
ret & = ~ ( HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
HCR_TLOR ) ;
}
return ret ;
}
static const ARMCPRegInfo el2_cp_reginfo [ ] = {
{ . name = " HCR_EL2 " , . state = ARM_CP_STATE_AA64 ,
. type = ARM_CP_IO ,
@ -6526,12 +6572,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
uint32_t cur_el , bool secure )
{
CPUARMState * env = cs - > env_ptr ;
int rw ;
int scr ;
int hcr ;
bool rw ;
bool scr ;
bool hcr ;
int target_el ;
/* Is the highest EL AArch64? */
int is64 = arm_feature ( env , ARM_FEATURE_AARCH64 ) ;
bool is64 = arm_feature ( env , ARM_FEATURE_AARCH64 ) ;
uint64_t hcr_el2 ;
if ( arm_feature ( env , ARM_FEATURE_EL3 ) ) {
rw = ( ( env - > cp15 . scr_el3 & SCR_RW ) = = SCR_RW ) ;
@ -6543,18 +6590,19 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
rw = is64 ;
}
hcr_el2 = arm_hcr_el2_eff ( env ) ;
switch ( excp_idx ) {
case EXCP_IRQ :
scr = ( ( env - > cp15 . scr_el3 & SCR_IRQ ) = = SCR_IRQ ) ;
hcr = arm_hcr_el2_imo ( env ) ;
hcr = hcr_el2 & HCR_IMO ;
break ;
case EXCP_FIQ :
scr = ( ( env - > cp15 . scr_el3 & SCR_FIQ ) = = SCR_FIQ ) ;
hcr = arm_hcr_el2_fmo ( env ) ;
hcr = hcr_el2 & HCR_FMO ;
break ;
default :
scr = ( ( env - > cp15 . scr_el3 & SCR_EA ) = = SCR_EA ) ;
hcr = arm_hcr_el2_amo ( env ) ;
hcr = hcr_el2 & HCR_AMO ;
break ;
} ;