diff --git a/arch/x86/include/asm/tasks.h b/arch/x86/include/asm/tasks.h index 2d8995fcc..7e128843b 100644 --- a/arch/x86/include/asm/tasks.h +++ b/arch/x86/include/asm/tasks.h @@ -30,7 +30,7 @@ * @file arch/x86/include/asm/tasks.h * @brief Task related structure definitions * - * This file contains the task_t structure definition + * This file contains the task_t structure definition * and task state define constants */ @@ -55,7 +55,7 @@ void switch_context(size_t** stack); * @param task Pointer to the task structure * @param ep The entry point for code execution * @param arg Arguments list pointer for the task's stack - * @param core_id Id of the core, which is firstly used by the task + * @param core_id Id of the core, which is firstly used by the task * @return * - 0 on success * - -EINVAL (-22) on failure @@ -77,6 +77,13 @@ static inline int jump_to_user_code(size_t ep, size_t stack) return 0; } +/** @brief Architecture dependent initialize routine + */ +static inline void arch_init_task(task_t* task) +{ + set_tss((size_t) task->stack + KERNEL_STACK_SIZE - 0x10, (size_t) task->ist_addr + KERNEL_STACK_SIZE - 0x10); +} + #ifdef __cplusplus } #endif diff --git a/arch/x86/kernel/isrs.c b/arch/x86/kernel/isrs.c index f5e1c32ee..dd2583f27 100644 --- a/arch/x86/kernel/isrs.c +++ b/arch/x86/kernel/isrs.c @@ -82,10 +82,11 @@ extern void isr29(void); extern void isr30(void); extern void isr31(void); -static void fault_handler(struct state *s); -extern void fpu_handler(struct state *s); +static void arch_fault_handler(struct state *s); +static void arch_fpu_handler(struct state *s); +extern void fpu_handler(void); -/* +/* * This is a very repetitive function... it's not hard, it's * just annoying. As you can see, we set the first 32 entries * in the IDT to the first 32 ISRs. We can't use a for loop @@ -94,7 +95,7 @@ extern void fpu_handler(struct state *s); * flags to 0x8E. This means that the entry is present, is * running in ring 0 (kernel level), and has the lower 5 bits * set to the required '14', which is represented by 'E' in - * hex. + * hex. */ void isrs_install(void) { @@ -174,11 +175,11 @@ void isrs_install(void) // install the default handler for(i=0; i<32; i++) - irq_install_handler(i, fault_handler); + irq_install_handler(i, arch_fault_handler); // set hanlder for fpu exceptions irq_uninstall_handler(7); - irq_install_handler(7, fpu_handler); + irq_install_handler(7, arch_fpu_handler); } /** @brief Exception messages @@ -186,29 +187,39 @@ void isrs_install(void) * This is a simple string array. It contains the message that * corresponds to each and every exception. We get the correct * message by accessing it like this: - * exception_message[interrupt_number] + * exception_message[interrupt_number] */ -static const char *exception_messages[] = { - "Division By Zero", "Debug", "Non Maskable Interrupt", +static const char *exception_messages[] = { + "Division By Zero", "Debug", "Non Maskable Interrupt", "Breakpoint", "Into Detected Overflow", "Out of Bounds", "Invalid Opcode", - "No Coprocessor", "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", - "Segment Not Present", "Stack Fault", "General Protection Fault", "Page Fault", - "Unknown Interrupt", "Coprocessor Fault", "Alignment Check", "Machine Check", + "No Coprocessor", "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", + "Segment Not Present", "Stack Fault", "General Protection Fault", "Page Fault", + "Unknown Interrupt", "Coprocessor Fault", "Alignment Check", "Machine Check", "SIMD Floating-Point", "Virtualization", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved" }; -/* +/* interrupt handler to save / restore the FPU context */ +static void arch_fpu_handler(struct state *s) +{ + (void) s; + + clts(); // clear the TS flag of cr0 + + fpu_handler(); +} + +/* * All of our Exception handling Interrupt Service Routines will * point to this function. This will tell us what exception has - * occured! Right now, we simply abort the current task. + * occured! Right now, we simply abort the current task. * All ISRs disable interrupts while they are being * serviced as a 'locking' mechanism to prevent an IRQ from * happening and messing up kernel data structures */ -static void fault_handler(struct state *s) +static void arch_fault_handler(struct state *s) { - + if (s->int_no < 32) LOG_INFO("%s", exception_messages[s->int_no]); else diff --git a/kernel/tasks.c b/kernel/tasks.c index d80ea3de6..1f83d211e 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -195,15 +195,11 @@ static void readyqueues_remove(uint32_t core_id, task_t* task) } -/* interrupt handler to save / restore the FPU context */ -void fpu_handler(struct state *s) +void fpu_handler(void) { - (void) s; - task_t* task = per_core(current_task); uint32_t core_id = CORE_ID; - clts(); // clear the TS flag of cr0 task->flags |= TASK_FPU_USED; if (!(task->flags & TASK_FPU_INIT)) { @@ -284,7 +280,7 @@ int multitasking_init(void) task_table[0].ist_addr = (char*)&boot_ist; set_per_core(kernel_stack, task_table[0].stack + KERNEL_STACK_SIZE - 0x10); set_per_core(current_task, task_table+0); - set_tss((size_t) task_table[0].stack + KERNEL_STACK_SIZE - 0x10, (size_t) task_table[0].ist_addr + KERNEL_STACK_SIZE - 0x10); + arch_init_task(task_table+0); readyqueues[core_id].idle = task_table+0; @@ -312,7 +308,7 @@ int set_idle_task(void) task_table[i].heap = NULL; readyqueues[core_id].idle = task_table+i; set_per_core(current_task, readyqueues[core_id].idle); - set_tss((size_t) task_table[i].stack + KERNEL_STACK_SIZE - 0x10, (size_t) task_table[i].ist_addr + KERNEL_STACK_SIZE - 0x10); + arch_init_task(task_table+i); ret = 0; break;