From 9e304bc981b80b40c65b072c7f28339235e9b187 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 5 Sep 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-09-05 --- carrera/devether.c | 76 ++++++++++++++++++++++++++++++++++++--------- carrera/faultmips.c | 12 ++++--- carrera/fns.h | 3 ++ carrera/io.h | 21 +++++++++++-- carrera/main.c | 74 +++++++++++++++++++++++++++++++++---------- carrera/mmu.c | 6 ++-- carrera/trap.c | 5 +-- port/devcons.c | 4 ++- 8 files changed, 157 insertions(+), 44 deletions(-) diff --git a/carrera/devether.c b/carrera/devether.c index f91c56e94cb03fc090419139f1eba804e067af0f..e64ce79cb6150890b32f4e079f96c8e568b650fb 100644 --- a/carrera/devether.c +++ b/carrera/devether.c @@ -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]; @@ -530,6 +558,12 @@ etherreset(void) ether[0]->arg = ether[0]; } +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; } diff --git a/carrera/faultmips.c b/carrera/faultmips.c index aad01303a48fac68b5645b3f7c2190382c89ccb5..55edef0d93019a88a5911e28b4ff1080e8d25899 100644 --- a/carrera/faultmips.c +++ b/carrera/faultmips.c @@ -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; } diff --git a/carrera/fns.h b/carrera/fns.h index 59591e56398d779c534d5f64d19a01db29b6948f..2fe9f326107e037944fd6eafabff1f3e96838e29 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -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) diff --git a/carrera/io.h b/carrera/io.h index e127c8e5bb4c0176b5f849b8a1b8ad8aa1c6ba80..bc4c922e885cbac617c210c24ac50a60fb57b3d2 100644 --- a/carrera/io.h +++ b/carrera/io.h @@ -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; }; diff --git a/carrera/main.c b/carrera/main.c index b6849bbec7af1b4402fd52f2ab74d172ea7e07d8..d6467d10a5a4181f28aa7ada06afbc0bb8d2fa70 100644 --- a/carrera/main.c +++ b/carrera/main.c @@ -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<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 */ } diff --git a/carrera/mmu.c b/carrera/mmu.c index fc4c441fc3856a3135bf4e455e9f20c764ff3e73..927d5cbc6a6f6151d8756c386fb965f8ebbb69d9 100644 --- a/carrera/mmu.c +++ b/carrera/mmu.c @@ -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); diff --git a/carrera/trap.c b/carrera/trap.c index aa3303211e209049125cda59ec47375db0e9b32e..e2cc67e0fbd744130e506944c5c1f6d12e9aeebd 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -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; } diff --git a/port/devcons.c b/port/devcons.c index 8dd9639cb6cb3656077ee9b02a423b9ad736fb61..e1d4c02ee0b662ae1e36919af0f99376e69d263f 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -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