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