* Now we deal with all x86 exceptions, i.e. we no longer panic() when a
user application performs a division by zero or causes a general protection fault. For some exceptions (e.g. machine check) I wasn't quite sure whether they can be caused by user apps at all, so we panic() in those cases. Wouldn't harm, if someone more knowledgable would check this, though. * Removed the unused fault handling stuff, respectively moved the little that was used into x86/arch_int.c. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13795 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7d971e51a1
commit
d08379a80b
@ -1,13 +0,0 @@
|
||||
/*
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef KERNEL_ARCH_FAULTS_H
|
||||
#define KERNEL_ARCH_FAULTS_H
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
int faults_init(kernel_args *ka);
|
||||
int arch_faults_init(kernel_args *ka);
|
||||
|
||||
#endif /* KERNEL_ARCH_FAULTS_H */
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef _NEWOS_KERNEL_ARCH_I386_FAULTS
|
||||
#define _NEWOS_KERNEL_ARCH_I386_FAULTS
|
||||
|
||||
struct iframe;
|
||||
|
||||
int i386_general_protection_fault(int errorcode);
|
||||
int i386_double_fault(struct iframe *frame);
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,6 @@ KernelMergeObject kernel_core.o :
|
||||
boot_item.cpp
|
||||
cpu.c
|
||||
elf.c
|
||||
faults.c
|
||||
heap.c
|
||||
image.c
|
||||
int.c
|
||||
|
@ -8,7 +8,6 @@ KernelStaticLibrary libppc :
|
||||
arch_debug.c
|
||||
arch_elf.c
|
||||
arch_exceptions.S
|
||||
arch_faults.c
|
||||
arch_int.c
|
||||
arch_mmu.cpp
|
||||
arch_real_time_clock.c
|
||||
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/stage2.h>
|
||||
|
||||
|
||||
int
|
||||
arch_faults_init(kernel_args *ka)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ KernelStaticLibrary libx86 :
|
||||
arch_debug.c
|
||||
arch_debug_console.c
|
||||
arch_elf.c
|
||||
arch_faults.c
|
||||
arch_int.c
|
||||
# arch_selector.c
|
||||
arch_real_time_clock.c
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <faults.h>
|
||||
#include <faults_priv.h>
|
||||
#include <boot/kernel_args.h>
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/faults.h>
|
||||
|
||||
// XXX this module is largely outdated. Will probably be removed later.
|
||||
|
||||
int arch_faults_init(kernel_args *ka)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i386_general_protection_fault(int errorcode)
|
||||
{
|
||||
return general_protection_fault(errorcode);
|
||||
}
|
||||
|
||||
int i386_double_fault(struct iframe *frame)
|
||||
{
|
||||
struct tss *tss = x86_get_main_tss();
|
||||
|
||||
frame->cs = tss->cs;
|
||||
frame->eip = tss->eip;
|
||||
frame->esp = tss->esp;
|
||||
frame->flags = tss->eflags;
|
||||
|
||||
panic("double fault! errorcode = 0x%x\n", frame->error_code);
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
@ -8,24 +8,24 @@
|
||||
|
||||
#include <vm.h>
|
||||
#include <int.h>
|
||||
#include <thread.h>
|
||||
#include <smp.h>
|
||||
#include <vm_priv.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <smp.h>
|
||||
#include <team.h>
|
||||
#include <thread.h>
|
||||
#include <vm_priv.h>
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/int.h>
|
||||
#include <arch/faults.h>
|
||||
#include <arch/vm.h>
|
||||
#include <arch/smp.h>
|
||||
#include <arch/user_debugger.h>
|
||||
#include <arch/vm.h>
|
||||
|
||||
#include <arch/x86/faults.h>
|
||||
#include <arch/x86/descriptors.h>
|
||||
|
||||
#include "interrupts.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//#define TRACE_ARCH_INT
|
||||
@ -67,7 +67,7 @@
|
||||
#define PIC_SLAVE_INT_BASE 0x28
|
||||
#define PIC_NUM_INTS 0x0f
|
||||
|
||||
const char *kInterruptNames[] = {
|
||||
static const char *kInterruptNames[] = {
|
||||
/* 0 */ "Divide Error Exception",
|
||||
/* 1 */ "Debug Exception",
|
||||
/* 2 */ "NMI Interrupt",
|
||||
@ -89,6 +89,7 @@ const char *kInterruptNames[] = {
|
||||
/* 18 */ "Machine-Check Exception",
|
||||
/* 19 */ "SIMD Floating-Point Exception",
|
||||
};
|
||||
static const int kInterruptNameCount = 20;
|
||||
|
||||
#define MAX_ARGS 16
|
||||
|
||||
@ -284,6 +285,45 @@ arch_int_are_interrupts_enabled(void)
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
exception_name(int number, char *buffer, int32 bufferSize)
|
||||
{
|
||||
if (number >= 0 && number < kInterruptNameCount)
|
||||
return kInterruptNames[number];
|
||||
|
||||
snprintf(buffer, bufferSize, "exception %d", number);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fatal_exception(struct iframe *frame)
|
||||
{
|
||||
char name[32];
|
||||
panic("Fatal exception \"%s\" occurred! Error code: 0x%x\n",
|
||||
exception_name(frame->vector, name, sizeof(name)), frame->error_code);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
unexpected_exception(struct iframe *frame, debug_exception_type type,
|
||||
int signal)
|
||||
{
|
||||
if (frame->cs == USER_CODE_SEG) {
|
||||
enable_interrupts();
|
||||
|
||||
if (user_debug_exception_occurred(type, signal))
|
||||
send_signal(team_get_current_team_id(), signal);
|
||||
} else {
|
||||
char name[32];
|
||||
panic("Unexpected exception \"%s\" occurred in kernel mode! "
|
||||
"Error code: 0x%x\n",
|
||||
exception_name(frame->vector, name, sizeof(name)),
|
||||
frame->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* keep the compiler happy, this function must be called only from assembly */
|
||||
void i386_handle_trap(struct iframe frame);
|
||||
|
||||
@ -307,19 +347,65 @@ i386_handle_trap(struct iframe frame)
|
||||
// dprintf("i386_handle_trap: vector 0x%x, ip 0x%x, cpu %d\n", frame.vector, frame.eip, smp_get_current_cpu());
|
||||
|
||||
switch (frame.vector) {
|
||||
case 1:
|
||||
|
||||
// fatal exceptions
|
||||
|
||||
case 2: // NMI Interrupt
|
||||
case 7: // Device Not Available Exception (#NM)
|
||||
case 9: // Coprocessor Segment Overrun
|
||||
case 10: // Invalid TSS Exception (#TS)
|
||||
case 11: // Segment Not Present (#NP)
|
||||
case 12: // Stack Fault Exception (#SS)
|
||||
case 18: // Machine-Check Exception (#MC)
|
||||
fatal_exception(&frame);
|
||||
break;
|
||||
|
||||
case 8: // Double Fault Exception (#DF)
|
||||
{
|
||||
struct tss *tss = x86_get_main_tss();
|
||||
|
||||
frame.cs = tss->cs;
|
||||
frame.eip = tss->eip;
|
||||
frame.esp = tss->esp;
|
||||
frame.flags = tss->eflags;
|
||||
|
||||
panic("double fault! errorcode = 0x%x\n", frame.error_code);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// exceptions we can handle
|
||||
// (most of them only when occurring in userland)
|
||||
|
||||
case 0: // Divide Error Exception (#DE)
|
||||
unexpected_exception(&frame, B_DIVIDE_ERROR, SIGFPE);
|
||||
break;
|
||||
|
||||
case 1: // Debug Exception (#DB)
|
||||
ret = i386_handle_debug_exception(&frame);
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case 3: // Breakpoint Exception (#BP)
|
||||
ret = i386_handle_breakpoint_exception(&frame);
|
||||
break;
|
||||
case 8: // double fault
|
||||
ret = i386_double_fault(&frame);
|
||||
|
||||
case 4: // Overflow Exception (#OF)
|
||||
unexpected_exception(&frame, B_OVERFLOW_EXCEPTION, SIGTRAP);
|
||||
break;
|
||||
case 13: // general protection fault
|
||||
ret = i386_general_protection_fault(frame.error_code);
|
||||
|
||||
case 5: // BOUND Range Exceeded Exception (#BR)
|
||||
unexpected_exception(&frame, B_BOUNDS_CHECK_EXCEPTION, SIGTRAP);
|
||||
break;
|
||||
case 14: // page fault
|
||||
|
||||
case 6: // Invalid Opcode Exception (#UD)
|
||||
unexpected_exception(&frame, B_INVALID_OPCODE_EXCEPTION, SIGILL);
|
||||
break;
|
||||
|
||||
case 13: // General Protection Exception (#GP)
|
||||
unexpected_exception(&frame, B_GENERAL_PROTECTION_FAULT, SIGKILL);
|
||||
break;
|
||||
|
||||
case 14: // Page-Fault Exception (#PF)
|
||||
{
|
||||
unsigned int cr2;
|
||||
addr_t newip;
|
||||
@ -347,6 +433,18 @@ i386_handle_trap(struct iframe frame)
|
||||
break;
|
||||
}
|
||||
|
||||
case 16: // x87 FPU Floating-Point Error (#MF)
|
||||
unexpected_exception(&frame, B_FLOATING_POINT_EXCEPTION, SIGFPE);
|
||||
break;
|
||||
|
||||
case 17: // Alignment Check Exception (#AC)
|
||||
unexpected_exception(&frame, B_ALIGNMENT_EXCEPTION, SIGTRAP);
|
||||
break;
|
||||
|
||||
case 19: // SIMD Floating-Point Exception (#XF)
|
||||
unexpected_exception(&frame, B_FLOATING_POINT_EXCEPTION, SIGFPE);
|
||||
break;
|
||||
|
||||
case 99: // syscall
|
||||
{
|
||||
uint64 retcode;
|
||||
@ -393,8 +491,11 @@ i386_handle_trap(struct iframe frame)
|
||||
|
||||
ret = int_io_interrupt_handler(frame.vector - ARCH_INTERRUPT_BASE);
|
||||
} else {
|
||||
panic("i386_handle_trap: unhandled trap 0x%x (%s) at ip 0x%x, thread 0x%x!\n",
|
||||
frame.vector, kInterruptNames[frame.vector], frame.eip, thread ? thread->id : -1);
|
||||
char name[32];
|
||||
panic("i386_handle_trap: unhandled trap 0x%x (%s) at ip 0x%x, "
|
||||
"thread 0x%x!\n", frame.vector,
|
||||
exception_name(frame.vector, name, sizeof(name)), frame.eip,
|
||||
thread ? thread->id : -1);
|
||||
ret = B_HANDLED_INTERRUPT;
|
||||
}
|
||||
break;
|
||||
|
@ -1,74 +0,0 @@
|
||||
/* Contains the basic code for fault handling. */
|
||||
|
||||
/*
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <kernel.h>
|
||||
#include <faults_priv.h>
|
||||
#include <debug.h>
|
||||
#include <arch/int.h>
|
||||
#include <int.h>
|
||||
#include <arch/faults.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int
|
||||
faults_init(kernel_args *ka)
|
||||
{
|
||||
dprintf("init_fault_handlers: entry\n");
|
||||
return arch_faults_init(ka);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
general_protection_fault(int errorcode)
|
||||
{
|
||||
panic("GENERAL PROTECTION FAULT: errcode 0x%x. Killing system.\n", errorcode);
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
fpu_fault_to_str(enum fpu_faults fpu_fault)
|
||||
{
|
||||
switch (fpu_fault) {
|
||||
default:
|
||||
case FPU_FAULT_CODE_UNKNOWN:
|
||||
return "unknown";
|
||||
case FPU_FAULT_CODE_DIVBYZERO:
|
||||
return "divbyzero";
|
||||
case FPU_FAULT_CODE_INVALID_OP:
|
||||
return "invalid op";
|
||||
case FPU_FAULT_CODE_OVERFLOW:
|
||||
return "overflow";
|
||||
case FPU_FAULT_CODE_UNDERFLOW:
|
||||
return "underflow";
|
||||
case FPU_FAULT_CODE_INEXACT:
|
||||
return "inexact";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fpu_fault(int fpu_fault)
|
||||
{
|
||||
panic("FPU FAULT: errcode 0x%x (%s), Killing system.\n", fpu_fault, fpu_fault_to_str(fpu_fault));
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fpu_disable_fault(void)
|
||||
{
|
||||
panic("FPU DISABLE FAULT: Killing system.\n");
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <debug.h>
|
||||
#include <arch/faults.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <vm.h>
|
||||
#include <timer.h>
|
||||
@ -109,8 +108,6 @@ _start(kernel_args *oldka, int cpu_num)
|
||||
TRACE(("init system info\n"));
|
||||
system_info_init(&ka);
|
||||
|
||||
TRACE(("init faults\n"));
|
||||
faults_init(&ka);
|
||||
TRACE(("init SMP\n"));
|
||||
smp_init(&ka);
|
||||
TRACE(("init timer\n"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user