diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-04-14 13:44:29 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-04-14 13:44:29 +0000 |
commit | 7c4c284c4af4551627097f914ce048245213c481 (patch) | |
tree | b4ca21e9cb1f8a2896755f8ad1443001f2dbf2ee /cpukit/score/cpu/lm32/cpu_asm.S | |
parent | Fix attribution. (diff) | |
download | rtems-7c4c284c4af4551627097f914ce048245213c481.tar.bz2 |
2009-04-14 Michael Walle <michael@walle.cc>
* cpu.h: corrected the registers in Context_Control and
in CPU_Interrupt_frame to correspond to the saved frame in cpu_asm.S
Also switched on CPU_ISR_PASSES_FRAME_POINTER.
* cpu_asm.S: Moved the restore part of _CPU_Context_switch for
easier reading. Fixed _CPU_Context_restore, it now moves the
argument and branches to a label in _CPU_Context_switch. Removed
unnecessary saves of registers in context switch and irq handling.
Rewrote irq code to call the C helper. Added some documentation
* irq.c: New file derived from c4x and nios2.
Diffstat (limited to 'cpukit/score/cpu/lm32/cpu_asm.S')
-rw-r--r-- | cpukit/score/cpu/lm32/cpu_asm.S | 254 |
1 files changed, 119 insertions, 135 deletions
diff --git a/cpukit/score/cpu/lm32/cpu_asm.S b/cpukit/score/cpu/lm32/cpu_asm.S index 80501bad1d..d169c5f611 100644 --- a/cpukit/score/cpu/lm32/cpu_asm.S +++ b/cpukit/score/cpu/lm32/cpu_asm.S @@ -13,44 +13,70 @@ * * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, * Micro-Research Finland Oy + * + * Michael Walle <michael@walle.cc>, 2009 */ #include <rtems/asm.h> #include <rtems/score/cpu_asm.h> -#define MICO32_FULL_CONTEXT_SAVE_RESTORE - /* void _CPU_Context_switch(run_context, heir_context) * * This routine performs a normal non-FP context switch. * * LM32 Specific Information: * - * XXX document implementation including references if appropriate + * Saves/restores all callee-saved general purpose registers as well as + * the stack pointer, return address and interrupt enable status register + * to/from the context. + * */ .globl _CPU_Context_switch _CPU_Context_switch: - sw (r1+0), r9 - sw (r1+4), r10 - sw (r1+8), r11 - sw (r1+12), r12 - sw (r1+16), r13 - sw (r1+20), r14 - sw (r1+24), r15 - sw (r1+28), r16 - sw (r1+32), r17 - sw (r1+36), r18 - sw (r1+40), r19 - sw (r1+44), r20 - sw (r1+48), r21 - sw (r1+52), r22 - sw (r1+56), r23 - sw (r1+60), r24 - sw (r1+64), r25 - sw (r1+68), gp - sw (r1+72), fp - sw (r1+76), sp - sw (r1+80), ra + sw (r1+0), r11 /* r1 is the first argument */ + sw (r1+4), r12 + sw (r1+8), r13 + sw (r1+12), r14 + sw (r1+16), r15 + sw (r1+20), r16 + sw (r1+24), r17 + sw (r1+28), r18 + sw (r1+32), r19 + sw (r1+36), r20 + sw (r1+40), r21 + sw (r1+44), r22 + sw (r1+48), r23 + sw (r1+52), r24 + sw (r1+56), r25 + sw (r1+60), gp + sw (r1+64), fp + sw (r1+68), sp + sw (r1+72), ra + rcsr r3, IE + sw (r1+76), r3 +_CPU_Context_switch_restore: + lw r11, (r2+0) /* r2 is the second argument */ + lw r12, (r2+4) + lw r13, (r2+8) + lw r14, (r2+12) + lw r15, (r2+16) + lw r16, (r2+20) + lw r17, (r2+24) + lw r18, (r2+28) + lw r19, (r2+32) + lw r20, (r2+36) + lw r21, (r2+40) + lw r22, (r2+44) + lw r23, (r2+48) + lw r24, (r2+52) + lw r25, (r2+56) + lw gp, (r2+60) + lw fp, (r2+64) + lw sp, (r2+68) + lw ra, (r2+72) + lw r3, (r2+76) + wcsr IE, r3 + ret /* * _CPU_Context_restore @@ -58,112 +84,90 @@ _CPU_Context_switch: * This routine is generally used only to restart self in an * efficient manner. It may simply be a label in _CPU_Context_switch. * - * NOTE: May be unnecessary to reload some registers. - * * LM32 Specific Information: * - * XXX document implementation including references if appropriate + * Moves argument #1 to #2 and branches to the restore part of the + * context switch code above. */ .globl _CPU_Context_restore _CPU_Context_restore: - lw r9, (r2+0) - lw r10, (r2+4) - lw r11, (r2+8) - lw r12, (r2+12) - lw r13, (r2+16) - lw r14, (r2+20) - lw r15, (r2+24) - lw r16, (r2+28) - lw r17, (r2+32) - lw r18, (r2+36) - lw r19, (r2+40) - lw r20, (r2+44) - lw r21, (r2+48) - lw r22, (r2+52) - lw r23, (r2+56) - lw r24, (r2+60) - lw r25, (r2+64) - lw gp, (r2+68) - lw fp, (r2+72) - lw ra, (r2+80) - /* Stack pointer must be restored last, in case it has been updated */ - lw sp, (r2+76) - nop - ret - -/* void __ISR_Handler() + mv r2, r1 + bi _CPU_Context_switch_restore + +/* void _ISR_Handler() * * This routine provides the RTEMS interrupt management. * * LM32 Specific Information: * - * XXX document implementation including references if appropriate + * Saves all the caller-saved general purpose registers as well as the + * return address, exception return address and breakpoint return address + * (the latter may be unnecessary) onto the stack, which is either the task + * stack (in case of a interrupted task) or the interrupt stack (if an + * interrupt was interrupted). + * After that, it figures out the pending interrupt with the highest + * priority and calls the main ISR handler written in C, which in turn + * handles interrupt nesting, software interrupt stack setup etc and + * finally calls the user ISR. + * At the end the saved registers are restored. + * */ .globl _ISR_Handler _ISR_Handler: - xor r0, r0, r0 - addi sp, sp, -128 - sw (sp+4), r1 - sw (sp+8), r2 - sw (sp+12), r3 - sw (sp+16), r4 - sw (sp+20), r5 - sw (sp+24), r6 - sw (sp+28), r7 - sw (sp+32), r8 - sw (sp+36), r9 - sw (sp+40), r10 -#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE - sw (sp+44), r11 - sw (sp+48), r12 - sw (sp+52), r13 - sw (sp+56), r14 - sw (sp+60), r15 - sw (sp+64), r16 - sw (sp+68), r17 - sw (sp+72), r18 - sw (sp+76), r19 - sw (sp+80), r20 - sw (sp+84), r21 - sw (sp+88), r22 - sw (sp+92), r23 - sw (sp+96), r24 - sw (sp+100), r25 - sw (sp+104), r26 - sw (sp+108), r27 -#endif - sw (sp+116), ra - sw (sp+120), ea - sw (sp+124), ba + xor r0, r0, r0 + addi sp, sp, -52 + sw (sp+4), r1 + sw (sp+8), r2 + sw (sp+12), r3 + sw (sp+16), r4 + sw (sp+20), r5 + sw (sp+24), r6 + sw (sp+28), r7 + sw (sp+32), r8 + sw (sp+36), r9 + sw (sp+40), r10 + sw (sp+44), ra + sw (sp+48), ea + sw (sp+52), ba - /* Scan through (IP & IM) bits starting from LSB until irq found */ - rcsr r2,IP - rcsr r3,IM - and r4,r2,r3 - or r1,r0,r0 - ori r5,r0,1 -find_irq: - and r6,r4,r5 - bne r6,r0,found_irq - sli r5,r5,1 - addi r1,r1,1 - bne r5,r0,find_irq - /* If we end up here there was no interrupt - this should never - happen! */ - bi exit_isr + /* + * Scan through IP & IM bits starting from LSB until irq vector is + * found. The vector is stored in r1, which is the first argument for + * __ISR_Handler. + */ + rcsr r2, IP + rcsr r3, IM + mv r1, r0 /* r1: counter for the vector number */ + and r2, r2, r3 /* r2: pending irqs, which are enabled */ + mvi r3, 1 /* r3: register for the walking 1 */ + /* + * If r2 is zero, there was no interrupt. + * This should never happen! + */ + be r2, r0, exit_isr +find_irq: + and r4, r2, r3 + bne r4, r0, found_irq + sli r3, r3, 1 + addi r1, r1, 1 + bi find_irq found_irq: - .extern _ISR_Vector_table - sli r1,r1,2 - mvhi r7,hi(_ISR_Vector_table) - ori r7,r7,lo(_ISR_Vector_table) - lw r6,(r7+0) - add r6,r6,r1 - lw r5,(r6+0) - call r5 + /* + * Call __ISR_Handler for further processing. + * r1 is the vector number, calculated above + * r2 is the pointer to the CPU_Interrupt_frame + */ + addi r2, sp, 4 + .extern __ISR_Handler + mvhi r3, hi(__ISR_Handler) + ori r3, r3, lo(__ISR_Handler) + call r3 + exit_isr: + /* Restore the saved registers */ lw r1, (sp+4) lw r2, (sp+8) lw r3, (sp+12) @@ -174,29 +178,9 @@ exit_isr: lw r8, (sp+32) lw r9, (sp+36) lw r10, (sp+40) -#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE - lw r11, (sp+44) - lw r12, (sp+48) - lw r13, (sp+52) - lw r14, (sp+56) - lw r15, (sp+60) - lw r16, (sp+64) - lw r17, (sp+68) - lw r18, (sp+72) - lw r19, (sp+76) - lw r20, (sp+80) - lw r21, (sp+84) - lw r22, (sp+88) - lw r23, (sp+92) - lw r24, (sp+96) - lw r25, (sp+100) - lw r26, (sp+104) - lw r27, (sp+108) -#endif - lw ra, (sp+116) - lw ea, (sp+120) - lw ba, (sp+124) - addi sp, sp, 128 - nop + lw ra, (sp+44) + lw ea, (sp+48) + lw ba, (sp+52) + addi sp, sp, 52 eret |