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 generic_timer_start(uint32_t time_ms)13void generic_timer_start(uint32_t time_ms) 14 { 15 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); 16 uint32_t timer_ticks; 17 18 cpu_spin_lock(&timer_lock); 19 20 if (timer_running == true) 21 goto exit; 22 23 /* The timer will fire time_ms from now */ 24 timer_ticks = (read_cntfrq() * time_ms) / 1000; 25 write_cntps_tval(timer_ticks); 26 27 /* Enable the secure physical timer */ 28 write_cntps_ctl(1); 29 30 timer_running = true; 31 32 exit: 33 cpu_spin_unlock(&timer_lock); 34 thread_set_exceptions(exceptions); 35 } 36 generic_timer_stop(void)37void generic_timer_stop(void) 38 { 39 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); 40 41 cpu_spin_lock(&timer_lock); 42 43 /* Disable the timer */ 44 write_cntps_ctl(0); 45 46 timer_running = false; 47 48 cpu_spin_unlock(&timer_lock); 49 thread_set_exceptions(exceptions); 50 } 51 generic_timer_handler(uint32_t time_ms)52void generic_timer_handler(uint32_t time_ms) 53 { 54 uint32_t timer_ticks; 55 56 /* Ensure that the timer did assert the interrupt */ 57 assert((read_cntps_ctl() >> 2)); 58 59 /* Disable the timer */ 60 write_cntps_ctl(0); 61 62 /* Reconfigure timer to fire time_ms from now */ 63 timer_ticks = (read_cntfrq() * time_ms) / 1000; 64 write_cntps_tval(timer_ticks); 65 66 /* Enable the secure physical timer */ 67 write_cntps_ctl(1); 68 } 69