From 02d61a7297cc7f419164ca047f7350169bd796f9 Mon Sep 17 00:00:00 2001 From: Rajat Goyal Date: Fri, 6 Jun 2025 06:53:07 +0000 Subject: [PATCH 1/2] Added Support Fort E2H Change-Id: Ib85c25126f4c5ea74daa2a5bd7ca391cce5cbaf3 Signed-off-by: Rajat Goyal --- val/common/include/acs_timer_support.h | 8 ++++ val/common/src/AArch64/ArchTimerSupport.S | 42 +++++++++++++++++-- val/common/src/acs_timer_support.c | 49 +++++++++++++++++++++-- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/val/common/include/acs_timer_support.h b/val/common/include/acs_timer_support.h index ae4f32e6..0c0655d1 100644 --- a/val/common/include/acs_timer_support.h +++ b/val/common/include/acs_timer_support.h @@ -57,6 +57,14 @@ 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 ArmReadCntFrq ( void diff --git a/val/common/src/AArch64/ArchTimerSupport.S b/val/common/src/AArch64/ArchTimerSupport.S index b1e4ae2b..935dfba2 100644 --- a/val/common/src/AArch64/ArchTimerSupport.S +++ b/val/common/src/AArch64/ArchTimerSupport.S @@ -39,13 +39,19 @@ .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(ArmWriteCntvTval) GCC_ASM_EXPORT(ArmReadCntvCtl) @@ -66,6 +72,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 @@ -89,7 +109,11 @@ ASM_PFX(ArmWriteCntkCtl): 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,17 +121,29 @@ 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) diff --git a/val/common/src/acs_timer_support.c b/val/common/src/acs_timer_support.c index 45f028d6..5f94a831 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,10 +71,12 @@ 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(); @@ -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,11 +147,19 @@ 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: From bb53c7d40141b562a27f0bbdc8b64177453f2027 Mon Sep 17 00:00:00 2001 From: Nick Graves Date: Fri, 13 Jun 2025 18:43:23 +0000 Subject: [PATCH 2/2] val/common: Add E2H support for EL0 virtual timers When EL2 host is enabled, access the EL2 TVAL and CTL registers instead of the EL0 registers. Change-Id: I6c9b7c7bd8a4a9a23c0ff7590c5b10ba4b799d5c Signed-off-by: Nick Graves --- val/common/include/acs_timer_support.h | 4 ++++ val/common/src/AArch64/ArchTimerSupport.S | 19 ++++++++++++++++++- val/common/src/acs_timer_support.c | 16 ++++++++++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/val/common/include/acs_timer_support.h b/val/common/include/acs_timer_support.h index 0c0655d1..3fc76753 100644 --- a/val/common/include/acs_timer_support.h +++ b/val/common/include/acs_timer_support.h @@ -64,6 +64,10 @@ 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 ( diff --git a/val/common/src/AArch64/ArchTimerSupport.S b/val/common/src/AArch64/ArchTimerSupport.S index 935dfba2..497030b5 100644 --- a/val/common/src/AArch64/ArchTimerSupport.S +++ b/val/common/src/AArch64/ArchTimerSupport.S @@ -53,9 +53,13 @@ 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) @@ -107,7 +111,6 @@ ASM_PFX(ArmWriteCntkCtl): isb ret - ASM_PFX(ArmReadCntpTval): mrs x0, cntp_tval_el0 // Read CNTP_TVAL (PL1 physical timer value register) ret @@ -149,23 +152,37 @@ 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 5f94a831..a1aebaf8 100644 --- a/val/common/src/acs_timer_support.c +++ b/val/common/src/acs_timer_support.c @@ -79,10 +79,10 @@ ArmArchTimerReadReg ( 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(); @@ -163,11 +163,19 @@ ArmArchTimerWriteReg ( 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: