tests/linux: use Akaros's CFLAGS
[akaros.git] / kern / arch / riscv / time.c
1 #include <arch/arch.h>
2 #include <arch/time.h>
3 #include <assert.h>
4 #include <ros/common.h>
5 #include <ros/procinfo.h>
6 #include <stdio.h>
7 #include <trap.h>
8
9 void timer_init(void)
10 {
11         __proc_global_info.tsc_freq = TSC_HZ;
12         cprintf("TSC Frequency: %llu\n", __proc_global_info.tsc_freq);
13 }
14
15 void set_core_timer(uint32_t usec, bool periodic)
16 {
17         // we could implement periodic timers using one-shot timers,
18         // but for now we only support one-shot
19         assert(!periodic);
20
21         if (usec) {
22                 uint32_t clocks = (uint64_t)usec * TSC_HZ / 1000000;
23
24                 int8_t irq_state = 0;
25                 disable_irqsave(&irq_state);
26
27                 mtpcr(PCR_COUNT, 0);
28                 mtpcr(PCR_COMPARE, clocks);
29                 mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER + SR_IM_SHIFT)));
30
31                 enable_irqsave(&irq_state);
32         } else {
33                 mtpcr(PCR_SR,
34                       mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER + SR_IM_SHIFT)));
35         }
36 }
37
38 void udelay(uint64_t usec)
39 {
40         if (__proc_global_info.tsc_freq != 0) {
41                 uint64_t start, end, now;
42
43                 start = read_tsc();
44                 end = start + (__proc_global_info.tsc_freq * usec) / 1000000;
45
46                 do {
47                         cpu_relax();
48                         now = read_tsc();
49                 } while (now < end || (now > start && end < start));
50         } else
51                 panic("udelay() was called before timer_init(), moron!");
52 }
53
54 uint64_t read_persistent_clock(void)
55 {
56         return 1242129600 * 1000000000UL; /* nanwan's birthday */
57 }