]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ppc/saturntimer.c
pc/vga*: use 64-bit physical addresses and check pci membar types and sizes
[plan9front.git] / sys / src / 9 / ppc / saturntimer.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8 #include "msaturn.h"
9
10 enum {
11         Timer_ctrl = Saturn + 0x0106,
12         Timer0_load = Saturn + 0x0200,
13         Timer0_cnt = Saturn + 0x0204,
14         Timer1_load = Saturn + 0x0300,
15         Timer1_cnt = Saturn + 0x0304,
16         
17         T0_event = RBIT(13, ushort),
18         T0_ie = RBIT(14, ushort),
19         T0_cen = RBIT(15, ushort),
20         T1_event = RBIT(5, ushort),
21         T1_ie = RBIT(6, ushort),
22         T1_cen = RBIT(7, ushort),
23 };
24
25 static ulong ticks;
26 static Lock tlock;
27 static ushort timer_ctl;
28
29 void
30 saturntimerintr(Ureg *u, void*)
31 {
32         ushort ctl = *(ushort*)Timer_ctrl, v = 0;
33
34         if(ctl&T1_event){
35                 v = T1_event;
36                 ticks++;
37         }
38                 
39         *(ushort*)Timer_ctrl = timer_ctl|T0_event|v;
40         intack();
41         timerintr(u, 0);
42 }
43
44 void
45 timerinit(void)
46 {
47         *(ushort*)Timer_ctrl = 0;
48         *(ulong*)Timer0_load = m->bushz  / HZ;
49         *(ulong*)Timer0_cnt = m->bushz / HZ;
50         *(ulong*)Timer1_load = m->bushz;
51         *(ulong*)Timer1_cnt = m->bushz;
52
53         intrenable(Vectimer0, saturntimerintr, nil, "timer");
54
55         timer_ctl = T0_cen|T0_ie|T1_cen;
56         *(ushort*)Timer_ctrl = timer_ctl;
57 }
58
59 uvlong
60 fastticks(uvlong *hz)
61 {
62         assert(*(ushort*)Timer_ctrl&T1_cen);
63         if(*(ushort*)Timer_ctrl&T1_event){
64                 *(ushort*)Timer_ctrl = timer_ctl|T1_event;
65                 ticks++;
66         }
67                 
68         if (hz)
69                 *hz = m->bushz;
70
71         return (uvlong)ticks*m->bushz+(uvlong)(m->bushz-*(ulong*)Timer1_cnt);
72 }
73
74 void
75 timerset(uvlong next)
76 {
77         ulong offset;
78         uvlong now;
79
80         ilock(&tlock);
81         *(ushort*)Timer_ctrl = T1_cen;
82
83         now = fastticks(nil);
84         offset = next - now;
85         if((long)offset < 10000)
86                 offset = 10000;
87         else if(offset > m->bushz)
88                 offset = m->bushz;
89
90         *(ulong*)Timer0_cnt = offset;
91         *(ushort*)Timer_ctrl = timer_ctl;
92         assert(*(ushort*)Timer_ctrl & T1_cen);
93         iunlock(&tlock);
94 }
95