source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S @ 3a6bfc6

4.104.114.84.95
Last change on this file since 3a6bfc6 was 3a6bfc6, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 12, 2000 at 1:15:01 PM

Added comment.

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 *  This file contains the assembly code for the PowerPC
3 *  IRQ veneers for RTEMS.
4 *
5 *  The license and distribution terms for this file may be
6 *  found in found in the file LICENSE in this distribution or at
7 *  http://www.OARcorp.com/rtems/license.html.
8 *
9 *  Modified to support the MCP750.
10 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
11 *
12 *
13 * $Id$
14 */
15       
16#include <bsp/vectors.h>
17#include <libcpu/cpu.h>
18#include <libcpu/raw_exception.h>
19#include <rtems/score/cpuopts.h>  /* for PPC_HAS_FPU */
20#include "asm.h"
21       
22
23#define SYNC \
24        sync; \
25        isync
26       
27        .text
28        .p2align 5     
29               
30        PUBLIC_VAR(decrementer_exception_vector_prolog_code)
31       
32SYM (decrementer_exception_vector_prolog_code):
33        /*
34         * let room for exception frame
35         */
36        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
37        stw     r4, GPR4_OFFSET(r1)
38        li      r4, ASM_DEC_VECTOR
39        ba      shared_raw_irq_code_entry
40
41        PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
42       
43        decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
44
45        PUBLIC_VAR(external_exception_vector_prolog_code)
46       
47SYM (external_exception_vector_prolog_code):
48        /*
49         * let room for exception frame
50         */
51        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
52        stw     r4, GPR4_OFFSET(r1)
53        li      r4, ASM_EXT_VECTOR
54        ba      shared_raw_irq_code_entry
55
56        PUBLIC_VAR (external_exception_vector_prolog_code_size)
57       
58        external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
59
60        PUBLIC_VAR(shared_raw_irq_code_entry)
61        PUBLIC_VAR(C_dispatch_irq_handler)
62       
63        .p2align 5
64SYM (shared_raw_irq_code_entry):
65        /*
66         * Entry conditions :
67         *      Registers already saved : R1, R4
68         *      R1  :   points to a location with enough room for the
69         *              interrupt frame
70         *      R4  :   vector number
71         */
72        /*
73         * Save SRR0/SRR1 As soon As possible as it is the minimal needed
74         * to reenable exception processing
75         */
76        stw     r0, GPR0_OFFSET(r1)
77        stw     r2, GPR2_OFFSET(r1)
78        stw     r3, GPR3_OFFSET(r1)
79       
80        mfsrr0  r0
81        mfsrr1  r2
82        mfmsr   r3
83       
84        stw     r0, SRR0_FRAME_OFFSET(r1)
85        stw     r2, SRR1_FRAME_OFFSET(r1)
86        /*
87         * Enable data and instruction address translation, exception recovery
88     *
89     * also, on CPUs with FP, enable FP so that FP context can be
90     * saved and restored (using FP instructions)
91         */
92#if (PPC_HAS_FPU == 0)
93        ori     r3, r3, MSR_RI | MSR_IR | MSR_DR
94#else
95        ori     r3, r3, MSR_RI | MSR_IR | MSR_DR | MSR_FP
96#endif
97        mtmsr   r3
98        SYNC
99        /*
100         * Push C scratch registers on the current stack. It may
101         * actually be the thread stack or the interrupt stack.
102         * Anyway we have to make it in order to be able to call C/C++
103         * functions. Depending on the nesting interrupt level, we will
104         * switch to the right stack later.
105         */
106        stw     r5, GPR5_OFFSET(r1)
107        stw     r6, GPR6_OFFSET(r1)
108        stw     r7, GPR7_OFFSET(r1)
109        stw     r8, GPR8_OFFSET(r1)
110        stw     r9, GPR9_OFFSET(r1)
111        stw     r10, GPR10_OFFSET(r1)
112        stw     r11, GPR11_OFFSET(r1)
113        stw     r12, GPR12_OFFSET(r1)
114        stw     r13, GPR13_OFFSET(r1)
115
116        mfcr    r5
117        mfctr   r6
118        mfxer   r7
119        mflr    r8
120       
121        stw     r5,  EXC_CR_OFFSET(r1)
122        stw     r6,  EXC_CTR_OFFSET(r1)
123        stw     r7,  EXC_XER_OFFSET(r1)
124        stw     r8,  EXC_LR_OFFSET(r1)
125
126        /*
127         * Add some non volatile registers to store information
128         * that will be used when returning from C handler
129         */
130        stw     r14, GPR14_OFFSET(r1)
131        stw     r15, GPR15_OFFSET(r1)
132        /*
133         * save current stack pointer location in R14
134         */
135        addi    r14, r1, 0
136        /*
137         * store part of _Thread_Dispatch_disable_level address in R15
138         */
139        addis r15,0, _Thread_Dispatch_disable_level@ha
140        /*
141         * Get current nesting level in R2
142         */
143        mfspr   r2, SPRG0
144        /*
145         * Check if stack switch is necessary
146         */
147        cmpwi   r2,0
148        bne     nested
149        mfspr   r1, SPRG1
150       
151nested:
152        /*
153         * Start Incrementing nesting level in R2
154         */
155        addi    r2,r2,1
156        /*
157         * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
158         */
159        lwz     r6,_Thread_Dispatch_disable_level@l(r15)
160        /*
161         * store new nesting level in SPRG0
162         */
163        mtspr   SPRG0, r2
164       
165        addi    r6, r6, 1
166        mfmsr   r5
167        /*
168         * store new _Thread_Dispatch_disable_level value
169         */
170        stw     r6, _Thread_Dispatch_disable_level@l(r15)
171        /*
172         * We are now running on the interrupt stack. External and decrementer
173         * exceptions are still disabled. I see no purpose trying to optimize
174         * further assembler code.
175         */
176        /*
177         * Call C exception handler for decrementer Interrupt frame is passed just
178         * in case...
179         */
180        addi    r3, r14, 0x8
181        bl      C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
182        /*
183         * start decrementing nesting level. Note : do not test result against 0
184         * value as an easy exit condition because if interrupt nesting level > 1
185         * then _Thread_Dispatch_disable_level > 1
186         */
187        mfspr   r2, SPRG0
188        /*
189         * start decrementing _Thread_Dispatch_disable_level
190         */
191        lwz     r3,_Thread_Dispatch_disable_level@l(r15)
192        addi    r2, r2, -1      /* Continue decrementing nesting level */
193        addi    r3, r3, -1      /* Continue decrementing _Thread_Dispatch_disable_level */
194        mtspr   SPRG0, r2       /* End decrementing nesting level */
195        stw     r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
196        cmpwi   r3, 0
197        /*
198         * switch back to original stack (done here just optimize registers
199         * contention. Could have been done before...)
200         */
201        addi    r1, r14, 0
202        bne     easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
203        /*
204         * Here we are running again on the thread system stack.
205         * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
206         * Interrupt are still disabled. Time to check if scheduler request to
207         * do something with the current thread...
208         */
209        addis   r4, 0, _Context_Switch_necessary@ha
210        lwz     r5, _Context_Switch_necessary@l(r4)
211        cmpwi   r5, 0
212        bne     switch
213       
214        addis   r6, 0, _ISR_Signals_to_thread_executing@ha
215        lwz     r7, _ISR_Signals_to_thread_executing@l(r6)
216        cmpwi   r7, 0
217        li      r8, 0
218        beq     easy_exit
219        stw     r8, _ISR_Signals_to_thread_executing@l(r6)
220        /*
221         * going to call _ThreadProcessSignalsFromIrq
222         * Push a complete exception like frame...
223         */
224        stmw    r16, GPR16_OFFSET(r1)
225        addi    r3, r1, 0x8
226        /*
227         * compute SP at exception entry
228         */
229        addi    r2, r1, EXCEPTION_FRAME_END
230        /*
231         * store it at the right place
232         */
233        stw     r2, GPR1_OFFSET(r1)
234        /*
235         * Call High Level signal handling code
236         */
237        bl      _ThreadProcessSignalsFromIrq
238        /*
239         * start restoring exception like frame
240         */
241        lwz     r31,  EXC_CTR_OFFSET(r1)
242        lwz     r30,  EXC_XER_OFFSET(r1)
243        lwz     r29,  EXC_CR_OFFSET(r1)
244        lwz     r28,  EXC_LR_OFFSET(r1)
245       
246        mtctr   r31
247        mtxer   r30
248        mtcr    r29
249        mtlr    r28
250       
251        lmw     r4, GPR4_OFFSET(r1)
252        lwz     r2, GPR2_OFFSET(r1)
253        lwz     r0, GPR0_OFFSET(r1)
254
255        /*
256         * Disable data and instruction translation. Make path non recoverable...
257         */
258        mfmsr   r3
259        xori    r3, r3, MSR_RI | MSR_IR | MSR_DR
260        mtmsr   r3
261        SYNC
262        /*
263         * Restore rfi related settings
264         */
265                 
266        lwz     r3, SRR1_FRAME_OFFSET(r1)
267        mtsrr1  r3
268        lwz     r3, SRR0_FRAME_OFFSET(r1)
269        mtsrr0  r3
270       
271        lwz     r3, GPR3_OFFSET(r1)
272        addi    r1,r1, EXCEPTION_FRAME_END
273        SYNC
274        rfi
275       
276switch:
277        bl      SYM (_Thread_Dispatch)
278       
279easy_exit:     
280        /*
281         * start restoring interrupt frame
282         */
283        lwz     r3,  EXC_CTR_OFFSET(r1)
284        lwz     r4,  EXC_XER_OFFSET(r1)
285        lwz     r5,  EXC_CR_OFFSET(r1)
286        lwz     r6,  EXC_LR_OFFSET(r1)
287       
288        mtctr   r3
289        mtxer   r4
290        mtcr    r5
291        mtlr    r6
292
293        lwz     r15, GPR15_OFFSET(r1)
294        lwz     r14, GPR14_OFFSET(r1)
295        lwz     r13, GPR13_OFFSET(r1)
296        lwz     r12, GPR12_OFFSET(r1)
297        lwz     r11, GPR11_OFFSET(r1)
298        lwz     r10, GPR10_OFFSET(r1)
299        lwz     r9, GPR9_OFFSET(r1)
300        lwz     r8, GPR8_OFFSET(r1)
301        lwz     r7, GPR7_OFFSET(r1)
302        lwz     r6, GPR6_OFFSET(r1)
303        lwz     r5, GPR5_OFFSET(r1)
304
305        /*
306         * Disable nested exception processing, data and instruction
307         * translation.
308         */
309        mfmsr   r3
310        xori    r3, r3, MSR_RI | MSR_IR | MSR_DR
311        mtmsr   r3
312        SYNC
313        /*
314         * Restore rfi related settings
315         */
316                 
317        lwz     r4, SRR1_FRAME_OFFSET(r1)
318        lwz     r2, SRR0_FRAME_OFFSET(r1)
319        lwz     r3, GPR3_OFFSET(r1)
320        lwz     r0, GPR0_OFFSET(r1)
321
322        mtsrr1  r4
323        mtsrr0  r2
324        lwz     r4, GPR4_OFFSET(r1)
325        lwz     r2, GPR2_OFFSET(r1)
326        addi    r1,r1, EXCEPTION_FRAME_END
327        SYNC
328        rfi
329
Note: See TracBrowser for help on using the repository browser.