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 <[email protected]> Haiku-Format: Haiku-format Bot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
764365384d
commit
653d40cc93
@@ -14,10 +14,11 @@
|
|||||||
|
|
||||||
static uint64 sTimerTicksUS;
|
static uint64 sTimerTicksUS;
|
||||||
static bigtime_t sTimerMaxInterval;
|
static bigtime_t sTimerMaxInterval;
|
||||||
|
static uint64 sBootTime;
|
||||||
|
|
||||||
#define TIMER_ARMED (1)
|
#define TIMER_ARMED (1)
|
||||||
#define TIMER_MASKED (2 | 1)
|
#define TIMER_MASKED (2 | 1)
|
||||||
#define TIMER_IRQ 30
|
#define TIMER_IRQ 27
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -26,22 +27,22 @@ arch_timer_set_hardware_timer(bigtime_t timeout)
|
|||||||
if (timeout > sTimerMaxInterval)
|
if (timeout > sTimerMaxInterval)
|
||||||
timeout = sTimerMaxInterval;
|
timeout = sTimerMaxInterval;
|
||||||
|
|
||||||
WRITE_SPECIALREG(CNTP_TVAL_EL0, timeout * sTimerTicksUS);
|
WRITE_SPECIALREG(CNTV_TVAL_EL0, timeout * sTimerTicksUS);
|
||||||
WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_ARMED);
|
WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_ARMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_timer_clear_hardware_timer()
|
arch_timer_clear_hardware_timer()
|
||||||
{
|
{
|
||||||
WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
|
WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_MASKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
arch_timer_interrupt(void *data)
|
arch_timer_interrupt(void *data)
|
||||||
{
|
{
|
||||||
WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
|
WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_MASKED);
|
||||||
return timer_interrupt();
|
return timer_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,9 +53,11 @@ arch_init_timer(kernel_args *args)
|
|||||||
sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000;
|
sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000;
|
||||||
sTimerMaxInterval = INT32_MAX / sTimerTicksUS;
|
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);
|
install_io_interrupt_handler(TIMER_IRQ, &arch_timer_interrupt, NULL, 0);
|
||||||
|
|
||||||
|
sBootTime = READ_SPECIALREG(CNTPCT_EL0);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,5 +65,5 @@ arch_init_timer(kernel_args *args)
|
|||||||
bigtime_t
|
bigtime_t
|
||||||
system_time(void)
|
system_time(void)
|
||||||
{
|
{
|
||||||
return READ_SPECIALREG(CNTPCT_EL0) / sTimerTicksUS;
|
return (READ_SPECIALREG(CNTPCT_EL0) - sBootTime) / sTimerTicksUS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user