From 653d40cc9317462de1aecc0a965f1084993c47ab Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 22 Aug 2024 08:34:38 +0000 Subject: [PATCH] kernel/arm64: Use virtual rather than physical timers. * Fixes exception in arch_init_timer on boot when trying to write CNTP_CTL_EL0 under virtualization on M1 Max. * Update TIMER_IRQ to match. * Boot now proceeds before crashing with an invalid page fault in device manager. Change-Id: I82f080bdc671258a1a35bf998d906e9010a6736e Reviewed-on: https://review.haiku-os.org/c/haiku/+/8091 Tested-by: Commit checker robot Haiku-Format: Haiku-format Bot Reviewed-by: Adrien Destugues --- src/system/kernel/arch/arm64/arch_timer.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/system/kernel/arch/arm64/arch_timer.cpp b/src/system/kernel/arch/arm64/arch_timer.cpp index 0c81e45c58..a2cd77f6fd 100644 --- a/src/system/kernel/arch/arm64/arch_timer.cpp +++ b/src/system/kernel/arch/arm64/arch_timer.cpp @@ -14,10 +14,11 @@ static uint64 sTimerTicksUS; static bigtime_t sTimerMaxInterval; +static uint64 sBootTime; #define TIMER_ARMED (1) #define TIMER_MASKED (2 | 1) -#define TIMER_IRQ 30 +#define TIMER_IRQ 27 void @@ -26,22 +27,22 @@ arch_timer_set_hardware_timer(bigtime_t timeout) if (timeout > sTimerMaxInterval) timeout = sTimerMaxInterval; - WRITE_SPECIALREG(CNTP_TVAL_EL0, timeout * sTimerTicksUS); - WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_ARMED); + WRITE_SPECIALREG(CNTV_TVAL_EL0, timeout * sTimerTicksUS); + WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_ARMED); } void arch_timer_clear_hardware_timer() { - WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED); + WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_MASKED); } int32 arch_timer_interrupt(void *data) { - WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED); + WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_MASKED); return timer_interrupt(); } @@ -52,9 +53,11 @@ arch_init_timer(kernel_args *args) sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000; sTimerMaxInterval = INT32_MAX / sTimerTicksUS; - WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED); + WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_MASKED); install_io_interrupt_handler(TIMER_IRQ, &arch_timer_interrupt, NULL, 0); + sBootTime = READ_SPECIALREG(CNTPCT_EL0); + return B_OK; } @@ -62,5 +65,5 @@ arch_init_timer(kernel_args *args) bigtime_t system_time(void) { - return READ_SPECIALREG(CNTPCT_EL0) / sTimerTicksUS; + return (READ_SPECIALREG(CNTPCT_EL0) - sBootTime) / sTimerTicksUS; }