summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-11-17 23:30:09 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2020-11-17 23:30:09 +0100
commit972f95aa637ed70a65e0e90d2e589b58a81d8a59 (patch)
tree95950c9adcc3e910ba9f3954e9b668a6ab114e4d
parent8cb33f2f18d8383fd78368110b3a78c7732da6f9 (diff)
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.
-rw-r--r--sys/src/9/pc/main.c4
-rw-r--r--sys/src/9/pc/trap.c20
-rw-r--r--sys/src/9/pc64/main.c2
-rw-r--r--sys/src/9/pc64/trap.c21
4 files changed, 20 insertions, 27 deletions
diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c
index 231a62ad3..39649d164 100644
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -23,15 +23,13 @@ void
main(void)
{
mach0init();
+ trapinit0();
bootargsinit();
ioinit();
i8250console();
quotefmtinstall();
screeninit();
-
print("\nPlan 9\n");
-
- trapinit0();
i8253init();
cpuidentify();
meminit0();
diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c
index fadb64f42..faaf90101 100644
--- 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,13 +195,13 @@ trapinit0(void)
int d1, v;
ulong vaddr;
Segdesc *idt;
+ ushort ptr[3];
idt = (Segdesc*)IDTADDR;
vaddr = (ulong)vectortable;
for(v = 0; v < 256; v++){
d1 = (vaddr & 0xFFFF0000)|SEGP;
switch(v){
-
case VectorBPT:
d1 |= SEGPL(3)|SEGIG;
break;
@@ -220,6 +218,10 @@ trapinit0(void)
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 @@ trapinit(void)
nmienable();
addarchfile("irqalloc", 0444, irqallocread, nil);
- trapinited = 1;
}
static char* excname[32] = {
@@ -328,13 +329,6 @@ trap(Ureg* ureg)
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 @@ trap(Ureg* ureg)
return;
}
}
+
+ /* early fault before trapinit() */
+ if(vno == VectorPF)
+ fault386(ureg, 0);
}
dumpregs(ureg);
diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c
index 50649d724..53bcd8887 100644
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -175,13 +175,13 @@ void
main(void)
{
mach0init();
+ trapinit0();
bootargsinit();
ioinit();
i8250console();
quotefmtinstall();
screeninit();
print("\nPlan 9\n");
- trapinit0();
i8253init();
cpuidentify();
meminit0();
diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c
index b1078c560..b7e71a919 100644
--- 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,13 +192,13 @@ trapinit0(void)
u32int d1, v;
uintptr vaddr;
Segdesc *idt;
+ uintptr ptr[2];
idt = (Segdesc*)IDTADDR;
vaddr = (uintptr)vectortable;
for(v = 0; v < 256; v++){
d1 = (vaddr & 0xFFFF0000)|SEGP;
switch(v){
-
case VectorBPT:
d1 |= SEGPL(3)|SEGIG;
break;
@@ -224,6 +222,9 @@ trapinit0(void)
vaddr += 6;
}
+ ((ushort*)&ptr[1])[-1] = sizeof(Segdesc)*512-1;
+ ptr[1] = IDTADDR;
+ lidt(&((ushort*)&ptr[1])[-1]);
}
void
@@ -240,7 +241,6 @@ trapinit(void)
trapenable(Vector15, unexpected, 0, "unexpected");
nmienable();
addarchfile("irqalloc", 0444, irqallocread, nil);
- trapinited = 1;
}
static char* excname[32] = {
@@ -324,13 +324,6 @@ trap(Ureg *ureg)
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 @@ trap(Ureg *ureg)
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);