From 3048a0ab1dace99f63cf370c028a927872c3f2c9 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 8 Dec 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-12-08 --- alphapc/dma.c | 6 +- mtx/clock.c | 30 +++++---- mtx/dat.h | 34 +++++----- mtx/fns.h | 5 +- mtx/l.s | 28 ++++---- mtx/main.c | 45 +++++++++---- mtx/mem.h | 7 +- mtx/trap.c | 169 +++++++++++++++---------------------------------- port/sysproc.c | 1 + 9 files changed, 140 insertions(+), 185 deletions(-) diff --git a/alphapc/dma.c b/alphapc/dma.c index 0576172eda766c0baf18a711587a7d1a17caceab..5a0ecf8597b4f0d67d31e70ae38db1a3733dde04 100644 --- a/alphapc/dma.c +++ b/alphapc/dma.c @@ -119,7 +119,7 @@ dmainit(int chan, int maxtransfer) return 1; return 0; } -//dmastatus(dp, chan, 'I'); +dmastatus(dp, chan, 'I'); xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024); if(xp->bva == nil) @@ -241,7 +241,7 @@ dmasetup(int chan, void *va, long len, int isread) outb(dp->count[chan], ((len>>dp->shift)-1)>>8); outb(dp->sbm, chan); /* enable the channel */ iunlock(dp); -//dmastatus(dp, chan, 'S'); +dmastatus(dp, chan, 'S'); return len; } @@ -273,7 +273,7 @@ dmaend(int chan) dp = &dma[(chan>>2)&1]; chan = chan & 3; -//dmastatus(dp, chan, 'E'); +dmastatus(dp, chan, 'E'); /* * disable the channel */ diff --git a/mtx/clock.c b/mtx/clock.c index aab32151f29642de4eeed6fab4e90b991cb78981..bfe7968d84dcc95ed4723587e5a342f18043417c 100644 --- a/mtx/clock.c +++ b/mtx/clock.c @@ -19,7 +19,9 @@ clockintr(Ureg *ureg) m->flushmmu = 0; } +print("portclock\n"); portclock(ureg); +print("done portclock\n"); } void @@ -27,10 +29,10 @@ delay(int l) { ulong i, j; -// j = m->delayloop; -// while(l-- > 0) -// for(i=0; i < j; i++) -// ; + j = m->loopconst; + while(l-- > 0) + for(i=0; i < j; i++) + ; } void @@ -38,13 +40,19 @@ microdelay(int l) { ulong i; -// l *= m->delayloop; -// l += 500; -// l /= 1000; -// if(l <= 0) -// l = 1; -// for(i = 0; i < l; i++) -// ; +return; + l *= m->loopconst; + l += 500; + l /= 1000; + if(l <= 0) + l = 1; + for(i = 0; i < l; i++) + ; +} + +void +clockinit(void) +{ } vlong diff --git a/mtx/dat.h b/mtx/dat.h index 2c781b15f1e1459de66595d20af822005a7b2dab..d3888a29357af7888243fcf739e967418d7f1044 100644 --- a/mtx/dat.h +++ b/mtx/dat.h @@ -52,9 +52,21 @@ enum FPinactive, }; +/* + * This structure must agree with fpsave and fprestore asm routines + */ struct FPsave { -int dummy; + double fpreg[32]; + union { + double fpscrd; + struct { + ulong pad; + ulong fpscr; + }; + }; + int fpistate; /* emulated fp */ + ulong emreg[32][3]; /* emulated fp */ }; struct Conf @@ -106,22 +118,6 @@ typedef void KMap; #define kmap(p) (KMap*)((p)->pa|KZERO) #define kunmap(k) -/* - * Process Control Block, used by PALcode - */ -struct PCB { - uvlong ksp; - uvlong usp; - uvlong ptbr; - ulong asn; - ulong pcc; - uvlong unique; - ulong fen; - ulong dummy; - uvlong rsrv1; - uvlong rsrv2; -}; - struct Mach { /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */ @@ -136,6 +132,8 @@ struct Mach Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ int inclockintr; + int cputype; + ulong loopconst; ulong fairness; /* for runproc */ @@ -156,8 +154,6 @@ struct Mach ulong spuriousintr; int lastintr; - PCB; - /* MUST BE LAST */ int stack[1]; }; diff --git a/mtx/fns.h b/mtx/fns.h index 73e8549af00a89bc0484fc6186dae9b5571fd3c6..b95e134411d4313f4ee9d1ffe8aaa36cd2c61d8d 100644 --- a/mtx/fns.h +++ b/mtx/fns.h @@ -12,7 +12,7 @@ void clockintr(Ureg*); void clrfptrap(void); #define coherence() void cpminit(void); -int cpuidentify(void); +void cpuidentify(void); void cpuidprint(void); void dcflush(void*, ulong); void delay(int); @@ -22,10 +22,9 @@ void dtlberror(void); void dumpregs(Ureg*); void delayloopinit(void); void eieio(void); -//#define eieio() void evenaddr(ulong); void faultpower(Ureg*, ulong addr, int read); -void firmware(int); +void firmware(void); void fpinit(void); int fpipower(Ureg*); void fpoff(void); diff --git a/mtx/l.s b/mtx/l.s index 33b2a3568e169cfe4b46d6b70c369b5993b7d751..259f09d8ed39e719dae2be11c3accda8799f6d4e 100644 --- a/mtx/l.s +++ b/mtx/l.s @@ -19,9 +19,13 @@ #define UREGSPACE (UREGSIZE+8) TEXT start(SB), $-4 + MOVW $setSB(SB), R2 + MOVW $MACHADDR, R(MACH) + MOVW $(KTZERO-8), R1 /* stack, in Mach */ BL main(SB) + RETURN /* not reached */ TEXT splhi(SB), $0 @@ -131,6 +135,13 @@ tas0: ISYNC RETURN +TEXT firmware(SB), $0 + MOVW $0, R4 + MOVW R4, SPR(SRR1) + MOVW $0x100, R5 + MOVW R5, SPR(SRR0) + RFI + TEXT getpvr(SB), $0 MOVW SPR(PVR), R3 RETURN @@ -192,14 +203,6 @@ TEXT trapvec(SB), $-4 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 @@ -209,7 +212,7 @@ TEXT trapvec(SB), $-4 /* switch to kernel stack */ MOVW R1, CR MOVW $(MACHADDR&~KZERO), R1 /* PADDR(m->) */ - MOVW 12(R1), R1 /* m->proc */ + MOVW 8(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) */ @@ -226,7 +229,6 @@ ktrap: BL trap(SB) BR restoreureg - /* * enter with stack set and mapped. * on return, SB (R2) has been set, and R3 has the Ureg*, @@ -241,7 +243,7 @@ TEXT saveureg(SB), $-4 MOVMW R2, 48(R1) /* r2:r31 */ MOVW $setSB(SB), R2 MOVW $(MACHADDR&~KZERO), R(MACH) - MOVW 12(R(MACH)), R(USER) + MOVW 8(R(MACH)), R(USER) MOVW $MACHADDR, R(MACH) MOVW SPR(SAVER1), R4 MOVW R4, 44(R1) @@ -271,9 +273,9 @@ TEXT saveureg(SB), $-4 // OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */ MOVW R5, SPR(SRR1) MOVW LR, R31 -// OR $KZERO, R31 /* return PC in KSEG0 */ + OR $KZERO, R31 /* return PC in KSEG0 */ MOVW R31, SPR(SRR0) -// OR $KZERO, R1 /* fix stack pointer */ + OR $KZERO, R1 /* fix stack pointer */ RFI /* returns to trap handler */ /* diff --git a/mtx/main.c b/mtx/main.c index d9c52a8efae137420827d294df6ef58ff2ade617..25dcf9cacfba0f290b6d0925e4d79658fe06eceb 100644 --- a/mtx/main.c +++ b/mtx/main.c @@ -13,24 +13,15 @@ FPsave initfp; void main(void) { + memset(edata, 0, (ulong)end-(ulong)edata); conf.nmach = 1; machinit(); - active.machs = 1; - active.exiting = 0; + clockinit(); 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(); @@ -42,12 +33,18 @@ for(;;); // swapinit(); // userinit(); // schedinit(); +spllo(); +putdec(64); +putmsr(getmsr() | MSR_IR | MSR_DR); +*(ulong*)-1 = 0; +firmware(); } void machinit(void) { memset(m, 0, sizeof(Mach)); +// m->cputype = getpvr()>>16; /* * For polled uart output at boot, need @@ -55,7 +52,28 @@ machinit(void) * be enough for a while. Cpuidentify will * calculate the real value later. */ -// m->loopconst = 100000; + m->loopconst = 100000; +m->loopconst = 5000; + + active.machs = 1; + active.exiting = 0; +} + +void +cpuidprint(void) +{ + char *id; + + id = "?"; + switch(m->cputype) { + case 9: + id = "PowerPC 604e"; + break; + default: + panic("unknown PowerPC"); + break; + } + print("cpu0: %s\n", id); } static struct @@ -214,8 +232,7 @@ exit(int ispanic) else delay(1000); - for(;;) - ; + firmware(); } /* diff --git a/mtx/mem.h b/mtx/mem.h index 801585dc764478280b4f1e2280891928a284b6d8..527f10b5a9af6de26dcbc9e976ab584bd169c0fd 100644 --- a/mtx/mem.h +++ b/mtx/mem.h @@ -148,7 +148,7 @@ /* * Fundamental addresses */ -#define MACHADDR (KTZERO-MAXMACH*MACHSIZE) +#define MACHADDR (KZERO+0x2000) #define MACHP(n) ((Mach *)(MACHADDR+(n)*MACHSIZE)) #define UREGSIZE ((8+32)*4) @@ -208,8 +208,9 @@ #define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ #define TSTKTOP KZERO /* top of temporary stack */ #define TSTKSIZ 100 -#define KZERO 0x80000000 /* base of kernel address space */ -#define KTZERO (KZERO+0x400000) /* first address in kernel text */ +//#define KZERO 0x80000000 /* base of kernel address space */ +#define KZERO 0 +#define KTZERO (KZERO+0x4000) /* first address in kernel text */ #define USTKSIZE (4*1024*1024) /* size of user stack */ #define PCI1 0x40000000 diff --git a/mtx/trap.c b/mtx/trap.c index 2dd46e23e93782295618006101d5ded1ff03a156..bede92b6a3d74725f9a700709c5a7b2d97a34ea9 100644 --- a/mtx/trap.c +++ b/mtx/trap.c @@ -32,7 +32,6 @@ struct } halloc; void faultpower(Ureg *ur, ulong addr, int read); -void kernfault(Ureg*, int); void syscall(Ureg* ureg); void noted(Ureg*, ulong); void reset(void); @@ -49,35 +48,17 @@ char *excname[] = "program exception", "floating-point unavailable", "decrementer", - "i/o controller interface error", + "reserved A", "reserved B", "system call", "trace trap", "floating point assist", "reserved F", - "software emulation", - "ITLB miss", - "DTLB miss", - "ITLB error", - "DTLB error", - "reserved 15", - "reserved 16", - "reserved 17", - "reserved 18", - "reserved 19", - "reserved 1A", - "reserved 1B", - "data breakpoint", - "instruction breakpoint", - "peripheral breakpoint", - "development port", - /* the following are made up on a program exception */ - "floating point exception", /* 20: FPEXC */ - "illegal instruction", /* 21 */ - "privileged instruction", /* 22 */ - "trap", /* 23 */ - "illegal operation", /* 24 */ - "breakpoint", /* 25 */ + "reserved 10", + "reserved 11", + "reserved 12", + "instruction address breakpoint", + "system management interrupt", }; char *fpcause[] = @@ -118,11 +99,10 @@ char *regname[]={ void trap(Ureg *ur) { - int ecode; - static struct {int callsched;} c = {1}; - int user; - char buf[ERRMAX]; + int ecode,user; + char buf[ERRMAX], *s; +if(m->loopconst != 5000) print("XXX\n"); print("trap\n"); m->intrts = fastticks(nil); ecode = (ur->cause >> 8) & 0xff; @@ -132,56 +112,58 @@ if(ur->status & MSR_RI == 0) print("double fault?: ecode = %d\n", ecode); switch(ecode){ case CEI: +print("intr\n"); intr(ur); break; case CDEC: +print("clock\n"); clockintr(ur); break; -/* - case CIMISS: - faultpower(ur, ur->pc, 1); - break; - case CITLBE: - faultpower(ur, ur->pc, 1); - break; - case CDMISS: -if(0) print("CDMISS: %lux %lux\n", m->epn, m->cmp1); - faultpower(ur, m->dar, 1); - break; - case CDTLBE: - faultpower(ur, m->dar, !(m->dsisr & (1<<25))); - break; -*/ case CSYSCALL: +print("syscall\n"); syscall(ur); break; case CPROG: +print("program\n"); if(ur->status & (1<<19)) - ecode = 0x20; - if(ur->status & (1<<18)) - ecode = 0x21; - if(ur->status & (1<<17)) - ecode = 0x22; - goto Default; - - Default: + s = "floating point exception"; + else if(ur->status & (1<<18)) + s = "illegal instruction"; + else if(ur->status & (1<<17)) + s = "privileged instruction"; + else + s = "undefined program exception"; + if(user){ + spllo(); + sprint(buf, "sys: trap: %s", s); + postnote(up, 1, buf, NDebug); + break; + } + dumpregs(ur); + panic(s); + break; + default: - spllo(); - print("ecode = %d\n", ecode); - if(ecode < 0 || ecode >= 0x1F) - ecode = 0x1F; - print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc); +print("default\n"); + if(ecode <= nelem(excname) && user){ + spllo(); + sprint(buf, "sys: trap: %s", excname[ecode]); + postnote(up, 1, buf, NDebug); + break; + } dumpregs(ur); - dumpstack(); - delay(100); - reset(); + if(ecode < nelem(excname)) + panic("%s", excname[ecode]); + panic("unknown trap/intr: %d\n", ecode); } - splhi(); - if(user) + + if(user && (up->procctl || up->nnote)){ + splhi(); notify(ur); + } } void @@ -203,8 +185,7 @@ if(0)print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx } print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx\n", up->pid, ureg->pc, addr, read, user, &ureg); dumpregs(ureg); - sprint(buf, "sys: trap: fault %s addr=0x%lux", - read? "read" : "write", addr); + sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr); postnote(up, 1, buf, NDebug); } up->insyscall = insyscall; @@ -251,14 +232,13 @@ trapinit(void) { int i; - putdec(~0); - putmsr(getmsr() & ~MSR_IP); - /* - * set all exceptions to trap + * set all exceptions to trap, except reset */ - for(i = 0x0; i < 0x2000; i += 0x100) + for(i = 0x200; i < 0x2000; i += 0x100) sethvec(i, trapvec); + + putmsr(getmsr() & ~MSR_IP); } void @@ -385,24 +365,6 @@ fpexcname(Ureg *ur, ulong fpscr, char *buf) return buf; } -#define KERNPC(x) (KTZERO<(ulong)(x)&&(ulong)(x)<(ulong)etext) - -void -kernfault(Ureg *ur, int code) -{ - Label l; - - print("panic: kfault %s dar=0x%lux\n", excname[code], getdar()); - print("u=0x%lux status=0x%lux pc=0x%lux sp=0x%lux\n", - up, ur->status, ur->pc, ur->sp); - dumpregs(ur); - l.sp = ur->sp; - l.pc = ur->pc; - dumpstack(); - for(;;) - sched(); -} - /* * Fill in enough of Ureg to get a stack trace, and call a function. * Used by debugging interface rdb. @@ -452,7 +414,7 @@ dumpregs(Ureg *ur) ulong *l; if(up) { print("registers for %s %ld\n", up->text, up->pid); -// if(ur->srr1 & MSR_PR == 0) + if(ur->srr1 & MSR_PR == 0) if(ur->usp < (ulong)up->kstack || ur->usp > (ulong)up->kstack+KSTACK) print("invalid stack ptr\n"); } @@ -468,7 +430,6 @@ dumpregs(Ureg *ur) static void linkproc(void) { -//print("linkproc %ulx\n", up); spllo(); (*up->kpfun)(up->kparg); pexit("", 0); @@ -484,36 +445,6 @@ kprocchild(Proc *p, void (*func)(void*), void *arg) p->kparg = arg; } -int -isvalid_pc(ulong pc) -{ - return KERNPC(pc) && (pc&3) == 0; -} - -void -dumplongs(char*, ulong*, int) -{ -} - -void -reset(void) -{ -#ifdef BLOG - IMM *io; - - io = m->iomem; - io->plprcrk = KEEP_ALIVE_KEY; // unlock - io->plprcr |= IBIT(24); // enable checkstop reset - putmsr(getmsr() & ~(MSR_ME|MSR_RI)); -predawn = 1; -print("reset = %ulx\n", getmsr()); - delay(1000); - // cause checkstop -> causes reset - *(uchar*)(0xdeadbeef) = 0; - *(ulong*)(0) = 0; -#endif -} - /* * called in sysfile.c */ diff --git a/port/sysproc.c b/port/sysproc.c index a6ddc67124a4d85df02df8e76c2d7270172b4ca9..f1a53910612643fcf004a3e44b64c57b81e1bc80 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -95,6 +95,7 @@ sysrfork(ulong *arg) incref(p->dot); memmove(p->note, up->note, sizeof(p->note)); + p->privatemem = up->privatemem; p->nnote = up->nnote; p->notified = 0; p->lastnote = up->lastnote;