M carrera/devether.c => carrera/devether.c +61 -15
@@ 17,6 17,7 @@
#define RD(rn) (delay(1), *(ulong*)((ulong)&SONICADDR->rn^4))
#define WR(rn, v) (delay(1), *(ulong*)((ulong)&SONICADDR->rn^4) = v)
+#define ISquad(s) if((ulong)s & 0x7) panic("sonoc: Quad alignment");
typedef struct
{
@@ 177,13 178,14 @@ enum{
Interface = -1, /* descriptor belongs to interface */
Nether = 1,
- Ntypes= 8,
+ Ntypes = 8,
};
/*
* CAM Descriptor
*/
-typedef struct {
+typedef struct
+{
uchar pad0[2];
ushort cep; /* CAM entry pointer */
uchar pad1[2];
@@ 234,7 236,6 @@ reset(Ether *ctlr)
{
int i;
-iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf);
/*
* Reset the SONIC, toggle the Rst bit.
* Set the data config register for synchronous termination
@@ 242,7 243,8 @@ iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf)
* Clear the descriptor and buffer area.
*/
WR(cr, Rst);
- WR(dcr, Sterm|Dw32|Lbr|Efm|W14tf);
+ WR(dcr, 0x2423); /* 5-19 Carrera manual */
+iprint("eobc #%lux\n", RD(eobc));
WR(cr, 0);
/*
@@ 255,7 257,7 @@ iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf)
* thus the size of the receive buffers must be sizeof(Etherpkt)+4.
* Set up the receive descriptors as a ring.
*/
- for(i = 0; i < Nrb; i++){
+ for(i = 0; i < Nrb; i++) {
ctlr->rra[i].wc0 = (sizeof(ctlr->rb[0])/2) & 0xFFFF;
ctlr->rra[i].wc1 = ((sizeof(ctlr->rb[0])/2)>>16) & 0xFFFF;
@@ 266,6 268,10 @@ iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf)
ctlr->rra[i].ptr1 = ctlr->rda[i].ptr1 = MS16(ctlr->rb[i]);
}
+ ISquad(ctlr->rra);
+ ISquad(ctlr->rda);
+ ISquad(ctlr->rb);
+
/*
* Terminate the receive descriptor ring
* and load the SONIC registers to describe the RDA.
@@ 275,6 281,7 @@ iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf)
WR(crda, LS16(ctlr->rda));
WR(urda, MS16(ctlr->rda));
WR(eobc, sizeof(ctlr->rb[0])/2 - 2);
+iprint("eobc #%lux\n", RD(eobc));
/*
* Load the SONIC registers to describe the RRA.
@@ 291,11 298,9 @@ iprint("reset sonic dcr=#%lux mydcr=#%lux\n", RD(dcr), Sterm|Dw32|Lbr|Efm|W14tf)
WR(rea, LS16(&ctlr->rra[Nrb]));
WR(rwp, LS16(&ctlr->rra[Nrb+1]));
-iprint("wait rra\n");
WR(cr, Rrra);
while(RD(cr) & Rrra)
;
-iprint("rra done\n");
/*
* Initialise the transmit descriptor area (TDA).
@@ 358,7 363,25 @@ iprint("rra done\n");
WR(rcr, Err|Rnt|Brd);
WR(tcr, 0);
WR(imr, AllIntr);
-iprint("reset done\n");
+}
+
+void
+pxp(RXpkt *rxpkt)
+{
+ print("%lux %lux\n", rxpkt->pad0[0], rxpkt->pad0[1]);
+ print("status %lux\n", rxpkt->status); /* receive status */
+ print("%lux %lux\n", rxpkt->pad1[0], rxpkt->pad1[1]);
+ print("count %lux\n", rxpkt->count); /* packet byte count */
+ print("%lux %lux\n", rxpkt->pad2[0], rxpkt->pad2[1]);
+ print("ptr0 %lux\n", rxpkt->ptr0); /* buffer pointer */
+ print("%lux %lux\n", rxpkt->pad3[0], rxpkt->pad3[1]);
+ print("ptr1 %lux\n", rxpkt->ptr1);
+ print("%lux %lux\n", rxpkt->pad4[0], rxpkt->pad4[1]);
+ print("seqno %lux\n", rxpkt->seqno); /* */
+ print("%lux %lux\n", rxpkt->pad5[0], rxpkt->pad5[1]);
+ print("link %lux\n", rxpkt->link); /* descriptor link and EOL */
+ print("%lux %lux\n", rxpkt->pad6[0], rxpkt->pad6[1]);
+ print("owner %lux\n", rxpkt->owner); /* in use */
}
void
@@ 379,6 402,7 @@ etherintr(void)
status = RD(isr) & AllIntr;
if(status == 0)
break;
+print("s %lux\n", status);
WR(isr, status);
@@ 410,8 434,8 @@ etherintr(void)
/*
* A packet arrived or we ran out of descriptors.
*/
- status &= ~(Pktrx|Rde);
rxpkt = &ctlr->rda[ctlr->rh];
+pxp(rxpkt);
while(rxpkt->owner == Host){
ctlr->inpackets++;
@@ 470,16 494,16 @@ etherintr(void)
* Warnings that something is afoot.
*/
if(status & Hbl){
- print("sonic: cd heartbeat lost\n");
+ iprint("sonic: cd heartbeat lost\n");
status &= ~Hbl;
}
if(status & Br){
- print("sonic: bus retry occurred\n");
+ iprint("sonic: bus retry occurred\n");
status &= ~Br;
}
if(status & AllIntr)
- print("sonic %ux\n", status);
+ iprint("sonic #%lux\n", status);
}
}
@@ 513,7 537,11 @@ etherreset(void)
*/
if(ether[0] == 0) {
ether[0] = xspanalloc(sizeof(Ether), BY2PG, 64*1024);
-/* memmove(ether[0]->ea, eeprom.ea, sizeof(ether[0]->ea)); */
+
+ if(PADDR(ether[0])+sizeof(Ether) > Ntranslation*BY2PG)
+ panic("sonic: 16M io map");
+
+ enetaddr(ether[0]->ea);
}
ctlr = ether[0];
@@ 531,6 559,12 @@ etherreset(void)
}
void
+enab(void)
+{
+ WR(cr, Rxen);
+}
+
+void
etherinit(void)
{
}
@@ 538,6 572,13 @@ etherinit(void)
Chan*
etherattach(char *spec)
{
+ static int enable;
+
+ if(enable == 0) {
+ enable = 1;
+ WR(cr, Rxen);
+ }
+
return devattach('l', spec);
}
@@ 594,6 635,8 @@ etherwrite(Chan *c, void *buf, long n, ulong offset)
USED(offset);
+iprint("ether tx\n");
+
if(n > ETHERMAXTU)
error(Ebadarg);
@@ 604,9 647,9 @@ etherwrite(Chan *c, void *buf, long n, ulong offset)
/* we handle data */
qlock(&ctlr->tlock);
tsleep(&ctlr->tr, isoutbuf, ctlr, 10000);
- if(!isoutbuf(ctlr)){
+
+ if(!isoutbuf(ctlr))
print("ether transmitter jammed\n");
- }
else {
p =(Etherpkt*)ctlr->tb[ctlr->th];
memmove(p->d, buf, n);
@@ 627,6 670,9 @@ etherwrite(Chan *c, void *buf, long n, ulong offset)
WR(cr, Txp);
}
qunlock(&ctlr->tlock);
+
+iprint("tx done %d\n", n);
+
return n;
}
M carrera/faultmips.c => carrera/faultmips.c +8 -4
@@ 97,7 97,8 @@ tstbadvaddr(Ureg *ur, int read)
break;
}
- /* print("ea %lux 0x%lux(R%d) bv 0x%lux pc 0x%lux\n", ea, off, rn, ur->badvaddr, ur->pc); /**/
+ /* print("ea %lux 0x%lux(R%d) bv 0x%lux pc 0x%lux\n",
+ ea, off, rn, ur->badvaddr, ur->pc); /**/
if(ur->badvaddr == ea)
return 0;
@@ 122,13 123,15 @@ faultmips(Ureg *ur, int user, int code)
addr &= ~(BY2PG-1);
read = !(code==CTLBM || code==CTLBS);
- print("fault: %s code %d va %lux pc %lux r31 %lux %lux\n", up->text, code, ur->badvaddr, ur->pc, ur->r31, tlbvirt());/**/
+ /* print("fault: %s code %d va %lux pc %lux r31 %lux %lux\n",
+ up->text, code, ur->badvaddr, ur->pc, ur->r31, tlbvirt());/**/
if(fault(addr, read) == 0)
return;
if(tstbadvaddr(ur, read)) {
-/* print("spurious badvaddr 0x%lux in %s at pc 0x%lux\n", ur->badvaddr, up->text, ur->pc);/**/
+ /* print("spurious badvaddr 0x%lux in %s at pc 0x%lux\n",
+ ur->badvaddr, up->text, ur->pc);/**/
return;
}
@@ 136,7 139,8 @@ faultmips(Ureg *ur, int user, int code)
p = "store";
if(read)
p = "load";
- sprint(buf, "sys: trap: fault %s addr=0x%lux r31=0x%lux", p, ur->badvaddr, ur->r31);
+ sprint(buf, "sys: trap: fault %s addr=0x%lux r31=0x%lux",
+ p, ur->badvaddr, ur->r31);
postnote(up, 1, buf, NDebug);
return;
}
M carrera/fns.h => carrera/fns.h +3 -0
@@ 102,10 102,13 @@ void wbflush(void);
void wrcompare(ulong);
void Xdelay(int);
+void serialinit(void);
void NS16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
void NS16552setup(ulong, ulong);
void NS16552intr(int);
void etherintr(void);
+void iomapinit(void);
+void enetaddr(uchar*);
#define waserror() setlabel(&up->errlab[up->nerrlab++])
#define kmapperm(x) kmap(x)
M carrera/io.h => carrera/io.h +19 -2
@@ 1,3 1,6 @@
+/*
+ * These register addresses have already been adjusted for BE operation
+ */
enum
{
Devicephys = 0x80000000,
@@ 34,6 37,20 @@ enum
Soundint = (1<<2),
Floppyint = (1<<1),
Parallelint = (1<<0),
- Intenareg = 0xE0040004,
- Intcause = 0xE0040007
+ Intenareg = 0xE0040004, /* Device interrupt enable */
+ Intcause = 0xE0040007, /* Decice interrupt cause register */
+
+ Ttbr = 0x8000001C, /* Translation table base address */
+ Tlrb = 0x80000024, /* Translation table limit address */
+ Tir = 0x8000002c, /* Translation invalidate register */
+ Ntranslation = 4096, /* Number of translation registers */
+};
+
+#define IO(type, reg) (*(type*)reg)
+
+typedef struct Tte Tte;
+struct Tte
+{
+ ulong hi;
+ ulong lo;
};
M carrera/main.c => carrera/main.c +57 -17
@@ 40,15 40,11 @@ main(void)
confinit();
savefpregs(&initfp);
machinit();
- active.exiting = 0;
- active.machs = 1;
kmapinit();
xinit();
+ iomapinit();
printinit();
-
- NS16552setup(Uart1, UartFREQ);
- NS16552special(0, 9600, &kbdq, &printq, kbdcr2nl);
-
+ serialinit();
vecinit();
iprint("\n\nBrazil\n");
pageinit();
@@ 58,6 54,10 @@ main(void)
rootfiles();
swapinit();
userinit();
+enab();
+spllo();
+for(;;)
+ ;
schedinit();
}
@@ 143,7 143,21 @@ machinit(void)
n = m->machno;
m->stb = &stlb[n][0];
+ m->speed = 50;
clockinit();
+
+ active.exiting = 0;
+ active.machs = 1;
+}
+
+/*
+ * Set up a console on serial port 2
+ */
+void
+serialinit(void)
+{
+ NS16552setup(Uart1, UartFREQ);
+ NS16552special(0, 9600, &kbdq, &printq, kbdcr2nl);
}
/*
@@ 166,7 180,40 @@ ioinit(void)
phys = PPN(Intctlphys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
puttlbx(2, Intctlvirt, phys, PTEGLOBL, PGSZ4K);
- *(ushort*)Intenareg = 0xffff;
+ /* Enable all devce interrupt */
+ IO(ushort, Intenareg) = 0xffff;
+}
+
+void
+enetaddr(uchar *ea)
+{
+ /** BUG get from PROM */
+ static uchar tea[] = { 0x00, 0x00, 0x77, 0x01, 0xD2, 0xba };
+
+ memmove(ea, tea, sizeof(tea));
+}
+
+/*
+ * All DMA and ether IO buffers must reside in the first 16M bytes of
+ * memory to be covered by the translation registers
+ */
+void
+iomapinit(void)
+{
+ int i;
+ Tte *t;
+
+ t = xspanalloc(Ntranslation*sizeof(Tte), BY2PG, 0);
+
+ for(i = 0; i < Ntranslation; i++)
+ t[i].lo = i<<PGSHIFT;
+
+ /* Set the translation table */
+ IO(ulong, Ttbr) = PADDR(t);
+ IO(ulong, Tlrb) = (Ntranslation-1)*sizeof(Tte);
+
+ /* Invalidate the old entries */
+ IO(ulong, Tir) = 0;
}
/*
@@ 272,10 319,10 @@ userinit(void)
void
exit(long type)
{
- int timer;
+ USED(type);
spllo();
- print("cpu %d exiting %d\n", m->machno, type);
+ print("cpu %d exiting\n", m->machno);
while(consactive())
delay(10);
splhi();
@@ 288,11 335,6 @@ confinit(void)
{
ulong ktop, top;
- /*
- * divide memory twixt user pages and kernel. Since
- * the kernel can't use anything above .5G unmapped,
- * make sure all that memory goes to the user.
- */
ktop = PGROUND((ulong)end);
ktop = PADDR(ktop);
top = (16*1024*1024)/BY2PG;
@@ 306,8 348,6 @@ confinit(void)
conf.base1 = 0;
conf.upages = (conf.npage*70)/100;
- if(top - conf.upages > (256*1024*1024)/BY2PG)
- conf.upages = top - (256*1024*1024)/BY2PG;
conf.nmach = 1;
@@ 320,7 360,7 @@ confinit(void)
conf.arp = 32;
conf.frag = 32;
- conf.copymode = 0; /* copy on reference */
+ conf.copymode = 0; /* copy on write */
}
M carrera/mmu.c => carrera/mmu.c +3 -3
@@ 97,12 97,12 @@ kmap(Page *pg)
k->virt = virt;
pte = PPN(pg->pa)|PTECOHERXCLW|PTEGLOBL|PTEWRITE|PTEVALID;
if(virt & BY2PG) {
- k->phys0 = PTEGLOBL;
+ k->phys0 = PTEGLOBL|PTECOHERXCLW;
k->phys1 = pte;
}
else {
k->phys0 = pte;
- k->phys1 = PTEGLOBL;
+ k->phys1 = PTEGLOBL|PTECOHERXCLW;
}
x = m->ktlbnext;
@@ 185,7 185,7 @@ kmapinval()
curpid = PTEPID(TLBPID(tlbvirt()));
ktlbx = m->ktlbx;
- for(i = 0; i < NTLB; i++, ktlbx++){
+ for(i = TLBROFF; i < NTLB; i++, ktlbx++){
if(*ktlbx == 0)
continue;
TLBINVAL(i, curpid);
M carrera/trap.c => carrera/trap.c +3 -2
@@ 205,6 205,7 @@ trap(Ureg *ur)
kernfault(ur, ecode);
if(!user && (ur->badvaddr & KSEGM) == KSEG3) {
+iprint("kf %lux %lux\n", ur->pc, ur->r31);
kfault(ur->badvaddr);
break;
}
@@ 285,7 286,7 @@ intr(Ureg *ur)
cause &= INTR7|INTR6|INTR5|INTR4|INTR3|INTR2|INTR1|INTR0;
if(cause & INTR3) {
- devint = *(uchar*)Intcause;
+ devint = IO(uchar, Intcause);
switch(devint) {
default:
panic("unknown devint=#%lux", devint);
@@ 304,7 305,7 @@ intr(Ureg *ur)
}
if(cause & INTR4) {
- devint = *(uchar*)I386ack;
+ devint = IO(uchar, I386ack);
iprint("i386ack=#%lux\n", devint);
cause &= ~INTR4;
}
M port/devcons.c => port/devcons.c +3 -1
@@ 122,6 122,7 @@ panic(char *fmt, ...)
strcpy(buf, "panic: ");
n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
+iprint("%s\n", buf);
putstrn(buf, n+1);
prflush();
dumpstack();
@@ 158,7 159,8 @@ pprint(char *fmt, ...)
void
prflush(void)
{
- while(qlen(printq) > 0) ;
+ while(consactive())
+ ;
}
void