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