source: rtems/c/src/lib/libbsp/powerpc/mbx8xx/irq/irq_asm.S @ 46c1096

4.104.114.84.95
Last change on this file since 46c1096 was 46c1096, checked in by Joel Sherrill <joel.sherrill@…>, on 01/16/02 at 22:33:34

2001-01-16 Eric Valette <valette@…>

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