M ip/devip.c => ip/devip.c +1 -0
@@ 496,6 496,7 @@ ipopen(Chan* c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
+ c->iounit = qiomaxatomic;
return c;
}
A mtx/clock.c => mtx/clock.c +56 -0
@@ 0,0 1,56 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "ureg.h"
+
+void
+clockintr(Ureg *ureg)
+{
+ // this needs to be here for synchronizing mp clocks
+ // see pc/mp.c's squidboy()
+ fastticks(nil);
+
+ if(m->flushmmu){
+ if(up)
+ flushmmu();
+ m->flushmmu = 0;
+ }
+
+ portclock(ureg);
+}
+
+void
+delay(int l)
+{
+ ulong i, j;
+
+// j = m->delayloop;
+// while(l-- > 0)
+// for(i=0; i < j; i++)
+// ;
+}
+
+void
+microdelay(int l)
+{
+ ulong i;
+
+// l *= m->delayloop;
+// l += 500;
+// l /= 1000;
+// if(l <= 0)
+// l = 1;
+// for(i = 0; i < l; i++)
+// ;
+}
+
+vlong
+fastticks(uvlong *hz)
+{
+ if(hz)
+ *hz = HZ;
+ return m->ticks;
+}
M mtx/l.s => mtx/l.s +245 -9
@@ 1,14 1,22 @@
#include "mem.h"
+/* use of SPRG registers in save/restore */
+#define SAVER0 SPRG0
+#define SAVER1 SPRG1
+#define SAVELR SPRG2
+#define SAVEXX SPRG3
+
+/* special instruction definitions */
#define BDNZ BC 16,0,
#define BDNE BC 0,2,
-#define NOOP OR R0,R0,R0
-#define TLBIA WORD $(31<<26)
+//#define TLBIA WORD $(31<<26)
+#define TLBIA WORD $((31<<26)|(370<<1))
+//#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1))
+
+/* on some models mtmsr doesn't synchronise enough (eg, 603e) */
+#define MSRSYNC SYNC; ISYNC
-/* Be-ware 603e chip bugs (mtmsr instruction) */
-#define FIX603e CROR 0,0,0
-#undef FIX603e
-#define FIX603e ISYNC; SYNC
+#define UREGSPACE (UREGSIZE+8)
TEXT start(SB), $-4
MOVW $setSB(SB), R2
@@ 23,7 31,7 @@ TEXT splhi(SB), $0
RLWNM $0, R3, $~MSR_EE, R4
SYNC
MOVW R4, MSR
- FIX603e
+ MSRSYNC
RETURN
TEXT splx(SB), $0
@@ 36,7 44,7 @@ TEXT splxpc(SB), $0
RLWMI $0, R3, $MSR_EE, R4
SYNC
MOVW R4, MSR
- FIX603e
+ MSRSYNC
RETURN
TEXT spllo(SB), $0
@@ 44,7 52,7 @@ TEXT spllo(SB), $0
OR $MSR_EE, R3, R4
SYNC
MOVW R4, MSR
- FIX603e
+ MSRSYNC
RETURN
TEXT spldone(SB), $0
@@ 68,3 76,231 @@ TEXT gotolabel(SB), $-4
MOVW 0(R3), R1
MOVW $1, R3
RETURN
+
+TEXT touser(SB), $-4
+ MOVW $(UTZERO+32), R5 /* header appears in text */
+ MOVW $(MSR_EE|MSR_PR|MSR_ME|MSR_IR|MSR_DR|MSR_RI), R4
+ MOVW R4, SPR(SRR1)
+ MOVW R3, R1
+ MOVW R5, SPR(SRR0)
+ RFI
+
+TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */
+ MOVW n+4(FP), R4
+ RLWNM $0, R3, $~(CACHELINESZ-1), R5
+ SUB R5, R3
+ ADD R3, R4
+ ADD $(CACHELINESZ-1), R4
+ SRAW $CACHELINELOG, R4
+ MOVW R4, CTR
+icf0: ICBI (R5)
+ ADD $CACHELINESZ, R5
+ BDNZ icf0
+ ISYNC
+ RETURN
+
+TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */
+ MOVW n+4(FP), R4
+ RLWNM $0, R3, $~(CACHELINESZ-1), R5
+ CMP R4, $0
+ BLE dcf1
+ SUB R5, R3
+ ADD R3, R4
+ ADD $(CACHELINESZ-1), R4
+ SRAW $CACHELINELOG, R4
+ MOVW R4, CTR
+dcf0: DCBF (R5)
+ ADD $CACHELINESZ, R5
+ BDNZ dcf0
+dcf1:
+ RETURN
+
+TEXT tas(SB), $0
+ SYNC
+ MOVW R3, R4
+ MOVW $0xdead,R5
+tas1:
+ DCBF (R4) /* fix for 603x bug */
+ LWAR (R4), R3
+ CMP R3, $0
+ BNE tas0
+ STWCCC R5, (R4)
+ BNE tas1
+tas0:
+ SYNC
+ ISYNC
+ RETURN
+
+TEXT getpvr(SB), $0
+ MOVW SPR(PVR), R3
+ RETURN
+
+TEXT getdec(SB), $0
+ MOVW SPR(DEC), R3
+ RETURN
+
+TEXT putdec(SB), $0
+ MOVW R3, SPR(DEC)
+ RETURN
+
+TEXT getdar(SB), $0
+ MOVW SPR(DAR), R3
+ RETURN
+
+TEXT getdsisr(SB), $0
+ MOVW SPR(DSISR), R3
+ RETURN
+
+TEXT getmsr(SB), $0
+ MOVW MSR, R3
+ RETURN
+
+TEXT putmsr(SB), $0
+ SYNC
+ MOVW R3, MSR
+ MSRSYNC
+ RETURN
+
+TEXT eieio(SB), $0
+ EIEIO
+ RETURN
+
+TEXT tlbflushall(SB), $0
+ TLBIA
+ RETURN
+
+TEXT tlbflush(SB), $0
+ TLBIE R3
+ RETURN
+
+TEXT gotopc(SB), $0
+ MOVW R3, CTR
+ MOVW LR, R31 /* for trace back */
+ BR (CTR)
+
+/*
+ * traps force memory mapping off.
+ * the following code has been executed at the exception
+ * vector location
+ * MOVW R0, SPR(SAVER0)
+ * MOVW LR, R0
+ * MOVW R0, SPR(SAVELR)
+ * bl trapvec(SB)
+ */
+TEXT trapvec(SB), $-4
+ MOVW LR, R0
+ 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
+ MOVW R0, CR
+ BC 4,17,ktrap
+
+ /* switch to kernel stack */
+ MOVW R1, CR
+ MOVW $(MACHADDR&~KZERO), R1 /* PADDR(m->) */
+ MOVW 12(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) */
+ ADD $(KSTACK-UREGSIZE), R1
+ BL saveureg(SB)
+ BL trap(SB)
+ BR restoreureg
+ktrap:
+ MOVW R1, CR
+ MOVW SPR(SAVER1), R1
+ RLWNM $0, R1, $~KZERO, R1 /* PADDR(m->proc->kstack) */
+ SUB $UREGSPACE, R1
+ BL saveureg(SB)
+ BL trap(SB)
+ BR restoreureg
+
+
+/*
+ * enter with stack set and mapped.
+ * on return, SB (R2) has been set, and R3 has the Ureg*,
+ * the MMU has been re-enabled, kernel text and PC are in KSEG,
+ * R(MACH) has been set, and R0 contains 0.
+ *
+ */
+TEXT saveureg(SB), $-4
+/*
+ * save state
+ */
+ MOVMW R2, 48(R1) /* r2:r31 */
+ MOVW $setSB(SB), R2
+ MOVW $(MACHADDR&~KZERO), R(MACH)
+ MOVW 12(R(MACH)), R(USER)
+ MOVW $MACHADDR, R(MACH)
+ MOVW SPR(SAVER1), R4
+ MOVW R4, 44(R1)
+ MOVW SPR(SAVER0), R5
+ MOVW R5, 40(R1)
+ MOVW CTR, R6
+ MOVW R6, 36(R1)
+ MOVW XER, R4
+ MOVW R4, 32(R1)
+ MOVW CR, R5
+ MOVW R5, 28(R1)
+ MOVW SPR(SAVELR), R6 /* LR */
+ MOVW R6, 24(R1)
+ /* pad at 20(R1) */
+ MOVW SPR(SRR0), R0
+ MOVW R0, 16(R1) /* old PC */
+ MOVW SPR(SRR1), R0
+ MOVW R0, 12(R1) /* old status */
+ MOVW SPR(SAVEXX), R0
+ MOVW R0, 8(R1) /* cause/vector */
+ ADD $8, R1, R3 /* Ureg* */
+ OR $KZERO, R3 /* fix ureg */
+ STWCCC R3, (R1) /* break any pending reservations */
+ MOVW $0, R0 /* compiler/linker expect R0 to be zero */
+
+ MOVW MSR, R5
+// OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */
+ MOVW R5, SPR(SRR1)
+ MOVW LR, R31
+// OR $KZERO, R31 /* return PC in KSEG0 */
+ MOVW R31, SPR(SRR0)
+// OR $KZERO, R1 /* fix stack pointer */
+ RFI /* returns to trap handler */
+
+/*
+ * restore state from Ureg and return from trap/interrupt
+ */
+TEXT forkret(SB), $0
+ BR restoreureg
+
+restoreureg:
+ MOVMW 48(R1), R2 /* r2:r31 */
+ /* defer R1 */
+ MOVW 40(R1), R0
+ MOVW R0, SPR(SAVER0)
+ MOVW 36(R1), R0
+ MOVW R0, CTR
+ MOVW 32(R1), R0
+ MOVW R0, XER
+ MOVW 28(R1), R0
+ MOVW R0, CR /* CR */
+ MOVW 24(R1), R0
+ MOVW R0, LR
+ /* pad, skip */
+ MOVW 16(R1), R0
+ MOVW R0, SPR(SRR0) /* old PC */
+ MOVW 12(R1), R0
+ MOVW R0, SPR(SRR1) /* old MSR */
+ /* cause, skip */
+ MOVW 44(R1), R1 /* old SP */
+ MOVW SPR(SAVER0), R0
+ RFI
M mtx/main.c => mtx/main.c +350 -3
@@ 13,10 13,357 @@ FPsave initfp;
void
main(void)
{
-// xinit();
- printinit();
+ conf.nmach = 1;
+ machinit();
+ active.machs = 1;
+ active.exiting = 0;
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();
+// procinit0();
+// initseg();
+// links();
+// chandevreset();
+// pageinit();
+// swapinit();
+// userinit();
+// schedinit();
+}
+
+void
+machinit(void)
+{
+ memset(m, 0, sizeof(Mach));
+
+ /*
+ * For polled uart output at boot, need
+ * a default delay constant. 100000 should
+ * be enough for a while. Cpuidentify will
+ * calculate the real value later.
+ */
+// m->loopconst = 100000;
+}
+
+static struct
+{
+ char *name;
+ char *val;
+}
+plan9ini[] =
+{
+ { "console", "0" },
+};
+
+char*
+getconf(char *name)
+{
+ int i;
+
+ for(i = 0; i < nelem(plan9ini); i++)
+ if(cistrcmp(name, plan9ini[i].name) == 0)
+ return plan9ini[i].val;
+ return nil;
+}
+
+void
+init0(void)
+{
+// char **p, *q, name[KNAMELEN];
+// int n;
+
+print("init0\n");
+
+ up->nerrlab = 0;
+
+ 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);
+ cnameclose(up->slash->name);
+ up->slash->name = newcname("/");
+ up->dot = cclone(up->slash);
+
+ chandevinit();
+
+ if(!waserror()){
+ ksetenv("cputype", "power");
+ if(cpuserver)
+ ksetenv("service", "cpu");
+ else
+ ksetenv("service", "terminal");
+
+/*
+ for(p = confenv; *p; p++) {
+ q = strchr(p[0], '=');
+ if(q == 0)
+ continue;
+ n = q-p[0];
+ if(n >= KNAMELEN)
+ n = KNAMELEN-1;
+ memmove(name, p[0], n);
+ name[n] = 0;
+ ksetenv(name, q+1);
+ }
+*/
+ poperror();
+ }
+ kproc("alarm", alarmkproc, 0);
+ 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);
+
+ /*
+ * 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;
+
+ lock(&active);
+ if(ispanic)
+ active.ispanic = ispanic;
+ else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
+ active.ispanic = 0;
+ once = active.machs & (1<<m->machno);
+ active.machs &= ~(1<<m->machno);
+ active.exiting = 1;
+ unlock(&active);
+
+ if(once)
+ print("cpu%d: exiting\n", m->machno);
+ spllo();
+ for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
+ delay(TK2MS(2));
+ if(active.machs == 0 && consactive() == 0)
+ break;
+ }
+
+ if(active.ispanic && m->machno == 0){
+ if(cpuserver)
+ delay(10000);
+ else
+ for(;;);
+ }
+ else
+ delay(1000);
+
+ for(;;)
+ ;
+}
+
+/*
+ * set up floating point for a new process
+ */
+void
+procsetup(Proc *p)
+{
+ USED(p);
+}
+
+/*
+ * Save the mach dependent part of the process state.
+ */
+void
+procsave(Proc *p)
+{
+ USED(p);
+}
+
+void
+confinit(void)
+{
+ int nbytes;
+ ulong pa;
+
+ conf.nmach = 1; /* processors */
+ conf.nproc = 60; /* processes */
+
+ // hard wire for now
+ pa = 0x200000; // leave 2 Meg for kernel
+ nbytes = 8*1024*1024; // leave room at the top as well
+
+ conf.npage0 = nbytes/BY2PG;
+ conf.base0 = pa;
+
+ conf.npage1 = 0;
+ conf.base1 = pa;
+
+ conf.npage = conf.npage0 + conf.npage1;
+
+ conf.upages = (conf.npage*60)/100;
+ conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
+
+ /* set up other configuration parameters */
+ conf.nswap = 0;
+ conf.nswppo = 0;
+ conf.nimage = 20;
+
+ conf.copymode = 0; /* copy on write */
+}
+
+static int
+getcfields(char* lp, char** fields, int n, char* sep)
+{
+ int i;
+
+ for(i = 0; lp && *lp && i < n; i++){
+ while(*lp && strchr(sep, *lp) != 0)
+ *lp++ = 0;
+ if(*lp == 0)
+ break;
+ fields[i] = lp;
+ while(*lp && strchr(sep, *lp) == 0){
+ if(*lp == '\\' && *(lp+1) == '\n')
+ *lp++ = ' ';
+ lp++;
+ }
+ }
+
+ return i;
+}
+
+int
+isaconfig(char *class, int ctlrno, ISAConf *isa)
+{
+ int i;
+ char cc[KNAMELEN], *p;
+
+ sprint(cc, "%s%d", class, ctlrno);
+
+ p = getconf(cc);
+ if(p == 0)
+ return 0;
+ isa->nopt = tokenize(p, isa->opt, NISAOPT);
+ for(i = 0; i < isa->nopt; i++){
+ p = isa->opt[i];
+ if(cistrncmp(p, "type=", 5) == 0)
+ isa->type = p + 5;
+ else if(cistrncmp(p, "port=", 5) == 0)
+ isa->port = strtoul(p+5, &p, 0);
+ else if(cistrncmp(p, "irq=", 4) == 0)
+ isa->irq = strtoul(p+4, &p, 0);
+ else if(cistrncmp(p, "dma=", 4) == 0)
+ isa->dma = strtoul(p+4, &p, 0);
+ else if(cistrncmp(p, "mem=", 4) == 0)
+ isa->mem = strtoul(p+4, &p, 0);
+ else if(cistrncmp(p, "size=", 5) == 0)
+ isa->size = strtoul(p+5, &p, 0);
+ else if(cistrncmp(p, "freq=", 5) == 0)
+ isa->freq = strtoul(p+5, &p, 0);
+ }
+ return 1;
+}
+
+int
+cistrcmp(char *a, char *b)
+{
+ int ac, bc;
+
+ for(;;){
+ ac = *a++;
+ bc = *b++;
+
+ if(ac >= 'A' && ac <= 'Z')
+ ac = 'a' + (ac - 'A');
+ if(bc >= 'A' && bc <= 'Z')
+ bc = 'a' + (bc - 'A');
+ ac -= bc;
+ if(ac)
+ return ac;
+ if(bc == 0)
+ break;
+ }
+ return 0;
+}
+
+int
+cistrncmp(char *a, char *b, int n)
+{
+ unsigned ac, bc;
+
+ while(n > 0){
+ ac = *a++;
+ bc = *b++;
+ n--;
+
+ if(ac >= 'A' && ac <= 'Z')
+ ac = 'a' + (ac - 'A');
+ if(bc >= 'A' && bc <= 'Z')
+ bc = 'a' + (bc - 'A');
+
+ ac -= bc;
+ if(ac)
+ return ac;
+ if(bc == 0)
+ break;
+ }
- for(;;);
+ return 0;
}
M mtx/mem.h => mtx/mem.h +3 -1
@@ 81,7 81,7 @@
#define SIA 955 /* Sampled Instruction Address */
#define SDA 959 /* Sampled Data Address */
-#define BIT(i) (1<<(32-(i))) /* Silly backwards register bit numbering scheme */
+#define BIT(i) (1<<(31-(i))) /* Silly backwards register bit numbering scheme */
/*
* Bit encodings for Machine State Register (MSR)
@@ 222,3 222,5 @@
#define FLASHAorB 0xfff00000
#define isphys(x) (((ulong)x&KZERO)!=0)
+
+#define getpgcolor(a) 0
M mtx/mmu.c => mtx/mmu.c +1 -116
@@ 13,8 13,6 @@ mmuinit(void)
int i;
print("mmuinit\n");
- for(i=0; i<STLBSIZE; i++)
- m->stb[i].virt = TLBINVLAID;
}
void
@@ 43,7 41,7 @@ if(0)print("mmuswitch()\n");
p->newtlb = 0;
}
tp = p->pidonmach[m->machno];
- putcasid(tp);
+// putcasid(tp);
}
void
@@ 54,119 52,6 @@ if(0)print("mmurelease(%ld)\n", p->pid);
}
void
-purgetlb(int pid)
-{
- int i, mno;
- Proc *sp, **pidproc;
- Softtlb *entry, *etab;
-
-if(0)print("purgetlb: pid = %d\n", pid);
- m->tlbpurge++;
- /*
- * find all pid entries that are no longer used by processes
- */
- mno = m->machno;
- pidproc = m->pidproc;
- for(i=1; i<NTLBPID; i++) {
- sp = pidproc[i];
- if(sp && sp->pidonmach[mno] != i)
- pidproc[i] = 0;
- }
-
- /*
- * shoot down the one we want
- */
- sp = pidproc[pid];
- if(sp != 0)
- sp->pidonmach[mno] = 0;
- pidproc[pid] = 0;
-
- /*
- * clean out all dead pids from the stlb;
- */
- entry = m->stb;
- for(etab = &entry[STLBSIZE]; entry < etab; entry++)
- if(pidproc[TLBPID(entry->virt)] == 0)
- entry->virt = TLBINVLAID;
-
- /*
- * clean up the hardware
- */
- tlbflushall();
-}
-
-int
-newtlbpid(Proc *p)
-{
- int i, s;
- Proc **h;
-
- i = m->lastpid;
- h = m->pidproc;
- for(s = 0; s < NTLBPID; s++) {
- i++;
- if(i >= NTLBPID)
- i = 1;
- if(h[i] == 0)
- break;
- }
-
- if(h[i]) {
- i = m->purgepid+1;
- if(i >= NTLBPID)
- i = 1;
- m->purgepid = i;
- purgetlb(i);
- }
-
- if(h[i] != 0)
- panic("newtlb");
-
- m->pidproc[i] = p;
- p->pidonmach[m->machno] = i;
- m->lastpid = i;
-if(0)print("newtlbpid: pid=%ld = tlbpid = %d\n", p->pid, i);
- return i;
-}
-
-void
putmmu(ulong va, ulong pa, Page *pg)
{
- char *ctl;
- int tp;
- ulong h;
-
- qlock(&m->stlblk);
-
- tp = up->pidonmach[m->machno];
- if(tp == 0) {
- tp = newtlbpid(up);
- putcasid(tp);
- }
-
- h = ((va>>12)^(va>>24)^(tp<<8)) & 0xfff;
- m->stb[h].virt = va|tp;
- m->stb[h].phys = pa;
- tlbflush(va);
-
- qunlock(&m->stlblk);
-
- ctl = &pg->cachectl[m->machno];
-if(0)print("putmmu tp=%d h=%ld va=%lux pa=%lux ctl=%x\n", tp, h,va, pa, *ctl);
- switch(*ctl) {
- default:
- panic("putmmu: %d\n", *ctl);
- break;
- case PG_NOFLUSH:
- break;
- case PG_TXTFLUSH:
- dcflush((void*)pg->va, BY2PG);
- icflush((void*)pg->va, BY2PG);
- *ctl = PG_NOFLUSH;
- break;
- case PG_NEWCOL:
-print("PG_NEWCOL!!\n");
- *ctl = PG_NOFLUSH;
- break;
- }
}
M mtx/trap.c => mtx/trap.c +47 -55
@@ 116,38 116,6 @@ char *regname[]={
};
void
-sethvec(int v, void (*r)(void))
-{
- ulong *vp, pa, o;
-
- vp = KADDR(v);
- vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */
- vp[1] = 0x7c0802a6; /* MOVW LR, R0 */
- vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */
- pa = PADDR(r);
- o = pa >> 25;
- if(o != 0 && o != 0x7F){
- /* a branch too far */
- vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */
- vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */
- vp[5] = 0x7c0803a6; /* MOVW R0, LR */
- vp[6] = 0x4e800021; /* BL (LR) */
- }else
- vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */
- dcflush(vp, 8*sizeof(ulong));
-}
-
-void
-sethvec2(int v, void (*r)(void))
-{
- ulong *vp;
-
- vp = (ulong*)KADDR(v);
- vp[0] = (18<<26)|(PADDR(r))|2; /* ba */
- dcflush(vp, sizeof(*vp));
-}
-
-void
trap(Ureg *ur)
{
int ecode;
@@ 155,6 123,7 @@ trap(Ureg *ur)
int user;
char buf[ERRMAX];
+print("trap\n");
m->intrts = fastticks(nil);
ecode = (ur->cause >> 8) & 0xff;
user = (ur->srr1 & MSR_PR) != 0;
@@ 256,38 225,40 @@ spurious(Ureg *ur, void *a)
Lock veclock;
void
+sethvec(int v, void (*r)(void))
+{
+ ulong *vp, pa, o;
+
+ vp = KADDR(v);
+ vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */
+ vp[1] = 0x7c0802a6; /* MOVW LR, R0 */
+ vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */
+ pa = PADDR(r);
+ o = pa >> 25;
+ if(o != 0 && o != 0x7F){
+ /* a branch too far */
+ vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */
+ vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */
+ vp[5] = 0x7c0803a6; /* MOVW R0, LR */
+ vp[6] = 0x4e800021; /* BL (LR) */
+ }else
+ vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */
+ dcflush(vp, 8*sizeof(ulong));
+}
+
+void
trapinit(void)
{
-#ifdef BLOG
int i;
- IMM *io;
-
- io = m->iomem;
- io->sypcr &= ~(1<<3); /* disable watchdog (821/823) */
- io->simask = 0; /* mask all */
- io->siel = ~0; /* edge sensitive, wake on all */
- io->cicr = 0; /* disable CPM interrupts */
- io->cipr = ~0; /* clear all interrupts */
- io->cimr = 0; /* mask all events */
- io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8);
- io->cicr |= 1 << 7; /* enable */
- io->tbscr = 1; /* TBE */
- io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */
- eieio();
putdec(~0);
+ putmsr(getmsr() & ~MSR_IP);
/*
* set all exceptions to trap
*/
for(i = 0x0; i < 0x2000; i += 0x100)
sethvec(i, trapvec);
-
- //sethvec(CEI<<8, intrvec);
- sethvec2(CIMISS<<8, itlbmiss);
- sethvec2(CDMISS<<8, dtlbmiss);
- sethvec2(CDTLBE<<8, dtlberror);
-#endif
}
void
@@ 432,19 403,34 @@ kernfault(Ureg *ur, int code)
sched();
}
+/*
+ * Fill in enough of Ureg to get a stack trace, and call a function.
+ * Used by debugging interface rdb.
+ */
void
-dumpstack(void)
+callwithureg(void (*fn)(Ureg*))
+{
+ Ureg ureg;
+ ureg.pc = getcallerpc(&fn);
+ ureg.sp = (ulong)&fn;
+ fn(&ureg);
+}
+
+void
+_dumpstack(Ureg *ureg)
{
ulong l, v;
int i;
if(up == 0)
return;
+
+ print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
i = 0;
for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)etext){
- print("%lux=%lux, ", l, v);
+ print("%.8lux=%.8lux ", l, v);
if(i++ == 4){
print("\n");
i = 0;
@@ 454,6 440,12 @@ dumpstack(void)
}
void
+dumpstack(void)
+{
+ callwithureg(_dumpstack);
+}
+
+void
dumpregs(Ureg *ur)
{
int i;
M port/devcons.c => port/devcons.c +2 -1
@@ 632,6 632,7 @@ consopen(Chan *c, int omode)
qnoblock(kprintoq, 1);
}else
qreopen(kprintoq);
+ c->iounit = qiomaxatomic;
break;
}
return c;
@@ 846,7 847,7 @@ consread(Chan *c, void *buf, long n, vlong off)
return n;
case Qosversion:
- snprint(tmp, sizeof tmp, "2000 %d", qiomaxatomic);
+ snprint(tmp, sizeof tmp, "2000");
n = readstr((ulong)offset, buf, n, tmp);
return n;
M port/devdraw.c => port/devdraw.c +3 -2
@@ 37,6 37,7 @@ enum
#define NHASH (1<<5)
#define HASHMASK (NHASH-1)
+#define IOUNIT (64*1024)
typedef struct Client Client;
typedef struct Draw Draw;
@@ 908,7 909,7 @@ drawopen(Chan *c, int omode)
if(c->qid.type & QTDIR){
c = devopen(c, omode, 0, 0, drawgen);
- c->iounit = 32*1024;
+ c->iounit = IOUNIT;
}
qlock(&sdraw);
@@ 949,7 950,7 @@ drawopen(Chan *c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
- c->iounit = 32*1024;
+ c->iounit = IOUNIT;
return c;
}
M port/devloopback.c => port/devloopback.c +1 -0
@@ 310,6 310,7 @@ loopbackopen(Chan *c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
+ c->iounit = qiomaxatomic;
return c;
}
M port/devpipe.c => port/devpipe.c +1 -0
@@ 207,6 207,7 @@ pipeopen(Chan *c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
+ c->iounit = qiomaxatomic;
return c;
}
M port/devtls.c => port/devtls.c +1 -0
@@ 481,6 481,7 @@ tlsopen(Chan *c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
+ c->iounit = qiomaxatomic;
return c;
}
M port/devuart.c => port/devuart.c +1 -0
@@ 242,6 242,7 @@ uartopen(Chan *c, int omode)
break;
}
+ c->iounit = qiomaxatomic;
return c;
}
M port/netif.c => port/netif.c +1 -0
@@ 181,6 181,7 @@ netifopen(Netif *nif, Chan *c, int omode)
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
+ c->iounit = qiomaxatomic;
return c;
}