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