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

4.104.114.84.95
Last change on this file since 1628414 was 1628414, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 18, 2002 at 8:55:01 PM

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

  • irq/irq.c: Reflect changes to <rtems/score/cpu.h>.
  • irq/irq_asm.S: Ditto.
  • network/network.c: Include <rtems/bspIo.h>.
  • start/start.S: Include <asm.h> instead of "asm.h".
  • vectors/vectors.S: Reflect changes to <rtems/score/cpu.h>.
  • 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 <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        /*
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
88        /*
89         * Enable data and instruction address translation, exception recovery
90         *
91         * also, on CPUs with FP, enable FP so that FP context can be
92         * saved and restored (using FP instructions)
93         */
94#if (PPC_HAS_FPU == 0)
95        ori     r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
96#else
97        ori     r3, r3, MSR_RI | /*MSR_IR | MSR_DR |*/ MSR_FP
98#endif
99        mtmsr   r3
100        SYNC
101       
102        /*
103         * Push C scratch registers on the current stack. It may
104         * actually be the thread stack or the interrupt stack.
105         * Anyway we have to make it in order to be able to call C/C++
106         * functions. Depending on the nesting interrupt level, we will
107         * switch to the right stack later.
108         */
109        stw     r5, GPR5_OFFSET(r1)
110        stw     r6, GPR6_OFFSET(r1)
111        stw     r7, GPR7_OFFSET(r1)
112        stw     r8, GPR8_OFFSET(r1)
113        stw     r9, GPR9_OFFSET(r1)
114        stw     r10, GPR10_OFFSET(r1)
115        stw     r11, GPR11_OFFSET(r1)
116        stw     r12, GPR12_OFFSET(r1)
117        stw     r13, GPR13_OFFSET(r1)
118
119        mfcr    r5
120        mfctr   r6
121        mfxer   r7
122        mflr    r8
123       
124        stw     r5,  EXC_CR_OFFSET(r1)
125        stw     r6,  EXC_CTR_OFFSET(r1)
126        stw     r7,  EXC_XER_OFFSET(r1)
127        stw     r8,  EXC_LR_OFFSET(r1)
128
129        /*
130         * Add some non volatile registers to store information
131         * that will be used when returning from C handler
132         */
133        stw     r14, GPR14_OFFSET(r1)
134        stw     r15, GPR15_OFFSET(r1)
135        /*
136         * save current stack pointer location in R14
137         */
138        addi    r14, r1, 0
139        /*
140         * store part of _Thread_Dispatch_disable_level address in R15
141         */
142        addis r15,0, _Thread_Dispatch_disable_level@ha
143        /*
144         * Get current nesting level in R2
145         */
146        mfspr   r2, SPRG0
147        /*
148         * Check if stack switch is necessary
149         */
150        cmpwi   r2,0
151        bne     nested
152        mfspr   r1, SPRG1
153       
154nested:
155        /*
156         * Start Incrementing nesting level in R2
157         */
158        addi    r2,r2,1
159        /*
160         * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
161         */
162        lwz     r6,_Thread_Dispatch_disable_level@l(r15)
163        /*
164         * store new nesting level in SPRG0
165         */
166        mtspr   SPRG0, r2
167       
168        addi    r6, r6, 1
169        mfmsr   r5
170        /*
171         * store new _Thread_Dispatch_disable_level value
172         */
173        stw     r6, _Thread_Dispatch_disable_level@l(r15)
174        /*
175         * We are now running on the interrupt stack. External and decrementer
176         * exceptions are still disabled. I see no purpose trying to optimize
177         * further assembler code.
178         */
179        /*
180         * Call C exception handler for decrementer Interrupt frame is passed just
181         * in case...
182         */
183        addi    r3, r14, 0x8
184        bl      C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
185        /*
186         * start decrementing nesting level. Note : do not test result against 0
187         * value as an easy exit condition because if interrupt nesting level > 1
188         * then _Thread_Dispatch_disable_level > 1
189         */
190        mfspr   r2, SPRG0
191        /*
192         * start decrementing _Thread_Dispatch_disable_level
193         */
194        lwz     r3,_Thread_Dispatch_disable_level@l(r15)
195        addi    r2, r2, -1      /* Continue decrementing nesting level */
196        addi    r3, r3, -1      /* Continue decrementing _Thread_Dispatch_disable_level */
197        mtspr   SPRG0, r2       /* End decrementing nesting level */
198        stw     r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
199        cmpwi   r3, 0
200        /*
201         * switch back to original stack (done here just optimize registers
202         * contention. Could have been done before...)
203         */
204        addi    r1, r14, 0
205        bne     easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
206        /*
207         * Here we are running again on the thread system stack.
208         * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
209         * Interrupt are still disabled. Time to check if scheduler request to
210         * do something with the current thread...
211         */
212        addis   r4, 0, _Context_Switch_necessary@ha
213        lwz     r5, _Context_Switch_necessary@l(r4)
214        cmpwi   r5, 0
215        bne     switch
216       
217        addis   r6, 0, _ISR_Signals_to_thread_executing@ha
218        lwz     r7, _ISR_Signals_to_thread_executing@l(r6)
219        cmpwi   r7, 0
220        li      r8, 0
221        beq     easy_exit
222        stw     r8, _ISR_Signals_to_thread_executing@l(r6)
223        /*
224         * going to call _ThreadProcessSignalsFromIrq
225         * Push a complete exception like frame...
226         */
227        stmw    r16, GPR16_OFFSET(r1)
228        addi    r3, r1, 0x8
229        /*
230         * compute SP at exception entry
231         */
232        addi    r2, r1, EXCEPTION_FRAME_END
233        /*
234         * store it at the right place
235         */
236        stw     r2, GPR1_OFFSET(r1)
237        /*
238         * Call High Level signal handling code
239         */
240        bl      _ThreadProcessSignalsFromIrq
241       
242
243        /*
244         * start restoring exception like frame
245         */
246        lwz     r31,  EXC_CTR_OFFSET(r1)
247        lwz     r30,  EXC_XER_OFFSET(r1)
248        lwz     r29,  EXC_CR_OFFSET(r1)
249        lwz     r28,  EXC_LR_OFFSET(r1)
250       
251        mtctr   r31
252        mtxer   r30
253        mtcr    r29
254        mtlr    r28
255       
256       
257        lmw     r4, GPR4_OFFSET(r1)
258
259       
260        lwz     r2, GPR2_OFFSET(r1)
261        lwz     r0, GPR0_OFFSET(r1)
262
263        /*
264         * Disable data and instruction translation. Make path non recoverable...
265         */
266        mfmsr   r3
267        xori    r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
268        mtmsr   r3
269        SYNC
270        /*
271         * Restore rfi related settings
272         */
273               
274        lwz     r3, SRR1_FRAME_OFFSET(r1)
275        mtsrr1  r3
276        lwz     r3, SRR0_FRAME_OFFSET(r1)
277        mtsrr0  r3
278       
279        lwz     r3, GPR3_OFFSET(r1)
280        addi    r1,r1, EXCEPTION_FRAME_END
281        SYNC
282        rfi
283       
284switch:
285        bl      SYM (_Thread_Dispatch)
286       
287easy_exit:     
288        /*
289         * start restoring interrupt frame
290         */
291        lwz     r3,  EXC_CTR_OFFSET(r1)
292        lwz     r4,  EXC_XER_OFFSET(r1)
293        lwz     r5,  EXC_CR_OFFSET(r1)
294        lwz     r6,  EXC_LR_OFFSET(r1)
295       
296        mtctr   r3
297        mtxer   r4
298        mtcr    r5
299        mtlr    r6
300
301        lwz     r15, GPR15_OFFSET(r1)
302        lwz     r14, GPR14_OFFSET(r1)
303        lwz     r13, GPR13_OFFSET(r1)
304        lwz     r12, GPR12_OFFSET(r1)
305        lwz     r11, GPR11_OFFSET(r1)
306        lwz     r10, GPR10_OFFSET(r1)
307        lwz     r9, GPR9_OFFSET(r1)
308        lwz     r8, GPR8_OFFSET(r1)
309        lwz     r7, GPR7_OFFSET(r1)
310        lwz     r6, GPR6_OFFSET(r1)
311        lwz     r5, GPR5_OFFSET(r1)
312
313        /*
314         * Disable nested exception processing, data and instruction
315         * translation.
316         */
317        mfmsr   r3
318        xori    r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
319        mtmsr   r3
320        SYNC
321       
322        /*
323         * Restore rfi related settings
324         */
325                 
326        lwz     r4, SRR1_FRAME_OFFSET(r1)
327        lwz     r2, SRR0_FRAME_OFFSET(r1)
328        lwz     r3, GPR3_OFFSET(r1)
329        lwz     r0, GPR0_OFFSET(r1)
330
331        mtsrr1  r4
332        mtsrr0  r2
333        lwz     r4, GPR4_OFFSET(r1)
334        lwz     r2, GPR2_OFFSET(r1)
335        addi    r1,r1, EXCEPTION_FRAME_END
336        SYNC
337        rfi
338
Note: See TracBrowser for help on using the repository browser.