FreeBSD/Linux Kernel Cross Reference
sys/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
Cache object: 304849788db9ded8c911e3298250609f
|