xref: /plan9-contrib/sys/src/9/mtx/raven.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier /*
2*9a747e4fSDavid du Colombier  *	``Nevermore!''
3*9a747e4fSDavid du Colombier  */
4*9a747e4fSDavid du Colombier #include	"u.h"
5*9a747e4fSDavid du Colombier #include	"../port/lib.h"
6*9a747e4fSDavid du Colombier #include	"mem.h"
7*9a747e4fSDavid du Colombier #include	"dat.h"
8*9a747e4fSDavid du Colombier #include	"fns.h"
9*9a747e4fSDavid du Colombier #include	"io.h"
10*9a747e4fSDavid du Colombier 
11*9a747e4fSDavid du Colombier typedef struct Raven Raven;
12*9a747e4fSDavid du Colombier struct Raven
13*9a747e4fSDavid du Colombier {
14*9a747e4fSDavid du Colombier 	ushort	vid;
15*9a747e4fSDavid du Colombier 	ushort	did;
16*9a747e4fSDavid du Colombier 	uchar	_pad4;
17*9a747e4fSDavid du Colombier 	uchar	rev;
18*9a747e4fSDavid du Colombier 	uchar	_pad6[2];
19*9a747e4fSDavid du Colombier 	ushort	gcsr;
20*9a747e4fSDavid du Colombier 	ushort	feat;
21*9a747e4fSDavid du Colombier 	uchar	_padC[7];
22*9a747e4fSDavid du Colombier 	uchar	padj;
23*9a747e4fSDavid du Colombier 	uchar	_pad14[12];
24*9a747e4fSDavid du Colombier 	ushort	errtst;
25*9a747e4fSDavid du Colombier 	ushort	erren;
26*9a747e4fSDavid du Colombier 	uchar	_pad24[3];
27*9a747e4fSDavid du Colombier 	uchar	errst;
28*9a747e4fSDavid du Colombier 	ulong	errad;
29*9a747e4fSDavid du Colombier 	uchar	_pad2C[2];
30*9a747e4fSDavid du Colombier 	ushort	errat;
31*9a747e4fSDavid du Colombier 	ulong	piack;
32*9a747e4fSDavid du Colombier 	uchar	_pad34[12];
33*9a747e4fSDavid du Colombier 
34*9a747e4fSDavid du Colombier 	struct {
35*9a747e4fSDavid du Colombier 		ushort	start;
36*9a747e4fSDavid du Colombier 		ushort	end;
37*9a747e4fSDavid du Colombier 		ushort	off;
38*9a747e4fSDavid du Colombier 		uchar	_pad;
39*9a747e4fSDavid du Colombier 		uchar	attr;
40*9a747e4fSDavid du Colombier 	} map[4];
41*9a747e4fSDavid du Colombier 
42*9a747e4fSDavid du Colombier 	struct {
43*9a747e4fSDavid du Colombier 		ulong	cntl;
44*9a747e4fSDavid du Colombier 		uchar	_pad[3];
45*9a747e4fSDavid du Colombier 		uchar	stat;
46*9a747e4fSDavid du Colombier 	} wdt[2];
47*9a747e4fSDavid du Colombier 
48*9a747e4fSDavid du Colombier 	ulong	gpr[4];
49*9a747e4fSDavid du Colombier };
50*9a747e4fSDavid du Colombier 
51*9a747e4fSDavid du Colombier enum {
52*9a747e4fSDavid du Colombier 	/* map[] attr bits */
53*9a747e4fSDavid du Colombier 	Iom = (1<<0),
54*9a747e4fSDavid du Colombier 	Mem = (1<<1),
55*9a747e4fSDavid du Colombier 	Wpen = (1<<4),
56*9a747e4fSDavid du Colombier 	Wen = (1<<6),
57*9a747e4fSDavid du Colombier 	Ren = (1<<7),
58*9a747e4fSDavid du Colombier };
59*9a747e4fSDavid du Colombier 
60*9a747e4fSDavid du Colombier static Raven *raven = (Raven*)RAVEN;
61*9a747e4fSDavid du Colombier static ulong mpic;
62*9a747e4fSDavid du Colombier 
63*9a747e4fSDavid du Colombier static void
setmap(int i,ulong addr,ulong len,ulong busaddr,int attr)64*9a747e4fSDavid du Colombier setmap(int i, ulong addr, ulong len, ulong busaddr, int attr)
65*9a747e4fSDavid du Colombier {
66*9a747e4fSDavid du Colombier 	raven->map[i].start = addr>>16;
67*9a747e4fSDavid du Colombier 	raven->map[i].end = (addr+len-1)>>16;
68*9a747e4fSDavid du Colombier 	raven->map[i].off = (busaddr-addr)>>16;
69*9a747e4fSDavid du Colombier 	raven->map[i].attr = attr;
70*9a747e4fSDavid du Colombier }
71*9a747e4fSDavid du Colombier 
72*9a747e4fSDavid du Colombier static ulong
swap32(ulong x)73*9a747e4fSDavid du Colombier swap32(ulong x)
74*9a747e4fSDavid du Colombier {
75*9a747e4fSDavid du Colombier 	return (x>>24)|((x>>8)&0xff00)|((x<<8)&0xff0000)|(x<<24);
76*9a747e4fSDavid du Colombier }
77*9a747e4fSDavid du Colombier 
78*9a747e4fSDavid du Colombier static ulong
mpic32r(int rno)79*9a747e4fSDavid du Colombier mpic32r(int rno)
80*9a747e4fSDavid du Colombier {
81*9a747e4fSDavid du Colombier 	return swap32(*(ulong*)(mpic+rno));
82*9a747e4fSDavid du Colombier }
83*9a747e4fSDavid du Colombier 
84*9a747e4fSDavid du Colombier static void
mpic32w(int rno,ulong x)85*9a747e4fSDavid du Colombier mpic32w(int rno, ulong x)
86*9a747e4fSDavid du Colombier {
87*9a747e4fSDavid du Colombier 	*(ulong*)(mpic+rno) = swap32(x);
88*9a747e4fSDavid du Colombier 	eieio();
89*9a747e4fSDavid du Colombier }
90*9a747e4fSDavid du Colombier 
91*9a747e4fSDavid du Colombier void
raveninit(void)92*9a747e4fSDavid du Colombier raveninit(void)
93*9a747e4fSDavid du Colombier {
94*9a747e4fSDavid du Colombier 	int i;
95*9a747e4fSDavid du Colombier 	Pcidev *p;
96*9a747e4fSDavid du Colombier 
97*9a747e4fSDavid du Colombier 	if(raven->vid != 0x1057 || raven->did !=0x4801)
98*9a747e4fSDavid du Colombier 		panic("raven not found");
99*9a747e4fSDavid du Colombier 
100*9a747e4fSDavid du Colombier 	/* set up a sensible hardware memory/IO map */
101*9a747e4fSDavid du Colombier 	setmap(0, PCIMEM0, PCISIZE0, 0, Wen|Ren|Mem);
102*9a747e4fSDavid du Colombier 	setmap(1, KZERO, IOSIZE, 0, Wen|Ren);	/* keeps PPCbug happy */
103*9a747e4fSDavid du Colombier 	setmap(2, PCIMEM1, PCISIZE1, PCISIZE0, Wen|Ren|Mem);
104*9a747e4fSDavid du Colombier 	setmap(3, IOMEM, IOSIZE, 0, Wen|Ren);	/* I/O must be slot 3 for PCI cfg space */
105*9a747e4fSDavid du Colombier 
106*9a747e4fSDavid du Colombier 	p = pcimatch(nil, 0x1057, 0x4801);
107*9a747e4fSDavid du Colombier 	if(p == nil)
108*9a747e4fSDavid du Colombier 		panic("raven PCI regs not found");
109*9a747e4fSDavid du Colombier 	mpic = (p->mem[1].bar+PCIMEM0);
110*9a747e4fSDavid du Colombier 
111*9a747e4fSDavid du Colombier 	/* ensure all interrupts are off, and routed to cpu 0 */
112*9a747e4fSDavid du Colombier 	for(i = 0; i < 16; i++) {
113*9a747e4fSDavid du Colombier 		mpic32w(0x10000+0x20*i, (1<<31));	/* mask */
114*9a747e4fSDavid du Colombier 		mpic32w(0x10010+0x20*i, 1);			/* route to cpu 0 */
115*9a747e4fSDavid du Colombier 	}
116*9a747e4fSDavid du Colombier 
117*9a747e4fSDavid du Colombier 	mpic32w(0x20080, 1);			/* cpu 0 task pri */
118*9a747e4fSDavid du Colombier //	mpic32w(0x21080, 1);			/* cpu 1 task pri */
119*9a747e4fSDavid du Colombier 	mpic32w(0x1020, (1<<29));		/* Mixed mode (8259 & Raven intrs both available) */
120*9a747e4fSDavid du Colombier }
121*9a747e4fSDavid du Colombier 
122*9a747e4fSDavid du Colombier void
mpicenable(int vec,Vctl * v)123*9a747e4fSDavid du Colombier mpicenable(int vec, Vctl *v)
124*9a747e4fSDavid du Colombier {
125*9a747e4fSDavid du Colombier 	ulong x;
126*9a747e4fSDavid du Colombier 
127*9a747e4fSDavid du Colombier 	x = (1<<22)|(15<<16)|vec;
128*9a747e4fSDavid du Colombier 	if(vec == 0)
129*9a747e4fSDavid du Colombier 		x |= (1<<23);
130*9a747e4fSDavid du Colombier 	mpic32w(0x10000+0x20*vec, x);
131*9a747e4fSDavid du Colombier 	if(vec != 0)
132*9a747e4fSDavid du Colombier 		v->eoi = mpiceoi;
133*9a747e4fSDavid du Colombier }
134*9a747e4fSDavid du Colombier 
135*9a747e4fSDavid du Colombier void
mpicdisable(int vec)136*9a747e4fSDavid du Colombier mpicdisable(int vec)
137*9a747e4fSDavid du Colombier {
138*9a747e4fSDavid du Colombier 	mpic32w(0x10000+0x20*vec, (1<<31));
139*9a747e4fSDavid du Colombier }
140*9a747e4fSDavid du Colombier 
141*9a747e4fSDavid du Colombier int
mpicintack(void)142*9a747e4fSDavid du Colombier mpicintack(void)
143*9a747e4fSDavid du Colombier {
144*9a747e4fSDavid du Colombier 	return mpic32r(0x200A0 + (m->machno<<12));
145*9a747e4fSDavid du Colombier }
146*9a747e4fSDavid du Colombier 
147*9a747e4fSDavid du Colombier int
mpiceoi(int vec)148*9a747e4fSDavid du Colombier mpiceoi(int vec)
149*9a747e4fSDavid du Colombier {
150*9a747e4fSDavid du Colombier 	USED(vec);
151*9a747e4fSDavid du Colombier 	mpic32w(0x200B0 + (m->machno<<12), 0);
152*9a747e4fSDavid du Colombier 	return 0;
153*9a747e4fSDavid du Colombier }
154