Warning clean up
[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
8 system_timing_t system_timing = {0};
9
10 void
11 timer_init(void)
12 {
13         system_timing.tsc_freq = TSC_HZ;
14         cprintf("TSC Frequency: %llu\n", system_timing.tsc_freq);
15 }
16
17 void
18 set_core_timer(uint32_t usec, bool periodic)
19 {
20         // we could implement periodic timers using one-shot timers,
21         // but for now we only support one-shot
22         assert(!periodic);
23
24         if (usec)
25         {
26                 uint32_t clocks =  (uint64_t)usec*TSC_HZ/1000000;
27
28                 int8_t irq_state = 0;
29                 disable_irqsave(&irq_state);
30
31                 mtpcr(PCR_COUNT, 0);
32                 mtpcr(PCR_COMPARE, clocks);
33                 mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER+SR_IM_SHIFT)));
34
35                 enable_irqsave(&irq_state);
36         }
37         else
38         {
39                 mtpcr(PCR_SR, mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER+SR_IM_SHIFT)));
40         }
41 }
42
43 void
44 udelay(uint64_t usec)
45 {
46         if (system_timing.tsc_freq != 0)
47         {
48                 uint64_t start, end, now;
49         
50                 start = read_tsc();
51                 end = start + (system_timing.tsc_freq * usec) / 1000000;
52
53                 do
54                 {
55                         cpu_relax();
56                         now = read_tsc();
57                 } while (now < end || (now > start && end < start));
58         }
59         else panic("udelay() was called before timer_init(), moron!");
60 }