M ip/gre.c => ip/gre.c +1 -1
@@ 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);
M ip/ipmux.c => ip/ipmux.c +7 -4
@@ 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);
M pc/apic.c => pc/apic.c +6 -4
@@ 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]);
M pc/archgeneric.c => pc/archgeneric.c +3 -2
@@ 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;
M pc/dat.h => pc/dat.h +5 -0
@@ 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];
};
M pc/etherelnk3.c => pc/etherelnk3.c +1 -0
@@ 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);
}
}
M pc/fns.h => pc/fns.h +2 -2
@@ 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);
M pc/l.s => pc/l.s +5 -6
@@ 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
M pc/mp.c => pc/mp.c +85 -1
@@ 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<<apic->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<<machno)))
+ continue;
+ apicno = machno2apicno[machno];
+ lapicicrw(1<<apicno, ApicNMI);
+ }
+ }
delay(1000);
splhi();
M pc/trap.c => pc/trap.c +16 -13
@@ 26,9 26,7 @@ intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf)
ctl = xalloc(sizeof(Irqctl));
if(v >= 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;
M pc/vgamga2164w.c => pc/vgamga2164w.c +2 -2
@@ 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,