diff --git a/val/common/include/acs_timer_support.h b/val/common/include/acs_timer_support.h index ae4f32e6..3fc76753 100644 --- a/val/common/include/acs_timer_support.h +++ b/val/common/include/acs_timer_support.h @@ -57,6 +57,18 @@ ArmArchTimerWriteReg ( uint64_t *data_buf ); +uint64_t ArmReadHcrEl2(void); +uint64_t ArmReadAA64MMFR1EL1(void); +uint64_t ArmReadAA64MMFR4EL1(void); +uint64_t ArmReadCntpCtl02(void); +uint64_t ArmReadCntpTval02(void); +void ArmWriteCntpCtl02(uint64_t val); +void ArmWriteCntpTval02(uint64_t val); +uint64_t ArmReadCntvCtl02(void); +uint64_t ArmReadCntvTval02(void); +void ArmWriteCntvCtl02(uint64_t val); +void ArmWriteCntvTval02(uint64_t val); + uint64_t ArmReadCntFrq ( void diff --git a/val/common/src/AArch64/ArchTimerSupport.S b/val/common/src/AArch64/ArchTimerSupport.S index b1e4ae2b..497030b5 100644 --- a/val/common/src/AArch64/ArchTimerSupport.S +++ b/val/common/src/AArch64/ArchTimerSupport.S @@ -39,17 +39,27 @@ .text .align 2 +GCC_ASM_EXPORT(ArmReadHcrEl2) +GCC_ASM_EXPORT(ArmReadAA64MMFR1EL1) +GCC_ASM_EXPORT(ArmReadAA64MMFR4EL1) GCC_ASM_EXPORT(ArmReadCntFrq) GCC_ASM_EXPORT(ArmReadCntPct) GCC_ASM_EXPORT(ArmReadCntkCtl) GCC_ASM_EXPORT(ArmWriteCntkCtl) GCC_ASM_EXPORT(ArmReadCntpTval) GCC_ASM_EXPORT(ArmWriteCntpTval) +GCC_ASM_EXPORT(ArmReadCntpTval02) +GCC_ASM_EXPORT(ArmWriteCntpTval02) GCC_ASM_EXPORT(ArmReadCntpCtl) +GCC_ASM_EXPORT(ArmReadCntpCtl02) GCC_ASM_EXPORT(ArmReadCntvTval) +GCC_ASM_EXPORT(ArmReadCntvTval02) GCC_ASM_EXPORT(ArmWriteCntvTval) +GCC_ASM_EXPORT(ArmWriteCntvTval02) GCC_ASM_EXPORT(ArmReadCntvCtl) +GCC_ASM_EXPORT(ArmReadCntvCtl02) GCC_ASM_EXPORT(ArmWriteCntvCtl) +GCC_ASM_EXPORT(ArmWriteCntvCtl02) GCC_ASM_EXPORT(ArmReadCntvCt) GCC_ASM_EXPORT(ArmReadCntpCval) GCC_ASM_EXPORT(ArmWriteCntpCval) @@ -66,6 +76,20 @@ GCC_ASM_EXPORT(ArmWriteCnthvCtl) GCC_ASM_EXPORT(ArmReadCnthvTval) GCC_ASM_EXPORT(ArmWriteCnthvTval) GCC_ASM_EXPORT(ArmWriteCntpCtl) +GCC_ASM_EXPORT(ArmWriteCntpCtl02) + +ASM_PFX(ArmReadHcrEl2): + mrs x0, hcr_el2 // Read HCR_EL2 + ret + +ASM_PFX(ArmReadAA64MMFR1EL1): + mrs x0, id_aa64mmfr1_el1 // Read ID_AA64MMFR1_EL1 + ret + +ASM_PFX(ArmReadAA64MMFR4EL1): + //mrs x0, id_aa64mmfr4_el1 // Read ID_AA64MMFR4_EL1 + mrs x0, s3_0_c0_c7_4 + ret ASM_PFX(ArmReadCntFrq): mrs x0, cntfrq_el0 // Read CNTFRQ @@ -87,9 +111,12 @@ ASM_PFX(ArmWriteCntkCtl): isb ret - ASM_PFX(ArmReadCntpTval): - mrs x0, cntp_tval_el0 // Read CNTP_TVAL (PL1 physical timer value register) + mrs x0, cntp_tval_el0 // Read CNTP_TVAL (PL1 physical timer value register) + ret + +ASM_PFX(ArmReadCntpTval02): + mrs x0, cntp_tval_el02 // Read CNTP_TVAL (PL1 physical timer value register) when EL2 Host ret ASM_PFX(ArmWriteCntpTval): @@ -97,39 +124,65 @@ ASM_PFX(ArmWriteCntpTval): isb ret +ASM_PFX(ArmWriteCntpTval02): + msr cntp_tval_el02, x0 // Write to CNTP_TVAL (PL1 physical timer value register) EL2 Host + isb + ret ASM_PFX(ArmReadCntpCtl): - mrs x0, cntp_ctl_el0 // Read CNTP_CTL (PL1 Physical Timer Control Register) + mrs x0, cntp_ctl_el0 // Read CNTP_CTL (PL1 Physical Timer Control Register) + ret + +ASM_PFX(ArmReadCntpCtl02): + mrs x0, cntp_ctl_el02 // Read CNTP_CTL (PL1 Physical Timer Control Register) when EL2 Host ret ASM_PFX(ArmWriteCntpCtl): - msr cntp_ctl_el0, x0 // Write to CNTP_CTL (PL1 Physical Timer Control Register) + msr cntp_ctl_el0, x0 // Write CNTP_CTL (PL1 Physical Timer Control Register) isb ret +ASM_PFX(ArmWriteCntpCtl02): + msr cntp_ctl_el02, x0 // Write CNTP_CTL (PL1 Physical Timer Control Register) when EL2 Host + isb + ret ASM_PFX(ArmReadCntvTval): mrs x0, cntv_tval_el0 // Read CNTV_TVAL (Virtual Timer Value register) ret +ASM_PFX(ArmReadCntvTval02): + mrs x0, cntv_tval_el02 // Read CNTV_TVAL (Virtual Timer value register) when EL2 Host + ret ASM_PFX(ArmWriteCntvTval): msr cntv_tval_el0, x0 // Write to CNTV_TVAL (Virtual Timer Value register) isb ret +ASM_PFX(ArmWriteCntvTval02): + msr cntv_tval_el02, x0 // Write to CNTV_TVAL (Virtual Timer value register) EL2 Host + isb + ret ASM_PFX(ArmReadCntvCtl): mrs x0, cntv_ctl_el0 // Read CNTV_CTL (Virtual Timer Control Register) ret +ASM_PFX(ArmReadCntvCtl02): + mrs x0, cntv_ctl_el02 // Read CNTV_CTL (Virtual Timer Control Register) when EL2 Host + ret ASM_PFX(ArmWriteCntvCtl): msr cntv_ctl_el0, x0 // Write to CNTV_CTL (Virtual Timer Control Register) isb ret +ASM_PFX(ArmWriteCntvCtl02): + msr cntv_ctl_el02, x0 // Write CNTV_CTL (Virtual Timer Control Register) when EL2 Host + isb + ret ASM_PFX(ArmReadCntvCt): mrs x0, cntvct_el0 // Read CNTVCT (Virtual Count Register) diff --git a/val/common/src/acs_timer_support.c b/val/common/src/acs_timer_support.c index 45f028d6..a1aebaf8 100644 --- a/val/common/src/acs_timer_support.c +++ b/val/common/src/acs_timer_support.c @@ -19,6 +19,30 @@ #include "common/include/acs_timer_support.h" #include "common/include/acs_common.h" +/** + @brief This API is used to get the effective HCR_EL2.E2H +**/ +uint8_t get_effective_e2h() +{ + uint32_t effective_E2H; + uint32_t hcr_e2h = VAL_EXTRACT_BITS(ArmReadHcrEl2(), 34, 34); + uint32_t feat_vhe = VAL_EXTRACT_BITS(ArmReadAA64MMFR1EL1(), 8, 11); + uint32_t e2h0 = VAL_EXTRACT_BITS(ArmReadAA64MMFR4EL1(), 24, 27); + + val_print(ACS_PRINT_DEBUG, "\n hcr_e2h : 0x%x", hcr_e2h); + val_print(ACS_PRINT_DEBUG, "\n feat_vhe : 0x%x", feat_vhe); + val_print(ACS_PRINT_DEBUG, "\n e2h0 : 0x%x", e2h0); + + if (feat_vhe == 0x0) //ID_AA64MMFR1_EL1.VH + effective_E2H = 0; + else if (e2h0 != 0x0) //E2H0 = 0 means implemented + effective_E2H = 1; + else + effective_E2H = hcr_e2h; + + return effective_E2H; +} + /** @brief This API is used to read Timer related registers @@ -31,6 +55,9 @@ ArmArchTimerReadReg ( ARM_ARCH_TIMER_REGS Reg ) { + static uint8_t effective_e2h = 0xFF; + if (effective_e2h == 0xFF) + effective_e2h = get_effective_e2h(); switch (Reg) { @@ -44,16 +71,18 @@ ArmArchTimerReadReg ( return ArmReadCntkCtl(); case CntpTval: - return ArmReadCntpTval(); + /* Add Check For E2H, If EL2 Host then access to cntp_tval_el02 */ + return effective_e2h ? ArmReadCntpTval02() : ArmReadCntpTval(); case CntpCtl: - return ArmReadCntpCtl(); + /* Add Check For E2H, If EL2 Host then access to cntp_ctl_el02 */ + return effective_e2h ? ArmReadCntpCtl02() : ArmReadCntpCtl(); case CntvTval: - return ArmReadCntvTval(); + return effective_e2h ? ArmReadCntvTval02() : ArmReadCntvTval(); case CntvCtl: - return ArmReadCntvCtl(); + return effective_e2h ? ArmReadCntvCtl02() : ArmReadCntvCtl(); case CntvCt: return ArmReadCntvCt(); @@ -103,6 +132,10 @@ ArmArchTimerWriteReg ( ) { + static uint8_t effective_e2h = 0xFF; + if (effective_e2h == 0xFF) + effective_e2h = get_effective_e2h(); + switch(Reg) { case CntPct: @@ -114,19 +147,35 @@ ArmArchTimerWriteReg ( break; case CntpTval: - ArmWriteCntpTval(*data_buf); + /* Add Check For E2H, If EL2 Host then access to cntp_tval_el02 */ + if (effective_e2h) + ArmWriteCntpTval02(*data_buf); + else + ArmWriteCntpTval(*data_buf); break; case CntpCtl: - ArmWriteCntpCtl(*data_buf); + /* Add Check For E2H, If EL2 Host then access to cntp_ctl_el02 */ + if (effective_e2h) + ArmWriteCntpCtl02(*data_buf); + else + ArmWriteCntpCtl(*data_buf); break; case CntvTval: - ArmWriteCntvTval(*data_buf); + if (effective_e2h) { + ArmWriteCntvTval02(*data_buf); + } else { + ArmWriteCntvTval(*data_buf); + } break; case CntvCtl: - ArmWriteCntvCtl(*data_buf); + if (effective_e2h) { + ArmWriteCntvCtl02(*data_buf); + } else { + ArmWriteCntvCtl(*data_buf); + } break; case CntvCt: