* Allocate a separate double fault stack for each CPU.
* Added x86_double_fault_get_cpu(), a save way to get the CPU index when in the double fault handler. smp_get_current_cpu() requires at least a somewhat intact thread structure, so we rather want to avoid it when handling a double fault. There are a lot more of those dependencies in the KDL entry code. Working on it... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32028 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bee3c7a915
commit
cc77aba101
@ -281,6 +281,7 @@ void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type);
|
|||||||
status_t x86_get_mtrr(uint32 index, uint64 *_base, uint64 *_length, uint8 *_type);
|
status_t x86_get_mtrr(uint32 index, uint64 *_base, uint64 *_length, uint8 *_type);
|
||||||
bool x86_check_feature(uint32 feature, enum x86_feature_type type);
|
bool x86_check_feature(uint32 feature, enum x86_feature_type type);
|
||||||
void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
|
void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
|
||||||
|
int x86_double_fault_get_cpu();
|
||||||
|
|
||||||
|
|
||||||
#define read_cr3(value) \
|
#define read_cr3(value) \
|
||||||
|
@ -83,8 +83,8 @@ static vint32 sTSCSyncRendezvous;
|
|||||||
segment_descriptor *gGDT = NULL;
|
segment_descriptor *gGDT = NULL;
|
||||||
|
|
||||||
/* Some specials for the double fault handler */
|
/* Some specials for the double fault handler */
|
||||||
//static struct tss sDoubleFaultTSS;
|
static uint8* sDoubleFaultStacks;
|
||||||
static uint32 sDoubleFaultStack[10240];
|
static const size_t kDoubleFaultStackSize = 4096; // size per CPU
|
||||||
|
|
||||||
static x86_cpu_module_info *sCpuModule;
|
static x86_cpu_module_info *sCpuModule;
|
||||||
|
|
||||||
@ -251,7 +251,9 @@ init_double_fault(int cpuNum)
|
|||||||
struct tss *tss = &gCPU[cpuNum].arch.double_fault_tss;
|
struct tss *tss = &gCPU[cpuNum].arch.double_fault_tss;
|
||||||
|
|
||||||
memset(tss, 0, sizeof(struct tss));
|
memset(tss, 0, sizeof(struct tss));
|
||||||
tss->sp0 = (uint32)sDoubleFaultStack + sizeof(sDoubleFaultStack);
|
size_t stackSize;
|
||||||
|
tss->sp0 = (uint32)x86_get_double_fault_stack(cpuNum, &stackSize);
|
||||||
|
tss->sp0 += stackSize;
|
||||||
tss->ss0 = KERNEL_DATA_SEG;
|
tss->ss0 = KERNEL_DATA_SEG;
|
||||||
read_cr3(tss->cr3);
|
read_cr3(tss->cr3);
|
||||||
// copy the current cr3 to the double fault cr3
|
// copy the current cr3 to the double fault cr3
|
||||||
@ -501,8 +503,19 @@ x86_check_feature(uint32 feature, enum x86_feature_type type)
|
|||||||
void*
|
void*
|
||||||
x86_get_double_fault_stack(int32 cpu, size_t* _size)
|
x86_get_double_fault_stack(int32 cpu, size_t* _size)
|
||||||
{
|
{
|
||||||
*_size = sizeof(sDoubleFaultStack);
|
*_size = kDoubleFaultStackSize;
|
||||||
return sDoubleFaultStack;
|
return sDoubleFaultStacks + kDoubleFaultStackSize * cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Returns the index of the current CPU. Can only be called from the double
|
||||||
|
fault handler.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
x86_double_fault_get_cpu()
|
||||||
|
{
|
||||||
|
uint32 stack = x86_read_ebp();
|
||||||
|
return (stack - (uint32)sDoubleFaultStacks) / kDoubleFaultStackSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -569,7 +582,6 @@ arch_cpu_init_post_vm(kernel_args *args)
|
|||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
// account for the segment descriptors
|
// account for the segment descriptors
|
||||||
|
|
||||||
gGDT = (segment_descriptor *)args->arch_args.vir_gdt;
|
gGDT = (segment_descriptor *)args->arch_args.vir_gdt;
|
||||||
create_area("gdt", (void **)&gGDT, B_EXACT_ADDRESS, B_PAGE_SIZE,
|
create_area("gdt", (void **)&gGDT, B_EXACT_ADDRESS, B_PAGE_SIZE,
|
||||||
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
@ -578,6 +590,10 @@ arch_cpu_init_post_vm(kernel_args *args)
|
|||||||
// (a fixed number of used GDT entries)
|
// (a fixed number of used GDT entries)
|
||||||
//i386_selector_init(gGDT); // pass the new gdt
|
//i386_selector_init(gGDT); // pass the new gdt
|
||||||
|
|
||||||
|
// allocate an area for the double fault stacks
|
||||||
|
create_area("double fault stacks", (void**)&sDoubleFaultStacks,
|
||||||
|
B_ANY_KERNEL_ADDRESS, kDoubleFaultStackSize * smp_get_num_cpus(),
|
||||||
|
B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
vm_translation_map_arch_info* kernelArchTranslationMap
|
vm_translation_map_arch_info* kernelArchTranslationMap
|
||||||
= vm_kernel_address_space()->translation_map.arch_data;
|
= vm_kernel_address_space()->translation_map.arch_data;
|
||||||
|
Loading…
Reference in New Issue
Block a user