source: rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S @ 1af911b8

4.104.114.84.95
Last change on this file since 1af911b8 was 1af911b8, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/17/06 at 02:40:57

Convert to utf-8.

  • Property mode set to 100644
File size: 13.2 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC5200 BSP                              |
3+-----------------------------------------------------------------+
4| File: irq_asm.S
5+-----------------------------------------------------------------+
6| Partially based on the code references which are named below.   |
7| Adaptions, modifications, enhancements and any recent parts of  |
8| the code are:                                                   |
9|                    Copyright (c) 2005                           |
10|                    Embedded Brains GmbH                         |
11|                    Obere Lagerstr. 30                           |
12|                    D-82178 Puchheim                             |
13|                    Germany                                      |
14|                    rtems@embedded-brains.de                     |
15+-----------------------------------------------------------------+
16| The license and distribution terms for this file may be         |
17| found in the file LICENSE in this distribution or at            |
18|                                                                 |
19| http://www.rtems.com/license/LICENSE.                           |
20|                                                                 |
21+-----------------------------------------------------------------+
22| this file contains the assembler portion of the irq handling    |
23+-----------------------------------------------------------------+
24\*===============================================================*/
25/***********************************************************************/
26/*                                                                     */
27/*   Module:       irq_asm.S                                           */
28/*   Date:         07/17/2003                                          */
29/*   Purpose:      RTEMS assembly code for PowerPC IRQ veneers         */
30/*                                                                     */
31/*---------------------------------------------------------------------*/
32/*                                                                     */
33/*   Description:  This file contains the assembly code for the        */
34/*                 PowerPC IRQ veneers for RTEMS.                      */
35/*                                                                     */
36/*---------------------------------------------------------------------*/
37/*                                                                     */
38/*   Code                                                              */
39/*   References:   RTEMS assembly code for PowerPC IRQ veneers         */
40/*   Module:       irq_asm.S                                           */
41/*   Project:      RTEMS 4.6.0pre1 / MCF8260ads BSP                    */
42/*   Version       1.2                                                 */
43/*   Date:         04/18/2002                                          */
44/*                                                                     */
45/*   Author(s) / Copyright(s):                                         */
46/*                                                                     */
47/*   The license and distribution terms for this file may be           */
48/*   found in found in the file LICENSE in this distribution or at     */
49/*   http://www.OARcorp.com/rtems/license.html.                        */
50/*                                                                     */
51/*   Modified to support the MCP750.                                   */
52/*   Modifications Copyright (C) 1999 Eric Valette.valette@crf.canon.fr*/
53/*                                                                     */
54/*---------------------------------------------------------------------*/
55/*                                                                     */
56/*   Partially based on the code references which are named above.     */
57/*   Adaptions, modifications, enhancements and any recent parts of    */
58/*   the code are under the right of                                   */
59/*                                                                     */
60/*         IPR Engineering, Dachauer Straße 38, D-80335 MÃŒnchen        */
61/*                        Copyright(C) 2003                            */
62/*                                                                     */
63/*---------------------------------------------------------------------*/
64/*                                                                     */
65/*   IPR Engineering makes no representation or warranties with        */
66/*   respect to the performance of this computer program, and          */
67/*   specifically disclaims any responsibility for any damages,        */
68/*   special or consequential, connected with the use of this program. */
69/*                                                                     */
70/*---------------------------------------------------------------------*/
71/*                                                                     */
72/*   Version history:  1.0                                             */
73/*                                                                     */
74/***********************************************************************/
75       
76/*#include <bsp/vectors.h>*/
77#include "../vectors/vectors.h"
78#include <rtems/score/cpuopts.h>  /* for PPC_HAS_FPU */
79#include <rtems/score/cpu.h>
80#include <rtems/asm.h>
81#include <libcpu/raw_exception.h>
82       
83#define SYNC \
84        sync; \
85        isync
86       
87        .text
88        .p2align 5     
89               
90        PUBLIC_VAR(decrementer_exception_vector_prolog_code)
91       
92SYM (decrementer_exception_vector_prolog_code):
93
94        /*
95         * let room for exception frame
96         */
97        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
98        stw     r4, GPR4_OFFSET(r1)
99        li      r4, ASM_DEC_VECTOR
100        ba      shared_raw_irq_code_entry
101
102        PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
103       
104        decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
105
106        PUBLIC_VAR(external_exception_vector_prolog_code)
107       
108SYM (external_exception_vector_prolog_code):
109        /*
110         * let room for exception frame
111         */
112        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
113        stw     r4, GPR4_OFFSET(r1)
114        li      r4, ASM_EXT_VECTOR
115        ba      shared_raw_irq_code_entry
116
117        PUBLIC_VAR (external_exception_vector_prolog_code_size)
118       
119        external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
120
121        PUBLIC_VAR(system_management_exception_vector_prolog_code)
122       
123SYM (system_management_exception_vector_prolog_code):
124        /*
125         * let room for exception frame
126         */
127        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
128        stw     r4, GPR4_OFFSET(r1)
129        li      r4, ASM_SYSMGMT_VECTOR
130        ba      shared_raw_irq_code_entry
131
132        PUBLIC_VAR (system_management_exception_vector_prolog_code_size)
133       
134        system_management_exception_vector_prolog_code_size = . - system_management_exception_vector_prolog_code
135
136        PUBLIC_VAR(shared_raw_irq_code_entry)
137        PUBLIC_VAR(C_dispatch_irq_handler)
138       
139        .p2align 5
140SYM (shared_raw_irq_code_entry):
141        /*
142         * Entry conditions :
143         *      Registers already saved : R1, R4
144         *      R1  :   points to a location with enough room for the
145         *              interrupt frame
146         *      R4  :   vector number
147         */
148        /*
149         * Save SRR0/SRR1 As soon As possible as it is the minimal needed
150         * to reenable exception processing
151         */
152        stw     r0, GPR0_OFFSET(r1)
153        stw     r2, GPR2_OFFSET(r1)
154        stw     r3, GPR3_OFFSET(r1)
155
156        mfsrr0  r0
157        mfsrr1  r2
158        mfmsr   r3
159
160        stw     r0, SRR0_FRAME_OFFSET(r1)
161        stw     r2, SRR1_FRAME_OFFSET(r1)
162       
163
164        /*
165         * Enable data and instruction address translation, exception recovery
166         *
167         * also, on CPUs with FP, enable FP so that FP context can be
168         * saved and restored (using FP instructions)
169         */
170#if (PPC_HAS_FPU == 0)
171        ori     r3, r3, MSR_RI  | MSR_DR/*| MSR_IR*/
172#else
173        ori     r3, r3, MSR_RI | MSR_DR | /*MSR_IR |*/ MSR_FP
174#endif
175        mtmsr   r3
176        SYNC
177       
178        /*
179         * Push C scratch registers on the current stack. It may
180         * actually be the thread stack or the interrupt stack.
181         * Anyway we have to make it in order to be able to call C/C++
182         * functions. Depending on the nesting interrupt level, we will
183         * switch to the right stack later.
184         */
185        stw     r5, GPR5_OFFSET(r1)
186        stw     r6, GPR6_OFFSET(r1)
187        stw     r7, GPR7_OFFSET(r1)
188        stw     r8, GPR8_OFFSET(r1)
189        stw     r9, GPR9_OFFSET(r1)
190        stw     r10, GPR10_OFFSET(r1)
191        stw     r11, GPR11_OFFSET(r1)
192        stw     r12, GPR12_OFFSET(r1)
193        stw     r13, GPR13_OFFSET(r1)
194
195        mfcr    r5
196        mfctr   r6
197        mfxer   r7
198        mflr    r8
199       
200        stw     r5,  EXC_CR_OFFSET(r1)
201        stw     r6,  EXC_CTR_OFFSET(r1)
202        stw     r7,  EXC_XER_OFFSET(r1)
203        stw     r8,  EXC_LR_OFFSET(r1)
204
205        /*
206         * Add some non volatile registers to store information
207         * that will be used when returning from C handler
208         */
209        stw     r14, GPR14_OFFSET(r1)
210        stw     r15, GPR15_OFFSET(r1)
211        /*
212         * save current stack pointer location in R14
213         */
214        addi    r14, r1, 0
215        /*
216         * store part of _Thread_Dispatch_disable_level address in R15
217         */
218        addis   r15,0, _Thread_Dispatch_disable_level@ha
219        /*
220         * Get current nesting level in R2
221         */
222/*      mfspr   r2, SPRG0 */
223        addis   r6, 0, _ISR_Nest_level@ha
224        lwz             r2, _ISR_Nest_level@l( r6 )
225
226        /*
227         * Check if stack switch is necessary
228         */
229        cmpwi   r2,0
230        bne     nested
231        mfspr   r1, SPRG1
232       
233nested:
234        /*
235         * Start Incrementing nesting level in R2
236         */
237        addi    r2,r2,1
238
239        addis   r6, 0, _ISR_Nest_level@ha
240        stw             r2, _ISR_Nest_level@l( r6 )
241
242        /*
243         * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
244         */
245        lwz             r6,_Thread_Dispatch_disable_level@l(r15)
246        /*
247         * store new nesting level in SPRG0
248         */
249/*      mtspr   SPRG0, r2 */
250
251        addi    r6, r6, 1
252        mfmsr   r5
253        /*
254         * store new _Thread_Dispatch_disable_level value
255         */
256        stw     r6, _Thread_Dispatch_disable_level@l(r15)
257        /*
258         * We are now running on the interrupt stack. External and decrementer
259         * exceptions are still disabled. I see no purpose trying to optimize
260         * further assembler code.
261         */
262        /*
263         * Call C exception handler for decrementer Interrupt frame is passed just
264         * in case...
265         */
266        addi    r3, r14, 0x8
267        bl      C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
268        /*
269         * start decrementing nesting level. Note : do not test result against 0
270         * value as an easy exit condition because if interrupt nesting level > 1
271         * then _Thread_Dispatch_disable_level > 1
272         */
273/*      mfspr   r2, SPRG0 */
274
275        addis   r6, 0, _ISR_Nest_level@ha
276        lwz             r2, _ISR_Nest_level@l( r6 )
277
278        /*
279         * start decrementing _Thread_Dispatch_disable_level
280         */
281        lwz     r3,_Thread_Dispatch_disable_level@l(r15)
282        addi    r2, r2, -1      /* Continue decrementing nesting level */
283        addi    r3, r3, -1      /* Continue decrementing _Thread_Dispatch_disable_level */
284
285        stw             r2, _ISR_Nest_level@l( r6 )
286/*      mtspr   SPRG0, r2 */    /* End decrementing nesting level */
287
288        stw             r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
289        cmpwi   r3, 0
290        /*
291         * switch back to original stack (done here just optimize registers
292         * contention. Could have been done before...)
293         */
294        addi    r1, r14, 0
295        bne     easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
296        /*
297         * Here we are running again on the thread system stack.
298         * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
299         * Interrupt are still disabled. Time to check if scheduler request to
300         * do something with the current thread...
301         */
302        addis   r4, 0, _Context_Switch_necessary@ha
303        lwz     r5, _Context_Switch_necessary@l(r4)
304        cmpwi   r5, 0
305        bne     switch
306       
307        addis   r6, 0, _ISR_Signals_to_thread_executing@ha
308        lwz     r7, _ISR_Signals_to_thread_executing@l(r6)
309        cmpwi   r7, 0
310        li      r8, 0
311        beq     easy_exit
312        stw     r8, _ISR_Signals_to_thread_executing@l(r6)
313        /*
314         * going to call _ThreadProcessSignalsFromIrq
315         * Push a complete exception like frame...
316         */
317        stmw    r16, GPR16_OFFSET(r1)
318        addi    r3, r1, 0x8
319        /*
320         * compute SP at exception entry
321         */
322        addi    r2, r1, EXCEPTION_FRAME_END
323        /*
324         * store it at the right place
325         */
326        stw     r2, GPR1_OFFSET(r1)
327        /*
328         * Call High Level signal handling code
329         */
330        bl      _ThreadProcessSignalsFromIrq
331       
332
333        /*
334         * start restoring exception like frame
335         */
336        lwz     r31,  EXC_CTR_OFFSET(r1)
337        lwz     r30,  EXC_XER_OFFSET(r1)
338        lwz     r29,  EXC_CR_OFFSET(r1)
339        lwz     r28,  EXC_LR_OFFSET(r1)
340       
341        mtctr   r31
342        mtxer   r30
343        mtcr    r29
344        mtlr    r28
345       
346       
347        lmw     r4, GPR4_OFFSET(r1)
348
349       
350        lwz     r2, GPR2_OFFSET(r1)
351        lwz     r0, GPR0_OFFSET(r1)
352
353        /*
354         * Disable data and instruction translation. Make path non recoverable...
355         */
356        mfmsr   r3
357        xori    r3, r3, MSR_RI | MSR_DR/*| MSR_IR */
358        mtmsr   r3
359        SYNC
360        /*
361         * Restore rfi related settings
362         */
363               
364        lwz     r3, SRR1_FRAME_OFFSET(r1)
365        mtsrr1  r3
366        lwz     r3, SRR0_FRAME_OFFSET(r1)
367        mtsrr0  r3
368       
369        lwz     r3, GPR3_OFFSET(r1)
370        addi    r1,r1, EXCEPTION_FRAME_END
371        SYNC
372        rfi
373       
374switch:
375        bl      SYM (_Thread_Dispatch)
376       
377easy_exit:     
378        /*
379         * start restoring interrupt frame
380         */
381        lwz     r3,  EXC_CTR_OFFSET(r1)
382        lwz     r4,  EXC_XER_OFFSET(r1)
383        lwz     r5,  EXC_CR_OFFSET(r1)
384        lwz     r6,  EXC_LR_OFFSET(r1)
385       
386        mtctr   r3
387        mtxer   r4
388        mtcr    r5
389        mtlr    r6
390
391        lwz     r15, GPR15_OFFSET(r1)
392        lwz     r14, GPR14_OFFSET(r1)
393        lwz     r13, GPR13_OFFSET(r1)
394        lwz     r12, GPR12_OFFSET(r1)
395        lwz     r11, GPR11_OFFSET(r1)
396        lwz     r10, GPR10_OFFSET(r1)
397        lwz     r9, GPR9_OFFSET(r1)
398        lwz     r8, GPR8_OFFSET(r1)
399        lwz     r7, GPR7_OFFSET(r1)
400        lwz     r6, GPR6_OFFSET(r1)
401        lwz     r5, GPR5_OFFSET(r1)
402
403        /*
404         * Disable nested exception processing, data and instruction
405         * translation.
406         */
407        mfmsr   r3
408        xori    r3, r3, MSR_RI | MSR_DR/*| MSR_IR */
409        mtmsr   r3
410        SYNC
411       
412        /*
413         * Restore rfi related settings
414         */
415                 
416        lwz     r4, SRR1_FRAME_OFFSET(r1)
417        lwz     r2, SRR0_FRAME_OFFSET(r1)
418        lwz     r3, GPR3_OFFSET(r1)
419        lwz     r0, GPR0_OFFSET(r1)
420
421        mtsrr1  r4
422        mtsrr0  r2
423        lwz     r4, GPR4_OFFSET(r1)
424        lwz     r2, GPR2_OFFSET(r1)
425        addi    r1,r1, EXCEPTION_FRAME_END
426        SYNC
427        rfi
428
Note: See TracBrowser for help on using the repository browser.