From 725df887ee04f36f44a028091facf2cc698135fa Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 7 Dec 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-12-07 --- ip/devip.c | 1 + mtx/clock.c | 56 +++++++ mtx/l.s | 254 ++++++++++++++++++++++++++++++-- mtx/main.c | 353 ++++++++++++++++++++++++++++++++++++++++++++- mtx/mem.h | 4 +- mtx/mmu.c | 117 +-------------- mtx/trap.c | 102 ++++++------- port/devcons.c | 3 +- port/devdraw.c | 5 +- port/devloopback.c | 1 + port/devpipe.c | 1 + port/devtls.c | 1 + port/devuart.c | 1 + port/netif.c | 1 + 14 files changed, 713 insertions(+), 187 deletions(-) create mode 100644 mtx/clock.c diff --git a/ip/devip.c b/ip/devip.c index 89392262fd5e883020462ec0f35eaf03e8d9838f..40861a26754c8d89d22e69ae38bff0e22ad69c96 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -496,6 +496,7 @@ ipopen(Chan* c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; + c->iounit = qiomaxatomic; return c; } diff --git a/mtx/clock.c b/mtx/clock.c new file mode 100644 index 0000000000000000000000000000000000000000..aab32151f29642de4eeed6fab4e90b991cb78981 --- /dev/null +++ b/mtx/clock.c @@ -0,0 +1,56 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" + +void +clockintr(Ureg *ureg) +{ + // this needs to be here for synchronizing mp clocks + // see pc/mp.c's squidboy() + fastticks(nil); + + if(m->flushmmu){ + if(up) + flushmmu(); + m->flushmmu = 0; + } + + portclock(ureg); +} + +void +delay(int l) +{ + ulong i, j; + +// j = m->delayloop; +// while(l-- > 0) +// for(i=0; i < j; i++) +// ; +} + +void +microdelay(int l) +{ + ulong i; + +// l *= m->delayloop; +// l += 500; +// l /= 1000; +// if(l <= 0) +// l = 1; +// for(i = 0; i < l; i++) +// ; +} + +vlong +fastticks(uvlong *hz) +{ + if(hz) + *hz = HZ; + return m->ticks; +} diff --git a/mtx/l.s b/mtx/l.s index 34ffb71e3184ddd887bfcd7046a9fa155a879fd6..33b2a3568e169cfe4b46d6b70c369b5993b7d751 100644 --- a/mtx/l.s +++ b/mtx/l.s @@ -1,14 +1,22 @@ #include "mem.h" +/* use of SPRG registers in save/restore */ +#define SAVER0 SPRG0 +#define SAVER1 SPRG1 +#define SAVELR SPRG2 +#define SAVEXX SPRG3 + +/* special instruction definitions */ #define BDNZ BC 16,0, #define BDNE BC 0,2, -#define NOOP OR R0,R0,R0 -#define TLBIA WORD $(31<<26) +//#define TLBIA WORD $(31<<26) +#define TLBIA WORD $((31<<26)|(370<<1)) +//#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1)) + +/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ +#define MSRSYNC SYNC; ISYNC -/* Be-ware 603e chip bugs (mtmsr instruction) */ -#define FIX603e CROR 0,0,0 -#undef FIX603e -#define FIX603e ISYNC; SYNC +#define UREGSPACE (UREGSIZE+8) TEXT start(SB), $-4 MOVW $setSB(SB), R2 @@ -23,7 +31,7 @@ TEXT splhi(SB), $0 RLWNM $0, R3, $~MSR_EE, R4 SYNC MOVW R4, MSR - FIX603e + MSRSYNC RETURN TEXT splx(SB), $0 @@ -36,7 +44,7 @@ TEXT splxpc(SB), $0 RLWMI $0, R3, $MSR_EE, R4 SYNC MOVW R4, MSR - FIX603e + MSRSYNC RETURN TEXT spllo(SB), $0 @@ -44,7 +52,7 @@ TEXT spllo(SB), $0 OR $MSR_EE, R3, R4 SYNC MOVW R4, MSR - FIX603e + MSRSYNC RETURN TEXT spldone(SB), $0 @@ -68,3 +76,231 @@ TEXT gotolabel(SB), $-4 MOVW 0(R3), R1 MOVW $1, R3 RETURN + +TEXT touser(SB), $-4 + MOVW $(UTZERO+32), R5 /* header appears in text */ + MOVW $(MSR_EE|MSR_PR|MSR_ME|MSR_IR|MSR_DR|MSR_RI), R4 + MOVW R4, SPR(SRR1) + MOVW R3, R1 + MOVW R5, SPR(SRR0) + RFI + +TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ + MOVW n+4(FP), R4 + RLWNM $0, R3, $~(CACHELINESZ-1), R5 + SUB R5, R3 + ADD R3, R4 + ADD $(CACHELINESZ-1), R4 + SRAW $CACHELINELOG, R4 + MOVW R4, CTR +icf0: ICBI (R5) + ADD $CACHELINESZ, R5 + BDNZ icf0 + ISYNC + RETURN + +TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ + MOVW n+4(FP), R4 + RLWNM $0, R3, $~(CACHELINESZ-1), R5 + CMP R4, $0 + BLE dcf1 + SUB R5, R3 + ADD R3, R4 + ADD $(CACHELINESZ-1), R4 + SRAW $CACHELINELOG, R4 + MOVW R4, CTR +dcf0: DCBF (R5) + ADD $CACHELINESZ, R5 + BDNZ dcf0 +dcf1: + RETURN + +TEXT tas(SB), $0 + SYNC + MOVW R3, R4 + MOVW $0xdead,R5 +tas1: + DCBF (R4) /* fix for 603x bug */ + LWAR (R4), R3 + CMP R3, $0 + BNE tas0 + STWCCC R5, (R4) + BNE tas1 +tas0: + SYNC + ISYNC + RETURN + +TEXT getpvr(SB), $0 + MOVW SPR(PVR), R3 + RETURN + +TEXT getdec(SB), $0 + MOVW SPR(DEC), R3 + RETURN + +TEXT putdec(SB), $0 + MOVW R3, SPR(DEC) + RETURN + +TEXT getdar(SB), $0 + MOVW SPR(DAR), R3 + RETURN + +TEXT getdsisr(SB), $0 + MOVW SPR(DSISR), R3 + RETURN + +TEXT getmsr(SB), $0 + MOVW MSR, R3 + RETURN + +TEXT putmsr(SB), $0 + SYNC + MOVW R3, MSR + MSRSYNC + RETURN + +TEXT eieio(SB), $0 + EIEIO + RETURN + +TEXT tlbflushall(SB), $0 + TLBIA + RETURN + +TEXT tlbflush(SB), $0 + TLBIE R3 + RETURN + +TEXT gotopc(SB), $0 + MOVW R3, CTR + MOVW LR, R31 /* for trace back */ + BR (CTR) + +/* + * traps force memory mapping off. + * the following code has been executed at the exception + * vector location + * MOVW R0, SPR(SAVER0) + * MOVW LR, R0 + * MOVW R0, SPR(SAVELR) + * bl trapvec(SB) + */ +TEXT trapvec(SB), $-4 + MOVW LR, R0 + MOVW R1, SPR(SAVER1) + MOVW R0, SPR(SAVEXX) /* vector */ + +/* + to enable hardware break points + MOVW MSR, R1 + OR $(MSR_RI), R1 + MOVW R1, MSR + ISYNC +*/ + + /* did we come from user space */ + MOVW SPR(SRR1), R0 + MOVW CR, R1 + MOVW R0, CR + BC 4,17,ktrap + + /* switch to kernel stack */ + MOVW R1, CR + MOVW $(MACHADDR&~KZERO), R1 /* PADDR(m->) */ + MOVW 12(R1), R1 /* m->proc */ + RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc) */ + MOVW 8(R1), R1 /* m->proc->kstack */ + RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc->kstack) */ + ADD $(KSTACK-UREGSIZE), R1 + BL saveureg(SB) + BL trap(SB) + BR restoreureg +ktrap: + MOVW R1, CR + MOVW SPR(SAVER1), R1 + RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc->kstack) */ + SUB $UREGSPACE, R1 + BL saveureg(SB) + BL trap(SB) + BR restoreureg + + +/* + * enter with stack set and mapped. + * on return, SB (R2) has been set, and R3 has the Ureg*, + * the MMU has been re-enabled, kernel text and PC are in KSEG, + * R(MACH) has been set, and R0 contains 0. + * + */ +TEXT saveureg(SB), $-4 +/* + * save state + */ + MOVMW R2, 48(R1) /* r2:r31 */ + MOVW $setSB(SB), R2 + MOVW $(MACHADDR&~KZERO), R(MACH) + MOVW 12(R(MACH)), R(USER) + MOVW $MACHADDR, R(MACH) + MOVW SPR(SAVER1), R4 + MOVW R4, 44(R1) + MOVW SPR(SAVER0), R5 + MOVW R5, 40(R1) + MOVW CTR, R6 + MOVW R6, 36(R1) + MOVW XER, R4 + MOVW R4, 32(R1) + MOVW CR, R5 + MOVW R5, 28(R1) + MOVW SPR(SAVELR), R6 /* LR */ + MOVW R6, 24(R1) + /* pad at 20(R1) */ + MOVW SPR(SRR0), R0 + MOVW R0, 16(R1) /* old PC */ + MOVW SPR(SRR1), R0 + MOVW R0, 12(R1) /* old status */ + MOVW SPR(SAVEXX), R0 + MOVW R0, 8(R1) /* cause/vector */ + ADD $8, R1, R3 /* Ureg* */ + OR $KZERO, R3 /* fix ureg */ + STWCCC R3, (R1) /* break any pending reservations */ + MOVW $0, R0 /* compiler/linker expect R0 to be zero */ + + MOVW MSR, R5 +// OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */ + MOVW R5, SPR(SRR1) + MOVW LR, R31 +// OR $KZERO, R31 /* return PC in KSEG0 */ + MOVW R31, SPR(SRR0) +// OR $KZERO, R1 /* fix stack pointer */ + RFI /* returns to trap handler */ + +/* + * restore state from Ureg and return from trap/interrupt + */ +TEXT forkret(SB), $0 + BR restoreureg + +restoreureg: + MOVMW 48(R1), R2 /* r2:r31 */ + /* defer R1 */ + MOVW 40(R1), R0 + MOVW R0, SPR(SAVER0) + MOVW 36(R1), R0 + MOVW R0, CTR + MOVW 32(R1), R0 + MOVW R0, XER + MOVW 28(R1), R0 + MOVW R0, CR /* CR */ + MOVW 24(R1), R0 + MOVW R0, LR + /* pad, skip */ + MOVW 16(R1), R0 + MOVW R0, SPR(SRR0) /* old PC */ + MOVW 12(R1), R0 + MOVW R0, SPR(SRR1) /* old MSR */ + /* cause, skip */ + MOVW 44(R1), R1 /* old SP */ + MOVW SPR(SAVER0), R0 + RFI diff --git a/mtx/main.c b/mtx/main.c index b75474ae5078adf95f93a5a6d5772bb8ba0c1858..d9c52a8efae137420827d294df6ef58ff2ade617 100644 --- a/mtx/main.c +++ b/mtx/main.c @@ -13,10 +13,357 @@ FPsave initfp; void main(void) { -// xinit(); - printinit(); + conf.nmach = 1; + machinit(); + active.machs = 1; + active.exiting = 0; i8250console(); print("\nPlan 9\n"); +// cpuidentify(); +// confinit(); +// xinit(); + trapinit(); +print("trapinit done\n"); +*(ulong*)-1 = 0; +print("survived!\n"); +spllo(); +putdec(64); +print("still here\n"); +{ void (*f)(void); f = (void (*)(void))0x200; f(); } +for(;;); +// printinit(); +// cpuidprint(); +// mmuinit(); +// procinit0(); +// initseg(); +// links(); +// chandevreset(); +// pageinit(); +// swapinit(); +// userinit(); +// schedinit(); +} + +void +machinit(void) +{ + memset(m, 0, sizeof(Mach)); + + /* + * For polled uart output at boot, need + * a default delay constant. 100000 should + * be enough for a while. Cpuidentify will + * calculate the real value later. + */ +// m->loopconst = 100000; +} + +static struct +{ + char *name; + char *val; +} +plan9ini[] = +{ + { "console", "0" }, +}; + +char* +getconf(char *name) +{ + int i; + + for(i = 0; i < nelem(plan9ini); i++) + if(cistrcmp(name, plan9ini[i].name) == 0) + return plan9ini[i].val; + return nil; +} + +void +init0(void) +{ +// char **p, *q, name[KNAMELEN]; +// int n; + +print("init0\n"); + + up->nerrlab = 0; + + spllo(); + + /* + * These are o.k. because rootinit is null. + * Then early kproc's will have a root and dot. + */ + up->slash = namec("#/", Atodir, 0, 0); + cnameclose(up->slash->name); + up->slash->name = newcname("/"); + up->dot = cclone(up->slash); + + chandevinit(); + + if(!waserror()){ + ksetenv("cputype", "power"); + if(cpuserver) + ksetenv("service", "cpu"); + else + ksetenv("service", "terminal"); + +/* + for(p = confenv; *p; p++) { + q = strchr(p[0], '='); + if(q == 0) + continue; + n = q-p[0]; + if(n >= KNAMELEN) + n = KNAMELEN-1; + memmove(name, p[0], n); + name[n] = 0; + ksetenv(name, q+1); + } +*/ + poperror(); + } + kproc("alarm", alarmkproc, 0); + touser((void*)(USTKTOP-8)); +} + +void +userinit(void) +{ + Proc *p; + Segment *s; + KMap *k; + Page *pg; + + p = newproc(); + p->pgrp = newpgrp(); + p->egrp = smalloc(sizeof(Egrp)); + p->egrp->ref = 1; + p->fgrp = dupfgrp(nil); + p->rgrp = newrgrp(); + p->procmode = 0640; + + strcpy(p->text, "*init*"); + strcpy(p->user, eve); + p->fpstate = FPinit; + + /* + * Kernel Stack + * + * N.B. The -12 for the stack pointer is important. + * 4 bytes for gotolabel's return PC + */ + p->sched.pc = (ulong)init0; + p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD; + + /* + * User Stack + */ + s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); + p->seg[SSEG] = s; + pg = newpage(1, 0, USTKTOP-BY2PG); + segpage(s, pg); + + /* + * Text + */ + s = newseg(SG_TEXT, UTZERO, 1); + s->flushme++; + p->seg[TSEG] = s; + pg = newpage(1, 0, UTZERO); + memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); + segpage(s, pg); + k = kmap(s->map[0]->pages[0]); + memmove((ulong*)VA(k), initcode, sizeof initcode); + kunmap(k); + + ready(p); +} + +void +exit(int ispanic) +{ + int ms, once; + + lock(&active); + if(ispanic) + active.ispanic = ispanic; + else if(m->machno == 0 && (active.machs & (1<machno)) == 0) + active.ispanic = 0; + once = active.machs & (1<machno); + active.machs &= ~(1<machno); + active.exiting = 1; + unlock(&active); + + if(once) + print("cpu%d: exiting\n", m->machno); + spllo(); + for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ + delay(TK2MS(2)); + if(active.machs == 0 && consactive() == 0) + break; + } + + if(active.ispanic && m->machno == 0){ + if(cpuserver) + delay(10000); + else + for(;;); + } + else + delay(1000); + + for(;;) + ; +} + +/* + * set up floating point for a new process + */ +void +procsetup(Proc *p) +{ + USED(p); +} + +/* + * Save the mach dependent part of the process state. + */ +void +procsave(Proc *p) +{ + USED(p); +} + +void +confinit(void) +{ + int nbytes; + ulong pa; + + conf.nmach = 1; /* processors */ + conf.nproc = 60; /* processes */ + + // hard wire for now + pa = 0x200000; // leave 2 Meg for kernel + nbytes = 8*1024*1024; // leave room at the top as well + + conf.npage0 = nbytes/BY2PG; + conf.base0 = pa; + + conf.npage1 = 0; + conf.base1 = pa; + + conf.npage = conf.npage0 + conf.npage1; + + conf.upages = (conf.npage*60)/100; + conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; + + /* set up other configuration parameters */ + conf.nswap = 0; + conf.nswppo = 0; + conf.nimage = 20; + + conf.copymode = 0; /* copy on write */ +} + +static int +getcfields(char* lp, char** fields, int n, char* sep) +{ + int i; + + for(i = 0; lp && *lp && i < n; i++){ + while(*lp && strchr(sep, *lp) != 0) + *lp++ = 0; + if(*lp == 0) + break; + fields[i] = lp; + while(*lp && strchr(sep, *lp) == 0){ + if(*lp == '\\' && *(lp+1) == '\n') + *lp++ = ' '; + lp++; + } + } + + return i; +} + +int +isaconfig(char *class, int ctlrno, ISAConf *isa) +{ + int i; + char cc[KNAMELEN], *p; + + sprint(cc, "%s%d", class, ctlrno); + + p = getconf(cc); + if(p == 0) + return 0; + isa->nopt = tokenize(p, isa->opt, NISAOPT); + for(i = 0; i < isa->nopt; i++){ + p = isa->opt[i]; + if(cistrncmp(p, "type=", 5) == 0) + isa->type = p + 5; + else if(cistrncmp(p, "port=", 5) == 0) + isa->port = strtoul(p+5, &p, 0); + else if(cistrncmp(p, "irq=", 4) == 0) + isa->irq = strtoul(p+4, &p, 0); + else if(cistrncmp(p, "dma=", 4) == 0) + isa->dma = strtoul(p+4, &p, 0); + else if(cistrncmp(p, "mem=", 4) == 0) + isa->mem = strtoul(p+4, &p, 0); + else if(cistrncmp(p, "size=", 5) == 0) + isa->size = strtoul(p+5, &p, 0); + else if(cistrncmp(p, "freq=", 5) == 0) + isa->freq = strtoul(p+5, &p, 0); + } + return 1; +} + +int +cistrcmp(char *a, char *b) +{ + int ac, bc; + + for(;;){ + ac = *a++; + bc = *b++; + + if(ac >= 'A' && ac <= 'Z') + ac = 'a' + (ac - 'A'); + if(bc >= 'A' && bc <= 'Z') + bc = 'a' + (bc - 'A'); + ac -= bc; + if(ac) + return ac; + if(bc == 0) + break; + } + return 0; +} + +int +cistrncmp(char *a, char *b, int n) +{ + unsigned ac, bc; + + while(n > 0){ + ac = *a++; + bc = *b++; + n--; + + if(ac >= 'A' && ac <= 'Z') + ac = 'a' + (ac - 'A'); + if(bc >= 'A' && bc <= 'Z') + bc = 'a' + (bc - 'A'); + + ac -= bc; + if(ac) + return ac; + if(bc == 0) + break; + } - for(;;); + return 0; } diff --git a/mtx/mem.h b/mtx/mem.h index 3cafc4aac251d32f7eb53a81997e375f947862f5..801585dc764478280b4f1e2280891928a284b6d8 100644 --- a/mtx/mem.h +++ b/mtx/mem.h @@ -81,7 +81,7 @@ #define SIA 955 /* Sampled Instruction Address */ #define SDA 959 /* Sampled Data Address */ -#define BIT(i) (1<<(32-(i))) /* Silly backwards register bit numbering scheme */ +#define BIT(i) (1<<(31-(i))) /* Silly backwards register bit numbering scheme */ /* * Bit encodings for Machine State Register (MSR) @@ -222,3 +222,5 @@ #define FLASHAorB 0xfff00000 #define isphys(x) (((ulong)x&KZERO)!=0) + +#define getpgcolor(a) 0 diff --git a/mtx/mmu.c b/mtx/mmu.c index b80b1d013f30bfc203f7e2dbf21acc45460585e9..9726d9045df83f2b4c340921de0721c00b68daea 100644 --- a/mtx/mmu.c +++ b/mtx/mmu.c @@ -13,8 +13,6 @@ mmuinit(void) int i; print("mmuinit\n"); - for(i=0; istb[i].virt = TLBINVLAID; } void @@ -43,7 +41,7 @@ if(0)print("mmuswitch()\n"); p->newtlb = 0; } tp = p->pidonmach[m->machno]; - putcasid(tp); +// putcasid(tp); } void @@ -53,120 +51,7 @@ if(0)print("mmurelease(%ld)\n", p->pid); memset(p->pidonmach, 0, sizeof p->pidonmach); } -void -purgetlb(int pid) -{ - int i, mno; - Proc *sp, **pidproc; - Softtlb *entry, *etab; - -if(0)print("purgetlb: pid = %d\n", pid); - m->tlbpurge++; - /* - * find all pid entries that are no longer used by processes - */ - mno = m->machno; - pidproc = m->pidproc; - for(i=1; ipidonmach[mno] != i) - pidproc[i] = 0; - } - - /* - * shoot down the one we want - */ - sp = pidproc[pid]; - if(sp != 0) - sp->pidonmach[mno] = 0; - pidproc[pid] = 0; - - /* - * clean out all dead pids from the stlb; - */ - entry = m->stb; - for(etab = &entry[STLBSIZE]; entry < etab; entry++) - if(pidproc[TLBPID(entry->virt)] == 0) - entry->virt = TLBINVLAID; - - /* - * clean up the hardware - */ - tlbflushall(); -} - -int -newtlbpid(Proc *p) -{ - int i, s; - Proc **h; - - i = m->lastpid; - h = m->pidproc; - for(s = 0; s < NTLBPID; s++) { - i++; - if(i >= NTLBPID) - i = 1; - if(h[i] == 0) - break; - } - - if(h[i]) { - i = m->purgepid+1; - if(i >= NTLBPID) - i = 1; - m->purgepid = i; - purgetlb(i); - } - - if(h[i] != 0) - panic("newtlb"); - - m->pidproc[i] = p; - p->pidonmach[m->machno] = i; - m->lastpid = i; -if(0)print("newtlbpid: pid=%ld = tlbpid = %d\n", p->pid, i); - return i; -} - void putmmu(ulong va, ulong pa, Page *pg) { - char *ctl; - int tp; - ulong h; - - qlock(&m->stlblk); - - tp = up->pidonmach[m->machno]; - if(tp == 0) { - tp = newtlbpid(up); - putcasid(tp); - } - - h = ((va>>12)^(va>>24)^(tp<<8)) & 0xfff; - m->stb[h].virt = va|tp; - m->stb[h].phys = pa; - tlbflush(va); - - qunlock(&m->stlblk); - - ctl = &pg->cachectl[m->machno]; -if(0)print("putmmu tp=%d h=%ld va=%lux pa=%lux ctl=%x\n", tp, h,va, pa, *ctl); - switch(*ctl) { - default: - panic("putmmu: %d\n", *ctl); - break; - case PG_NOFLUSH: - break; - case PG_TXTFLUSH: - dcflush((void*)pg->va, BY2PG); - icflush((void*)pg->va, BY2PG); - *ctl = PG_NOFLUSH; - break; - case PG_NEWCOL: -print("PG_NEWCOL!!\n"); - *ctl = PG_NOFLUSH; - break; - } } diff --git a/mtx/trap.c b/mtx/trap.c index 9e11071b731d939a8108b854ac511b6f975554a8..2dd46e23e93782295618006101d5ded1ff03a156 100644 --- a/mtx/trap.c +++ b/mtx/trap.c @@ -115,38 +115,6 @@ char *regname[]={ "R30", "R31", }; -void -sethvec(int v, void (*r)(void)) -{ - ulong *vp, pa, o; - - vp = KADDR(v); - vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */ - vp[1] = 0x7c0802a6; /* MOVW LR, R0 */ - vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */ - pa = PADDR(r); - o = pa >> 25; - if(o != 0 && o != 0x7F){ - /* a branch too far */ - vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */ - vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */ - vp[5] = 0x7c0803a6; /* MOVW R0, LR */ - vp[6] = 0x4e800021; /* BL (LR) */ - }else - vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ - dcflush(vp, 8*sizeof(ulong)); -} - -void -sethvec2(int v, void (*r)(void)) -{ - ulong *vp; - - vp = (ulong*)KADDR(v); - vp[0] = (18<<26)|(PADDR(r))|2; /* ba */ - dcflush(vp, sizeof(*vp)); -} - void trap(Ureg *ur) { @@ -155,6 +123,7 @@ trap(Ureg *ur) int user; char buf[ERRMAX]; +print("trap\n"); m->intrts = fastticks(nil); ecode = (ur->cause >> 8) & 0xff; user = (ur->srr1 & MSR_PR) != 0; @@ -255,39 +224,41 @@ spurious(Ureg *ur, void *a) Lock veclock; +void +sethvec(int v, void (*r)(void)) +{ + ulong *vp, pa, o; + + vp = KADDR(v); + vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */ + vp[1] = 0x7c0802a6; /* MOVW LR, R0 */ + vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */ + pa = PADDR(r); + o = pa >> 25; + if(o != 0 && o != 0x7F){ + /* a branch too far */ + vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */ + vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */ + vp[5] = 0x7c0803a6; /* MOVW R0, LR */ + vp[6] = 0x4e800021; /* BL (LR) */ + }else + vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ + dcflush(vp, 8*sizeof(ulong)); +} + void trapinit(void) { -#ifdef BLOG int i; - IMM *io; - - io = m->iomem; - io->sypcr &= ~(1<<3); /* disable watchdog (821/823) */ - io->simask = 0; /* mask all */ - io->siel = ~0; /* edge sensitive, wake on all */ - io->cicr = 0; /* disable CPM interrupts */ - io->cipr = ~0; /* clear all interrupts */ - io->cimr = 0; /* mask all events */ - io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8); - io->cicr |= 1 << 7; /* enable */ - io->tbscr = 1; /* TBE */ - io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */ - eieio(); putdec(~0); + putmsr(getmsr() & ~MSR_IP); /* * set all exceptions to trap */ for(i = 0x0; i < 0x2000; i += 0x100) sethvec(i, trapvec); - - //sethvec(CEI<<8, intrvec); - sethvec2(CIMISS<<8, itlbmiss); - sethvec2(CDMISS<<8, dtlbmiss); - sethvec2(CDTLBE<<8, dtlberror); -#endif } void @@ -432,19 +403,34 @@ kernfault(Ureg *ur, int code) sched(); } +/* + * Fill in enough of Ureg to get a stack trace, and call a function. + * Used by debugging interface rdb. + */ void -dumpstack(void) +callwithureg(void (*fn)(Ureg*)) +{ + Ureg ureg; + ureg.pc = getcallerpc(&fn); + ureg.sp = (ulong)&fn; + fn(&ureg); +} + +void +_dumpstack(Ureg *ureg) { ulong l, v; int i; if(up == 0) return; + + print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp); i = 0; for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ v = *(ulong*)l; if(KTZERO < v && v < (ulong)etext){ - print("%lux=%lux, ", l, v); + print("%.8lux=%.8lux ", l, v); if(i++ == 4){ print("\n"); i = 0; @@ -453,6 +439,12 @@ dumpstack(void) } } +void +dumpstack(void) +{ + callwithureg(_dumpstack); +} + void dumpregs(Ureg *ur) { diff --git a/port/devcons.c b/port/devcons.c index 357f6eb432af8662a731794f6c6fe4e49d3e741b..359a03e6a2296a8e59c16f5ee1627026a50939a0 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -632,6 +632,7 @@ consopen(Chan *c, int omode) qnoblock(kprintoq, 1); }else qreopen(kprintoq); + c->iounit = qiomaxatomic; break; } return c; @@ -846,7 +847,7 @@ consread(Chan *c, void *buf, long n, vlong off) return n; case Qosversion: - snprint(tmp, sizeof tmp, "2000 %d", qiomaxatomic); + snprint(tmp, sizeof tmp, "2000"); n = readstr((ulong)offset, buf, n, tmp); return n; diff --git a/port/devdraw.c b/port/devdraw.c index fa16e5826943df710b66948d6faf13fa48e99deb..2d553fb78d9988041e44d2f94ecc18f1fd4b196c 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -37,6 +37,7 @@ enum #define NHASH (1<<5) #define HASHMASK (NHASH-1) +#define IOUNIT (64*1024) typedef struct Client Client; typedef struct Draw Draw; @@ -908,7 +909,7 @@ drawopen(Chan *c, int omode) if(c->qid.type & QTDIR){ c = devopen(c, omode, 0, 0, drawgen); - c->iounit = 32*1024; + c->iounit = IOUNIT; } qlock(&sdraw); @@ -949,7 +950,7 @@ drawopen(Chan *c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; - c->iounit = 32*1024; + c->iounit = IOUNIT; return c; } diff --git a/port/devloopback.c b/port/devloopback.c index b1f039a663be877466aceb3dd8537fc62f5d987a..02468b2e38a875fd71330c8e51c2c3991618eb6c 100644 --- a/port/devloopback.c +++ b/port/devloopback.c @@ -310,6 +310,7 @@ loopbackopen(Chan *c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; + c->iounit = qiomaxatomic; return c; } diff --git a/port/devpipe.c b/port/devpipe.c index 23c48e632593907f965244ec44db22470a09b9e8..890e4eaa98038bfe937cf5bde76f28b8aaff9862 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -207,6 +207,7 @@ pipeopen(Chan *c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; + c->iounit = qiomaxatomic; return c; } diff --git a/port/devtls.c b/port/devtls.c index cdb311f80fdd04649846cdd47ac570ec45b14178..16d17b64e38dc90e17a96883922ce311faf76d29 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -481,6 +481,7 @@ tlsopen(Chan *c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; + c->iounit = qiomaxatomic; return c; } diff --git a/port/devuart.c b/port/devuart.c index ff7a906474da72b6738d4c328d26c7fedbab0bdf..942c316b2c473b201b9b5cc0725ebbadc7889943 100644 --- a/port/devuart.c +++ b/port/devuart.c @@ -242,6 +242,7 @@ uartopen(Chan *c, int omode) break; } + c->iounit = qiomaxatomic; return c; } diff --git a/port/netif.c b/port/netif.c index 5b996d6dbe6c6a348d224590bd2b8fac042bfed7..759cb5f7ae1190222300de7068c75be8078ea8aa 100644 --- a/port/netif.c +++ b/port/netif.c @@ -181,6 +181,7 @@ netifopen(Netif *nif, Chan *c, int omode) c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; + c->iounit = qiomaxatomic; return c; }