From a1f2561eedf54fb054cc69653fa7c657d23596e0 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 1 Apr 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-04-01 --- ip/gre.c | 2 +- ip/ipmux.c | 11 ++++--- pc/apic.c | 10 +++--- pc/archgeneric.c | 5 +-- pc/dat.h | 5 +++ pc/etherelnk3.c | 1 + pc/fns.h | 4 +-- pc/l.s | 11 +++---- pc/mp.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++- pc/trap.c | 29 ++++++++-------- pc/vgamga2164w.c | 4 +-- 11 files changed, 133 insertions(+), 35 deletions(-) diff --git a/ip/gre.c b/ip/gre.c index 5cfa9b2ea781344ae1b9e0b35b214ca3a4f2ae2c..4da12f1a55530354b43073d1b7df6dc2408dcc13 100644 --- a/ip/gre.c +++ b/ip/gre.c @@ -68,7 +68,7 @@ greconnect(Conv *c, char **argv, int argc) break; if(tc == c) continue; - if(tc->rport == c->rport && tc->raddr == c->raddr){ + if(tc->rport == c->rport && ipcmp(tc->raddr, c->raddr) == 0){ err = "already connected to that addr/proto"; ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); diff --git a/ip/ipmux.c b/ip/ipmux.c index b3b5d54555f64ae37263fc0d2ec24d883e6441bd..68ecd864e3f25f1e989e185273cc47939b2bed55 100644 --- a/ip/ipmux.c +++ b/ip/ipmux.c @@ -59,12 +59,13 @@ struct Ipmux { Ipmux *yes; Ipmux *no; - uchar type; + uchar type; /* type of field (Txxxx) */ uchar len; /* length in bytes of item to compare */ + uchar n; /* number of items val points to */ short off; /* offset of comparison */ - int n; /* number of items val points to */ uchar *val; uchar *mask; + uchar *e; /* val + n*len */ int ref; /* so we can garbage collect */ Conv *conv; @@ -269,6 +270,7 @@ parsemux(char *p) v += f->len; } + f->e = f->val + f->n*f->len; return f; parseerror: @@ -370,6 +372,7 @@ ipmuxcopy(Ipmux *f) nf->no = ipmuxcopy(f->no); nf->yes = ipmuxcopy(f->yes); nf->val = smalloc(f->n*f->len); + nf->e = nf->val + f->n*f->len; memmove(nf->val, f->val, f->n*f->len); return nf; } @@ -629,13 +632,14 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp) rlock(f); c = nil; mux = f->ipmux->priv; +match: while(mux != nil){ if(mux->len + mux->off > len){ mux = mux->no; continue; } v = mux->val; - for(e = v + mux->n*mux->len; v < e; v = ve){ + for(e = mux->e; v < e; v = ve){ m = mux->mask; hp = h + mux->off; for(ve = v + mux->len; v < ve; v++){ @@ -650,7 +654,6 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp) } } mux = mux->no; -match:; } runlock(f); diff --git a/pc/apic.c b/pc/apic.c index 212314f93baa646f1440eb1243bd107929228b4c..864034f4e3c7e9d50563cc92fa664fe6ee54b2a6 100644 --- a/pc/apic.c +++ b/pc/apic.c @@ -121,17 +121,19 @@ lapiconline(int clkin) static int lapictimerinit(void) { - ulong hi, lo, v; + ulong lo, v; + vlong tsc; v = m->cpumhz*1000; lapicw(LapicTDCR, LapicX1); lapicw(LapicTIMER, ApicIMASK|LapicCLKIN|LapicONESHOT|VectorTIMER); lapicw(LapicTICR, v); - wrmsr(0x10, 0, 0); + wrmsr(0x10, 0); do{ - rdmsr(0x10, &hi, &lo); + rdmsr(0x10, &tsc); + lo = (ulong)tsc; }while(lo < v); return ((v-lapicr(LapicTCCR)+500)/1000)*1000*1000; @@ -160,7 +162,7 @@ lapicinit(Apic* apic) case 0x526: /* stepping cB1 */ case 0x52B: /* stepping E0 */ case 0x52C: /* stepping cC0 */ - wrmsr(0x0E, 0, 1<<14); /* TR12 */ + wrmsr(0x0E, 1<<14); /* TR12 */ break; } lapicw(LapicLINT0, apic->lintr[0]); diff --git a/pc/archgeneric.c b/pc/archgeneric.c index c81b83756d58f3a352f755974012ba8901aa881a..4276ab1fe301efad7da71e5923905b3821c41a0d 100644 --- a/pc/archgeneric.c +++ b/pc/archgeneric.c @@ -88,7 +88,8 @@ cpuidentify(void) { int family, model; X86type *t; - ulong cr4, mct[2]; + ulong cr4; + vlong mct; cpuid(m->cpuidid, &m->cpuidax, &m->cpuiddx); family = X86FAMILY(m->cpuidax); @@ -115,7 +116,7 @@ cpuidentify(void) cr4 |= 0x40; /* machine check enable */ putcr4(cr4); if(m->cpuiddx & 0x80) - rdmsr(0x01, &mct[1], &mct[0]); + rdmsr(0x01, &mct); } return t->family; diff --git a/pc/dat.h b/pc/dat.h index c9683944a5924f6e0ad6c307264068994f3e7f9e..a1f752dbf201b149eb1db6db761f3183b73a5c94 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -178,6 +178,11 @@ struct Mach char cpuidid[16]; char* cpuidtype; + vlong mtrrcap; + vlong mtrrdef; + vlong mtrrfix[11]; + vlong mtrrvar[32]; /* 256 max. */ + int stack[1]; }; diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 14a9d7052a9189af12d553330a4568bf5c1637ff..d796aaeaf08682e469e6e10bd5ceb7924aecfe82 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -1525,6 +1525,7 @@ scanphy(Ether* ether) x <<= 6; x |= miir(ether, i, 3)>>10; XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(ether, i, 1)); + USED(x); } } diff --git a/pc/fns.h b/pc/fns.h index d5fd8321c40e51c55748aad2aa293b3cfaa6c6df..4a47e89f539ddbf1f5b22b3e760db5b36e692c53 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -91,7 +91,7 @@ void procsave(Proc*); void procsetup(Proc*); void putcr3(ulong); void putcr4(ulong); -void rdmsr(int, ulong*, ulong*); +void rdmsr(int, vlong*); void screeninit(void); int screenprint(char*, ...); /* debugging */ void (*screenputs)(char*, int); @@ -105,7 +105,7 @@ void umbrwfree(ulong, int); ulong upamalloc(ulong, int, int); void upafree(ulong, int); void vectortable(void); -void wrmsr(int, ulong, ulong); +void wrmsr(int, vlong); void wbflush(void); int xchgw(ushort*, int); diff --git a/pc/l.s b/pc/l.s index da13812929dfc41c66c5e56bbfbfa558971d44e7..95152009dfc999afa020b2458606460c2fd7556a 100644 --- a/pc/l.s +++ b/pc/l.s @@ -284,16 +284,15 @@ TEXT putcr4(SB), $0 TEXT rdmsr(SB), $0 /* model-specific register */ MOVL index+0(FP), CX RDMSR - MOVL hi+4(FP), CX - MOVL DX, (CX) - MOVL lo+8(FP), CX - MOVL AX, (CX) + MOVL vlong+4(FP), CX /* &vlong */ + MOVL AX, (CX) /* lo */ + MOVL DX, 4(CX) /* hi */ RET TEXT wrmsr(SB), $0 MOVL index+0(FP), CX - MOVL hi+4(FP), DX - MOVL lo+8(FP), AX + MOVL lo+4(FP), AX + MOVL hi+8(FP), DX WRMSR RET diff --git a/pc/mp.c b/pc/mp.c index 8b980036e6ff0ecebde33164a974d0c2323c7157..85f3ad3ccf66d93b2dad7408b948a811431c1d30 100644 --- a/pc/mp.c +++ b/pc/mp.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "io.h" +#include "ureg.h" #include "mp.h" #include "apbootstrap.h" @@ -287,6 +288,58 @@ mklintr(PCMPintr* p) return v; } +static void +checkmtrr(void) +{ + int i, vcnt; + Mach *mach0; + + /* + * If there are MTRR registers, snarf them for validation. + */ + if(!(m->cpuiddx & 0x1000)) + return; + + rdmsr(0x0FE, &m->mtrrcap); + rdmsr(0x2FF, &m->mtrrdef); + if(m->mtrrcap & 0x0100){ + rdmsr(0x250, &m->mtrrfix[0]); + rdmsr(0x258, &m->mtrrfix[1]); + rdmsr(0x259, &m->mtrrfix[2]); + for(i = 0; i < 8; i++) + rdmsr(0x268+i, &m->mtrrfix[(i+3)]); + } + vcnt = m->mtrrcap & 0x00FF; + if(vcnt > nelem(m->mtrrvar)) + vcnt = nelem(m->mtrrvar); + for(i = 0; i < vcnt; i++) + rdmsr(0x200+i, &m->mtrrvar[i]); + + /* + * If not the bootstrap processor, compare. + */ + if(m->machno == 0) + return; + + mach0 = MACHP(0); + if(mach0->mtrrcap != m->mtrrcap) + print("mtrrcap%d: %lluX %lluX\n", + m->machno, mach0->mtrrcap, m->mtrrcap); + if(mach0->mtrrdef != m->mtrrdef) + print("mtrrdef%d: %lluX %lluX\n", + m->machno, mach0->mtrrdef, m->mtrrdef); + for(i = 0; i < 11; i++){ + if(mach0->mtrrfix[i] != m->mtrrfix[i]) + print("mtrrfix%d: i%d: %lluX %lluX\n", + m->machno, i, mach0->mtrrfix[i], m->mtrrfix[i]); + } + for(i = 0; i < vcnt; i++){ + if(mach0->mtrrvar[i] != m->mtrrvar[i]) + print("mtrrvar%d: i%d: %lluX %lluX\n", + m->machno, i, mach0->mtrrvar[i], m->mtrrvar[i]); + } +} + #define PDX(va) ((((ulong)(va))>>22) & 0x03FF) #define PTX(va) ((((ulong)(va))>>12) & 0x03FF) @@ -301,6 +354,7 @@ squidboy(Apic* apic) cpuidentify(); cpuidprint(); + checkmtrr(); lock(&mprdthilock); mprdthi |= (1<apicno)<<24; @@ -392,6 +446,21 @@ mpstartap(Apic* apic) nvramwrite(0x0F, 0x00); } +static void +senddbgnmi(void) +{ + /* + * NMI all excluding self. + */ + lapicicrw(0, 0x000C0000|ApicNMI); +} + +static void +mpdbg(Ureg* ureg, void*) +{ + iprint("MPDBG: cpu%d: PC 0x%uX\n", m->machno, ureg->pc); +} + void mpinit(void) { @@ -482,6 +551,8 @@ mpinit(void) intrenable(VectorSPURIOUS, lapicspurious, 0, BUSUNKNOWN); lapiconline(clkin); + checkmtrr(); + /* * Initialise the application processors. */ @@ -493,10 +564,13 @@ mpinit(void) /* * Remember to set conf.copymode here if nmach > 1. - * Look for an ExtINT line and enable it. + * Should look for an ExtINT line and enable it. */ if(conf.nmach > 1) conf.copymode = 1; + + consdebug = senddbgnmi; + intrenable(VectorNMI, mpdbg, 0, BUSUNKNOWN); } static int @@ -624,6 +698,8 @@ mpintrenable(int v, int tbdf, Irqctl* irqctl) void mpshutdown(void) { + int apicno, machno; + /* * To be done... */ @@ -639,6 +715,14 @@ mpshutdown(void) } print("apshutdown: active = 0x%2.2uX\n", active.machs); + if(active.machs){ + for(machno = 1; machno < conf.nmach; machno++){ + if(!(active.machs & (1<= VectorINTR && arch->intrenable(v, tbdf, ctl) == -1){ unlock(&irqctllock); - /* - print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf); - */ + //print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf); xfree(ctl); return; } @@ -77,7 +75,7 @@ trapinit(void) break; case VectorSYSCALL: - d1 |= SEGPL(3)|SEGTG; + d1 |= SEGPL(3)|SEGIG; break; default: @@ -157,6 +155,11 @@ trap(Ureg* ureg) if(ctl->eoi) ctl->eoi(v); + + /* preemptive scheduling */ + if(ctl->isintr && v != VectorTIMER && v != VectorCLOCK) + if(up && up->state == Running && anyhigher()) + sched(); } else if(v <= 16 && user){ spllo(); @@ -188,9 +191,11 @@ trap(Ureg* ureg) } else{ if(v == VectorNMI){ - if(m->machno != 0) + nmienable(); + if(m->machno != 0){ + print("cpu%d: PC %8.8uX\n", m->machno, ureg->pc); for(;;); - //nmienable(); + } } dumpregs(ureg); if(v < nelem(excname)) @@ -230,7 +235,7 @@ void dumpregs(Ureg* ureg) { extern ulong etext; - ulong mca[2], mct[2]; + vlong mca, mct; dumpregs2(ureg); @@ -245,10 +250,9 @@ dumpregs(Ureg* ureg) if(m->cpuiddx & 0x9A){ print(" CR4 %8.8luX", getcr4()); if((m->cpuiddx & 0xA0) == 0xA0){ - rdmsr(0x00, &mca[1], &mca[0]); - rdmsr(0x01, &mct[1], &mct[0]); - print("\n MCA %8.8luX:%8.8luX MCT %8.8luX", - mca[1], mca[0], mct[0]); + rdmsr(0x00, &mca); + rdmsr(0x01, &mct); + print("\n MCA %8.8lluX MCT %8.8lluX", mca, mct); } } print("\n ur %luX up %luX\n", ureg, up); @@ -353,11 +357,10 @@ syscall(Ureg* ureg) scallnr = ureg->ax; up->scallnr = scallnr; if(scallnr == RFORK && up->fpstate == FPactive){ - splhi(); fpsave(&up->fpsave); up->fpstate = FPinactive; - spllo(); } + spllo(); sp = ureg->usp; up->nerrlab = 0; diff --git a/pc/vgamga2164w.c b/pc/vgamga2164w.c index 7be867579516740b247a7c4899df1c880ac7029b..6b20f9d75c942471eb8a6300bf781ceecabc5484 100644 --- a/pc/vgamga2164w.c +++ b/pc/vgamga2164w.c @@ -131,10 +131,10 @@ tvp3026load(VGAscr* scr, Cursor* curs) * Write to the indirect control register to make sure * direct register is enabled and upper 2 bits of cursor * RAM address are 0. - * The LSBs of the cursor RAM address are in PaddrW. + * Put 0 in index register for lower 8 bits of cursor RAM address. */ tvp3026disable(scr); - vgao(PaddrW, 0x00); + *(tvp3026+Index) = 0; /* * Initialise the 64x64 cursor RAM array. There are 2 planes,