Skip to content
This repository was archived by the owner on Aug 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions val/common/include/acs_timer_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
61 changes: 57 additions & 4 deletions val/common/src/AArch64/ArchTimerSupport.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -87,49 +111,78 @@ 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):
msr cntp_tval_el0, x0 // Write to CNTP_TVAL (PL1 physical timer value register)
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)
Expand Down
65 changes: 57 additions & 8 deletions val/common/src/acs_timer_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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) {

Expand All @@ -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();
Expand Down Expand Up @@ -103,6 +132,10 @@ ArmArchTimerWriteReg (
)
{

static uint8_t effective_e2h = 0xFF;
if (effective_e2h == 0xFF)
effective_e2h = get_effective_e2h();

switch(Reg) {

case CntPct:
Expand All @@ -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:
Expand Down