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

4.104.114.84.95
Last change on this file since c178d34 was cd35cf9, checked in by Joel Sherrill <joel.sherrill@…>, on 04/18/02 at 20:55:13

2002-04-18 Ralf Corsepius <corsepiu@…>

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