xref: /optee_os/core/arch/arm/kernel/timer_a64.c (revision 19a31ec40245ae01a9adcd206eec2a4bb4479fc9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018, Linaro Limited
4  */
5 
6 #include <arm64.h>
7 #include <kernel/spinlock.h>
8 #include <kernel/timer.h>
9 
10 static unsigned int timer_lock = SPINLOCK_UNLOCK;
11 static bool timer_running;
12 
13 void generic_timer_start(uint32_t time_ms)
14 {
15 	uint32_t exceptions = cpu_spin_lock_xsave(&timer_lock);
16 	uint32_t timer_ticks = 0;
17 
18 	if (timer_running == true)
19 		goto exit;
20 
21 	/* The timer will fire time_ms from now */
22 	timer_ticks = ((uint64_t)read_cntfrq() * time_ms) / 1000;
23 	write_cntps_tval(timer_ticks);
24 
25 	/* Enable the secure physical timer */
26 	write_cntps_ctl(1);
27 
28 	timer_running = true;
29 
30 exit:
31 	cpu_spin_unlock_xrestore(&timer_lock, exceptions);
32 }
33 
34 void generic_timer_stop(void)
35 {
36 	uint32_t exceptions = cpu_spin_lock_xsave(&timer_lock);
37 
38 	/* Disable the timer */
39 	write_cntps_ctl(0);
40 
41 	timer_running = false;
42 
43 	cpu_spin_unlock_xrestore(&timer_lock, exceptions);
44 }
45 
46 void generic_timer_handler(uint32_t time_ms)
47 {
48 	uint32_t timer_ticks = 0;
49 
50 	/* Ensure that the timer did assert the interrupt */
51 	assert((read_cntps_ctl() >> 2));
52 
53 	/* Disable the timer */
54 	write_cntps_ctl(0);
55 
56 	/* Reconfigure timer to fire time_ms from now */
57 	timer_ticks = ((uint64_t)read_cntfrq() * time_ms) / 1000;
58 	write_cntps_tval(timer_ticks);
59 
60 	/* Enable the secure physical timer */
61 	write_cntps_ctl(1);
62 }
63