shithub: riscv

Download patch

ref: 972f95aa637ed70a65e0e90d2e589b58a81d8a59
parent: 8cb33f2f18d8383fd78368110b3a78c7732da6f9
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Nov 17 18:30:09 EST 2020

pc, pc64: load idt early in trapinit0()

loading the interrupt vector table early allows
us to handle traps during bootup before mmuinit()
which gives better diagnostics for debugging.

we also can handle general protection fault on
rdmsr() and wrmsr() which helps during
cpuidentify() and archinit() when probing for
cpu features.

--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -23,15 +23,13 @@
 main(void)
 {
 	mach0init();
+	trapinit0();
 	bootargsinit();
 	ioinit();
 	i8250console();
 	quotefmtinstall();
 	screeninit();
-
 	print("\nPlan 9\n");
-	
-	trapinit0();
 	i8253init();
 	cpuidentify();
 	meminit0();
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -9,8 +9,6 @@
 #include	"../port/error.h"
 #include	<trace.h>
 
-static int trapinited;
-
 void	noted(Ureg*, ulong);
 
 static void debugexc(Ureg*, void*);
@@ -197,6 +195,7 @@
 	int d1, v;
 	ulong vaddr;
 	Segdesc *idt;
+	ushort ptr[3];
 
 	idt = (Segdesc*)IDTADDR;
 	vaddr = (ulong)vectortable;
@@ -203,7 +202,6 @@
 	for(v = 0; v < 256; v++){
 		d1 = (vaddr & 0xFFFF0000)|SEGP;
 		switch(v){
-
 		case VectorBPT:
 			d1 |= SEGPL(3)|SEGIG;
 			break;
@@ -220,6 +218,10 @@
 		idt[v].d1 = d1;
 		vaddr += 6;
 	}
+	ptr[0] = sizeof(Segdesc)*256-1;
+	ptr[1] = IDTADDR & 0xFFFF;
+	ptr[2] = IDTADDR >> 16;
+	lidt(ptr);
 }
 
 void
@@ -237,7 +239,6 @@
 	nmienable();
 
 	addarchfile("irqalloc", 0444, irqallocread, nil);
-	trapinited = 1;
 }
 
 static char* excname[32] = {
@@ -328,13 +329,6 @@
 	Vctl *ctl, *v;
 	Mach *mach;
 
-	if(!trapinited){
-		/* fault386 can give a better error message */
-		if(ureg->trap == VectorPF)
-			fault386(ureg, nil);
-		panic("trap %lud: not ready", ureg->trap);
-	}
-
 	m->perf.intrts = perfticks();
 	user = userureg(ureg);
 	if(user){
@@ -482,6 +476,10 @@
 					return;
 				}
 			}
+
+			/* early fault before trapinit() */
+			if(vno == VectorPF)
+				fault386(ureg, 0);
 		}
 
 		dumpregs(ureg);
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -175,6 +175,7 @@
 main(void)
 {
 	mach0init();
+	trapinit0();
 	bootargsinit();
 	ioinit();
 	i8250console();
@@ -181,7 +182,6 @@
 	quotefmtinstall();
 	screeninit();
 	print("\nPlan 9\n");
-	trapinit0();
 	i8253init();
 	cpuidentify();
 	meminit0();
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -9,8 +9,6 @@
 #include	"../port/error.h"
 #include	<trace.h>
 
-static int trapinited;
-
 void	noted(Ureg*, ulong);
 
 static void debugexc(Ureg*, void*);
@@ -194,6 +192,7 @@
 	u32int d1, v;
 	uintptr vaddr;
 	Segdesc *idt;
+	uintptr ptr[2];
 
 	idt = (Segdesc*)IDTADDR;
 	vaddr = (uintptr)vectortable;
@@ -200,7 +199,6 @@
 	for(v = 0; v < 256; v++){
 		d1 = (vaddr & 0xFFFF0000)|SEGP;
 		switch(v){
-
 		case VectorBPT:
 			d1 |= SEGPL(3)|SEGIG;
 			break;
@@ -224,6 +222,9 @@
 
 		vaddr += 6;
 	}
+	((ushort*)&ptr[1])[-1] = sizeof(Segdesc)*512-1;
+	ptr[1] = IDTADDR;
+	lidt(&((ushort*)&ptr[1])[-1]);
 }
 
 void
@@ -240,7 +241,6 @@
 	trapenable(Vector15, unexpected, 0, "unexpected");
 	nmienable();
 	addarchfile("irqalloc", 0444, irqallocread, nil);
-	trapinited = 1;
 }
 
 static char* excname[32] = {
@@ -324,13 +324,6 @@
 	Vctl *ctl, *v;
 	Mach *mach;
 
-	if(!trapinited){
-		/* faultamd64 can give a better error message */
-		if(ureg->type == VectorPF)
-			faultamd64(ureg, nil);
-		panic("trap %llud: not ready", ureg->type);
-	}
-
 	m->perf.intrts = perfticks();
 	user = userureg(ureg);
 	if(user){
@@ -447,11 +440,15 @@
 					return;
 				}
 			} else if(pc == _peekinst){
-				if(vno == VectorGPF){
+				if(vno == VectorGPF || vno == VectorPF){
 					ureg->pc += 2;
 					return;
 				}
 			}
+
+			/* early fault before trapinit() */
+			if(vno == VectorPF)
+				faultamd64(ureg, 0);
 		}
 
 		dumpregs(ureg);