source: rtems/bsps/powerpc/ss555/start/irq_asm.S @ 90232bc

5
Last change on this file since 90232bc was 5249a4c, checked in by Sebastian Huber <sebastian.huber@…>, on 06/07/18 at 05:18:23

powerpc: Fix ss555 build

The mpc555 define is provided via <bspopts.h>. It must not be used in
cpukit header files.

Update #3425.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[8430205]1/*
2 * irq_asm.S
3 *
[359e537]4 *  This file contains the assembly code for the PowerPC
[8430205]5 *  IRQ veneers for RTEMS.
6 *
7 *  The license and distribution terms for this file may be
[e71a3a84]8 *  found in the file LICENSE in this distribution or at
[c499856]9 *  http://www.rtems.org/license/LICENSE.
[8430205]10 *
11 *
12 *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
13 *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
14 *
15 *  Derived from libbsp/powerpc/mbx8xx/irq/irq_asm.S:
16 *
17 *  Modified to support the MCP750.
18 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
19 *
20 *  Till Straumann <strauman@slac.stanford.edu>, 2003/7:
21 *    - store isr nesting level in _ISR_Nest_level rather than
22 *      SPRG0 - RTEMS relies on that variable.
23 */
[359e537]24
[297d99b1]25#include <rtems/asm.h>
[8430205]26#include <rtems/score/cpu.h>
[5048a0a]27#include <rtems/score/percpu.h>
[8430205]28#include <libcpu/vectors.h>
29#include <libcpu/raw_exception.h>
[5249a4c]30#include <bsp.h>
[8430205]31
32#define SYNC \
33        sync; \
34        isync
[359e537]35
[8430205]36/*
37 * Common handler for interrupt exceptions.
38 *
39 * The function CPU_rtems_irq_mng_init() initializes the decrementer and
40 * external interrupt entries in the exception handler table with pointers
41 * to this routine, which saves the remainder of the interrupted code's
42 * state, then calls C_dispatch_irq_handler().
43 *
44 * On entry, R1 points to a new exception stack frame in which R3, R4, and
45 * LR have been saved.  R4 holds the exception number.
46 */
47        PUBLIC_VAR(C_dispatch_irq_handler)
[359e537]48
[8430205]49        PUBLIC_VAR(dispatch_irq_handler)
50SYM (dispatch_irq_handler):
51        /*
[359e537]52         * Save SRR0/SRR1 As soon As possible as it is the minimal needed
[8430205]53         * to re-enable exception processing.
[359e537]54         *
[8430205]55         * Note that R2 should never change (it's the EABI pointer to
[359e537]56         * .sdata2), but we save it just in case.
[8430205]57         */
58        stw     r0, GPR0_OFFSET(r1)
59        stw     r2, GPR2_OFFSET(r1)
[359e537]60
[8430205]61        mfsrr0  r0
62        mfsrr1  r3
[359e537]63
[8430205]64        stw     r0, SRR0_FRAME_OFFSET(r1)
65        stw     r3, SRR1_FRAME_OFFSET(r1)
66
67        /*
68         * Enable exception recovery.  Also enable FP so that FP context
69         * can be saved and restored (using FP instructions).
70         */
71        mfmsr   r3
72        ori     r3, r3, MSR_RI | MSR_FP
73        mtmsr   r3
74        SYNC
75
76        /*
77         * Push C scratch registers on the current stack. It may actually be
78         * the thread stack or the interrupt stack.  Anyway we have to make
79         * it in order to be able to call C/C++ functions. Depending on the
80         * nesting interrupt level, we will switch to the right stack later.
81         */
82        stw     r5, GPR5_OFFSET(r1)
83        stw     r6, GPR6_OFFSET(r1)
84        stw     r7, GPR7_OFFSET(r1)
85        stw     r8, GPR8_OFFSET(r1)
86        stw     r9, GPR9_OFFSET(r1)
87        stw     r10, GPR10_OFFSET(r1)
88        stw     r11, GPR11_OFFSET(r1)
89        stw     r12, GPR12_OFFSET(r1)
90        stw     r13, GPR13_OFFSET(r1)
91
92        mfcr    r5
93        mfctr   r6
94        mfxer   r7
[359e537]95
[8430205]96        stw     r5,  EXC_CR_OFFSET(r1)
97        stw     r6,  EXC_CTR_OFFSET(r1)
98        stw     r7,  EXC_XER_OFFSET(r1)
[359e537]99
[8430205]100        /*
101         * Add some non volatile registers to store information that will be
102         * used when returning from C handler.
103         */
104        stw     r14, GPR14_OFFSET(r1)
105        stw     r15, GPR15_OFFSET(r1)
106
107        /*
108         * Save current stack pointer location in R14.
109         */
110        addi    r14, r1, 0
111
112        /*
[e626c60]113         * store part of THREAD_DISPATCH_DISABLE_LEVEL address in R15
[8430205]114         */
[e626c60]115        addis r15, 0, THREAD_DISPATCH_DISABLE_LEVEL@ha
[8430205]116
117        /*
118         * Retrieve current nesting level from _ISR_Nest_level
119         */
[5048a0a]120        lis             r7, ISR_NEST_LEVEL@ha
121        lwz             r3, ISR_NEST_LEVEL@l(r7)
[8430205]122
123        /*
124         * Check if stack switch is necessary
125         */
126        cmpwi   r3, 0
127        bne     nested
128
129        mfspr   r1, SPRG1               /* switch to interrupt stack */
[359e537]130nested:
[8430205]131
[359e537]132        /*
[8430205]133         * Start Incrementing nesting level in R3
134         */
135        addi    r3, r3, 1
136
137        /*
[e626c60]138         * Start Incrementing THREAD_DISPATCH_DISABLE_LEVEL R4 = THREAD_DISPATCH_DISABLE_LEVEL
[8430205]139         */
[e626c60]140        lwz     r6, THREAD_DISPATCH_DISABLE_LEVEL@l(r15)
[8430205]141
142        /* store new nesting level in _ISR_Nest_level */
[5048a0a]143        stw     r3, ISR_NEST_LEVEL@l(r7)
[8430205]144
145        addi    r6, r6, 1
146
147        /*
[e626c60]148         * store new THREAD_DISPATCH_DISABLE_LEVEL value
[8430205]149         */
[e626c60]150        stw     r6, THREAD_DISPATCH_DISABLE_LEVEL@l(r15)
[8430205]151
152        /*
153         * We are now running on the interrupt stack. External and decrementer
154         * exceptions are still disabled. I see no purpose trying to optimize
[359e537]155         * further assembler code.
[8430205]156         */
157
158        /*
[359e537]159         * Call C exception handler for decrementer or external interrupt.
[8430205]160         * Pass frame along just in case..
161         *
162         * C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4)
163         */
164        addi    r3, r14, 0x8
165        bl      C_dispatch_irq_handler
166
167        /*
[359e537]168         * start decrementing nesting level. Note : do not test result against 0
[8430205]169         * value as an easy exit condition because if interrupt nesting level > 1
[e626c60]170         * then THREAD_DISPATCH_DISABLE_LEVEL > 1
[8430205]171         */
[5048a0a]172        lis             r7, ISR_NEST_LEVEL@ha
173        lwz             r4, ISR_NEST_LEVEL@l(r7)
[8430205]174
175        /*
[e626c60]176         * start decrementing THREAD_DISPATCH_DISABLE_LEVEL
[8430205]177         */
[e626c60]178        lwz     r3,THREAD_DISPATCH_DISABLE_LEVEL@l(r15)
[8430205]179
180        addi    r4, r4, -1      /* Continue decrementing nesting level */
[e626c60]181        addi    r3, r3, -1      /* Continue decrementing THREAD_DISPATCH_DISABLE_LEVEL */
[8430205]182
[5048a0a]183        stw     r4, ISR_NEST_LEVEL@l(r7) /* End decrementing nesting level */
[e626c60]184        stw     r3,THREAD_DISPATCH_DISABLE_LEVEL@l(r15) /* End decrementing THREAD_DISPATCH_DISABLE_LEVEL */
[8430205]185
186        cmpwi   r3, 0
187
188        /*
[359e537]189         * switch back to original stack (done here just optimize registers
[8430205]190         * contention. Could have been done before...)
191         */
192        addi    r1, r14, 0
[e626c60]193        bne     easy_exit /* if (THREAD_DISPATCH_DISABLE_LEVEL != 0) goto easy_exit */
[8430205]194
195        /*
196         * Here we are running again on the thread system stack.
[e626c60]197         * We have interrupt nesting level = THREAD_DISPATCH_DISABLE_LEVEL = 0.
[359e537]198         * Interrupt are still disabled. Time to check if scheduler request to
[8430205]199         * do something with the current thread...
200         */
[5048a0a]201        addis   r4, 0, DISPATCH_NEEDED@ha
202        lbz     r5, DISPATCH_NEEDED@l(r4)
[8430205]203        cmpwi   r5, 0
204        beq     easy_exit
205
206        /*
[5048a0a]207         * going to call _Thread_Dispatch
[8430205]208         * Push a complete exception like frame...
209         */
210        stmw    r16, GPR16_OFFSET(r1)
211        addi    r3, r1, 0x8
212
213        /*
214         * compute SP at exception entry
215         */
216        addi    r4, r1, EXCEPTION_FRAME_END
217
218        /*
219         * store it at the right place
220         */
221        stw     r4, GPR1_OFFSET(r1)
222
223        /*
224         * Call High Level signal handling code
225         */
[5048a0a]226        bl      _Thread_Dispatch
[8430205]227
228        /*
229         * start restoring exception like frame
230         */
231        lwz     r31,  EXC_CTR_OFFSET(r1)
232        lwz     r30,  EXC_XER_OFFSET(r1)
233        lwz     r29,  EXC_CR_OFFSET(r1)
234        lwz     r28,  EXC_LR_OFFSET(r1)
[359e537]235
[8430205]236        mtctr   r31
237        mtxer   r30
238        mtcr    r29
239        mtlr    r28
[359e537]240
[8430205]241        lmw     r4, GPR4_OFFSET(r1)
242        lwz     r2, GPR2_OFFSET(r1)
243        lwz     r0, GPR0_OFFSET(r1)
244
245        /*
246         * Make path non recoverable...
247         */
248        mtspr   nri, r0
249        SYNC
250
251        /*
252         * Restore rfi related settings
253         */
[359e537]254
[8430205]255        lwz     r3, SRR1_FRAME_OFFSET(r1)
256        mtsrr1  r3
257        lwz     r3, SRR0_FRAME_OFFSET(r1)
258        mtsrr0  r3
[359e537]259
[8430205]260        lwz     r3, GPR3_OFFSET(r1)
261        addi    r1,r1, EXCEPTION_FRAME_END
262        SYNC
263        rfi
264
[359e537]265
266easy_exit:
[8430205]267        /*
268         * start restoring interrupt frame
269         */
270        lwz     r3,  EXC_CTR_OFFSET(r1)
271        lwz     r4,  EXC_XER_OFFSET(r1)
272        lwz     r5,  EXC_CR_OFFSET(r1)
273        lwz     r6,  EXC_LR_OFFSET(r1)
[359e537]274
[8430205]275        mtctr   r3
276        mtxer   r4
277        mtcr    r5
278        mtlr    r6
279
280        lwz     r15, GPR15_OFFSET(r1)
281        lwz     r14, GPR14_OFFSET(r1)
282        lwz     r13, GPR13_OFFSET(r1)
283        lwz     r12, GPR12_OFFSET(r1)
284        lwz     r11, GPR11_OFFSET(r1)
285        lwz     r10, GPR10_OFFSET(r1)
286        lwz     r9, GPR9_OFFSET(r1)
287        lwz     r8, GPR8_OFFSET(r1)
288        lwz     r7, GPR7_OFFSET(r1)
289        lwz     r6, GPR6_OFFSET(r1)
290        lwz     r5, GPR5_OFFSET(r1)
291
292        /*
293         * Disable nested exception processing.
294         */
295        mtspr   nri, r0
296        SYNC
297
298        /*
299         * Restore rfi related settings
300         */
301        lwz     r4, SRR1_FRAME_OFFSET(r1)
302        lwz     r3, SRR0_FRAME_OFFSET(r1)
303        lwz     r2, GPR2_OFFSET(r1)
304        lwz     r0, GPR0_OFFSET(r1)
305
306        mtsrr1  r4
307        mtsrr0  r3
308        lwz     r4, GPR4_OFFSET(r1)
309        lwz     r3, GPR3_OFFSET(r1)
310        addi    r1,r1, EXCEPTION_FRAME_END
311        SYNC
312        rfi
Note: See TracBrowser for help on using the repository browser.