1 /* 2 * Copyright 2019-2022 Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #include <boot/stage2.h> 6 #include <kernel.h> 7 #include <debug.h> 8 #include <int.h> 9 10 #include <timer.h> 11 #include <arch/timer.h> 12 #include <arch/cpu.h> 13 14 15 static uint64 sTimerTicksUS; 16 static bigtime_t sTimerMaxInterval; 17 static uint64 sBootTime; 18 19 #define TIMER_DISABLED (0) 20 #define TIMER_ENABLE (1) 21 #define TIMER_IMASK (2) 22 #define TIMER_ISTATUS (4) 23 24 #define TIMER_IRQ 27 25 26 27 void 28 arch_timer_set_hardware_timer(bigtime_t timeout) 29 { 30 if (timeout > sTimerMaxInterval) 31 timeout = sTimerMaxInterval; 32 33 WRITE_SPECIALREG(CNTV_TVAL_EL0, timeout * sTimerTicksUS); 34 WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_ENABLE); 35 } 36 37 38 void 39 arch_timer_clear_hardware_timer() 40 { 41 WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); 42 } 43 44 45 int32 46 arch_timer_interrupt(void *data) 47 { 48 WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); 49 return timer_interrupt(); 50 } 51 52 53 int 54 arch_init_timer(kernel_args *args) 55 { 56 sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000; 57 sTimerMaxInterval = INT32_MAX / sTimerTicksUS; 58 59 WRITE_SPECIALREG(CNTV_CTL_EL0, TIMER_DISABLED); 60 install_io_interrupt_handler(TIMER_IRQ, &arch_timer_interrupt, NULL, 0); 61 62 sBootTime = READ_SPECIALREG(CNTPCT_EL0); 63 64 return B_OK; 65 } 66 67 68 bigtime_t 69 system_time(void) 70 { 71 return (READ_SPECIALREG(CNTPCT_EL0) - sBootTime) / sTimerTicksUS; 72 } 73