blob: 1300e93386d44682fcd401ad6272d4b8aea98d18 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "axp.h"
#include "ureg.h"
void
clockinit(void)
{
}
uvlong
cycletimer(void)
{
ulong pcc;
vlong delta;
pcc = rpcc(nil) & 0xFFFFFFFF;
if(m->cpuhz == 0){
/*
* pcclast is needed to detect wraparound of
* the cycle timer which is only 32-bits.
* m->cpuhz is set from the info passed from
* the firmware.
* This could be in clockinit if can
* guarantee no wraparound between then and now.
*
* All the clock stuff needs work.
*/
m->cpuhz = hwrpb->cfreq;
m->pcclast = pcc;
}
delta = pcc - m->pcclast;
if(delta < 0)
delta += 0x100000000LL;
m->pcclast = pcc;
m->fastclock += delta;
return MACHP(0)->fastclock;
}
uvlong
fastticks(uvlong* hz)
{
uvlong ticks;
int x;
x = splhi();
ticks = cycletimer();
splx(x);
if(hz)
*hz = m->cpuhz;
return ticks;
}
ulong
µs(void)
{
return fastticks2us(cycletimer());
}
/*
* performance measurement ticks. must be low overhead.
* doesn't have to count over a second.
*/
ulong
perfticks(void)
{
return rpcc(nil);
}
void
timerset(Tval)
{
}
void
microdelay(int us)
{
uvlong eot;
eot = fastticks(nil) + (m->cpuhz/1000000)*us;
while(fastticks(nil) < eot)
;
}
void
delay(int millisecs)
{
microdelay(millisecs*1000);
}
void
clock(Ureg *ureg)
{
static int count;
cycletimer();
/* HZ == 100, timer == 1024Hz. error < 1ms */
count += 100;
if (count < 1024)
return;
count -= 1024;
timerintr(ureg, 0);
}
|