xref: /inferno-os/os/js/clock.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"u.h"
2*74a4d8c2SCharles.Forsyth #include	"../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include	"mem.h"
4*74a4d8c2SCharles.Forsyth #include	"dat.h"
5*74a4d8c2SCharles.Forsyth #include	"fns.h"
6*74a4d8c2SCharles.Forsyth #include	"io.h"
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth #include	"ureg.h"
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth typedef struct Clock0link Clock0link;
11*74a4d8c2SCharles.Forsyth typedef struct Clock0link {
12*74a4d8c2SCharles.Forsyth 	void		(*clock)(void);
13*74a4d8c2SCharles.Forsyth 	Clock0link*	link;
14*74a4d8c2SCharles.Forsyth } Clock0link;
15*74a4d8c2SCharles.Forsyth 
16*74a4d8c2SCharles.Forsyth static Clock0link *clock0link;
17*74a4d8c2SCharles.Forsyth static Lock clock0lock;
18*74a4d8c2SCharles.Forsyth 
19*74a4d8c2SCharles.Forsyth void
microdelay(int ms)20*74a4d8c2SCharles.Forsyth microdelay(int ms)
21*74a4d8c2SCharles.Forsyth {
22*74a4d8c2SCharles.Forsyth 	int i;
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth 	ms *= 13334;		/* experimentally indetermined */
25*74a4d8c2SCharles.Forsyth 	for(i=0; i<ms; i++)
26*74a4d8c2SCharles.Forsyth 		;
27*74a4d8c2SCharles.Forsyth }
28*74a4d8c2SCharles.Forsyth 
29*74a4d8c2SCharles.Forsyth typedef struct Ctr Ctr;
30*74a4d8c2SCharles.Forsyth struct Ctr
31*74a4d8c2SCharles.Forsyth {
32*74a4d8c2SCharles.Forsyth 	ulong	lim;
33*74a4d8c2SCharles.Forsyth 	ulong	ctr;
34*74a4d8c2SCharles.Forsyth 	ulong	limnr;	/* non-resetting */
35*74a4d8c2SCharles.Forsyth 	ulong	ctl;
36*74a4d8c2SCharles.Forsyth };
37*74a4d8c2SCharles.Forsyth Ctr	*ctr;
38*74a4d8c2SCharles.Forsyth 
39*74a4d8c2SCharles.Forsyth void
clockinit(void)40*74a4d8c2SCharles.Forsyth clockinit(void)
41*74a4d8c2SCharles.Forsyth {
42*74a4d8c2SCharles.Forsyth 	KMap *k;
43*74a4d8c2SCharles.Forsyth 
44*74a4d8c2SCharles.Forsyth 	putphys(TIMECONFIG, 0);	/* it's a processor counter */
45*74a4d8c2SCharles.Forsyth 	k = kmappa(CLOCK, PTENOCACHE|PTEIO);
46*74a4d8c2SCharles.Forsyth 	ctr = (Ctr*)VA(k);
47*74a4d8c2SCharles.Forsyth 	ctr->lim = (CLOCKFREQ/HZ)<<10;
48*74a4d8c2SCharles.Forsyth }
49*74a4d8c2SCharles.Forsyth 
50*74a4d8c2SCharles.Forsyth void
clock(Ureg * ur)51*74a4d8c2SCharles.Forsyth clock(Ureg *ur)
52*74a4d8c2SCharles.Forsyth {
53*74a4d8c2SCharles.Forsyth 	Clock0link *lp;
54*74a4d8c2SCharles.Forsyth 	ulong i;
55*74a4d8c2SCharles.Forsyth 
56*74a4d8c2SCharles.Forsyth 	USED(ur);
57*74a4d8c2SCharles.Forsyth 
58*74a4d8c2SCharles.Forsyth 	i = ctr->lim;	/* clear interrupt */
59*74a4d8c2SCharles.Forsyth 	USED(i);
60*74a4d8c2SCharles.Forsyth 	 /* is this needed? page 6-43 801-3137-10 suggests so */
61*74a4d8c2SCharles.Forsyth 	ctr->lim = (CLOCKFREQ/HZ)<<10;
62*74a4d8c2SCharles.Forsyth 
63*74a4d8c2SCharles.Forsyth 	m->ticks++;
64*74a4d8c2SCharles.Forsyth 
65*74a4d8c2SCharles.Forsyth 	if(up)
66*74a4d8c2SCharles.Forsyth 		up->pc = ur->pc;
67*74a4d8c2SCharles.Forsyth 
68*74a4d8c2SCharles.Forsyth 	checkalarms();
69*74a4d8c2SCharles.Forsyth 
70*74a4d8c2SCharles.Forsyth 	lock(&clock0lock);
71*74a4d8c2SCharles.Forsyth 	for(lp = clock0link; lp; lp = lp->link)
72*74a4d8c2SCharles.Forsyth 		lp->clock();
73*74a4d8c2SCharles.Forsyth 	unlock(&clock0lock);
74*74a4d8c2SCharles.Forsyth 
75*74a4d8c2SCharles.Forsyth 	if(up && up->state == Running) {
76*74a4d8c2SCharles.Forsyth 		if(anyready())
77*74a4d8c2SCharles.Forsyth 			sched();
78*74a4d8c2SCharles.Forsyth 	}
79*74a4d8c2SCharles.Forsyth }
80*74a4d8c2SCharles.Forsyth 
81*74a4d8c2SCharles.Forsyth Timer*
addclock0link(void (* clockfunc)(void),int)82*74a4d8c2SCharles.Forsyth addclock0link(void (*clockfunc)(void), int)
83*74a4d8c2SCharles.Forsyth {
84*74a4d8c2SCharles.Forsyth 	Clock0link *lp;
85*74a4d8c2SCharles.Forsyth 
86*74a4d8c2SCharles.Forsyth 	if((lp = malloc(sizeof(Clock0link))) == 0){
87*74a4d8c2SCharles.Forsyth 		print("addclock0link: too many links\n");
88*74a4d8c2SCharles.Forsyth 		return nil;
89*74a4d8c2SCharles.Forsyth 	}
90*74a4d8c2SCharles.Forsyth 	ilock(&clock0lock);
91*74a4d8c2SCharles.Forsyth 	lp->clock = clockfunc;
92*74a4d8c2SCharles.Forsyth 	lp->link = clock0link;
93*74a4d8c2SCharles.Forsyth 	clock0link = lp;
94*74a4d8c2SCharles.Forsyth 	iunlock(&clock0lock);
95*74a4d8c2SCharles.Forsyth 	return nil;
96*74a4d8c2SCharles.Forsyth }
97*74a4d8c2SCharles.Forsyth 
98*74a4d8c2SCharles.Forsyth uvlong
fastticks(uvlong * hz)99*74a4d8c2SCharles.Forsyth fastticks(uvlong *hz)
100*74a4d8c2SCharles.Forsyth {
101*74a4d8c2SCharles.Forsyth 	if(hz)
102*74a4d8c2SCharles.Forsyth 		*hz = HZ;
103*74a4d8c2SCharles.Forsyth 	return m->ticks;
104*74a4d8c2SCharles.Forsyth }
105