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