AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
timer.c
Go to the documentation of this file.
1
10
11#include <core/system.h>
12#include <cpu/cpu.h>
13#include <dev/irq.h>
14#include <platform/virt.h>
15
17static void (*tick)(void);
18
21static void timer_irq(void *arg __unused)
22{
23 /* the next tick comes `interval` counts from now */
24 write_sysreg(cntv_tval_el0, interval);
25
26 if (tick)
27 tick();
28}
29
37uint64_t timer_setup(uint64_t period_ns, void (*handler)(void))
38{
39 freq = read_sysreg(cntfrq_el0);
40 interval = freq * period_ns / 1000000000ULL;
41 tick = handler;
42
44
45 write_sysreg(cntv_tval_el0, interval);
46 write_sysreg(cntv_ctl_el0, 1); /* enabled, and not masked */
47 isb();
48
49 printk("timer: %ld Hz counter, the tick every %ld counts\n", freq, interval);
50 return interval * 1000000000ULL / freq;
51}
52
53/*
54 * Returns the monotonic clock: the counter's time since boot, in ns.
55 */
57{
58 uint64_t f = read_sysreg(cntfrq_el0), c = read_sysreg(cntvct_el0);
59 return c / f * 1000000000ULL + c % f * 1000000000ULL / f;
60}
61
62/*
63 * Returns the time since boot, in microseconds.
64 */
66{
67 return arch_rtime_ns() / 1000;
68}
69
70/*
71 * Returns the time since boot, in milliseconds.
72 */
74{
75 return arch_rtime_ns() / 1000000;
76}
77
78/*
79 * Returns the counter, which changes all the time, as a source of
80 * randomness.
81 */
83{
84 return read_sysreg(cntvct_el0);
85}
int irq_install(unsigned irq, irq_handler_t fn, void *arg)
Installs a handler for an IRQ.
Definition irq.c:32
#define read_sysreg(r)
Definition cpu.h:33
#define isb()
Definition cpu.h:45
#define write_sysreg(r, v)
Definition cpu.h:39
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
#define NULL
Definition stddef.h:27
unsigned long long int uint64_t
Definition stddef.h:23
An installed handler, on its interrupt's list.
Definition irq.c:19
uint64_t arch_rtime_ns(void)
Reads the monotonic clock, which starts at boot.
Definition timer.c:56
static uint64_t interval
Definition timer.c:16
static uint64_t freq
Definition timer.c:16
static void timer_irq(void *arg)
Handles the timer's interrupt: arms the next tick, and runs the tick's handler.
Definition timer.c:21
uint64_t arch_rtime_us(void)
Reads the monotonic clock, in microseconds.
Definition timer.c:65
uint64_t arch_rtime_ms(void)
Reads the monotonic clock, in milliseconds.
Definition timer.c:73
static void(*) tick(void)
Definition timer.c:17
uint64_t arch_cycles(void)
Reads a counter that changes as fast as the CPU runs, which the kernel uses as a source of randomness...
Definition timer.c:82
#define VIRT_TIMER_IRQ
Definition virt.h:26
uint64_t timer_setup(uint64_t period_ns, void(*handler)(void))
Starts the tick.
Definition timer.c:37