M ip/ethermedium.c => ip/ethermedium.c +9 -1
@@ 429,6 429,12 @@ recvarp(Ipifc *ifc)
break;
case ARPREPLY:
+ if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
+ if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
+ print("arp: 0x%E also has ip addr %V\n", e->sha, e->spa);
+ break;
+ }
+ }
arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
break;
@@ 440,8 446,10 @@ recvarp(Ipifc *ifc)
/* check for someone that think's they're me */
v4tov6(ip, e->spa);
if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
- if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0)
+ if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
print("arp: 0x%E also has ip addr %V\n", e->sha, e->spa);
+ break;
+ }
} else {
if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0){
print("arp: %V also has ether addr %E\n", e->spa, e->sha);
M mtx/fns.h => mtx/fns.h +3 -0
@@ 67,6 67,7 @@ void mpicdisable(int);
void mpicenable(int, Vctl*);
int mpiceoi(int);
int mpicintack(void);
+int newmmupid(void);
void outb(int, int);
void outsb(int, void*, int);
void outs(int, ushort);
@@ 94,10 95,12 @@ void procsetup(Proc*);
void putdec(ulong);
void putmsr(ulong);
void putsdr1(ulong);
+void putsr(int, ulong);
void raveninit(void);
void screeninit(void);
int screenprint(char*, ...); /* debugging */
int segflush(void*, ulong);
+void sync(void);
int tas(void*);
void touser(void*);
void trapinit(void);
M mtx/l.s => mtx/l.s +9 -0
@@ 281,10 281,19 @@ TEXT putsdr1(SB), $0
MOVW R3, SPR(SDR1)
RETURN
+TEXT putsr(SB), $0
+ MOVW 4(FP), R4
+ MOVW R4, SEG(R3)
+ RETURN
+
TEXT eieio(SB), $0
EIEIO
RETURN
+TEXT sync(SB), $0
+ SYNC
+ RETURN
+
TEXT tlbflushall(SB), $0
MOVW $64, R3
MOVW R3, CTR
M mtx/main.c => mtx/main.c +0 -2
@@ 137,8 137,6 @@ init0(void)
poperror();
}
kproc("alarm", alarmkproc, 0);
-print("touser forestalled\n");
-for(;;);
touser((void*)(USTKTOP-8));
}
M mtx/mem.h => mtx/mem.h +5 -39
@@ 141,46 141,12 @@
#define PPN(x) ((x)&~(BY2PG-1))
/*
- * MMU
+ * Second pte word, known by fault.c, passed to putmmu()
*/
-
-/* L1 table entry and Mx_TWC flags */
-#define PTEVALID (1<<0)
-#define PTEWT (1<<1) /* write through */
-#define PTE4K (0<<2)
-#define PTE512K (1<<2)
-#define PTE8MB (3<<2)
-#define PTEG (1<<4) /* guarded */
-
-/* L2 table entry and Mx_RPN flags (also PTEVALID) */
-#define PTECI (1<<1) /* cache inhibit */
-#define PTESH (1<<2) /* page is shared; ASID ignored */
-#define PTELPS (1<<3) /* large page size */
-//#define PTEWRITE 0x9F0
-
-#define PTEKERNEL (0<<2)
-#define PTEUSER (1<<2)
-#define PTESIZE (1<<7)
-
-#define NTLBPID 16
-#define TLBPID(n) ((n)&(NTLBPID-1))
-
-/*
- * portable MMU bits for fault.c - though still machine specific
- */
-//#define PTEVALID (MMUPP|MMUV)
-#define PTEWRITE (2<<10)
-#define PTERONLY (3<<10)
-#define PTEUNCACHED (1<<4)
-
-/*
- * physical MMU bits
- */
-
-/* TLB and MxEPN flag */
-#define TLBVALID (1<<9)
-
-#define TLBSETS 32 /* number of tlb sets (603/603e) */
+#define PTEVALID 0 /* implied for putmmu -- real V bit in first pte word */
+#define PTEWRITE 2
+#define PTERONLY 3
+#define PTEUNCACHED BIT(26)
/*
* Address spaces
M mtx/mmu.c => mtx/mmu.c +69 -8
@@ 16,11 16,25 @@
static struct {
Lock;
- void *base; /* start of page table in kernel virtual space */
+ ulong base; /* start of page table in kernel virtual space */
ulong size; /* number of bytes in page table */
- int slotgen; /* used to choose which pte to alocate in pteg */
+ ulong mask; /* hash mask */
+ int slotgen; /* next pte (byte offset) when pteg is full */
+ int pidgen; /* next mmu pid to use */
} ptab;
+/*
+ * VSID is 24 bits. 3 are required to distinguish segments in user
+ * space (kernel space only uses the BATs).
+ */
+
+#define VSID(pid, i) (((pid)<<3)|i)
+
+enum {
+ PIDBASE = 1,
+ PIDMAX = ((1<<21)-1),
+};
+
void
mmuinit(void)
{
@@ 36,8 50,10 @@ mmuinit(void)
}
ptab.size = (1<<(lhash+6));
- ptab.base = xspanalloc(ptab.size, 0, ptab.size);
+ 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;
}
void
@@ 57,7 73,7 @@ flushmmu(void)
void
mmuswitch(Proc *p)
{
- int mp;
+ int i, mp;
if(p->newtlb) {
p->mmupid = 0;
@@ 67,8 83,8 @@ mmuswitch(Proc *p)
if(mp == 0)
mp = newmmupid();
-// for(i = 0; i < 8; i++)
-// putsr(i,
+ for(i = 0; i < 8; i++)
+ putsr(i<<28, VSID(mp, i)|BIT(1)|BIT(2));
}
void
@@ 78,12 94,57 @@ mmurelease(Proc* p)
}
void
-putmmu(ulong va, ulong pa, Page *pg)
+putmmu(ulong va, ulong pa, Page*)
{
+ int mp;
+ ulong *p, *ep, *q, pteg;
+ ulong vsid, ptehi, x, hash;
+
+ mp = up->mmupid;
+ if(mp == 0)
+ panic("putmmu pid");
+
+ vsid = VSID(mp, va>>28);
+ hash = (vsid ^ (va>>12)&0xffff) & ptab.mask;
+ ptehi = BIT(0)|(vsid<<7)|((va>>22)&0x3f);
+
+ pteg = ptab.base + 64*hash;
+ p = (ulong*)pteg;
+ ep = (ulong*)(pteg+64);
+ q = nil;
+ lock(&ptab);
+ tlbflush(va);
+ while(p < ep) {
+ x = p[0];
+ if(x == ptehi) {
+ q = p;
+if(q[1] == pa) panic("putmmu already set pte");
+ break;
+ }
+ if(q == nil && (x & BIT(0)) == 0)
+ q = p;
+ p += 2;
+ }
+ if(q == nil) {
+ q = (ulong*)(pteg+ptab.slotgen);
+ ptab.slotgen = (ptab.slotgen + 8) & 0x3f;
+ }
+ q[0] = ptehi;
+ q[1] = pa;
+ sync();
+ unlock(&ptab);
}
int
newmmupid(void)
{
- return -1;
+ int pid;
+
+ lock(&ptab);
+ pid = ptab.pidgen++;
+ unlock(&ptab);
+ if(pid > PIDMAX)
+ panic("newmmupid");
+ up->mmupid = pid;
+ return pid;
}
M mtx/trap.c => mtx/trap.c +12 -1
@@ 211,6 211,7 @@ char *regname[]={
void
trap(Ureg *ur)
{
+ ulong dsisr;
int ecode,user;
char buf[ERRMAX], *s;
@@ 231,6 232,16 @@ trap(Ureg *ur)
case CSYSCALL:
syscall(ur);
break;
+ case CISI:
+ faultpower(ur, ur->pc, 1);
+ break;
+ case CDSI:
+ dsisr = getdsisr();
+ if(dsisr & BIT(6))
+ faultpower(ur, getdar(), 0);
+ else
+ faultpower(ur, getdar(), 1);
+ break;
case CPROG:
if(ur->status & (1<<19))
s = "floating point exception";
@@ 282,7 293,7 @@ faultpower(Ureg *ureg, ulong addr, int read)
if(n < 0){
if(!user){
dumpregs(ureg);
- panic("fault: 0x%lux\n", addr);
+ panic("fault: 0x%lux", addr);
}
sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr);
postnote(up, 1, buf, NDebug);