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:
@@ -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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user