154 lines
2.5 KiB
C
154 lines
2.5 KiB
C
/*
|
|
* ``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;
|
|
}
|