]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/sgi/clock.c
devvmx: remove unncessary locking in gotcmd() sleep test function
[plan9front.git] / sys / src / 9 / sgi / clock.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
8 #include        "ureg.h"
9
10 enum {
11         Cyccntres       = 2, /* counter advances at ½ clock rate */
12         Basetickfreq    = 150*Mhz / Cyccntres,  /* sgi/indy */
13
14         Instrs          = 10*Mhz,
15 };
16
17 static long
18 issue1loop(void)
19 {
20         register int i;
21         long st;
22
23         i = Instrs;
24         st = perfticks();
25         do {
26                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
27                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
28                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
29                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
30                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
31                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
32                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
33                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
34                 --i; --i; --i; --i; --i; --i; --i; --i; --i; --i;
35                 --i; --i; --i; --i; --i;
36                 /* omit 3 (--i) to account for conditional branch, nop & jump */
37                 i -= 1+3;        /* --i plus 3 omitted (--i) instructions */
38         } while(--i >= 0);
39         return perfticks() - st;
40 }
41
42 /* estimate instructions/s. */
43 static int
44 guessmips(long (*loop)(void), char *)
45 {
46         int s;
47         long cyc;
48
49         do {
50                 s = splhi();
51                 cyc = loop();
52                 splx(s);
53                 if (cyc < 0)
54                         iprint("again...");
55         } while (cyc < 0);
56         /*
57          * Instrs instructions took cyc cycles @ Basetickfreq Hz.
58          * round the result.
59          */
60         return (((vlong)Basetickfreq * Instrs) / cyc + Mhz/2) / Mhz;
61 }
62
63 void
64 clockinit(void)
65 {
66         int mips;
67
68         /*
69          * calibrate fastclock
70          */
71         mips = guessmips(issue1loop, "single");
72
73         /*
74          * m->delayloop should be the number of delay loop iterations
75          * needed to consume 1 ms, assuming 2 instr'ns in the delay loop.
76          */
77         m->delayloop = mips*Mhz / (1000 * 2);
78         if(m->delayloop == 0)
79                 m->delayloop = 1;
80
81         m->speed = mips;
82         m->hz = m->speed*Mhz;
83         m->cyclefreq = Basetickfreq;
84         m->maxperiod = Basetickfreq / HZ;
85         m->minperiod = Basetickfreq / (100*HZ);
86         m->lastcount = rdcount();
87         wrcompare(m->lastcount+m->maxperiod);
88
89         intron(INTR7);
90 }
91
92 void
93 clock(Ureg *ur)
94 {
95         wrcompare(rdcount()+m->maxperiod);      /* side-effect: dismiss intr */
96         timerintr(ur, 0);
97 }
98
99 void
100 microdelay(int n)
101 {
102         ulong now;
103         now = µs();
104         while(µs() - now < n);
105 }
106
107 void
108 delay(int n)
109 {
110         while(--n >= 0)
111                 microdelay(1000);
112 }
113
114 ulong
115 µs(void)
116 {
117         return fastticks2us(fastticks(nil));
118 }
119
120 uvlong
121 fastticks(uvlong *hz)
122 {
123         int x;
124         ulong delta, count;
125
126         if(hz)
127                 *hz = Basetickfreq;
128
129         /* avoid reentry on interrupt or trap, to prevent recursion */
130         x = splhi();
131         count = rdcount();
132         delta = count - m->lastcount;
133         m->lastcount = count;
134         m->fastticks += delta;
135         splx(x);
136
137         return m->fastticks;
138 }
139
140 ulong
141 perfticks(void)
142 {
143         return rdcount();
144 }
145
146 void
147 timerset(Tval next)
148 {
149         long period;
150
151         period = next - fastticks(nil);
152         if(period < m->minperiod)
153                 period = m->minperiod;
154         else if(period > m->maxperiod - m->minperiod)
155                 period = m->maxperiod;
156         wrcompare(rdcount()+period);
157 }