M alphapc/dma.c => alphapc/dma.c +3 -3
@@ 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
*/
M mtx/clock.c => mtx/clock.c +19 -11
@@ 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
M mtx/dat.h => mtx/dat.h +15 -19
@@ 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];
};
M mtx/fns.h => mtx/fns.h +2 -3
@@ 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);
M mtx/l.s => mtx/l.s +15 -13
@@ 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 */
/*
M mtx/main.c => mtx/main.c +31 -14
@@ 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();
}
/*
M mtx/mem.h => mtx/mem.h +4 -3
@@ 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
M mtx/trap.c => mtx/trap.c +50 -119
@@ 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
*/
M port/sysproc.c => port/sysproc.c +1 -0
@@ 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;