xref: /haiku/src/system/kernel/arch/arm64/arch_timer.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
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 
18 #define TIMER_ARMED (1)
19 #define TIMER_MASKED (2 | 1)
20 #define TIMER_IRQ 30
21 
22 
23 void
24 arch_timer_set_hardware_timer(bigtime_t timeout)
25 {
26 	if (timeout > sTimerMaxInterval)
27 		timeout = sTimerMaxInterval;
28 
29 	WRITE_SPECIALREG(CNTP_TVAL_EL0, timeout * sTimerTicksUS);
30 	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_ARMED);
31 }
32 
33 
34 void
35 arch_timer_clear_hardware_timer()
36 {
37 	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
38 }
39 
40 
41 int32
42 arch_timer_interrupt(void *data)
43 {
44 	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
45 	return timer_interrupt();
46 }
47 
48 
49 int
50 arch_init_timer(kernel_args *args)
51 {
52 	sTimerTicksUS = READ_SPECIALREG(CNTFRQ_EL0) / 1000000;
53 	sTimerMaxInterval = INT32_MAX / sTimerTicksUS;
54 
55 	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
56 	install_io_interrupt_handler(TIMER_IRQ, &arch_timer_interrupt, NULL, 0);
57 
58 	return B_OK;
59 }
60 
61 
62 bigtime_t
63 system_time(void)
64 {
65 	return READ_SPECIALREG(CNTPCT_EL0) / sTimerTicksUS;
66 }
67