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