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