xref: /inferno-os/os/boot/mpc/cpm.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "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 enum {
9*74a4d8c2SCharles.Forsyth 	BDSIZE=	1024,	/* TO DO: check this */
10*74a4d8c2SCharles.Forsyth };
11*74a4d8c2SCharles.Forsyth 
12*74a4d8c2SCharles.Forsyth static	Map	bdmapv[BDSIZE/sizeof(BD)];
13*74a4d8c2SCharles.Forsyth static	RMap	bdmap = {"buffer descriptors"};
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth void
cpminit(void)16*74a4d8c2SCharles.Forsyth cpminit(void)
17*74a4d8c2SCharles.Forsyth {
18*74a4d8c2SCharles.Forsyth 	IMM *io;
19*74a4d8c2SCharles.Forsyth 
20*74a4d8c2SCharles.Forsyth 	io = m->iomem;
21*74a4d8c2SCharles.Forsyth 	io->sdcr = 1;
22*74a4d8c2SCharles.Forsyth 	io->lccr &= ~1;	/* disable LCD */
23*74a4d8c2SCharles.Forsyth 	io->pcint = 0;	/* disable all port C interrupts */
24*74a4d8c2SCharles.Forsyth 	io->pcso = 0;
25*74a4d8c2SCharles.Forsyth 	io->pcdir =0;
26*74a4d8c2SCharles.Forsyth 	io->pcpar = 0;
27*74a4d8c2SCharles.Forsyth 	io->pcdat = 0;
28*74a4d8c2SCharles.Forsyth 	io->papar = 0;
29*74a4d8c2SCharles.Forsyth 	io->padir = 0;
30*74a4d8c2SCharles.Forsyth 	io->paodr = 0;
31*74a4d8c2SCharles.Forsyth 	io->padat = 0;
32*74a4d8c2SCharles.Forsyth 	io->pbpar = 0;
33*74a4d8c2SCharles.Forsyth 	io->pbdir = 0;
34*74a4d8c2SCharles.Forsyth 	io->pbodr = 0;
35*74a4d8c2SCharles.Forsyth 	io->pbdat = 0;
36*74a4d8c2SCharles.Forsyth 	eieio();
37*74a4d8c2SCharles.Forsyth 
38*74a4d8c2SCharles.Forsyth 	for(io->cpcr = 0x8001; io->cpcr & 1;)	/* reset all CPM channels */
39*74a4d8c2SCharles.Forsyth 		eieio();
40*74a4d8c2SCharles.Forsyth 
41*74a4d8c2SCharles.Forsyth 	mapinit(&bdmap, bdmapv, sizeof(bdmapv));
42*74a4d8c2SCharles.Forsyth 	mapfree(&bdmap, DPBASE, BDSIZE);
43*74a4d8c2SCharles.Forsyth }
44*74a4d8c2SCharles.Forsyth 
45*74a4d8c2SCharles.Forsyth void
cpmop(int op,int cno,int param)46*74a4d8c2SCharles.Forsyth cpmop(int op, int cno, int param)
47*74a4d8c2SCharles.Forsyth {
48*74a4d8c2SCharles.Forsyth 	IMM *io;
49*74a4d8c2SCharles.Forsyth 	int s;
50*74a4d8c2SCharles.Forsyth 
51*74a4d8c2SCharles.Forsyth 	s = splhi();
52*74a4d8c2SCharles.Forsyth 	io = m->iomem;
53*74a4d8c2SCharles.Forsyth 	eieio();
54*74a4d8c2SCharles.Forsyth 	while(io->cpcr & 1)
55*74a4d8c2SCharles.Forsyth 		eieio();
56*74a4d8c2SCharles.Forsyth 	io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1;
57*74a4d8c2SCharles.Forsyth 	eieio();
58*74a4d8c2SCharles.Forsyth 	while(io->cpcr & 1)
59*74a4d8c2SCharles.Forsyth 		eieio();
60*74a4d8c2SCharles.Forsyth 	splx(s);
61*74a4d8c2SCharles.Forsyth }
62*74a4d8c2SCharles.Forsyth 
63*74a4d8c2SCharles.Forsyth /*
64*74a4d8c2SCharles.Forsyth  * connect SCCx clocks in NSMI mode (x=1 for USB)
65*74a4d8c2SCharles.Forsyth  */
66*74a4d8c2SCharles.Forsyth void
sccnmsi(int x,int rcs,int tcs)67*74a4d8c2SCharles.Forsyth sccnmsi(int x, int rcs, int tcs)
68*74a4d8c2SCharles.Forsyth {
69*74a4d8c2SCharles.Forsyth 	IMM *io;
70*74a4d8c2SCharles.Forsyth 	ulong v;
71*74a4d8c2SCharles.Forsyth 	int sh;
72*74a4d8c2SCharles.Forsyth 
73*74a4d8c2SCharles.Forsyth 	sh = (x-1)*8;	/* each SCCx field in sicr is 8 bits */
74*74a4d8c2SCharles.Forsyth 	v = (((rcs&7)<<3) | (tcs&7)) << sh;
75*74a4d8c2SCharles.Forsyth 	io = ioplock();
76*74a4d8c2SCharles.Forsyth 	io->sicr = (io->sicr & ~(0xFF<<sh)) | v;
77*74a4d8c2SCharles.Forsyth 	iopunlock();
78*74a4d8c2SCharles.Forsyth }
79*74a4d8c2SCharles.Forsyth 
80*74a4d8c2SCharles.Forsyth void
scc2stop(void)81*74a4d8c2SCharles.Forsyth scc2stop(void)
82*74a4d8c2SCharles.Forsyth {
83*74a4d8c2SCharles.Forsyth 	SCC *scc;
84*74a4d8c2SCharles.Forsyth 
85*74a4d8c2SCharles.Forsyth 	scc = IOREGS(0xA20, SCC);
86*74a4d8c2SCharles.Forsyth 	if(scc->gsmrl & (3<<4)){
87*74a4d8c2SCharles.Forsyth 		cpmop(GracefulStopTx, SCC2ID, 0);
88*74a4d8c2SCharles.Forsyth 		cpmop(CloseRxBD, SCC2ID, 0);
89*74a4d8c2SCharles.Forsyth 		delay(1);
90*74a4d8c2SCharles.Forsyth 		scc->gsmrl &= ~(3<<4);	/* disable current use */
91*74a4d8c2SCharles.Forsyth 		archetherdisable(SCC2ID);
92*74a4d8c2SCharles.Forsyth 	}
93*74a4d8c2SCharles.Forsyth }
94*74a4d8c2SCharles.Forsyth 
95*74a4d8c2SCharles.Forsyth BD *
bdalloc(int n)96*74a4d8c2SCharles.Forsyth bdalloc(int n)
97*74a4d8c2SCharles.Forsyth {
98*74a4d8c2SCharles.Forsyth 	ulong a;
99*74a4d8c2SCharles.Forsyth 
100*74a4d8c2SCharles.Forsyth 	a = mapalloc(&bdmap, 0, n*sizeof(BD), 0);
101*74a4d8c2SCharles.Forsyth 	if(a == 0)
102*74a4d8c2SCharles.Forsyth 		panic("bdalloc");
103*74a4d8c2SCharles.Forsyth 	return KADDR(a);
104*74a4d8c2SCharles.Forsyth }
105*74a4d8c2SCharles.Forsyth 
106*74a4d8c2SCharles.Forsyth void
bdfree(BD * b,int n)107*74a4d8c2SCharles.Forsyth bdfree(BD *b, int n)
108*74a4d8c2SCharles.Forsyth {
109*74a4d8c2SCharles.Forsyth 	if(b){
110*74a4d8c2SCharles.Forsyth 		eieio();
111*74a4d8c2SCharles.Forsyth 		mapfree(&bdmap, PADDR(b), n*sizeof(BD));
112*74a4d8c2SCharles.Forsyth 	}
113*74a4d8c2SCharles.Forsyth }
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth /*
116*74a4d8c2SCharles.Forsyth  * initialise receive and transmit buffer rings.
117*74a4d8c2SCharles.Forsyth  */
118*74a4d8c2SCharles.Forsyth int
ioringinit(Ring * r,int nrdre,int ntdre,int bufsize)119*74a4d8c2SCharles.Forsyth ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
120*74a4d8c2SCharles.Forsyth {
121*74a4d8c2SCharles.Forsyth 	int i, x;
122*74a4d8c2SCharles.Forsyth 
123*74a4d8c2SCharles.Forsyth 	/* the ring entries must be aligned on sizeof(BD) boundaries */
124*74a4d8c2SCharles.Forsyth 	r->nrdre = nrdre;
125*74a4d8c2SCharles.Forsyth 	if(r->rdr == nil)
126*74a4d8c2SCharles.Forsyth 		r->rdr = bdalloc(nrdre);
127*74a4d8c2SCharles.Forsyth 	/* the buffer size must align with cache lines since the cache doesn't snoop */
128*74a4d8c2SCharles.Forsyth 	bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
129*74a4d8c2SCharles.Forsyth 	if(r->rrb == nil)
130*74a4d8c2SCharles.Forsyth 		r->rrb = malloc(nrdre*bufsize);
131*74a4d8c2SCharles.Forsyth 	if(r->rdr == nil || r->rrb == nil)
132*74a4d8c2SCharles.Forsyth 		return -1;
133*74a4d8c2SCharles.Forsyth 	dcflush(r->rrb, nrdre*bufsize);
134*74a4d8c2SCharles.Forsyth 	x = PADDR(r->rrb);
135*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nrdre; i++){
136*74a4d8c2SCharles.Forsyth 		r->rdr[i].length = 0;
137*74a4d8c2SCharles.Forsyth 		r->rdr[i].addr = x;
138*74a4d8c2SCharles.Forsyth 		r->rdr[i].status = BDEmpty|BDInt;
139*74a4d8c2SCharles.Forsyth 		x += bufsize;
140*74a4d8c2SCharles.Forsyth 	}
141*74a4d8c2SCharles.Forsyth 	r->rdr[i-1].status |= BDWrap;
142*74a4d8c2SCharles.Forsyth 	r->rdrx = 0;
143*74a4d8c2SCharles.Forsyth 
144*74a4d8c2SCharles.Forsyth 	r->ntdre = ntdre;
145*74a4d8c2SCharles.Forsyth 	if(r->tdr == nil)
146*74a4d8c2SCharles.Forsyth 		r->tdr = bdalloc(ntdre);
147*74a4d8c2SCharles.Forsyth 	if(r->txb == nil)
148*74a4d8c2SCharles.Forsyth 		r->txb = malloc(ntdre*sizeof(Block*));
149*74a4d8c2SCharles.Forsyth 	if(r->tdr == nil || r->txb == nil)
150*74a4d8c2SCharles.Forsyth 		return -1;
151*74a4d8c2SCharles.Forsyth 	for(i = 0; i < ntdre; i++){
152*74a4d8c2SCharles.Forsyth 		r->txb[i] = nil;
153*74a4d8c2SCharles.Forsyth 		r->tdr[i].addr = 0;
154*74a4d8c2SCharles.Forsyth 		r->tdr[i].length = 0;
155*74a4d8c2SCharles.Forsyth 		r->tdr[i].status = 0;
156*74a4d8c2SCharles.Forsyth 	}
157*74a4d8c2SCharles.Forsyth 	r->tdr[i-1].status |= BDWrap;
158*74a4d8c2SCharles.Forsyth 	r->tdrh = 0;
159*74a4d8c2SCharles.Forsyth 	r->tdri = 0;
160*74a4d8c2SCharles.Forsyth 	r->ntq = 0;
161*74a4d8c2SCharles.Forsyth 	return 0;
162*74a4d8c2SCharles.Forsyth }
163