xref: /inferno-os/os/mpc/pit.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth /*
2*74a4d8c2SCharles.Forsyth  * programmable interrupt timer
3*74a4d8c2SCharles.Forsyth  */
4*74a4d8c2SCharles.Forsyth 
5*74a4d8c2SCharles.Forsyth #include	"u.h"
6*74a4d8c2SCharles.Forsyth #include	"../port/lib.h"
7*74a4d8c2SCharles.Forsyth #include	"mem.h"
8*74a4d8c2SCharles.Forsyth #include	"dat.h"
9*74a4d8c2SCharles.Forsyth #include	"fns.h"
10*74a4d8c2SCharles.Forsyth #include	"io.h"
11*74a4d8c2SCharles.Forsyth #include	"ureg.h"
12*74a4d8c2SCharles.Forsyth 
13*74a4d8c2SCharles.Forsyth enum {
14*74a4d8c2SCharles.Forsyth 	/* piscr */
15*74a4d8c2SCharles.Forsyth 	PTE =	1<<0,
16*74a4d8c2SCharles.Forsyth 	PITF =	1<<1,
17*74a4d8c2SCharles.Forsyth 	PIE =	1<<2,
18*74a4d8c2SCharles.Forsyth 	PS =	1<<7,
19*74a4d8c2SCharles.Forsyth };
20*74a4d8c2SCharles.Forsyth 
21*74a4d8c2SCharles.Forsyth static void
pitinterrupt(Ureg *,void *)22*74a4d8c2SCharles.Forsyth pitinterrupt(Ureg*, void*)
23*74a4d8c2SCharles.Forsyth {
24*74a4d8c2SCharles.Forsyth 	IMM *io;
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth 	io = m->iomem;
27*74a4d8c2SCharles.Forsyth 	if(io->piscr & PS){
28*74a4d8c2SCharles.Forsyth 		io->piscr |= PS;	/* clear by writing 1 */
29*74a4d8c2SCharles.Forsyth 		/* do whatever is required */
30*74a4d8c2SCharles.Forsyth 	}
31*74a4d8c2SCharles.Forsyth }
32*74a4d8c2SCharles.Forsyth 
33*74a4d8c2SCharles.Forsyth static void
pitreset(void)34*74a4d8c2SCharles.Forsyth pitreset(void)
35*74a4d8c2SCharles.Forsyth {
36*74a4d8c2SCharles.Forsyth 	IMM *io;
37*74a4d8c2SCharles.Forsyth 
38*74a4d8c2SCharles.Forsyth 	io = ioplock();
39*74a4d8c2SCharles.Forsyth 	io->piscrk = KEEP_ALIVE_KEY;
40*74a4d8c2SCharles.Forsyth 	io->piscr = (PITlevel<<8) | PS | PITF;
41*74a4d8c2SCharles.Forsyth 	if(0)
42*74a4d8c2SCharles.Forsyth 		io->piscrk = ~KEEP_ALIVE_KEY;
43*74a4d8c2SCharles.Forsyth 	/* piscrk is left unlocked for interrupt routine */
44*74a4d8c2SCharles.Forsyth 	iopunlock();
45*74a4d8c2SCharles.Forsyth 	intrenable(PITlevel, pitinterrupt, nil, BUSUNKNOWN, "pit");
46*74a4d8c2SCharles.Forsyth }
47*74a4d8c2SCharles.Forsyth 
48*74a4d8c2SCharles.Forsyth static ulong
pitload(ulong usec)49*74a4d8c2SCharles.Forsyth pitload(ulong usec)
50*74a4d8c2SCharles.Forsyth {
51*74a4d8c2SCharles.Forsyth 	IMM *io;
52*74a4d8c2SCharles.Forsyth 	ulong v;
53*74a4d8c2SCharles.Forsyth 
54*74a4d8c2SCharles.Forsyth 	v = ((usec*m->oscclk)/512);
55*74a4d8c2SCharles.Forsyth 	if(v == 0 || v >= (1<<16))
56*74a4d8c2SCharles.Forsyth 		return 0;	/* can't do */
57*74a4d8c2SCharles.Forsyth 	io = ioplock();
58*74a4d8c2SCharles.Forsyth 	io->pitck = KEEP_ALIVE_KEY;
59*74a4d8c2SCharles.Forsyth 	io->pitc = (v-1)<<16;
60*74a4d8c2SCharles.Forsyth 	io->pitck = ~KEEP_ALIVE_KEY;
61*74a4d8c2SCharles.Forsyth 	io->piscrk = KEEP_ALIVE_KEY;
62*74a4d8c2SCharles.Forsyth 	io->piscr = (PITlevel<<8) | PS | PIE | PITF | PTE;
63*74a4d8c2SCharles.Forsyth 	if(0)
64*74a4d8c2SCharles.Forsyth 		io->piscrk = ~KEEP_ALIVE_KEY;
65*74a4d8c2SCharles.Forsyth 	/* piscrk is left unlocked for interrupt routine */
66*74a4d8c2SCharles.Forsyth 	iopunlock();
67*74a4d8c2SCharles.Forsyth 	return (v*512)/m->oscclk;
68*74a4d8c2SCharles.Forsyth }
69