M mtx/clock.c => mtx/clock.c +3 -3
@@ 28,16 28,16 @@ delayloopinit(void)
void
clockinit(void)
{
- /* XXX the hardcoding of these values is WRONG */
+ /* XXX this should not be hard coded! */
m->cpuhz = 300000000;
m->bushz = 66666666;
m->dechz = m->bushz/4; /* true for all 604e */
- m->tbhz = m->dechz; /* conjecture; manual says bugger all */
+ m->tbhz = m->dechz; /* conjecture; manual doesn't say */
delayloopinit();
- clkreload = m->dechz/HZ-1; /* decremented at 1/4 bus clock speed */
+ clkreload = m->dechz/HZ-1;
putdec(clkreload);
}
M mtx/dat.h => mtx/dat.h +6 -0
@@ 152,6 152,12 @@ struct Mach
int intr;
int flushmmu; /* make current proc flush it's mmu state */
+ ulong ptabbase; /* start of page table in kernel virtual space */
+ int slotgen; /* next pte (byte offset) when pteg is full */
+ int mmupid; /* next mmu pid to use */
+ int minpid;
+ int maxpid;
+
ulong spuriousintr;
int lastintr;
M mtx/devrtc.c => mtx/devrtc.c +19 -2
@@ 21,8 21,9 @@ enum{
/*
* register offsets into time of day clock
*/
- NVflags= 0x1ff0,
- NVctl= 0x1ff8,
+ NVflags= 0x1ff0,
+ NVwatchdog= 0x1ff7,
+ NVctl= 0x1ff8,
NVsec,
NVmin,
NVhour,
@@ 37,6 38,14 @@ enum{
RTsign = (1<<5),
RTcal = 0x1f,
+ /* NVwatchdog */
+ WDsteer = (1<<7), /* 0 -> intr, 1 -> reset */
+ WDmult = (1<<2), /* 5 bits of multiplier */
+ WDres0 = (0<<0), /* 1/16 sec resolution */
+ WDres1 = (1<<0), /* 1/4 sec resolution */
+ WDres2 = (2<<0), /* 1 sec resolution */
+ WDres3 = (3<<0), /* 4 sec resolution */
+
Qdir = 0,
Qrtc,
Qnvram,
@@ 244,6 253,14 @@ nvcksum(void)
{
}
+void
+watchreset(void)
+{
+ splhi();
+ nvput(NVwatchdog, WDsteer|(1*WDmult)|WDres0);
+ for(;;);
+}
+
static int
getbcd(int bcd)
{
M mtx/fns.h => mtx/fns.h +2 -2
@@ 16,7 16,6 @@ void delayloopinit(void);
void eieio(void);
void evenaddr(ulong);
void faultpower(Ureg*, ulong addr, int read);
-void firmware(void);
void fpinit(void);
void fprestore(FPsave*);
void fpsave(FPsave*);
@@ 91,7 90,7 @@ Pcidev* pcimatch(Pcidev*, int, int);
Pcidev* pcimatchtbdf(int);
void pcireset(void);
void pcisetbme(Pcidev*);
-#define procrestore(p)
+#define procrestore(p)
void procsave(Proc*);
void procsetup(Proc*);
void putdec(ulong);
@@ 114,6 113,7 @@ void tlbflushall(void);
void uartinstall(void);
void uartwait(void); /* debugging */
#define userureg(ur) (((ur)->status & MSR_PR) != 0)
+void watchreset(void);
void wbflush(void);
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
M mtx/l.s => mtx/l.s +0 -17
@@ 49,10 49,6 @@
/* set R2 to correct value */
MOVW $setSB(SB), R2
- /* save SPR(SPRG3), or else we can't go back to firmware! */
- MOVW SPR(SPRG3), R3
- MOVW R3, initsprg3(SB)
-
/* debugger sets R1 to top of usable memory +1 */
MOVW R1, memsize(SB)
@@ 70,7 66,6 @@
RETURN /* not reached */
GLOBL mach0(SB), $(MAXMACH*BY2PG)
-GLOBL initsprg3(SB), $4
GLOBL memsize(SB), $4
/*
@@ 285,18 280,6 @@ tas0:
ISYNC
RETURN
-TEXT firmware(SB), $0
- MOVW initsprg3(SB), R3
- MOVW R3, SPR(SPRG3)
-// MOVW $0x4000, R3
-// MOVW R3, SPR(SPRG3)
- MOVW R0, SPR(HID0)
- MOVW $MSR_IP, R4
- MOVW R4, SPR(SRR1)
- MOVW $0xfff00100, R5
- MOVW R5, SPR(SRR0)
- RFI
-
TEXT getpvr(SB), $0
MOVW SPR(PVR), R3
RETURN
M mtx/main.c => mtx/main.c +1 -1
@@ 240,7 240,7 @@ exit(int ispanic)
else
delay(1000);
- firmware();
+ watchreset();
}
/*
M mtx/mmu.c => mtx/mmu.c +30 -36
@@ 14,16 14,8 @@
* mmu pids, with a background kproc to purge stale pids en mass.
*/
-static struct {
- Lock;
- ulong base; /* start of page table in kernel virtual space */
- ulong size; /* number of bytes in page table */
- ulong mask; /* hash mask */
- int slotgen; /* next pte (byte offset) when pteg is full */
-
- int pidlock;
- int pidgen; /* next mmu pid to use */
-} ptab;
+static ulong ptabsize; /* number of bytes in page table */
+static ulong ptabmask; /* hash mask */
/*
* VSID is 24 bits. 3 are required to distinguish segments in user
@@ 42,20 34,28 @@ mmuinit(void)
{
int lhash, mem;
extern ulong memsize; /* passed in from ROM monitor */
-
- /* heuristically size the hash table */
- lhash = 10; /* log of hash table size */
- mem = (1<<23);
- while(mem < memsize) {
- lhash++;
- mem <<= 1;
+ ulong v;
+
+ if(ptabsize == 0) {
+ /* heuristically size the hash table */
+ lhash = 10;
+ mem = (1<<23);
+ while(mem < memsize) {
+ lhash++;
+ mem <<= 1;
+ }
+ ptabsize = (1<<(lhash+6));
+ ptabmask = (1<<lhash)-1;
}
- ptab.size = (1<<(lhash+6));
- ptab.base = (ulong)xspanalloc(ptab.size, 0, ptab.size);
- putsdr1(PADDR(ptab.base) | ((1<<(lhash-10))-1));
- ptab.pidgen = PIDBASE;
- ptab.mask = (1<<lhash)-1;
+ m->ptabbase = (ulong)xspanalloc(ptabsize, 0, ptabsize);
+ putsdr1(PADDR(m->ptabbase) | (ptabmask>>10));
+ m->mmupid = PIDBASE;
+
+ v = getdec();
+ memset((void*)m->ptabbase, 0, ptabsize);
+ v -= getdec();
+ print("memset took %lud cycles, dechz %lud\n", v, m->dechz);
}
void
@@ 114,14 114,13 @@ putmmu(ulong va, ulong pa, Page *pg)
panic("putmmu pid");
vsid = VSID(mp, va>>28);
- hash = (vsid ^ (va>>12)&0xffff) & ptab.mask;
+ hash = (vsid ^ (va>>12)&0xffff) & ptabmask;
ptehi = PTE0(1, vsid, 0, va);
- pteg = ptab.base + BY2PTEG*hash;
+ pteg = m->ptabbase + BY2PTEG*hash;
p = (ulong*)pteg;
ep = (ulong*)(pteg+BY2PTEG);
q = nil;
- ilock(&ptab);
tlbflush(va);
while(p < ep) {
x = p[0];
@@ 135,13 134,12 @@ if(q[1] == pa) print("putmmu already set pte\n");
p += 2;
}
if(q == nil) {
- q = (ulong*)(pteg+ptab.slotgen);
- ptab.slotgen = (ptab.slotgen + BY2PTE) & (BY2PTEG-1);
+ q = (ulong*)(pteg+m->slotgen);
+ m->slotgen = (m->slotgen + BY2PTE) & (BY2PTEG-1);
}
q[0] = ptehi;
q[1] = pa;
sync();
- iunlock(&ptab);
ctl = &pg->cachectl[m->machno];
switch(*ctl) {
@@ 164,14 162,10 @@ newmmupid(void)
{
int pid;
- /* can't use lock() here as we're called from within sched() */
- while(!tas(&ptab.pidlock))
- ;
- pid = ptab.pidgen++;
- if(pid > PIDMAX)
- pid = PIDBASE;
- ptab.pidlock = 0;
- coherence();
+ pid = m->mmupid++;
+ if(m->mmupid > PIDMAX)
+ panic("ran out of mmu pids");
+// m->mmupid = PIDBASE;
up->mmupid = pid;
return pid;
}