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

4.104.114.84.95
Last change on this file since 5edbffe was 5edbffe, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 22, 2001 at 2:46:02 PM

01-10-22 Andy Dachs <a.dachs@…>

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