xref: /inferno-os/os/boot/rpcg/clock.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #include	"u.h"
2 #include	"lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"io.h"
7 #include	"ureg.h"
8 
9 enum {
10 	Timebase = 4,	/* system clock cycles per time base cycle */
11 };
12 
13 void	(*archclocktick)(void);	/* set by arch*.c when desired */
14 
15 static	ulong	clkreload;
16 
17 void
18 delay(int l)
19 {
20 	ulong i, j;
21 
22 	j = m->delayloop;
23 	while(l-- > 0)
24 		for(i=0; i < j; i++)
25 			;
26 }
27 
28 void
29 microdelay(int l)
30 {
31 	ulong i;
32 
33 	l *= m->delayloop;
34 	l /= 1000;
35 	if(l <= 0)
36 		l = 1;
37 	for(i = 0; i < l; i++)
38 		;
39 }
40 
41 void
42 clockintr(Ureg*, void*)
43 {
44 	putdec(clkreload);
45 	m->ticks++;
46 	checkalarms();
47 	if(archclocktick != nil)
48 		archclocktick();
49 }
50 
51 void
52 clockinit(void)
53 {
54 	long x;
55 
56 	m->delayloop = m->cpuhz/1000;	/* initial estimate */
57 	do {
58 		x = gettbl();
59 		delay(10);
60 		x = gettbl() - x;
61 	} while(x < 0);
62 
63 	/*
64 	 *  fix count
65 	 */
66 	m->delayloop = ((vlong)m->delayloop*(10*m->clockgen/1000))/(x*Timebase);
67 	if(m->delayloop == 0)
68 		m->delayloop = 1;
69 	clkreload = (m->clockgen/Timebase)/HZ-1;
70 	putdec(clkreload);
71 }
72