M mpc/clock.c => mpc/clock.c +2 -2
@@ 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;
M mpc/dat.h => mpc/dat.h +3 -2
@@ 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<<m->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;
M mpc/devuart.c => mpc/devuart.c +3 -0
@@ 826,6 826,9 @@ uartkick(Uart *p)
if(p->outb == nil)
txstart(p);
iunlock(&p->plock);
+
+ if(predawn)
+ uartwait();
}
/*
M mpc/fns.h => mpc/fns.h +2 -1
@@ 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);
M mpc/l.s => mpc/l.s +57 -3
@@ 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,10 570,32 @@ 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
MOVW R0, 16(R1) /* old PC */
M mpc/main.c => mpc/main.c +115 -8
@@ 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
@@ 71,6 81,103 @@ machinit(void)
}
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)
{
int ms, once;
M mpc/mem.h => mpc/mem.h +1 -1
@@ 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)
M mpc/mmu.c => mpc/mmu.c +10 -1
@@ 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);
+}
M mpc/trap.c => mpc/trap.c +44 -9
@@ 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,8 200,7 @@ 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);
}
@@ 199,6 208,31 @@ trap(Ureg *ur)
}
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)
{
USED(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);
M port/devdraw.c => port/devdraw.c +1 -1
@@ 1830,7 1830,7 @@ drawactive(int active)
if(active){
drawblankscreen(0);
sdraw.blanktime = 0;
- }else {
+ }else{
if(TK2MS(sdraw.blanktime) > BLANKTIME)
drawblankscreen(1);
else