/* * Copyright 2019-2022 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #include #include #include #include #include #include #include static uint64 sTimerTicksUS; static bigtime_t sTimerMaxInterval; static uint64 sBootTime; #define TIMER_DISABLED (0) #define TIMER_ENABLE (1) #define TIMER_IMASK (2) #define TIMER_ISTATUS (4) #define TIMER_IRQ 27 void arch_timer_set_hardware_timer(bigtime_t timeout) { if (timeout > sTimerMaxInterval) timeout = sTimerMaxInterval; WRITE_SPECIALREG(CNTV_TVAL_EL0, timeout * sTimerTicksUS); WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_ENABLE); } void arch_timer_clear_hardware_timer() { WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); } int32 arch_timer_interrupt(void *data) { WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); return timer_interrupt(); } int arch_init_timer(kernel_args *args) { sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000; sTimerMaxInterval = INT32_MAX / sTimerTicksUS; WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); install_io_interrupt_handler(TIMER_IRQ, &arch_timer_interrupt, NULL, 0); sBootTime = READ_SPECIALREG(CNTPCT_EL0); return B_OK; } bigtime_t system_time(void) { return (READ_SPECIALREG(CNTPCT_EL0) - sBootTime) / sTimerTicksUS; }