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
15static uint64 sTimerTicksUS;
16static bigtime_t sTimerMaxInterval;
17
18#define TIMER_ARMED (1)
19#define TIMER_MASKED (2 | 1)
20#define TIMER_IRQ 30
21
22
23void
24arch_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
34void
35arch_timer_clear_hardware_timer()
36{
37	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
38}
39
40
41int32
42arch_timer_interrupt(void *data)
43{
44	WRITE_SPECIALREG(CNTP_CTL_EL0, TIMER_MASKED);
45	return timer_interrupt();
46}
47
48
49int
50arch_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
62bigtime_t
63system_time(void)
64{
65	return READ_SPECIALREG(CNTPCT_EL0) / sTimerTicksUS;
66}
67