From 78ef0ba5abb22ccef56406cb203f4887bdfc84d5 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 8 Jan 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-01-08 --- ip/ethermedium.c | 10 ++++++- mtx/fns.h | 3 ++ mtx/l.s | 9 ++++++ mtx/main.c | 2 -- mtx/mem.h | 44 ++++----------------------- mtx/mmu.c | 77 +++++++++++++++++++++++++++++++++++++++++++----- mtx/trap.c | 13 +++++++- 7 files changed, 107 insertions(+), 51 deletions(-) diff --git a/ip/ethermedium.c b/ip/ethermedium.c index 775742894f6a05e92c94b3fc5673f8c7c824569e..4d8605c0b42bb2cf468b7d5bf2ecfba514fac8c2 100644 --- a/ip/ethermedium.c +++ b/ip/ethermedium.c @@ -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); diff --git a/mtx/fns.h b/mtx/fns.h index 8eeb741cbeed4fea55a8a7496fecd9fc09aaf723..ddb5b11e1a5ef9aa5275365a3c5b781044460032 100644 --- a/mtx/fns.h +++ b/mtx/fns.h @@ -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); diff --git a/mtx/l.s b/mtx/l.s index 409c47f08089cc63950f711b9731cd2bcde9d986..96a56de7589a45064581f16da6ced6ff66b63b90 100644 --- a/mtx/l.s +++ b/mtx/l.s @@ -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 diff --git a/mtx/main.c b/mtx/main.c index d9d95d613f1366f68deb2e4310a4d3a47cb78438..c837d1a5f771dfea8c14a183015d56f4919442f3 100644 --- a/mtx/main.c +++ b/mtx/main.c @@ -137,8 +137,6 @@ init0(void) poperror(); } kproc("alarm", alarmkproc, 0); -print("touser forestalled\n"); -for(;;); touser((void*)(USTKTOP-8)); } diff --git a/mtx/mem.h b/mtx/mem.h index 56ba1855bc4e89ee7996bf68d6fc8d2b4e5a5497..66ff0652a615726735d2c8ea71b7de24a5b76f32 100644 --- a/mtx/mem.h +++ b/mtx/mem.h @@ -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 diff --git a/mtx/mmu.c b/mtx/mmu.c index 9fb16e83469172befcd7e228785a5f27821b6277..868c1c3531f839314636273615ba4ef283242947 100644 --- a/mtx/mmu.c +++ b/mtx/mmu.c @@ -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<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; } diff --git a/mtx/trap.c b/mtx/trap.c index e42df7e6449aa8f170ba3f3220370510bccc4e86..ebc7270f2398c92da1b74401e966da71111b7c0f 100644 --- a/mtx/trap.c +++ b/mtx/trap.c @@ -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);