diff options
Diffstat (limited to 'core/minute-ia/switch.S')
-rw-r--r-- | core/minute-ia/switch.S | 81 |
1 files changed, 27 insertions, 54 deletions
diff --git a/core/minute-ia/switch.S b/core/minute-ia/switch.S index 1fdcc61bb8..c5098b9003 100644 --- a/core/minute-ia/switch.S +++ b/core/minute-ia/switch.S @@ -9,6 +9,8 @@ #include "registers.h" #include "task_defs.h" +#include "irq_handler_common.S" + .text .extern current_task @@ -17,6 +19,7 @@ .global __task_start .global __switchto .global default_int_handler +.global sw_irq_handler # Start the task scheduling. Start current_task (hook_task) # This function is not an ISR but imitates the sequence. @@ -67,72 +70,43 @@ default_int_handler: ASM_LOCK_PREFIX subl $1, __in_isr popa iret +.endfunc + +.align 4 +.func sw_irq_handler +sw_irq_handler: + pusha + ASM_LOCK_PREFIX addl $1, __in_isr + + # Call sw irq handler with irq number(%ecx) from task_trigger_irq. + # Pass 0 for both desched and resched since we don't need to deschedule + # our current task (and idle task can always be rescheduled) + irq_handler_common $0 $0 %ecx + + # Indicate completion of servicing the interrupt to LAPIC. + # No IOAPIC EOI needed as this is SW triggered. + movl $0x00, LAPIC_EOI_REG + # Decrement ISR counter and restore general purpose registers. + ASM_LOCK_PREFIX subl $1, __in_isr + popa + iret .endfunc + # Switches from one task to another if ready. # __schedule triggers software interrupt ISH_TS_VECTOR, which is handled by # __switchto .align 4 .func __switchto __switchto: - - # Save current task pusha ASM_LOCK_PREFIX addl $1, __in_isr - movl %esp, %eax - movl $stack_end, %esp # use system stack - push %eax # push sp of preempted context - # __schedule() copies 'resched' to %ecx and 'desched' to %edx before - # triggering ISH_TS_VECTOR - # - # Push %ecx and %edx into stack to pass them as function parameters - # to switch_handler(desched, resched). After call, we clean up stack - # pointer. Note, we do this now before task_start_irq has a chance - # to clobber these caller-saved registers. - push %ecx - push %edx - -#ifdef CONFIG_TASK_PROFILING - push $ISH_TS_VECTOR - call task_start_irq_handler - addl $0x4, %esp -#endif - - # Stack is already set up from previous pushes - call switch_handler - addl $0x8, %esp # Clean up stack - pop %esp # restore sp of preempted context - - test %eax, %eax # Check if task switch required - jz 1f - - movl current_task, %eax - -#ifdef CONFIG_FPU - movl USE_FPU_OFFSET(%eax), %ebx - test %ebx, %ebx - jz 2f - fnsave FPU_CTX_OFFSET(%eax) # Save current FPU context(current->fp_ctx) - 2: -#endif - - # Save SP of current task and switch to new task - movl %esp, (%eax) - movl next_task, %eax - movl %eax, current_task - movl (%eax), %esp - -#ifdef CONFIG_FPU - movl USE_FPU_OFFSET(%eax), %ebx - test %ebx, %ebx - jz 1f - frstor FPU_CTX_OFFSET(%eax) # Restore next FPU context -#endif - - 1: + # triggering ISH_TS_VECTOR. + # Call sw_irq with an invalid IRQ so it will skip calling a routine + irq_handler_common %edx %ecx $CONFIG_IRQ_COUNT # Indicate completion of servicing the interrupt to LAPIC. # No IOAPIC EOI needed as this is SW triggered. @@ -142,5 +116,4 @@ __switchto: ASM_LOCK_PREFIX subl $1, __in_isr popa iret - .endfunc |