diff -Nru /n/sources/plan9/sys/src/9/rb/clock.c /sys/src/9/rb/clock.c --- /n/sources/plan9/sys/src/9/rb/clock.c Mon Jul 15 22:01:47 2013 +++ /sys/src/9/rb/clock.c Sun May 19 00:00:00 2019 @@ -12,31 +12,32 @@ enum { Cyccntres = 2, /* counter advances at ½ clock rate (mips 24k) */ - Basetickfreq = 680*Mhz / Cyccntres, /* rb450g */ }; +ulong basetickfreq = 680*Mhz / Cyccntres; /* rb450g */ + void (*kproftimer)(ulong); void silencewdog(void) { - *Rstwdogtimer = Basetickfreq * 2 * 5; /* pet the dog */ + *Rstwdogtimer = basetickfreq * 2 * 5; /* pet the dog */ } void sicwdog(void) { - *Rstwdogtimer = Basetickfreq * 2; + *Rstwdogtimer = basetickfreq * 2; *Rstwdogctl = Wdogreset; /* wake the dog */ } void wdogreset(void) { - *Rstwdogtimer = Basetickfreq / 100; + *Rstwdogtimer = basetickfreq / 100; *Rstwdogctl = Wdogreset; /* wake the dog */ coherence(); - *Rstwdogtimer = Basetickfreq / 10000; + *Rstwdogtimer = basetickfreq / 10000; coherence(); } @@ -74,12 +75,12 @@ speed = m->speed; if (speed == 0) - speed = Basetickfreq / Mhz * Cyccntres; + speed = basetickfreq / Mhz * Cyccntres; cyc = (ulong)l * (speed / Cyccntres); s = splhi(); cnt = rdcount(); x = cnt + cyc; - if (x < cnt || x >= ~0ul - Basetickfreq) { + if (x < cnt || x >= ~0ul - basetickfreq) { /* counter will wrap between now and x, or x is too near ~0 */ wrcount(0); /* somewhat drastic */ wrcompare(rdcompare() - cnt); /* match new count */ @@ -143,10 +144,10 @@ iprint("again..."); } while (cyc < 0); /* - * Instrs instructions took cyc cycles @ Basetickfreq Hz. + * Instrs instructions took cyc cycles @ basetickfreq Hz. * round the result. */ - return (((vlong)Basetickfreq * Instrs) / cyc + Mhz/2) / Mhz; + return (((vlong)basetickfreq * Instrs) / cyc + Mhz/2) / Mhz; } void @@ -154,6 +155,7 @@ { int mips; + basetickfreq = m->hz / Cyccntres; silencewdog(); /* @@ -169,11 +171,8 @@ if(m->delayloop == 0) m->delayloop = 1; - m->speed = mips; - m->hz = m->speed*Mhz; - - m->maxperiod = Basetickfreq / HZ; - m->minperiod = Basetickfreq / (100*HZ); + m->maxperiod = basetickfreq / HZ; + m->minperiod = basetickfreq / (100*HZ); wrcompare(rdcount()+m->maxperiod); /* @@ -188,7 +187,7 @@ /* * Tval is supposed to be in fastticks units. - * One fasttick unit is 1/Basetickfreq seconds. + * One fasttick unit is 1/basetickfreq seconds. */ void timerset(Tval next) @@ -221,7 +220,7 @@ ulong delta, count; if(hz) - *hz = Basetickfreq; + *hz = basetickfreq; /* avoid reentry on interrupt or trap, to prevent recursion */ x = splhi(); @@ -269,7 +268,7 @@ *cycp = fastticks(nil); } -Lock mpsynclock; +static Lock mpsynclock; /* * synchronize all clocks with processor 0 diff -Nru /n/sources/plan9/sys/src/9/rb/dat.h /sys/src/9/rb/dat.h --- /n/sources/plan9/sys/src/9/rb/dat.h Sun Jul 21 06:22:29 2013 +++ /sys/src/9/rb/dat.h Thu Aug 16 00:00:00 2018 @@ -8,6 +8,7 @@ typedef struct Notsave Notsave; typedef struct Pcidev Pcidev; typedef struct PMMU PMMU; +typedef struct Rbconf Rbconf; typedef struct Softtlb Softtlb; typedef struct Ureg Ureg; typedef struct Proc Proc; @@ -60,6 +60,7 @@ ulong nmach; /* processors */ ulong nproc; /* processes */ Confmem mem[1]; + /* npage may exclude kernel pages */ ulong npage; /* total physical pages of memory */ ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ @@ -71,6 +72,14 @@ int nuart; /* number of uart devices */ }; +struct Rbconf { + char *ether0mac; + char *memsize; + char *hz; + char *console; + char *null; /* act as end of argv when rebooting */ +}; + /* * floating point registers */ @@ -211,7 +212,11 @@ struct { Lock; - long machs; /* bitmap of processors */ + union { + uvlong machs; /* bitmap of active CPUs */ + ulong machsmap[(MAXMACH+BI2WD-1)/BI2WD]; + }; + int nmachs; /* number of bits set in machs(map) */ short exiting; int ispanic; }active; @@ -223,3 +228,5 @@ extern FPsave initfp; extern int normalprint; +extern ulong memsize; +extern Rbconf rbconf; diff -Nru /n/sources/plan9/sys/src/9/rb/devether.c /sys/src/9/rb/devether.c --- /n/sources/plan9/sys/src/9/rb/devether.c Tue Jul 23 01:37:08 2013 +++ /sys/src/9/rb/devether.c Tue May 26 00:00:00 2020 @@ -1,15 +1,11 @@ /* - * Atheros 71xx ethernets for rb450g. + * Atheros 7161 & 8316 ethernets for rb450g. + * second 7161 has the 8316 switch with 4 ports on it. * - * all 5 PHYs are accessible only through first ether's register space. + * all 5 PHYs are accessible only through first 7161's register space. * - * TODO: - * promiscuous mode. - * make ether1 work: probably needs mii/phy initialisation, + * TODO: make second 7161 work: probably needs mii/phy initialisation, * maybe needs 8316 switch code too (which requires mdio, phy, etc. glop). - * to maybe do some day: - * dig mac addresses out & config phy/mii via spi or other grot and swill - * (instead of editing rb config file). */ #include "u.h" #include "../port/lib.h" @@ -32,9 +28,6 @@ Rbsz = ETHERMAXTU + 4, /* 4 for CRC */ }; -extern uchar arge0mac[Eaddrlen]; /* see rb config file */ -extern uchar arge1mac[Eaddrlen]; - typedef struct Arge Arge; typedef struct Ctlr Ctlr; typedef struct Desc Desc; @@ -282,9 +275,7 @@ /* receiver */ Rendez rrendez; - uint rintr; /* count */ int pktstoread; /* flag */ - int discard; /* rx descriptors */ Desc* rdba; /* base address */ Block** rd; @@ -294,7 +285,6 @@ /* transmitter */ Rendez trendez; - uint tintr; /* count */ int pktstosend; /* flag */ int ntq; /* tx descriptors */ @@ -302,18 +292,22 @@ Block** td; uint tdh; /* head */ uint tdt; /* tail */ + + /* stats */ + uint rintr; /* count */ + int discard; + uint tintr; /* count */ }; struct Etherif { uintptr regs; int irq; - uchar *mac; int phymask; }; static Etherif etherifs[] = { - { 0x1a000000, ILenet0, arge0mac, 1<<4 }, - { 0x19000000, ILenet1, arge1mac, MASK(4) }, + { 0x1a000000, ILenet0, 1<<4 }, + { 0x19000000, ILenet1, MASK(4) }, }; static Ether *etherxx[MaxEther]; @@ -381,7 +375,7 @@ Swglobalmtumask = 0x7fff, }; -#ifdef NOTYET +#ifdef INIT_SWITCH void * devicegetparent(int) { @@ -1051,17 +1045,14 @@ delay(100); } - /* - * Set all Ethernet address registers to the same initial values - * set all four addresses to 66-88-aa-cc-dd-ee - */ eaddr = ether->ea; arge->staaddr1 = eaddr[2]<<24 | eaddr[3]<<16 | eaddr[4]<<8 | eaddr[5]; arge->staaddr2 = eaddr[0]<< 8 | eaddr[1]; - arge->fifocfg[0] = Fifocfg0all << Fifocfg0enshift; /* undocumented magic */ - arge->fifocfg[1] = 0x0fff0000; /* undocumented magic */ - arge->fifocfg[2] = 0x00001fff; /* undocumented magic */ + /* undocumented magic */ + arge->fifocfg[0] = Fifocfg0all << Fifocfg0enshift; + arge->fifocfg[1] = 0x0fff0000; + arge->fifocfg[2] = 0x00001fff; arge->fiforxfiltmatch = Ffmatchdflt; arge->fiforxfiltmask = Ffmaskdflt; @@ -1121,11 +1112,14 @@ /* * strategy: RouterBOOT has initialised arge0, try to leave it alone. + * sadly, staaddr[12] seem to have been tampered with. * copy arge0 registers to arge1, with a few exceptions. */ static int athreset(Ether *ether) { + char *p; + uchar zeromac[Eaddrlen]; Arge *arge; Ctlr *ctlr; Etherif *ep; @@ -1146,7 +1140,13 @@ ether->port = (uint)arge; ether->irq = ep->irq; - memmove(ether->ea, ep->mac, Eaddrlen); + if (rbconf.ether0mac && (p = strchr(rbconf.ether0mac, '='))) + parseether(ether->ea, p+1); + if(memcmp(ether->ea, zeromac, sizeof zeromac) == 0) + panic("ether%d: no mac", ether->ctlrno); + ether->ea[5] += ether->ctlrno; + if (ether->ea[5] == 0) + ether->ea[4]++; ether->ifstat = ifstat; ether->promiscuous = promiscuous; ether->multicast = multicast; @@ -1155,6 +1155,9 @@ athhwreset(ether); return 0; } + +extern int sprint(char*, char*, ...); +#pragma varargck argpos sprint 2 static Ether* etherprobe(int ctlrno) diff -Nru /n/sources/plan9/sys/src/9/rb/faultmips.c /sys/src/9/rb/faultmips.c --- /n/sources/plan9/sys/src/9/rb/faultmips.c Wed May 14 14:44:59 2014 +++ /sys/src/9/rb/faultmips.c Wed May 7 00:00:00 2014 @@ -226,10 +226,10 @@ } /* - * called in syscallfmt.c, sysfile.c, sysproc.c + * called in sysfile.c */ void -validalign(uintptr addr, unsigned align) +validalign(ulong addr, ulong align) { /* * Plan 9 is a 32-bit O/S, and the hardware it runs on diff -Nru /n/sources/plan9/sys/src/9/rb/fns.h /sys/src/9/rb/fns.h --- /n/sources/plan9/sys/src/9/rb/fns.h Wed May 14 14:45:00 2014 +++ /sys/src/9/rb/fns.h Wed Jun 13 00:00:00 2018 @@ -12,11 +12,11 @@ void coherence(void); void cycles(uvlong *); void dcflush(void*, ulong); +void validalign(ulong, ulong); void faultmips(Ureg*, int, int); ulong fcr31(void); void firmware(int); void fpclear(void); -void fpsave(FPsave *); void fptrap(Ureg*); int fpuemu(Ureg *); void fpwatch(Ureg *); @@ -122,11 +122,13 @@ void touser(uintptr); void unleash(void); #define userureg(ur) ((ur)->status & KUSER) -void validalign(uintptr, unsigned); void vecinit(void); void vector0(void); void vector100(void); void vector180(void); +void* vmap(uintptr, usize); +int vmapsync(ulong); +void vunmap(void*, usize); void wdogreset(void); void wrcompare(ulong); void wrcount(ulong); diff -Nru /n/sources/plan9/sys/src/9/rb/fpimips.c /sys/src/9/rb/fpimips.c --- /n/sources/plan9/sys/src/9/rb/fpimips.c Tue Jul 23 00:38:26 2013 +++ /sys/src/9/rb/fpimips.c Tue Sep 29 00:00:00 2015 @@ -37,9 +37,9 @@ #define dbgstuck _dbgstuck #else #define DBG(bits) (0) -#define internsane(i, ur) do { USED(ur); } while(0) -#define intpr(i, reg, fmt, ufp) do {} while(0) -#define dbgstuck(pc, ur, ufp) do {} while(0) +#define internsane(i, ur) do { USED(i, ur); } while(0) +#define intpr(i, reg, fmt, ufp) do { USED(i, reg, fmt, ufp); } while(0) +#define dbgstuck(pc, ur, ufp) do { USED(pc, ur, ufp); } while(0) #endif #define OFR(memb) (uintptr)&((Ureg*)0)->memb /* offset into Ureg of memb */ @@ -306,19 +306,15 @@ /* debugging: print internal representation of an fp reg */ static void -_intpr(Internal *i, int reg, int fmt, FPsave *ufp) +_intpr(Internal *i, uint reg, int fmt, FPsave *) { - USED(i); + USED(i, reg, fmt); if (!(DBG(Dbgregs))) return; - if (fmt == Fdouble && reg < 31) - iprint("\tD%02d: l %08lux h %08lux =\ts %d e %04d h %08lux l %08lux\n", - reg, FREG(ufp, reg), FREG(ufp, reg+1), - i->s, i->e, i->h, i->l); - else - iprint("\tF%02d: %08lux =\ts %d e %04d h %08lux l %08lux\n", - reg, FREG(ufp, reg), - i->s, i->e, i->h, i->l); + if (reg < Nfpregs) + iprint("\t%c%02d: %c e %04d %08lux%08lux\n", + (fmt == Fdouble || fmt == Fvlong? 'D': 'F'), reg, + (i->s? '-': '+'), i->e, i->h, i->l); delay(75); } @@ -364,27 +360,25 @@ switch (fmt) { case Ffloat: fpis2i(&intrn, &FREG(ufp, rm)); - internsane(&intrn, ur); - fpii2d(&d, &intrn); break; case Fdouble: dreg2dbl(&d, rm, ufp); break; case Flong: fpiw2i(&intrn, &FREG(ufp, rm)); - internsane(&intrn, ur); - fpii2d(&d, &intrn); break; case Fvlong: vreg2dbl(&d, rm, ufp); fpiv2i(&intrn, &d); + break; + } + if (fmt != Fdouble) { + if (DBG(Dbgregs)) + intpr(&intrn, rd, Fdouble, ufp); internsane(&intrn, ur); fpii2d(&d, &intrn); - break; } dbl2dreg(rd, &d, ufp); - if (fmt != Fdouble && DBG(Dbgregs)) - intpr(&intrn, rm, Fdouble, ufp); } /* convert fmt (rm) to single (rd) */ @@ -412,7 +406,7 @@ } if (fmt != Ffloat) { if(DBG(Dbgregs)) - intpr(&intrn, rm, Ffloat, ufp); + intpr(&intrn, rd, Ffloat, ufp); internsane(&intrn, ur); fpii2s(&FREG(ufp, rd), &intrn); } @@ -443,7 +437,7 @@ } if (fmt != Flong) { if(DBG(Dbgregs)) - intpr(&intrn, rm, Flong, ufp); + intpr(&intrn, rd, Flong, ufp); internsane(&intrn, ur); fpii2w((long *)&FREG(ufp, rd), &intrn); } @@ -474,7 +468,7 @@ } if (fmt != Fvlong) { if(DBG(Dbgregs)) - intpr(&intrn, rm, Fvlong, ufp); + intpr(&intrn, rd, Fvlong, ufp); internsane(&intrn, ur); fpii2v((vlong *)&FREG(ufp, rd), &intrn); } @@ -525,7 +519,7 @@ fld(int d, ulong ea, int n, FPsave *ufp) { if(DBG(Dbgmoves)) - iprint("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d); + iprint("MOV%c\t%#lux, F%d\n", n==8? 'D': 'F', ea, d); if (n == 4) memmove(&FREG(ufp, d), (void *)ea, 4); else if (n == 8){ @@ -541,7 +535,7 @@ fst(ulong ea, int s, int n, FPsave *ufp) { if(DBG(Dbgmoves)) - iprint("MOV%c F%d,#%lux\n", n==8? 'D': 'F', s, ea); + iprint("MOV%c\tF%d,%#lux\n", n==8? 'D': 'F', s, ea); if (n == 4) memmove((void *)ea, &FREG(ufp, s), 4); else if (n == 8){ @@ -837,7 +831,7 @@ qunlock(&watchlock); ur->pc = ufp->fpdelaypc; /* pc of fp branch */ - ur->cause &= BD; /* take no chances */ + ur->cause &= ~BD; /* take no chances */ ufp->fpstatus = ufp->fpdelaysts; followbr(ur); /* sets ur->pc to fp branch target */ if (DBG(Dbgdelay)) @@ -1213,7 +1207,7 @@ } static FPsave * -fpinit(Ureg *ur) +fpinit(Ureg *) { int i, n; Double d; @@ -1241,7 +1235,6 @@ else i = n; tmp = fpconst[i]; - internsane(&tmp, ur); fpii2d(&d, &tmp); dbl2dreg(n, &d, ufp); } diff -Nru /n/sources/plan9/sys/src/9/rb/init9.s /sys/src/9/rb/init9.s --- /n/sources/plan9/sys/src/9/rb/init9.s Fri May 17 19:32:33 2013 +++ /sys/src/9/rb/init9.s Wed Mar 11 00:00:00 2020 @@ -5,4 +5,4 @@ MOVW R1, 4(R29) MOVW R2, 8(R29) JAL startboot(SB) - + NOP diff -Nru /n/sources/plan9/sys/src/9/rb/initreboot.s /sys/src/9/rb/initreboot.s --- /n/sources/plan9/sys/src/9/rb/initreboot.s Wed Jun 19 18:25:33 2013 +++ /sys/src/9/rb/initreboot.s Wed Mar 11 00:00:00 2020 @@ -9,11 +9,12 @@ TEXT _main(SB), $0 MOVW $setR30(SB), R30 JMP main(SB) + NOP /* target for JALRHB in BARRIERS */ TEXT ret(SB), $-4 JMP (R22) - NOP + NOP TEXT setsp(SB), $-4 MOVW R1, SP @@ -26,6 +27,18 @@ RETURN /* + * next_kernel(entry, r4, r5, r6, r7) + * set R4-R7 for next kernel, then jump to it. + */ +TEXT next_kernel(SB), $-4 + MOVW r4+4(FP), R4 + MOVW r5+8(FP), R5 + MOVW r6+12(FP), R6 + MOVW r7+16(FP), R7 + JMP (R1) + NOP + +/* * cache manipulation */ @@ -42,7 +55,7 @@ SUBU $CACHELINESZ, R9 ADDU $CACHELINESZ, R1 BGTZ R9, iccache - NOP + NOP MOVW R0, R1 /* index, not address */ MOVW $DCACHESIZE, R9 @@ -51,10 +64,10 @@ SUBU $CACHELINESZ, R9 ADDU $CACHELINESZ, R1 BGTZ R9, dccache - NOP + NOP SYNC - MOVW R10, M(STATUS) + MOVW R10, M(STATUS) /* restore processor level */ JRHB(31) /* return and clear all hazards */ SCHED diff -Nru /n/sources/plan9/sys/src/9/rb/io.h /sys/src/9/rb/io.h --- /n/sources/plan9/sys/src/9/rb/io.h Wed Jul 3 21:11:08 2013 +++ /sys/src/9/rb/io.h Tue Mar 20 00:00:00 2018 @@ -300,8 +300,6 @@ #define PCIWINDOW 0 #define PCIWADDR(va) (PADDR(va)+PCIWINDOW) -#define ISAWINDOW 0 -#define ISAWADDR(va) (PADDR(va)+ISAWINDOW) /* SMBus transactions */ enum diff -Nru /n/sources/plan9/sys/src/9/rb/l.s /sys/src/9/rb/l.s --- /n/sources/plan9/sys/src/9/rb/l.s Thu Sep 19 00:08:25 2013 +++ /sys/src/9/rb/l.s Sat Jul 4 00:00:00 2020 @@ -12,6 +12,12 @@ * Boot only processor */ TEXT start(SB), $-4 + /* save parameters passed from routerboot */ + MOVW R4, R19 /* argc */ + MOVW R5, R20 /* argv */ + MOVW R6, R21 /* envp */ + MOVW R7, R23 /* memory size */ + MOVW $setR30(SB), R30 PUTC('9', R1, R2) @@ -21,7 +27,7 @@ CONST(SANITY, R2) SUBU R1, R2, R2 BNE R2, insane - NOP + NOP MOVW R0, M(COMPARE) EHB @@ -42,7 +48,7 @@ MOVW R1, M(CACHEECC) /* aka ErrCtl */ EHB JAL cleancache(SB) - NOP + NOP MOVW $TLBROFF, R1 MOVW R1, M(WIRED) @@ -68,18 +74,34 @@ MOVW R0, (R1) ADDU $BY2WD, R1 BNE R1, SP, clrmach - NOP + NOP MOVW R0, 0(R(MACH)) /* m->machno = 0 */ MOVW R0, R(USER) /* up = nil */ - /* zero bss, byte-by-byte */ + /* zero bss */ MOVW $edata(SB), R1 MOVW $end(SB), R2 clrbss: - MOVB R0, (R1) - ADDU $1, R1 + MOVW R0, (R1) + ADDU $BY2WD, R1 BNE R1, R2, clrbss - NOP + NOP + + MOVW R0, HI + MOVW R0, LO + +PUTC('\r', R1, R2) +PUTC('\n', R1, R2) + + /* + * restore parameters passed from routerboot and + * pass them as arguments to main(). + */ + SUB $(5*4), SP /* reserve space for args to main() + link */ + MOVW R19, R1 /* argc */ + MOVW R20, 8(SP) /* argv */ + MOVW R21, 12(SP) /* envp */ + MOVW R23, 16(SP) /* memory size */ MOVW $0x16, R16 MOVW $0x17, R17 @@ -90,22 +112,20 @@ MOVW $0x22, R22 MOVW $0x23, R23 - MOVW R0, HI - MOVW R0, LO - -PUTC('\r', R1, R2) -PUTC('\n', R1, R2) JAL main(SB) - NOP + NOP + + /* shouldn't get here */ CONST(ROM, R1) JMP (R1) /* back to the rom */ + NOP #define PUT(c) PUTC(c, R1, R2) #define DELAY(lab) \ CONST(34000000, R3); \ lab: SUBU $1, R3; \ BNE R3, lab; \ - NOP + NOP insane: /* @@ -119,12 +139,12 @@ PUT('\r'); PUT('\n'); DELAY(dl5) CONST(ROM, R1) JMP (R1) /* back to the rom */ - NOP + NOP /* target for JALRHB in BARRIERS */ TEXT ret(SB), $-4 JMP (R22) - NOP + NOP /* print R1 in hex; clobbers R3—8 */ TEXT printhex(SB), $-4 @@ -137,16 +157,16 @@ AND $0xf, R6 SGTU R6, R7, R8 BEQ R8, prdec /* branch if R6 <= 9 */ - NOP + NOP ADD $('a'-10), R6 JMP prchar - NOP + NOP prdec: ADD $'0', R6 prchar: PUTC(R6, R3, R4) BNE R5, prtop - NOP + NOP RETURN /* @@ -154,6 +174,7 @@ * - argument is stack pointer to user */ TEXT touser(SB), $-4 + DI(0) /* ensure intrs see consistent M(STATUS) */ MOVW R1, SP MOVW $(UTZERO+32), R2 /* header appears in text */ MOVW R2, M(EPC) @@ -193,7 +214,7 @@ TEXT wait(SB), $-4 WAIT - NOP + NOP MOVW R1, M(STATUS) /* interrupts restored */ EHB @@ -238,6 +259,14 @@ RETURN /* + * bit twiddling + */ + +TEXT clz(SB), $-4 /* dest = clz(src): count leading zeroes */ + CLZ(1, 1) + RETURN + +/* * process switching */ @@ -276,9 +305,9 @@ EHB MOVW M(INDEX), R1 BGEZ R1, index /* if tlb entry found, use it */ - NOP + NOP BEQ R4, dont /* not valid? cf. kunmap */ - NOP + NOP MOVW M(RANDOM), R1 /* write random tlb entry */ MOVW R1, M(INDEX) index: @@ -365,7 +394,7 @@ EHB MOVW M(INDEX), R1 BLTZ R1, gettlbp1 /* if no tlb entry found, return */ - NOP + NOP EHB TLBR /* read indexed tlb entry */ EHB @@ -399,14 +428,16 @@ /* * exceptions. + * * mips promises that there will be no current hazards upon entry * to exception handlers. */ + /* will be copied into low memory vectors; must fit in 32 words */ TEXT vector0(SB), $-4 MOVW $utlbmiss(SB), R26 JMP (R26) - NOP + NOP /* * compute stlb hash index. @@ -416,9 +447,8 @@ * stir in swizzled asid; we get best results with asid in both high & low bits. * * page = tlbvirt >> (PGSHIFT+1); // ignoring even/odd bit - * R27 = ((tlbvirt<<(STLBLOG-8) ^ (uchar)tlbvirt ^ page ^ - * ((page & (MASK(HIPFNBITS) << STLBLOG)) >> HIPFNBITS)) & - * (STLBSIZE-1)) * 12; + * arg = (tlbvirt<<(STLBLOG-8) ^ (uchar)tlbvirt ^ page ^ + * ((page & (MASK(HIPFNBITS) << STLBLOG)) >> HIPFNBITS)) & (STLBSIZE-1); */ #define STLBHASH(arg, tmp, tmp2) \ MOVW arg, tmp2; \ @@ -430,10 +460,24 @@ MOVW tmp2, tmp; /* asid in low byte */ \ SLL $(STLBLOG-8), tmp; /* move asid to high bits */ \ XOR tmp, arg; /* include asid in high bits too */ \ - AND $0xff, tmp2, tmp; /* asid in low byte */ \ + MOVBU tmp2, tmp; /* asid in low byte of tlbvirt */ \ XOR tmp, arg; /* include asid in low bits */ \ CONST (STLBSIZE-1, tmp); \ AND tmp, arg /* chop to fit */ +/* + * vc -S generated essentially this, which uses 4 registers and + * R28 for big constants: + MOVW R1, R4 + SRL $(PGSHIFT+1), R1, R3 // page = tlbvirt>>(PGSHIFT+1) + SLL $(STLBLOG-8), R1, R1 // tlbvirt<<(STLBLOG-8) + MOVBU R4, R5 // (uchar)tlbvirt + XOR R5, R1 + XOR R3, R1 + AND $(MASK(HIPFNBITS) << STLBLOG), R3 + SRL $HIPFNBITS, R3 + XOR R3, R1 + AND $(STLBSIZE-1), R1 // chop to fit + */ TEXT utlbmiss(SB), $-4 /* @@ -441,27 +485,25 @@ * it's unsaved so far. avoid R24 (up in kernel) and R25 (m in kernel). */ /* update statistics */ - CONST (MACHADDR, R26) /* R26 = m-> */ - MOVW 16(R26), R27 + CONST (MACHADDR+16, R26) /* R26 = &m->tlbfault */ + MOVW (R26), R27 ADDU $1, R27 - MOVW R27, 16(R26) /* m->tlbfault++ */ + MOVW R27, (R26) /* m->tlbfault++ */ MOVW R23, M(DESAVE) /* save R23 */ -#ifdef KUTLBSTATS +#ifdef KUTLBSTATS + ADDU $4, R26 /* &m->ktlbfault */ + MOVW M(STATUS), R23 AND $KUSER, R23 BEQ R23, kmiss - - MOVW 24(R26), R27 - ADDU $1, R27 - MOVW R27, 24(R26) /* m->utlbfault++ */ - JMP either + NOP + ADDU $4, R26 /* m->utlbfault */ kmiss: - MOVW 20(R26), R27 + MOVW (R26), R27 ADDU $1, R27 - MOVW R27, 20(R26) /* m->ktlbfault++ */ -either: + MOVW R27, (R26) /* m->[ku]tlbfault++ */ #endif /* compute stlb index */ @@ -470,7 +512,7 @@ STLBHASH(R27, R26, R23) MOVW M(DESAVE), R23 /* restore R23 */ - /* scale to a byte index (multiply by 12) */ + /* scale to a byte index (multiply by 12 [3 ulongs]) */ SLL $1, R27, R26 /* × 2 */ ADDU R26, R27 /* × 3 */ SLL $2, R27 /* × 12 */ @@ -482,22 +524,22 @@ MOVW M(BADVADDR), R26 AND $BY2PG, R26 BNE R26, utlbodd /* odd page? */ - NOP + NOP utlbeven: MOVW 4(R27), R26 /* R26 = m->stb[hash].phys0 */ BEQ R26, stlbm /* nothing cached? do it the hard way */ - NOP + NOP MOVW R26, M(TLBPHYS0) EHB MOVW 8(R27), R26 /* R26 = m->stb[hash].phys1 */ JMP utlbcom - MOVW R26, M(TLBPHYS1) /* branch delay slot */ + MOVW R26, M(TLBPHYS1) /* branch delay slot */ utlbodd: MOVW 8(R27), R26 /* R26 = m->stb[hash].phys1 */ BEQ R26, stlbm /* nothing cached? do it the hard way */ - NOP + NOP MOVW R26, M(TLBPHYS1) EHB MOVW 4(R27), R26 /* R26 = m->stb[hash].phys0 */ @@ -508,10 +550,10 @@ MOVW M(TLBVIRT), R26 MOVW (R27), R27 /* R27 = m->stb[hash].virt */ BEQ R27, stlbm /* nothing cached? do it the hard way */ - NOP + NOP /* is the stlb entry for the right virtual address? */ BNE R26, R27, stlbm /* M(TLBVIRT) != m->stb[hash].virt? */ - NOP + NOP /* if an entry exists, overwrite it, else write a random one */ CONST (PGSZ, R27) @@ -521,38 +563,36 @@ EHB MOVW M(INDEX), R26 BGEZ R26, utlindex /* if tlb entry found, rewrite it */ - EHB /* delay slot */ + EHB /* delay slot */ TLBWR /* else write random tlb entry */ ERET utlindex: TLBWI /* write indexed tlb entry */ ERET -/* not in the stlb either; make trap.c figure it out */ -stlbm: +/* + * will be copied into low memory vectors; must fit in 32 words + * and avoid relative branches. + */ +TEXT vector100(SB), $-4 /* cache trap */ +TEXT vector180(SB), $-4 /* most exceptions */ +stlbm: /* not in the stlb either; make trap.c figure it out */ MOVW $exception(SB), R26 JMP (R26) - NOP + NOP TEXT stlbhash(SB), $-4 STLBHASH(R1, R2, R3) RETURN -TEXT vector100(SB), $-4 - MOVW $exception(SB), R26 - JMP (R26) - NOP - -TEXT vector180(SB), $-4 - MOVW $exception(SB), R26 - JMP (R26) - NOP - +/* + * exceptions other than tlb miss come here directly. + */ TEXT exception(SB), $-4 MOVW M(STATUS), R26 AND $KUSER, R26, R27 BEQ R27, waskernel - MOVW SP, R27 /* delay slot */ + MOVW SP, R27 /* delay slot */ wasuser: CONST (MACHADDR, SP) /* m-> */ @@ -563,7 +603,7 @@ MOVW R31, Ureg_r31(SP) JAL savereg1(SB) - NOP + NOP MOVW R30, Ureg_r30(SP) MOVW R(MACH), Ureg_r25(SP) @@ -577,17 +617,17 @@ AND $(EXCMASK<<2), R26, R1 SUBU $(CSYS<<2), R1 BNE R1, notsys - NOP + NOP /* the carrera does this: */ // ADDU $8, SP, R1 /* first arg for syscall */ MOVW SP, R1 /* first arg for syscall */ - JAL syscall(SB) - SUBU $Notuoffset, SP /* delay slot */ + JAL syscall(SB) /* to C */ + SUBU $Notuoffset, SP /* delay slot */ sysrestore: JAL restreg1(SB) - ADDU $Notuoffset, SP /* delay slot */ + ADDU $Notuoffset, SP /* delay slot */ MOVW Ureg_r31(SP), R31 MOVW Ureg_status(SP), R26 @@ -595,36 +635,36 @@ MOVW R26, M(STATUS) EHB MOVW Ureg_pc(SP), R26 /* old pc */ +erettor26: MOVW Ureg_sp(SP), SP MOVW R26, M(EPC) ERET notsys: JAL savereg2(SB) - NOP + NOP /* the carrera does this: */ // ADDU $8, SP, R1 /* first arg for trap */ MOVW SP, R1 /* first arg for trap */ - JAL trap(SB) - SUBU $Notuoffset, SP /* delay slot */ + JAL trap(SB) /* to C for user trap */ + SUBU $Notuoffset, SP /* delay slot */ ADDU $Notuoffset, SP restore: JAL restreg1(SB) - NOP + NOP JAL restreg2(SB) /* restores R28, among others */ - NOP + NOP MOVW Ureg_r30(SP), R30 MOVW Ureg_r31(SP), R31 MOVW Ureg_r25(SP), R(MACH) MOVW Ureg_r24(SP), R(USER) - MOVW Ureg_sp(SP), SP - MOVW R26, M(EPC) - ERET + JMP erettor26 + NOP waskernel: SUBU $UREGSIZE, SP @@ -633,21 +673,21 @@ MOVW R31, Ureg_r31(SP) JAL savereg1(SB) - NOP + NOP JAL savereg2(SB) - NOP + NOP /* the carrera does this: */ // ADDU $8, SP, R1 /* first arg for trap */ - MOVW SP, R1 /* first arg for trap */ - JAL trap(SB) - SUBU $Notuoffset, SP /* delay slot */ + MOVW SP, R1 /* first arg for trap */ + JAL trap(SB) /* to C for kernel trap */ + SUBU $Notuoffset, SP /* delay slot */ ADDU $Notuoffset, SP JAL restreg1(SB) - NOP + NOP /* * if about to return to `wait', interrupt arrived just before @@ -658,21 +698,20 @@ MOVW $wait(SB), R1 SUBU R1, R31 BNE R31, notwait - NOP + NOP ADD $BY2WD, R26 /* advance saved pc */ MOVW R26, Ureg_pc(SP) notwait: JAL restreg2(SB) /* restores R28, among others */ - NOP + NOP MOVW Ureg_r31(SP), R31 - MOVW Ureg_sp(SP), SP - MOVW R26, M(EPC) - ERET + JMP erettor26 + NOP TEXT forkret(SB), $0 JMP sysrestore - MOVW R0, R1 /* delay slot; child returns 0 */ + MOVW R0, R1 /* delay slot; child returns 0 */ /* * save mandatory registers. @@ -795,14 +834,6 @@ MOVW Ureg_pc(SP), R26 RETURN -#ifdef OLD_MIPS_EXAMPLE -/* this appears to be a dreg from the distant past */ -TEXT rfnote(SB), $0 - MOVW R1, R26 /* 1st arg is &uregpointer */ - JMP restore - SUBU $(BY2WD), R26, SP /* delay slot: pc hole */ -#endif - /* * degenerate floating-point stuff */ @@ -833,36 +864,7 @@ SC(2, 3) NOP BEQ R3, tas1 - NOP - RETURN - -TEXT ainc(SB), $0 - MOVW R1, R2 /* address of counter */ -loop: - MOVW $1, R3 - LL(2, 1) - NOP - ADDU R1, R3 - MOVW R3, R1 /* return new value */ - SC(2, 3) - NOP - BEQ R3, loop - NOP - RETURN - -TEXT adec(SB), $0 - SYNC - MOVW R1, R2 /* address of counter */ -loop1: - MOVW $-1, R3 - LL(2, 1) - NOP - ADDU R1, R3 - MOVW R3, R1 /* return new value */ - SC(2, 3) - NOP - BEQ R3, loop1 - NOP + NOP RETURN /* used by the semaphore implementation */ @@ -873,7 +875,7 @@ LL(2, 1) /* R1 = (R2) */ NOP BNE R1, R3, fail - NOP + NOP MOVW R4, R1 SC(2, 1) /* (R2) = R1 if (R2) hasn't changed; R1 = success */ NOP @@ -905,7 +907,7 @@ CACHE PI+HINV, (R8) /* invalidate in I */ SUBU $CACHELINESZ, R9 BGTZ R9, icflush1 - ADDU $CACHELINESZ, R8 /* delay slot */ + ADDU $CACHELINESZ, R8 /* delay slot */ BARRIERS(7, R7, ic2hb); /* return to kseg0 (cached) */ MOVW R10, M(STATUS) @@ -927,7 +929,7 @@ CACHE PD+HWBI, (R8) /* flush & invalidate in D */ SUBU $CACHELINESZ, R9 BGTZ R9, dcflush1 - ADDU $CACHELINESZ, R8 /* delay slot */ + ADDU $CACHELINESZ, R8 /* delay slot */ SYNC EHB MOVW R10, M(STATUS) @@ -944,7 +946,7 @@ CACHE PI+IWBI, (R1) /* flush & invalidate I by index */ SUBU $CACHELINESZ, R9 BGTZ R9, iccache - ADDU $CACHELINESZ, R1 /* delay slot */ + ADDU $CACHELINESZ, R1 /* delay slot */ BARRIERS(7, R7, cc2hb); /* return to kseg0 (cached) */ @@ -954,7 +956,7 @@ CACHE PD+IWBI, (R1) /* flush & invalidate D by index */ SUBU $CACHELINESZ, R9 BGTZ R9, dccache - ADDU $CACHELINESZ, R1 /* delay slot */ + ADDU $CACHELINESZ, R1 /* delay slot */ SYNC MOVW R10, M(STATUS) diff -Nru /n/sources/plan9/sys/src/9/rb/main.c /sys/src/9/rb/main.c --- /n/sources/plan9/sys/src/9/rb/main.c Thu Jul 25 22:46:17 2013 +++ /sys/src/9/rb/main.c Wed Mar 25 00:00:00 2020 @@ -36,8 +36,10 @@ Conf conf; FPsave initfp; +Rbconf rbconf; int normalprint; +ulong memsize; char * getconf(char *) @@ -156,17 +158,59 @@ return -1; } +/* + * parse args kmac=AA:BB:CC:DD:EE:FF for ether0 mac, mem=256M, + * HZ=340000000, console=ttyS0,115200. + * args seem to live above 8MB, where they are likely to be clobbered + * by kernel allocations, so make copies for rebooting. + * + * at this early stage, we can't use the usual kernel memory allocators, + * thus we can't use kstrdup. + */ +static void +saverbconfig(int argc, char **argv) +{ + int i; + char *p; + static char ether0mac[32], mem[16], hz[16], console[32]; + + if (argv == nil) + return; + rbconf.ether0mac = ether0mac; + rbconf.memsize = mem; + rbconf.hz = hz; + rbconf.console = console; + for (i = 0; i < argc; i++) { + p = argv[i]; + if (strncmp(p, "kmac=", 5) == 0) + strncpy(rbconf.ether0mac, p, sizeof ether0mac); + else if (strncmp(p, "mem=", 4) == 0) + strncpy(rbconf.memsize, p, sizeof mem); + else if (strncmp(p, "HZ=", 3) == 0) + strncpy(rbconf.hz, p, sizeof hz); + else if (strncmp(p, "console=", 8) == 0) + strncpy(rbconf.console, p, sizeof console); + } + memsize = 256*MB; /* routerboard default */ + p = strchr(rbconf.memsize, '='); + if (p) + memsize = atoi(p+1) * MB; +} + +/* arguments come from routerboot; only argc and argv are non-zero. */ void -main(void) +main(int argc, char **argv, char **envp, ulong memsz) { stopwdog(); /* tranquilise the dog */ optionsinit("/boot/boot boot"); + saverbconfig(argc, argv); + USED(envp, memsz); + confinit(); savefpregs(&initfp); - machinit(); /* calls clockinit */ active.exiting = 0; - active.machs = 1; + cpuactive(0); kmapinit(); xinit(); @@ -176,7 +220,7 @@ vecinit(); normalprint = 1; - print("\nPlan 9\n"); + print("\nPlan 9 from Bell Labs (mips)\n"); prcpuid(); if (PTECACHABILITY == PTENONCOHERWT) print("caches configured as write-through\n"); @@ -253,7 +297,7 @@ if(!waserror()){ ksetenv("cputype", "mips", 0); - snprint(buf, sizeof buf, "mips %s rb450g", conffile); + snprint(buf, sizeof buf, "mips %s", conffile); ksetenv("terminal", buf, 0); if(cpuserver) ksetenv("service", "cpu", 0); @@ -288,7 +332,7 @@ * of the argument list checked in syscall. */ i = oargblen+1; - p = UINT2PTR(STACKALIGN(base + BY2PG - Stkheadroom - i)); + p = (char *)STACKALIGN(base + BY2PG - Stkheadroom - i); memmove(p, oargb, i); /* @@ -300,7 +344,7 @@ * not the usual (int argc, char* argv[]) */ av = (char**)(p - (oargc+1)*sizeof(char*)); - ssize = base + BY2PG - PTR2UINT(av); + ssize = base + BY2PG - (uintptr)av; for(i = 0; i < oargc; i++) *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BY2PG); *av = nil; @@ -434,16 +478,16 @@ ilock(&active); if(ispanic) active.ispanic = ispanic; - else if(m->machno == 0 && (active.machs & (1<machno)) == 0) + else if(m->machno == 0 && !iscpuactive(m->machno)) active.ispanic = 0; - once = active.machs & (1<machno); + once = iscpuactive(m->machno); /* * setting exiting will make hzclock() on each processor call exit(0), * which calls shutdown(0) and idles non-bootstrap cpus and returns * on bootstrap processors (to permit a reboot). clearing our bit * in machs avoids calling exit(0) from hzclock() on this processor. */ - active.machs &= ~(1<machno); + cpuinactive(m->machno); active.exiting = 1; iunlock(&active); @@ -455,7 +499,7 @@ ms = MAXMACH * 1000; for(; ms > 0; ms -= TK2MS(2)){ delay(TK2MS(2)); - if(active.machs == 0 && consactive() == 0) + if(active.nmachs == 0 && consactive() == 0) break; } delay(100); @@ -463,14 +507,25 @@ /* * the new kernel is already loaded at address `code' - * of size `size' and entry point `entry'. + * of size `size' and physical entry point `entry'. */ void reboot(void *entry, void *code, ulong size) { - void (*f)(ulong, ulong, ulong); + Rbconf *rbc; + void (*f)(void *, ulong, ulong, ulong); writeconf(); + /* + * copy rbconf and contents into allocated memory, thus safe from + * being overwritten by the new kernel in the reboot trampoline + * code below. + */ + rbc = smalloc(sizeof *rbc); + kstrdup(&rbc->ether0mac, rbconf.ether0mac); + kstrdup(&rbc->memsize, rbconf.memsize); + kstrdup(&rbc->hz, rbconf.hz); + kstrdup(&rbc->console, rbconf.console); /* * the boot processor is cpu0. execute this function on it @@ -513,13 +568,16 @@ /* setup reboot trampoline function */ f = (void*)REBOOTADDR; memmove(f, rebootcode, sizeof(rebootcode)); + dcflush(f, sizeof(rebootcode)); icflush(f, sizeof(rebootcode)); setstatus(BEV); /* also, kernel mode, no interrupts */ coherence(); /* off we go - never to return */ - (*f)((ulong)entry, (ulong)code, size); + if (((ulong)entry & KSEGM) == 0) /* physical address? */ + entry = KADDR(entry); /* make it kernel virtual */ + (*f)(rbc, (ulong)entry, (ulong)code, size); panic("loaded kernel returned!"); } @@ -534,14 +592,14 @@ delay(1000); lock(&active); - active.machs &= ~(1<machno); + cpuinactive(m->machno); active.exiting = 1; unlock(&active); spllo(); print("cpu %d exiting\n", m->machno); timer = 0; - while(active.machs || consactive()) { + while(active.nmachs || consactive()) { if(timer++ > 400) break; delay(10); @@ -581,14 +639,15 @@ void confinit(void) { + char *p; ulong kpages, ktop; /* * divide memory twixt user pages and kernel. */ conf.mem[0].base = ktop = PADDR(PGROUND((ulong)end)); - /* fixed memory on routerboard */ - conf.mem[0].npage = MEMSIZE/BY2PG - ktop/BY2PG; + assert(memsize > 16*MB); + conf.mem[0].npage = memsize/BY2PG - ktop/BY2PG; conf.npage = conf.mem[0].npage; conf.nuart = 1; @@ -601,11 +660,11 @@ conf.ialloc = (kpages/2)*BY2PG; kpages *= BY2PG; - kpages -= conf.upages*sizeof(Page) - + conf.nproc*sizeof(Proc) - + conf.nimage*sizeof(Image) - + conf.nswap - + conf.nswppo*sizeof(Page*); + kpages -= conf.upages*sizeof(Page) /* palloc.pages in pageinit */ + + conf.nproc*sizeof(Proc) /* procalloc.free in procinit0 */ + + conf.nimage*sizeof(Image) /* imagealloc.free in initseg */ + + conf.nswap /* swapalloc.swmap in swapinit */ + + conf.nswppo*sizeof(Page*); /* iolist in swapinit */ mainmem->maxsize = kpages; /* @@ -614,7 +673,12 @@ */ m->machno = 0; m->speed = 680; /* initial guess at MHz, for rb450g */ - m->hz = m->speed * Mhz; + m->hz = 680 * Mhz; + p = strchr(rbconf.hz, '='); + if (p) { + m->hz = 2 * strtol(p+1, 0, 10); + m->speed = m->hz / Mhz; + } conf.nmach = 1; /* set up other configuration parameters */ diff -Nru /n/sources/plan9/sys/src/9/rb/mem.h /sys/src/9/rb/mem.h --- /n/sources/plan9/sys/src/9/rb/mem.h Tue Jul 23 00:28:29 2013 +++ /sys/src/9/rb/mem.h Tue May 26 00:00:00 2020 @@ -14,23 +14,15 @@ #define MAXBY2PG (16*1024) /* rounding for UTZERO in executables; see mkfile */ #define UTROUND(t) ROUNDUP((t), MAXBY2PG) -#ifndef BIGPAGES #define BY2PG 4096 /* bytes per page */ #define PGSHIFT 12 /* log2(BY2PG) */ #define PGSZ PGSZ4K #define MACHSIZE (2*BY2PG) -#else -/* 16K pages work very poorly */ -#define BY2PG (16*1024) /* bytes per page */ -#define PGSHIFT 14 /* log2(BY2PG) */ -#define PGSZ PGSZ16K -#define MACHSIZE BY2PG -#endif #define KSTACK 8192 /* Size of kernel stack */ #define WD2PG (BY2PG/BY2WD) /* words per page */ -#define MAXMACH 1 /* max # cpus system can run; see active.machs */ +#define MAXMACH 1 /* max # cpus system can run */ #define STACKALIGN(sp) ((sp) & ~7) /* bug: assure with alloc */ #define BLOCKALIGN 16 #define CACHELINESZ 32 /* mips24k */ @@ -261,16 +251,10 @@ #define PHYSCONS (KSEG1|0x18020000) /* i8250 uart */ #define PIDXSHFT 12 -#ifndef BIGPAGES +/* future ref.: no cache aliases are possible with pages of 16K or larger */ #define NCOLOR 8 #define PIDX ((NCOLOR-1)<>PIDXSHFT) % NCOLOR) -#else -/* no cache aliases are possible with pages of 16K or larger */ -#define NCOLOR 1 -#define PIDX 0 -#define getpgcolor(a) 0 -#endif #define KMAPSHIFT 15 #define PTEGLOBL (1<<0) @@ -294,10 +278,10 @@ #define PTEPID(n) (n) #define PTEMAPMEM (1024*1024) #define PTEPERTAB (PTEMAPMEM/BY2PG) -#define SEGMAPSIZE 512 +#define SEGMAPSIZE (ROUND(USTKTOP, PTEMAPMEM) / PTEMAPMEM) #define SSEGMAPSIZE 16 -#define STLBLOG 15 +#define STLBLOG 16 /* was 15 */ #define STLBSIZE (1<= KZERO || pa >= MEMSIZE) + if(pa >= KZERO || pa >= memsize) return 0; - return MEMSIZE - pa; + return memsize - pa; +} + +/* + * although needed by the pc port, this mapping can be trivial on our mips systems, + * which have less memory. + */ +void* +vmap(uintptr pa, usize) +{ + return UINT2PTR(KSEG0|pa); +} + +void +vunmap(void* v, usize size) +{ + /* + upafree(PADDR(v), size); + */ + USED(v, size); } diff -Nru /n/sources/plan9/sys/src/9/rb/notes/9rb.ms /sys/src/9/rb/notes/9rb.ms --- /n/sources/plan9/sys/src/9/rb/notes/9rb.ms Tue Jul 23 22:25:12 2013 +++ /sys/src/9/rb/notes/9rb.ms Mon Jun 8 00:00:00 2020 @@ -1,11 +1,16 @@ +.nr PS 11 +.nr VS 13 .FP palatino +. .TM +.DA 23 July 2013 .TL Plan 9 on the Mikrotik RB450G Routerboard .AU Geoff Collyer .AI .MH +. .NH 1 Motivation .LP @@ -57,7 +62,7 @@ The fix could be better, in particular the technique for keeping stores out of branch delay slots. .NH 2 -Driver for Undocumented Ethernet Controller +Driver for Undocumented Atheros 7161 Ethernet Controller .LP The FreeBSD Atheros .I arge @@ -151,11 +156,6 @@ (around 20k–30k per second). It probably doesn't help that one 16K page is half of the L1 data cache and one quarter of the L1 instruction cache. -.LP -Page size is controlled by -.CW BIGPAGES -in -.CW mem.h . .NH 3 Combined TLB Pool .LP @@ -179,11 +179,3 @@ .CW uarti8250.c that makes output work most of the time (characters do sometimes get dropped). -.LP -The Ethernet driver currently does not -dig out the MAC addresses from the hardware, -so you'll need to edit the -.CW rb -configuration file for each Routerboard; the format should be obvious. -I don't have the stomach to dig the MAC address out of the hardware -via SPI or whatever vile interface it requires. Binary files /n/sources/plan9/sys/src/9/rb/nvram and /sys/src/9/rb/nvram differ diff -Nru /n/sources/plan9/sys/src/9/rb/rb /sys/src/9/rb/rb --- /n/sources/plan9/sys/src/9/rb/rb Wed Jul 3 23:32:59 2013 +++ /sys/src/9/rb/rb Thu Mar 5 00:00:00 2020 @@ -9,15 +9,15 @@ mnt srv dup -# rtc +# rtc # no hardware tod clock ssl tls cap kprof - fs +# fs - ether netif + ether ethermii netif ip arp chandial inferno ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum uart link @@ -30,7 +30,6 @@ fpi fpimips fpimem - ethermii ip tcp @@ -38,15 +37,13 @@ ipifc icmp icmp6 - gre +# only used by mobile ip code +# gre ipmux esp port int cpuserver = 1; - uchar arge0mac[] = { 0xd4, 0xca, 0x6d, 0x7d, 0xf1, 0xce, }; - uchar arge1mac[] = { 0xd4, 0xca, 0x6d, 0x7d, 0xf1, 0xcf, }; -}; boot cpu tcp diff -Nru /n/sources/plan9/sys/src/9/rb/rebootcode.c /sys/src/9/rb/rebootcode.c --- /n/sources/plan9/sys/src/9/rb/rebootcode.c Thu Jul 18 17:57:31 2013 +++ /sys/src/9/rb/rebootcode.c Wed Mar 11 00:00:00 2020 @@ -20,36 +20,40 @@ }; void putc(int); +void next_kernel(void *, ulong, char **, char **, ulong); /* - * Copy the new kernel to its correct location in physical memory, + * Copy the new kernel to its correct location in memory, * flush caches, ignore TLBs (we're in KSEG0 space), and jump to - * the start of the kernel. + * the start of the kernel. Argument addresses are virtual (KSEG0). */ void -main(ulong aentry, ulong acode, ulong asize) +main(Rbconf *rbconf, ulong aentry, ulong acode, ulong asize) { - void (*kernel)(void); - static ulong entry, code, size; + static ulong entry, code, size, argc; + static char **argv; - putc('B'); putc('o'); putc('o'); putc('t'); + putc('B'); putc('o'); /* copy args to heap before moving stack to before a.out header */ + argv = (char **)rbconf; entry = aentry; code = acode; size = asize; setsp(entry-0x20-4); + putc('o'); memmove((void *)entry, (void *)code, size); - + putc('t'); cleancache(); coherence(); + putc(' '); /* - * jump to kernel entry point. + * jump to new kernel's entry point. + * pass routerboot arg vector in R4-R5. + * off we go - never to return. */ - putc(' '); - kernel = (void*)entry; - (*kernel)(); /* off we go - never to return */ + next_kernel((void*)entry, 4, argv, 0, 0); putc('?'); putc('!'); diff -Nru /n/sources/plan9/sys/src/9/rb/trap.c /sys/src/9/rb/trap.c --- /n/sources/plan9/sys/src/9/rb/trap.c Tue Jul 23 01:51:54 2013 +++ /sys/src/9/rb/trap.c Mon Jun 8 00:00:00 2020 @@ -548,7 +548,7 @@ return buf; } -#define KERNPC(x) (KTZERO <= (ulong)(x) && (ulong)(x) < (ulong)&etext) +// #define KERNPC(x) (KTZERO <= (ulong)(x) && (ulong)(x) < (ulong)&etext) void kernfault(Ureg *ur, int code) diff -Nru /n/sources/plan9/sys/src/9/rb/uarti8250.c /sys/src/9/rb/uarti8250.c --- /n/sources/plan9/sys/src/9/rb/uarti8250.c Tue Jul 23 00:25:37 2013 +++ /sys/src/9/rb/uarti8250.c Tue May 26 00:00:00 2020 @@ -118,7 +118,7 @@ typedef struct Ctlr { - u32int* io; + ulong* io; int irq; int tbdf; int iena; @@ -135,7 +135,7 @@ extern PhysUart i8250physuart; static Ctlr i8250ctlr[] = { -{ .io = (u32int*)PHYSCONS, +{ .io = (ulong*)PHYSCONS, .irq = ILduart0, .tbdf = -1, .poll = 0, }, @@ -396,7 +396,7 @@ static int i8250baud(Uart* uart, int baud) { -#ifdef notdef /* don't change the speed */ +#ifdef CHANGE_SPEED ulong bgc; Ctlr *ctlr; extern int i8250freq; /* In the config file */ diff -Nru /n/sources/plan9/sys/src/9/rb/words /sys/src/9/rb/words --- /n/sources/plan9/sys/src/9/rb/words Tue Jul 23 22:14:11 2013 +++ /sys/src/9/rb/words Thu May 14 00:00:00 2015 @@ -22,7 +22,7 @@ ll/sc target memory must be cached. 1 uart 8250 (actually 16550ish) -2 ethers arge[01] ar71xx, 2nd has 4 ports & a bridge +2 ethers arge[01] ar7161, 2nd has 4 ports & a bridge pci bus(es) no video no disk but has flash, alas @@ -44,8 +44,8 @@ irqs 2 pci 3 ehci -4 arge1 ar71xx @ 0x19:: + ar8316 switch -5 arge0 ar71xx @ 0x1a:: +4 arge1 ar7161 @ 0x19:: + ar8316 switch +5 arge0 ar7161 @ 0x1a:: 6 uart 7 clock