From f472fe0260eb0ccd2457d05aca8840e7f101cb38 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 27 Jan 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-01-27 --- mpc/clock.c | 4 +- mpc/dat.h | 5 +- mpc/devuart.c | 3 ++ mpc/fns.h | 3 +- mpc/l.s | 60 ++++++++++++++++++++++-- mpc/main.c | 123 +++++++++++++++++++++++++++++++++++++++++++++---- mpc/mem.h | 2 +- mpc/mmu.c | 11 ++++- mpc/trap.c | 53 +++++++++++++++++---- port/devdraw.c | 2 +- 10 files changed, 238 insertions(+), 28 deletions(-) diff --git a/mpc/clock.c b/mpc/clock.c index 2263ca33b600dad96049a30ae93c2213e0b6d09c..0ac36d048ae5236d2324ac4b81124096c9190fb6 100644 --- a/mpc/clock.c +++ b/mpc/clock.c @@ -110,8 +110,8 @@ clockintr(Ureg *ur) m->iomem->swsr = 0xaa39; m->ticks++; -// if(m->ticks%MS2TK(1000) == 0) -// *(uchar*)(NIMMEM+0x2200) = (m->ticks/MS2TK(1000))&2; + if(m->ticks%MS2TK(1000) == 0) + *(uchar*)(NIMMEM+0x2200) = (m->ticks/MS2TK(1000))&2; if(up) up->pc = ur->pc; diff --git a/mpc/dat.h b/mpc/dat.h index ecc5ced40f52ac4ba563898387cd5596d5a4480c..ce845ecb59a35dd535b4a3723fad01d123cd04ab 100644 --- a/mpc/dat.h +++ b/mpc/dat.h @@ -110,12 +110,12 @@ struct Mach { /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */ int machno; /* physical id of processor (unused) */ - ulong splpc; /* pc of last caller to splhi (unused) */ + ulong splpc; /* pc of last caller to splhi */ int mmask; /* 1<machno (unused) */ + Proc *proc; /* current process on this processor */ /* ordering from here on irrelevant */ ulong ticks; /* of the clock since boot time */ - Proc *proc; /* current process on this processor */ Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ @@ -215,3 +215,4 @@ struct extern register Mach *m; extern register Proc *up; +extern int predawn; diff --git a/mpc/devuart.c b/mpc/devuart.c index 6b58071a26620914eb9ac4630e2825e6d7414f0b..74df9c4b0cd9c167d1fa861b61f5f5a72c97c266 100644 --- a/mpc/devuart.c +++ b/mpc/devuart.c @@ -826,6 +826,9 @@ uartkick(Uart *p) if(p->outb == nil) txstart(p); iunlock(&p->plock); + + if(predawn) + uartwait(); } /* diff --git a/mpc/fns.h b/mpc/fns.h index 873ea98592cbbd391ea80cfb8e3d73c6876be995..2ae180049ad5441ca7f0e58a96bfe4e2020665aa 100644 --- a/mpc/fns.h +++ b/mpc/fns.h @@ -22,7 +22,7 @@ void dumpregs(Ureg*); //void eieio(void); #define eieio() void evenaddr(ulong); -void faultpower(Ureg*); +void faultpower(Ureg*, ulong addr, int read); void firmware(int); void fpinit(void); int fpipower(Ureg*); @@ -72,6 +72,7 @@ int segflush(void*, ulong); void spireset(void); long spioutin(void*, long, void*); int tas(void*); +void touser(void*); void trapinit(void); void trapvec(void); void uartinstall(void); diff --git a/mpc/l.s b/mpc/l.s index 29a027729a5c2e1c580fce64242058dde5cbac13..9dd8ce99450412e0cd5c350c5aabedef1a8540ac 100644 --- a/mpc/l.s +++ b/mpc/l.s @@ -196,6 +196,14 @@ ltlb: MOVW R5, SPR(MI_RPN) BDNZ ltlb + /* lock kernel entries in tlb - also reset tlb index*/ + MOVW $(MMUCIDEF|MMURSV4), R4 + MOVW R4, SPR(MI_CTR) /* i-mmu control */ + ISYNC + MOVW $(MMUCIDEF|MMUWTDEF|MMURSV4), R4 + MOVW R4, SPR(MD_CTR) /* d-mmu control */ + ISYNC + /* enable MMU */ MOVW MSR, R4 OR $(MSR_IR|MSR_DR), R4 @@ -262,6 +270,14 @@ TEXT gotolabel(SB), $-4 MOVW $1, R3 RETURN +TEXT touser(SB), $-4 + MOVW $(UTZERO+32), R5 /* header appears in text */ + MOVW $(MSR_EE|MSR_PR|MSR_ME|MSR_IP|MSR_IR|MSR_DR|MSR_RI), R4 + MOVW R4, SPR(SRR1) + MOVW R3, R1 + MOVW R5, SPR(SRR0) + RFI + /* * enter with stack set and mapped. * on return, SB (R2) has been set, and R3 has the Ureg*, @@ -276,6 +292,8 @@ TEXT saveureg(SB), $-4 */ MOVMW R2, 48(R1) /* r2:r31 */ MOVW $setSB(SB), R2 + MOVW $mach0(SB), R(MACH) + MOVW 12(R(MACH)), R(USER) MOVW SPR(SAVER1), R4 MOVW R4, 44(R1) MOVW SPR(SAVER0), R5 @@ -413,7 +431,22 @@ TEXT flushmmu(SB), $0 TLBIA RETURN -TEXT putmmu(SB), $0 +TEXT _putmmu(SB), $0 + MOVW MSR, R7 + MOVW $~(MSR_DR|MSR_IR), R8 + AND R7, R8 + MOVW R8, MSR + OR $MMUEV, R3 + MOVW R3, SPR(MD_EPN) + MOVW R3, SPR(MI_EPN) + MOVW $(MMUWT|MMUV), R5 + MOVW R5, SPR(MI_TWC) + MOVW R5, SPR(MD_TWC) + MOVW 4(FP), R6 + MOVW R6, SPR(MD_RPN) + MOVW R6, SPR(MI_RPN) + MOVW SPR(MD_CTR), R3 + MOVW R7, MSR RETURN TEXT gotopc(SB), $0 @@ -530,7 +563,6 @@ TEXT dtlbmiss(SB), $-4 /* * traps force memory mapping off. - * this code goes to too much effort (for the Inferno environment) to restore it. */ TEXT trapvec(SB), $-4 traps: @@ -538,9 +570,31 @@ traps: MOVW R0, SPR(SAVEXX) /* vector */ MOVW R1, SPR(SAVER1) - SUB $UREGSPACE, R1 + MOVW CR, R1 + MOVW MSR, R0 + OR $(MSR_DR|MSR_IR), R0 /* make data space usable */ + MOVW R0, MSR MOVW SPR(SRR0), R0 /* save SRR0/SRR1 now, since DLTB might be missing stack page */ MOVW R0, LR + MOVW SPR(SRR1), R0 + ANDCC $MSR_PR, R0 + BEQ ktrap + + /* switch to kernel stack */ + MOVW R1, CR + MOVW R2, R0 + MOVW $setSB(SB), R2 + MOVW $mach0(SB), R1 /* m-> */ + MOVW R0, R2 + MOVW 12(R1), R1 /* m->proc */ + MOVW 8(R1), R1 /* m->proc->kstack */ + ADD $(KSTACK-UREGSIZE), R1 + BR trap1 +ktrap: + MOVW R1, CR + MOVW SPR(SAVER1), R1 + SUB $UREGSPACE, R1 +trap1: MOVW SPR(SRR1), R0 MOVW R0, 12(R1) /* save status: could take DLTB miss here */ MOVW LR, R0 diff --git a/mpc/main.c b/mpc/main.c index 9ae33dcf14a692b10845b920ab9627b9af2f0421..dec9b1e5070c3bb374557526ed141b098b2c4241 100644 --- a/mpc/main.c +++ b/mpc/main.c @@ -13,6 +13,8 @@ char *confname[MAXCONF]; char *confval[MAXCONF]; int nconf; +int predawn = 1; + Conf conf; void @@ -30,8 +32,6 @@ flash(void) void main(void) { - int i; - machinit(); clockinit(); confinit(); @@ -41,13 +41,23 @@ main(void) cpminit(); uartinstall(); mmuinit(); - spllo(); - for(i=0; ; i++) { - print("hello again %d\n", i); - delay(100); +if(0) { + predawn = 0; + print("spllo() = %ux\n", spllo()); + for(;;) { + print("hello\n"); + delay(1000); } - - reset(); +} + pageinit(); + procinit0(); + initseg(); + links(); + chandevreset(); + swapinit(); + userinit(); +predawn = 0; + schedinit(); } void @@ -70,6 +80,103 @@ machinit(void) m->clockgen = osc*MHz; /* clock generator frequency (cycles) */ } +void +bootargs(ulong base) +{ +print("bootargs = %ux\n", base); + USED(base); +} + +void +init0(void) +{ + int i; + + up->nerrlab = 0; + +print("spllo = %ux\n", 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); + up->dot = cclone(up->slash, 0); + + chandevinit(); + + if(!waserror()){ + ksetenv("cputype", "power"); + if(cpuserver) + ksetenv("service", "cpu"); + else + ksetenv("service", "terminal"); + for(i = 0; i < nconf; i++) + if(confname[i] && confname[i][0] != '*') + ksetenv(confname[i], confval[i]); + poperror(); + } + kproc("alarm", alarmkproc, 0); + print("to user!!\n"); + 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); + k = kmap(pg); + bootargs(VA(k)); + kunmap(k); + + /* + * 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) { diff --git a/mpc/mem.h b/mpc/mem.h index cfa04db1b8b755a8cf772a42582bc3a59751b039..0476477ab0633f3972e3ebeb59808faf09155041 100644 --- a/mpc/mem.h +++ b/mpc/mem.h @@ -122,7 +122,7 @@ /* * portable MMU bits for fault.c - though still machine specific */ -#define PTEVALID (1<<0) +#define PTEVALID (MMUPP|MMUSH|MMUCI|MMUV) #define PTEWRITE (2<<10) #define PTERONLY (3<<10) #define PTEUNCACHED (1<<4) diff --git a/mpc/mmu.c b/mpc/mmu.c index b29ccf1273a8cb9fab4dbb36e2bf54929607995a..e581bf41123c656afc1c9e2ecbab698d9ca18d93 100644 --- a/mpc/mmu.c +++ b/mpc/mmu.c @@ -9,7 +9,7 @@ void mmuinit(void) { -iprint("mmuinit\n"); + print("mmuinit\n"); kernelmmu(); } @@ -26,3 +26,12 @@ mmurelease(Proc* proc) } +void +putmmu(ulong va, ulong pa, Page*) +{ + int x, r; +print("putmmu va=%ux pa=%ux\n", va, pa); + x = splhi(); + r = _putmmu(va, pa); + splx(x); +} diff --git a/mpc/trap.c b/mpc/trap.c index 5569e3d4daeb4a3b9e837fcd586fdfdf6fb47337..1ac2dc92c234acb2172a96cbaf9f1cb5c093cf62 100644 --- a/mpc/trap.c +++ b/mpc/trap.c @@ -31,6 +31,7 @@ struct int free; } halloc; +void faultpower(Ureg *ur, ulong addr, int read); void kernfault(Ureg*, int); char *excname[] = @@ -161,14 +162,15 @@ trap(Ureg *ur) clockintr(ur); break; - case CMCHECK: - case CDSI: - case CISI: case CIMISS: - case CDMISS: case CITLBE: + faultpower(ur, ur->pc, 1); + break; + case CDMISS: + faultpower(ur, getdepn(), 1); + break; case CDTLBE: - goto Default; + faultpower(ur, getdar(), !(getdsisr() & (1<<25))); break; case CEMU: @@ -176,6 +178,14 @@ trap(Ureg *ur) goto Default; break; + case CSYSCALL: + spllo(); + print("syscall!\n"); + dumpregs(ur); + delay(100); + splhi(); + break; + case CPROG: if(ur->status & (1<<19)) ecode = 0x20; @@ -190,14 +200,38 @@ trap(Ureg *ur) print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc); dumpregs(ur); dumpstack(); - if(m->machno == 0) - spllo(); + spllo(); exit(1); } splhi(); } +void +faultpower(Ureg *ureg, ulong addr, int read) +{ + int user, insyscall, n; + char buf[ERRLEN]; + + user = (ureg->srr1 & MSR_PR) != 0; +print("fault: pc = %ux, addr = %ux read = %d user = %d stack=%ux\n", ureg->pc, addr, read, user, &ureg); + insyscall = up->insyscall; + up->insyscall = 1; + spllo(); + n = fault(addr, read); + if(n < 0){ + if(!user){ + dumpregs(ureg); + panic("fault: 0x%lux\n", addr); + } + sprint(buf, "sys: trap: fault %s addr=0x%lux", + read? "read" : "write", addr); + postnote(up, 1, buf, NDebug); + } + up->insyscall = insyscall; + splhi(); +} + void spurious(Ureg *ur, void *a) { @@ -413,8 +447,8 @@ dumpregs(Ureg *ur) ulong *l; if(up) { print("registers for %s %d\n", up->text, up->pid); - if(ur->usp < (ulong)up->kstack || - ur->usp > (ulong)up->kstack+KSTACK) + if(ur->srr1 & MSR_PR == 0) + if(ur->usp < (ulong)up->kstack || ur->usp > (ulong)up->kstack+KSTACK) print("invalid stack ptr\n"); } else @@ -429,6 +463,7 @@ dumpregs(Ureg *ur) static void linkproc(void) { +print("linkproc %ux\n", up); spllo(); (*up->kpfun)(up->kparg); pexit("", 0); diff --git a/port/devdraw.c b/port/devdraw.c index 4acc9e2e67a8620f8b765efc8d240b34aeaee6dc..38d1338fcfa604815571ec3430352f4ff5f3aa57 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -1830,7 +1830,7 @@ drawactive(int active) if(active){ drawblankscreen(0); sdraw.blanktime = 0; - }else { + }else{ if(TK2MS(sdraw.blanktime) > BLANKTIME) drawblankscreen(1); else