source: rtems/c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S @ 89fcd5ca

4.104.114.84.95
Last change on this file since 89fcd5ca was 89fcd5ca, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 1, 2002 at 10:55:52 PM

2002-11-01 Joel Sherrill <joel@…>

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