forked from Imagelibrary/rtems
2009-10-29 Till Straumann <strauman@slac.stanford.edu>
* shared/irq/irq_asm.S: Make sure stack is aligned to CPU_STACK_ALIGNMENT for *all* C-routines (including _Thread_Dispatch() and _ThreadProcessSignalsFromIrq()) not only C_dispatch_isr(). * shared/irq/irq.c: Added IRQ statistics counters.
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
|
2009-10-29 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
|
* shared/irq/irq_asm.S: Make sure stack is aligned to CPU_STACK_ALIGNMENT
|
||||||
|
for *all* C-routines (including _Thread_Dispatch() and
|
||||||
|
_ThreadProcessSignalsFromIrq()) not only C_dispatch_isr().
|
||||||
|
|
||||||
|
* shared/irq/irq.c: Added IRQ statistics counters.
|
||||||
|
|
||||||
2009-10-29 Till Straumann <strauman@slac.stanford.edu>
|
2009-10-29 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
* shared/irq/irq_asm.S: Beautification; ajusted margins and
|
* shared/irq/irq_asm.S: Beautification; ajusted margins and
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <rtems/score/apiext.h>
|
#include <rtems/score/apiext.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pointer to the mask representing the additionnal irq vectors
|
* pointer to the mask representing the additionnal irq vectors
|
||||||
@@ -32,6 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
|
rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
|
||||||
|
|
||||||
|
uint32_t irq_count[BSP_IRQ_LINES_NUMBER] = {0};
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
BSP_irq_count_dump(FILE *f)
|
||||||
|
{
|
||||||
|
uint32_t tot = 0;
|
||||||
|
int i;
|
||||||
|
if ( !f )
|
||||||
|
f = stdout;
|
||||||
|
for ( i=0; i<BSP_IRQ_LINES_NUMBER; i++ ) {
|
||||||
|
tot += irq_count[i];
|
||||||
|
fprintf(f,"IRQ %2u: %9"PRIu32"\n", i, irq_count[i]);
|
||||||
|
}
|
||||||
|
return tot;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------+
|
/*-------------------------------------------------------------------------+
|
||||||
| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
|
| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
|
||||||
+--------------------------------------------------------------------------*/
|
+--------------------------------------------------------------------------*/
|
||||||
@@ -228,6 +246,7 @@ void bsp_interrupt_handler_default(rtems_vector_number vector)
|
|||||||
|
|
||||||
void C_dispatch_isr(int vector)
|
void C_dispatch_isr(int vector)
|
||||||
{
|
{
|
||||||
|
irq_count[vector]++;
|
||||||
bsp_interrupt_handler_dispatch(vector);
|
bsp_interrupt_handler_dispatch(vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,13 @@
|
|||||||
#error "Missing header? CPU_STACK_ALIGNMENT is not defined here"
|
#error "Missing header? CPU_STACK_ALIGNMENT is not defined here"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Stack frame we use for intermediate storage */
|
||||||
|
#define ARG_OFF 0
|
||||||
|
#define MSK_OFF 4
|
||||||
|
#define EBP_OFF 8 /* code restoring ebp/esp relies on */
|
||||||
|
#define ESP_OFF 12 /* esp being on top of ebp! */
|
||||||
|
#define FRM_SIZ 16
|
||||||
|
|
||||||
BEGIN_CODE
|
BEGIN_CODE
|
||||||
|
|
||||||
SYM (_ISR_Handler):
|
SYM (_ISR_Handler):
|
||||||
@@ -51,11 +58,24 @@ SYM (_ISR_Handler):
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now switch stacks if necessary
|
* Establish an aligned stack frame
|
||||||
|
* original-sp
|
||||||
|
* saved-bp
|
||||||
|
* saved-irq-mask
|
||||||
|
* vector-arg-to-C_dispatch_isr <- aligned SP
|
||||||
*/
|
*/
|
||||||
|
movl esp, eax
|
||||||
|
subl $FRM_SIZ, esp
|
||||||
|
andl $ - CPU_STACK_ALIGNMENT, esp
|
||||||
|
movl eax, ESP_OFF(esp)
|
||||||
|
movl ebp, EBP_OFF(esp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* acknowledge the interrupt
|
||||||
|
*
|
||||||
|
*/
|
||||||
movw SYM (i8259s_cache), ax /* move current i8259 interrupt mask in ax */
|
movw SYM (i8259s_cache), ax /* move current i8259 interrupt mask in ax */
|
||||||
pushl eax /* push it on the stack */
|
movl eax, MSK_OFF(esp) /* save in stack frame */
|
||||||
/*
|
/*
|
||||||
* compute the new PIC mask:
|
* compute the new PIC mask:
|
||||||
*
|
*
|
||||||
@@ -72,10 +92,6 @@ SYM (_ISR_Handler):
|
|||||||
movb ah, al
|
movb ah, al
|
||||||
outb $PIC_SLAVE_IMR_IO_PORT
|
outb $PIC_SLAVE_IMR_IO_PORT
|
||||||
|
|
||||||
/*
|
|
||||||
* acknowledge the interrupt
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
movb $PIC_EOI, al
|
movb $PIC_EOI, al
|
||||||
cmpl $7, ecx
|
cmpl $7, ecx
|
||||||
jbe .master
|
jbe .master
|
||||||
@@ -83,18 +99,20 @@ SYM (_ISR_Handler):
|
|||||||
.master:
|
.master:
|
||||||
outb $PIC_MASTER_COMMAND_IO_PORT
|
outb $PIC_MASTER_COMMAND_IO_PORT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now switch stacks if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
.check_stack_switch:
|
.check_stack_switch:
|
||||||
pushl ebp
|
|
||||||
movl esp, ebp /* ebp = previous stack pointer */
|
movl esp, ebp /* ebp = previous stack pointer */
|
||||||
cmpl $0, SYM (_ISR_Nest_level) /* is this the outermost interrupt? */
|
cmpl $0, SYM (_ISR_Nest_level) /* is this the outermost interrupt? */
|
||||||
jne nested /* No, then continue */
|
jne nested /* No, then continue */
|
||||||
movl SYM (_CPU_Interrupt_stack_high), esp
|
movl SYM (_CPU_Interrupt_stack_high), esp
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to insure that the old stack pointer is on the
|
* We want to insure that the old stack pointer is in ebp
|
||||||
* stack we will be on at the end of the ISR when we restore it.
|
* By saving it on every interrupt, all we have to do is
|
||||||
* By saving it on every interrupt, all we have to do is pop it
|
* movl ebp->esp near the end of every interrupt.
|
||||||
* near the end of every interrupt.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nested:
|
nested:
|
||||||
@@ -102,26 +120,19 @@ nested:
|
|||||||
incl SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
|
incl SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure CPU_STACK_ALIGNMENT for C-code.
|
|
||||||
* esp = (esp - 4) & ~(CPU_STACK_ALIGNMENT - 1)
|
|
||||||
* makes sure 'esp' is aligned AND there is enough space
|
|
||||||
* for the vector argument on the stack!
|
|
||||||
*/
|
|
||||||
subl $4, esp
|
|
||||||
|
|
||||||
andl $ - CPU_STACK_ALIGNMENT, esp
|
|
||||||
/*
|
|
||||||
* re-enable interrupts at processor level as the current
|
* re-enable interrupts at processor level as the current
|
||||||
* interrupt source is now masked via i8259
|
* interrupt source is now masked via i8259
|
||||||
*/
|
*/
|
||||||
sti
|
sti
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ECX is preloaded with the vector number but it is a scratch register
|
* ECX is preloaded with the vector number; store as arg
|
||||||
* so we must save it again.
|
* on top of stack. Note that _CPU_Interrupt_stack_high
|
||||||
|
* was adjusted in _CPU_Interrupt_stack_setup() (score/rtems/cpu.h)
|
||||||
|
* to make sure there is space.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
movl ecx, (esp) /* store vector arg in stack */
|
movl ecx, ARG_OFF(esp) /* store vector arg in stack */
|
||||||
call C_dispatch_isr
|
call C_dispatch_isr
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -130,15 +141,15 @@ nested:
|
|||||||
cli
|
cli
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* restore stack
|
* Restore stack. This moves back to the task stack
|
||||||
|
* when all interrupts are unnested.
|
||||||
*/
|
*/
|
||||||
movl ebp, esp
|
movl ebp, esp
|
||||||
popl ebp
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* restore the original i8259 masks
|
* restore the original i8259 masks
|
||||||
*/
|
*/
|
||||||
popl eax
|
movl MSK_OFF(esp), eax
|
||||||
movw ax, SYM (i8259s_cache)
|
movw ax, SYM (i8259s_cache)
|
||||||
outb $PIC_MASTER_IMR_IO_PORT
|
outb $PIC_MASTER_IMR_IO_PORT
|
||||||
movb ah, al
|
movb ah, al
|
||||||
@@ -186,6 +197,10 @@ nested:
|
|||||||
* eip, CS, Flags).
|
* eip, CS, Flags).
|
||||||
*/
|
*/
|
||||||
.exit:
|
.exit:
|
||||||
|
/* restore ebp and original esp */
|
||||||
|
addl $EBP_OFF, esp
|
||||||
|
popl ebp
|
||||||
|
popl esp
|
||||||
/*
|
/*
|
||||||
* BEGINNING OF DE-ESTABLISH SEGMENTS
|
* BEGINNING OF DE-ESTABLISH SEGMENTS
|
||||||
*
|
*
|
||||||
@@ -241,7 +256,10 @@ PUBLIC (raw_idt_notify)
|
|||||||
SYM (default_raw_idt_handler):
|
SYM (default_raw_idt_handler):
|
||||||
pusha
|
pusha
|
||||||
cld
|
cld
|
||||||
|
mov esp, ebp
|
||||||
|
andl $ - CPU_STACK_ALIGNMENT, esp
|
||||||
call raw_idt_notify
|
call raw_idt_notify
|
||||||
|
mov ebp, esp
|
||||||
popa
|
popa
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user