Changeset d5136d9 in rtems for c/src/lib/libbsp/arm/shared/irq/irq_asm.S
- Timestamp:
- 07/17/02 17:17:53 (21 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- f9c74e5
- Parents:
- 3e2f5cc1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/arm/shared/irq/irq_asm.S
r3e2f5cc1 rd5136d9 3 3 * This file contains the implementation of the IRQ handler 4 4 * 5 * Copyright (c) 2002 Advent Networks, Inc. 6 * Jay Monkman <jmonkman@adventnetworks.com> 7 * 5 8 * CopyRight (C) 2000 Canon Research France SA. 6 9 * Emmanuel Raguet, mailto:raguet@crf.canon.fr 10 * 11 * Modified Andy Dachs <a.dachs@sstl.co.uk> 12 * Copyright (c) 2001 Surrey Satellite Technolgy Limited 7 13 * 8 14 * The license and distribution terms for this file may be … … 15 21 #include "asm.h" 16 22 #define __asm__ 17 #include <registers.h> 23 24 .globl _ISR_Handler 25 _ISR_Handler: 26 stmdb sp!, {r0, r1, r2, r3} /* save regs on INT stack */ 27 stmdb sp!, {lr} /* now safe to call C funcs */ 28 29 30 /* one nest level deeper */ 31 ldr r0, =_ISR_Nest_level 32 ldr r1, [r0] 33 add r1, r1,#1 34 str r1, [r0] 35 36 /* disable multitasking */ 37 ldr r0, =_Thread_Dispatch_disable_level 38 ldr r1, [r0] 39 add r1, r1,#1 40 str r1, [r0] 41 42 /* BSP specific function to INT handler */ 43 /* FIXME: I'm not sure why I can't save just r12. I'm also */ 44 /* not sure which of r1-r3 are important. */ 45 stmdb sp!, {r0-r12} 46 bl ExecuteITHandler 47 ldmia sp!, {r0-r12} 48 49 /* one less nest level */ 50 ldr r0, =_ISR_Nest_level 51 ldr r1, [r0] 52 sub r1, r1,#1 53 str r1, [r0] 54 55 /* unnest multitasking */ 56 ldr r0, =_Thread_Dispatch_disable_level 57 ldr r1, [r0] 58 sub r1, r1,#1 59 str r1, [r0] 60 61 /* If thread dispatching is disabled, exit */ 62 cmp r1, #0 63 bne exitit 64 65 /* If a task switch is necessary, call scheduler */ 66 ldr r0, =_Context_Switch_necessary 67 ldr r1, [r0] 68 cmp r1, #0 69 70 /* since bframe is going to clear _ISR_Signals_to_thread_executing, */ 71 /* we need to load it here */ 72 ldr r0, =_ISR_Signals_to_thread_executing 73 ldr r1, [r0] 74 bne bframe 75 76 /* If a signals to be sent (_ISR_Signals_to_thread_executing != 0), */ 77 /* call scheduler */ 78 cmp r1, #0 79 beq exitit 80 81 /* _ISR_Signals_to_thread_executing = FALSE */ 82 mov r1, #0 83 str r1, [r0] 84 85 bframe: 86 87 /* Now we need to set up the return from this ISR to be _ISR_Dispatch */ 88 /* To do that, we need to save the current lr_int and spsr_int on the */ 89 /* SVC stack */ 90 mrs r0, spsr 91 ldmia sp!, {r1} /* get lr off stack */ 92 stmdb sp!, {r1} 93 mrs r2, cpsr 94 orr r3, r2, #0x1 /* change to SVC mode */ 95 msr cpsr_c, r3 96 97 /* now in SVC mode */ 98 stmdb sp!, {r0, r1} /* put spsr_int and lr_int on SVC stack */ 99 msr cpsr_c, r2 /* change back to INT mode */ 100 101 /* now in INT mode */ 102 103 /* replace lr with address of _ISR_Dispatch */ 104 ldr lr, =_ISR_Dispatch 105 add lr, lr, #0x4 /* On entry to an ISR, the lr is */ 106 /* the return address + 4, so */ 107 /* we have to emulate that */ 108 ldmia sp!, {r0} /* out with the old */ 109 stmdb sp!, {lr} /* in with the new (lr) */ 110 111 112 mrs r0, spsr 113 orr r0, r0, #0xc0 114 msr spsr, r0 115 116 exitit: 117 ldmia sp!, {lr} /* restore regs from INT stack */ 118 ldmia sp!, {r0, r1, r2, r3} /* restore regs from INT stack */ 119 subs pc, lr, #4 /* return */ 18 120 19 121 20 /*21 * WARNING : register r5 is important. If you need to use it,22 * to forget to save it !!!!!!!!!!23 */24 25 .globl _ISR_Handler26 _ISR_Handler:27 stmdb sp!, {r4,r5,lr} /* save regs on INT stack */28 mrs r4, cpsr /* save current CSPR */29 mov r5, r4 /* copy CSPR */30 orr r4, r4, #331 msr cpsr, r4 /* switch to SVC mode */32 33 stmdb sp!, {r0-r3,r12,r14} /* save scratch regs on SVC stack */34 122 35 msr cpsr, r5 /* switch back to INT mode */ 123 /* on entry to _ISR_Dispatch, we're in SVC mode */ 124 .globl _ISR_Dispatch 125 _ISR_Dispatch: 126 stmdb sp!, {r0-r12,lr} /* save regs on SVC stack */ 127 /* (now safe to call C funcs) */ 128 /* we don't save lr, since */ 129 /* it's just going to get */ 130 /* overwritten */ 36 131 37 ldr r0, =_ISR_Nest_level /* one nest level deeper */ 38 ldr r1, [r0] 39 add r1, r1,#1 40 str r1, [r0] 41 42 ldr r0, =_Thread_Dispatch_disable_level /* disable multitasking */ 43 ldr r1, [r0] 44 add r1, r1,#1 45 str r1, [r0] 132 bl _Thread_Dispatch 133 ldmia sp!, {r0-r12, lr} 46 134 47 b ExecuteITHandler /* BSP specific function to INT handler */ 135 stmdb sp!, {r0-r2} 136 /* Now we have to screw with the stack */ 137 mov r0, sp /* copy the SVC stack pointer */ 138 139 mrs r1, cpsr 140 bic r2, r1, #0x1 /* change to INT mode */ 141 orr r2, r2, #0xc0 /* disable interrupts */ 142 msr cpsr_c, r2 48 143 49 .globl ReturnFromHandler 50 ReturnFromHandler : 51 ldr r0, =_ISR_Nest_level /* one less nest level */ 52 ldr r1, [r0] 53 sub r1, r1,#1 54 str r1, [r0] 55 56 ldr r0, =_Thread_Dispatch_disable_level /* unnest multitasking */ 57 ldr r1, [r0] 58 sub r1, r1,#1 59 str r1, [r0] 144 /* now in INT mode */ 145 stmdb sp!, {r4, r5, r6} /* save temp vars on INT stack */ 146 ldmia r0!, {r4, r5, r6} /* Get r0-r3 from SVC stack */ 147 stmdb sp!, {r4, r5, r6} /* and save them on INT stack */ 148 149 ldmia r0!, {r4, r5} /* get saved values from SVC stack */ 150 /* r4=spsr, r5=lr */ 151 mov lr, r5 /* restore lr_int */ 152 msr spsr, r4 /* restore spsr_int */ 60 153 61 cmp r1, #0 /* is dispatch enabled */ 62 bne exitit /* Yes, then exit */ 154 /* switch to SVC mode, update sp, then return to INT mode */ 155 msr cpsr_c, r1 /* switch to SVC mode */ 156 mov sp, r0 /* update sp_svc */ 157 msr cpsr_c, r2 /* switch back to INT mode */ 63 158 64 ldr r0, =_Context_Switch_necessary /* task switch necessary ? */ 65 ldr r1, [r0] 66 cmp r1, #0 67 bne schedule /* yes, call scheduler */ 68 69 ldr r0, =_ISR_Signals_to_thread_executing 70 ldr r1, [r0] /* signals sent to Run_thread */ 71 cmp r1, #0 /* while in interrupt handler ? */ 72 beq exitit /* No, exit */ 73 74 bframe: 75 mov r1, #0 /* _ISR_Signals_to_thread_executing = FALSE */ 76 str r1, [r0] 77 /* 78 * At this point, we need a complete exception context for the 79 * current thread. We need to complete the interrupt exception 80 * with the "not-yet-saved" registers 81 */ 82 /* 83 * currently exception context = interrupt handler 84 * it needs to be optimized 85 */ 86 bl _ThreadProcessSignalsFromIrq 87 b exitit 88 89 schedule: 90 /* 91 * the scratch registers have already been saved and we are already 92 * back on the thread system stack. So we can call _Thread_Displatch 93 * directly 94 */ 95 bl _Thread_Dispatch 96 /* 97 * fall through exit to restore complete contex (scratch registers 98 * eip, CS, Flags). 99 */ 100 exitit: 101 b AckControler /* BSP specific function to ack PIC */ 159 /* pop all the registers from the stack */ 160 ldmia sp!, {r0, r1, r2} 161 ldmia sp!, {r4, r5, r6} 102 162 103 .globl ReturnFromAck 104 ReturnFromAck : 105 ldmia sp!, {r0-r3,r12,r14} /* restore regs from SVC stack */ 106 msr cpsr, r5 /* switch back to INT mode */ 107 ldmia sp!, {r4,r5,lr} /* restore regs from INT stack */ 108 subs pc,r14,#4 /* return */ 109 163 /* Finally, we can return to the interrupted task */ 164 subs pc, lr, #4 165 166 167 168 169
Note: See TracChangeset
for help on using the changeset viewer.