Included some code from NewOS to set up a double fault handler. Doesn't seem to work yet, though.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10443 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-12-14 01:46:04 +00:00
parent bd6c26014a
commit 09eaf756d0
2 changed files with 41 additions and 7 deletions
+32 -6
View File
@@ -11,6 +11,7 @@
#include <vm.h> #include <vm.h>
#include <smp.h> #include <smp.h>
#include <arch/x86/selector.h> #include <arch/x86/selector.h>
#include <arch/x86/interrupts.h>
#include <tls.h> #include <tls.h>
#include <boot/kernel_args.h> #include <boot/kernel_args.h>
@@ -18,14 +19,40 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
extern void reboot(void);
void reboot(void); // from arch_x86.S
static struct tss **sTSS; static struct tss **sTSS;
static int *sIsTSSLoaded; static int *sIsTSSLoaded;
segment_descriptor *gGDT = NULL; segment_descriptor *gGDT = NULL;
/* Some specials for the double fault handler */
static struct tss sDoubleFaultTSS;
static uint32 sDoubleFaultStack[1024];
static void
init_double_fault(void)
{
/* set up the double fault tss */
memset(&sDoubleFaultTSS, 0, sizeof(struct tss));
sDoubleFaultTSS.sp0 = (uint32)sDoubleFaultStack + sizeof(sDoubleFaultStack);
sDoubleFaultTSS.ss0 = KERNEL_DATA_SEG;
read_cr3(sDoubleFaultTSS.cr3); // copy the current cr3 to the double fault cr3
sDoubleFaultTSS.eip = (uint32)&trap8;
sDoubleFaultTSS.es = KERNEL_DATA_SEG;
sDoubleFaultTSS.cs = KERNEL_CODE_SEG;
sDoubleFaultTSS.ss = KERNEL_DATA_SEG;
sDoubleFaultTSS.ds = KERNEL_DATA_SEG;
sDoubleFaultTSS.fs = KERNEL_DATA_SEG;
sDoubleFaultTSS.gs = KERNEL_DATA_SEG;
sDoubleFaultTSS.ldt_seg_selector = KERNEL_DATA_SEG;
set_tss_descriptor(&gGDT[DOUBLE_FAULT_TSS_SEGMENT], (addr_t)&sDoubleFaultTSS, sizeof(struct tss));
x86_set_task_gate(8, DOUBLE_FAULT_TSS_SEGMENT << 3);
}
status_t status_t
arch_cpu_preboot_init(kernel_args *args) arch_cpu_preboot_init(kernel_args *args)
@@ -101,16 +128,16 @@ arch_cpu_init_post_vm(kernel_args *args)
DT_DATA_WRITEABLE, DPL_USER); DT_DATA_WRITEABLE, DPL_USER);
} }
return 0; init_double_fault();
return B_OK;
} }
void void
i386_set_tss_and_kstack(addr_t kstack) i386_set_tss_and_kstack(addr_t kstack)
{ {
int currentCPU = smp_get_current_cpu(); int32 currentCPU = smp_get_current_cpu();
// dprintf("i386_set_kstack: kstack 0x%x, cpu %d\n", kstack, currentCPU);
if (!sIsTSSLoaded[currentCPU]) { if (!sIsTSSLoaded[currentCPU]) {
short seg = ((TSS_BASE_SEGMENT + currentCPU) << 3) | DPL_KERNEL; short seg = ((TSS_BASE_SEGMENT + currentCPU) << 3) | DPL_KERNEL;
asm("movw %0, %%ax;" asm("movw %0, %%ax;"
@@ -119,7 +146,6 @@ i386_set_tss_and_kstack(addr_t kstack)
} }
sTSS[currentCPU]->sp0 = kstack; sTSS[currentCPU]->sp0 = kstack;
// dprintf("done\n");
} }
+9 -1
View File
@@ -105,6 +105,14 @@ set_system_gate(int n, void *addr)
} }
void
x86_set_task_gate(int32 n, int32 segment)
{
idt[n].a = (segment << 16);
idt[n].b = 0x8000 | (0 << 13) | (0x5 << 8); // present, dpl 0, type 5
}
void void
arch_int_enable_io_interrupt(int irq) arch_int_enable_io_interrupt(int irq)
{ {
@@ -324,7 +332,7 @@ arch_int_init(kernel_args *args)
set_intr_gate(5, &trap5); set_intr_gate(5, &trap5);
set_intr_gate(6, &trap6); set_intr_gate(6, &trap6);
set_intr_gate(7, &trap7); set_intr_gate(7, &trap7);
set_intr_gate(8, &trap8); // trap8 (double fault) is set in arch_cpu.c
set_intr_gate(9, &trap9); set_intr_gate(9, &trap9);
set_intr_gate(10, &trap10); set_intr_gate(10, &trap10);
set_intr_gate(11, &trap11); set_intr_gate(11, &trap11);