summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_asm.S100
1 files changed, 46 insertions, 54 deletions
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_asm.S b/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
index bbc1afb5d6..f77dd7f0cf 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
@@ -44,9 +44,17 @@ SYM (_ISR_Handler):
* Before this was point is reached the vectors unique
* entry point did the following:
*
- * 1. saved scratch registers registers eax edx ecx
+ * 1. saved scratch registers registers eax edx ecx"
* 2. put the vector number in ecx.
*
+ * BEGINNING OF ESTABLISH SEGMENTS
+ *
+ * WARNING: If an interrupt can occur when the segments are
+ * not correct, then this is where we should establish
+ * the segments. In addition to establishing the
+ * segments, it may be necessary to establish a stack
+ * in the current data area on the outermost interrupt.
+ *
* NOTE: If the previous values of the segment registers are
* pushed, do not forget to adjust SAVED_REGS.
*
@@ -74,8 +82,6 @@ SYM (_ISR_Handler):
movl ebx, EBX_OFF(esp)
movl eax, ESP_OFF(esp)
movl ebp, EBP_OFF(esp)
- movw SYM (i8259s_cache), ax /* save current i8259 interrupt mask */
- movl eax, MSK_OFF(esp) /* save in stack frame */
#ifdef __SSE__
/* NOTE: SSE only is supported if the BSP enables fxsave/fxrstor
@@ -96,54 +102,15 @@ SYM (_ISR_Handler):
ldmxcsr ARG_OFF(esp) /* clean-slate MXCSR */
#endif
-.check_stack_switch:
- movl esp, ebp /* ebp = previous stack pointer */
-#if defined(RTEMS_SMP) && defined(BSP_HAS_SMP)
- call SYM(_CPU_SMP_Get_current_processor)
- sall $PER_CPU_CONTROL_SIZE_LOG2, eax
- addl $SYM(_Per_CPU_Information), eax
- movl eax, ebx
- pushl ecx
- call SYM(_ISR_SMP_Enter)
- popl ecx
- cmpl $0, eax
- jne .i8259
- movl PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
-
-#else
- movl $SYM(_Per_CPU_Information), ebx
-
- /*
- * Is this the outermost interrupt?
- * Switch stacks if necessary
- */
- cmpl $0, PER_CPU_ISR_NEST_LEVEL(ebx)
- jne nested /* No, then continue */
- movl PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
-
- /*
- * We want to insure that the old stack pointer is in ebp
- * By saving it on every interrupt, all we have to do is
- * movl ebp->esp near the end of every interrupt.
- */
-
-nested:
- incl PER_CPU_ISR_NEST_LEVEL(ebx) /* one nest level deeper */
- incl SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
-#endif
- /*
- * i8259 Management
- */
-
-.i8259:
/* Do not disable any 8259 interrupts if this isn't from one */
cmp ecx, 16 /* is this a PIC IRQ? */
- jge .end_of_i8259
+ jge .check_stack_switch
/*
* acknowledge the interrupt
*/
- movw SYM (i8259s_cache), ax /* fetch current i8259 interrupt mask */
+ movw SYM (i8259s_cache), ax /* save current i8259 interrupt mask */
+ movl eax, MSK_OFF(esp) /* save in stack frame */
/*
* compute the new PIC mask:
@@ -167,7 +134,39 @@ nested:
outb $PIC_SLAVE_COMMAND_IO_PORT
.master:
outb $PIC_MASTER_COMMAND_IO_PORT
-.end_of_i8259:
+
+ /*
+ * Now switch stacks if necessary
+ */
+
+PUBLIC (ISR_STOP)
+ISR_STOP:
+.check_stack_switch:
+ movl esp, ebp /* ebp = previous stack pointer */
+
+ movl $SYM(_Per_CPU_Information), ebx
+
+ /* is this the outermost interrupt? */
+ cmpl $0, PER_CPU_ISR_NEST_LEVEL(ebx)
+ jne nested /* No, then continue */
+ movl PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
+
+ /*
+ * We want to insure that the old stack pointer is in ebp
+ * By saving it on every interrupt, all we have to do is
+ * movl ebp->esp near the end of every interrupt.
+ */
+
+nested:
+ incl PER_CPU_ISR_NEST_LEVEL(ebx) /* one nest level deeper */
+ incl SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
+
+ /*
+ * GCC versions starting with 4.3 no longer place the cld
+ * instruction before string operations. We need to ensure
+ * it is set correctly for ISR handlers.
+ */
+ cld
/*
* re-enable interrupts at processor level as the current
@@ -210,14 +209,8 @@ nested:
outb $PIC_MASTER_IMR_IO_PORT
movb ah, al
outb $PIC_SLAVE_IMR_IO_PORT
-.dont_restore_i8259:
-
-#if defined(RTEMS_SMP) && defined(BSP_HAS_SMP)
- call SYM(_ISR_SMP_Exit)
- testl eax, eax
- je .exit
-#else
+.dont_restore_i8259:
decl PER_CPU_ISR_NEST_LEVEL(ebx) /* one less ISR nest level */
/* If interrupts are nested, */
/* then dispatching is disabled */
@@ -231,7 +224,6 @@ nested:
/* Is task switch necessary? */
jne .schedule /* Yes, then call the scheduler */
jmp .exit /* No, exit */
-#endif
.schedule:
/*