01ceef29bf37f020500ef84101d8a89350a4d0f2
[akaros.git] / kern / arch / sparc / timer.c
1 #include <arch/timer.h>
2 #include <ros/common.h>
3 #include <arch/trap.h>
4 #include <arch/arch.h>
5 #include <stdio.h>
6 #include <assert.h>
7
8 #ifdef __SHARC__
9 #pragma nosharc
10 #endif
11
12 system_timing_t system_timing = {0};
13 volatile uint32_t timer_ticks = 0;
14
15 asm (
16 ".global handle_timer_interrupt         \n\t"
17 "handle_timer_interrupt:                \n\t"
18 "       mov     " XSTR(CORE_ID_REG) ",%l3       \n\t"
19 "       mov     %psr,%l4                        \n\t"
20 "       cmp     %l3,0                           \n\t"
21 "       bne     1f                              \n\t"
22 "        mov    %l4,%psr                        \n\t"
23 "       sethi   %hi(timer_ticks),%l4            \n\t"
24 "       ld      [%l4+%lo(timer_ticks)],%l5      \n\t"
25 "       inc     %l5                             \n\t"
26 "       st      %l5,[%l4+%lo(timer_ticks)]      \n\t"
27 "1:     jmp     %l1                             \n\t"
28 "        rett   %l2                             \n\t" );
29
30 void
31 timer_init(void)
32 {       
33 #if 0
34         uint32_t ticks = timer_ticks;
35         uint64_t tsc_ticks;
36
37         while(ticks == timer_ticks) ;
38
39         ticks = timer_ticks;
40         tsc_ticks = read_tsc();
41
42         while(ticks == timer_ticks) ;
43
44         system_timing.tsc_freq = (read_tsc() - tsc_ticks)*INTERRUPT_TIMER_HZ;
45 #endif
46         system_timing.tsc_freq = 1000000;
47
48         cprintf("TSC Frequency: %llu\n", system_timing.tsc_freq);
49 }
50
51 void
52 udelay(uint64_t usec)
53 {
54         if (system_timing.tsc_freq != 0)
55         {
56                 uint64_t start, end, now;
57         
58                 start = read_tsc();
59                 end = start + (system_timing.tsc_freq * usec) / 1000000;
60
61                 do
62                 {
63                         cpu_relax();
64                         now = read_tsc();
65                 } while (now < end || (now > start && end < start));
66         }
67         else panic("udelay() was called before timer_init(), moron!");
68 }