1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <sys/types.h>
9 #include <lk/err.h>
10 #include <kernel/thread.h>
11 #include <platform.h>
12 #include <platform/interrupts.h>
13 #include <platform/timer.h>
14 #include <platform/armemu.h>
15 #include "platform_p.h"
16 
17 static platform_timer_callback t_callback;
18 
platform_set_periodic_timer(platform_timer_callback callback,void * arg,lk_time_t interval)19 status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
20     t_callback = callback;
21 
22     *REG(PIT_CLEAR) = 1;
23     *REG(PIT_INTERVAL) = interval;
24     *REG(PIT_START_PERIODIC) = 1;
25 
26     unmask_interrupt(INT_PIT);
27 
28     return NO_ERROR;
29 }
30 
current_time_hires(void)31 lk_bigtime_t current_time_hires(void) {
32     lk_bigtime_t time;
33     *REG(SYSINFO_TIME_LATCH) = 1;
34     time = *REG(SYSINFO_TIME_SECS) * 1000000ULL;
35     time += *REG(SYSINFO_TIME_USECS);
36 
37     return time;
38 }
39 
current_time(void)40 lk_time_t current_time(void) {
41     lk_time_t time;
42     *REG(SYSINFO_TIME_LATCH) = 1;
43     time = *REG(SYSINFO_TIME_SECS) * 1000;
44     time += *REG(SYSINFO_TIME_USECS) / 1000;
45 
46     return time;
47 }
48 
platform_tick(void * arg)49 static enum handler_return platform_tick(void *arg) {
50     *REG(PIT_CLEAR_INT) = 1;
51     if (t_callback) {
52         return t_callback(arg, current_time());
53     } else {
54         return INT_NO_RESCHEDULE;
55     }
56 }
57 
platform_init_timer(void)58 void platform_init_timer(void) {
59     register_int_handler(INT_PIT, &platform_tick, NULL);
60 }
61 
62