source: rtems/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S @ 599e719a

4.104.114.84.9
Last change on this file since 599e719a was 599e719a, checked in by Till Straumann <strauman@…>, on Jun 19, 2006 at 8:14:05 PM

filter exception vector for altivec and remap 0xf20 to
assigned vector number alias.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * (c) 1999, Eric Valette valette@crf.canon.fr
3 *
4 *
5 *  This file contains the assembly code for the PowerPC
6 *  exception veneers for RTEMS.
7 *
8 * $Id$
9 */
10
11#include <rtems/asm.h>
12#include <rtems/score/cpu.h>
13#include <bsp/vectors.h>
14#include <libcpu/raw_exception.h>
15
16#define SYNC \
17        sync; \
18        isync
19
20        PUBLIC_VAR (__rtems_start)
21        .section .entry_point_section,"awx",@progbits
22/*
23 * Entry point information used by bootloader code
24 */
25SYM (__rtems_start):
26        .long   __rtems_entry_point
27
28        /*
29         * end of special Entry point section
30         */
31        .text
32        /* 603e shadows GPR0..GPR3 for certain exceptions. We must switch
33         * that off before we can use the stack pointer. Note that this is
34         * ONLY safe if the shadowing is actually active -- otherwise, r1
35         * is destroyed. We deliberately use r1 so problems become obvious
36         * if this is abused!
37         */
38PUBLIC_VAR(tgpr_clr_exception_vector_code_prolog)
39SYM (tgpr_clr_exception_vector_code_prolog):
40        mfmsr   r1
41        rlwinm  r1,r1,0,15,13
42        mtmsr   r1
43        isync
44        /* fall thru */
45PUBLIC_VAR(default_exception_vector_code_prolog)
46SYM (default_exception_vector_code_prolog):
47        /*
48         * let room for exception frame
49         */
50        stw     r3, GPR3_OFFSET-EXCEPTION_FRAME_END(r1)
51        mflr    r3
52        stw     r3, EXC_LR_OFFSET-EXCEPTION_FRAME_END(r1)
53        bla     push_normalized_frame
54
55        /* IMPORTANT: prologue size MUST be < 32 bytes; 'altivec unavailable' exception
56         *            is already at 0xf20 :-(
57         */
58
59        PUBLIC_VAR (default_exception_vector_code_prolog_size)
60        PUBLIC_VAR (tgpr_clr_exception_vector_code_prolog_size)
61
62        default_exception_vector_code_prolog_size = . - default_exception_vector_code_prolog
63        tgpr_clr_exception_vector_code_prolog_size= . - tgpr_clr_exception_vector_code_prolog
64
65        .p2align 5
66PUBLIC_VAR (push_normalized_frame)
67SYM (push_normalized_frame):
68        stwu    r1, - (EXCEPTION_FRAME_END)(r1)
69        mfcr    r3
70        stw     r3,  EXC_CR_OFFSET(r1)
71        /*
72         * r3 = exception vector entry point
73         * (256 * vector number) + few instructions
74         */
75        mflr    r3
76        /* mask upper bits in case vectors are in the high area (psim) */
77        rlwinm  r3, r3, 32-5, 20, 31
78        /*
79         * Remap altivec unavaliable (0xf20) to its vector number...
80         */
81        cmplwi  r3,(ASM_VEC_VECTOR_OFFSET>>5)
82        bne     1f
83        li              r3,ASM_VEC_VECTOR<<3
841:
85        /*
86         * r3 = r3 >> 8 = vector #
87         */
88        srwi    r3,r3,3
89        stw     r3, EXCEPTION_NUMBER_OFFSET(r1)
90        stw     r0, GPR0_OFFSET(r1)
91        /* R2 should never change (EABI: pointer to .sdata2) - we
92         * save it nevertheless..
93         */
94        stw     r2, GPR2_OFFSET(r1)
95        mfsrr0  r3
96        stw     r3, SRR0_FRAME_OFFSET(r1)
97        mfsrr1  r3
98        stw     r3, SRR1_FRAME_OFFSET(r1)
99        /*
100         * Save general purpose registers
101         * Already saved in prolog : R1, R3, LR.
102         * Saved a few line above  : R0, R2
103         *
104         * Manual says that "stmw" instruction may be slower than
105         * series of individual "stw" but who cares about performance
106         * for the DEFAULT exception handler?
107         */
108        stmw    r4, GPR4_OFFSET(r1)     /* save R4->R31 */
109
110        mfctr   r30
111        stw     r30,  EXC_CTR_OFFSET(r1)
112        mfxer   r28
113        stw     r28,  EXC_XER_OFFSET(r1)
114        mfmsr   r28
115        stw     r28,  EXC_MSR_OFFSET(r1)
116        mfdar   r28
117        stw     r28,  EXC_DAR_OFFSET(r1)
118        /*
119         * compute SP at exception entry
120         */
121        addi    r3, r1, EXCEPTION_FRAME_END
122        /*
123         * store it at the right place
124         */
125        stw     r3, GPR1_OFFSET(r1)
126        /*
127         * Enable data and instruction address translation, exception nesting
128         */
129        mfmsr   r3
130        ori     r3,r3, MSR_RI | MSR_IR | MSR_DR
131        mtmsr   r3
132        SYNC
133
134        /*
135         * Call C exception handler
136         */
137        /*
138         * store the execption frame address in r3 (first param)
139         */
140        addi    r3, r1, 0x8
141        /* clear CR[6] to make sure no varargs fn callee assumes there are FP args passed */
142        crxor   6,6,6
143        /*
144         * globalExceptHdl(r3)
145         */
146        addis   r4, 0, globalExceptHdl@ha
147        lwz     r5, globalExceptHdl@l(r4)
148        mtlr    r5
149        blrl
150        /*
151         * Restore registers status
152         */
153        lwz     r31,  EXC_CR_OFFSET(r1)
154        mtcr    r31
155        lwz     r30,  EXC_CTR_OFFSET(r1)
156        mtctr   r30
157        lwz     r29,  EXC_LR_OFFSET(r1)
158        mtlr    r29
159        lwz     r28,  EXC_XER_OFFSET(r1)
160        mtxer   r28
161
162        lmw     r4, GPR4_OFFSET(r1)
163        lwz     r2, GPR2_OFFSET(r1)
164        lwz     r0, GPR0_OFFSET(r1)
165
166        /*
167         * Disable data and instruction translation. Make path non recoverable...
168         */
169        mfmsr   r3
170        xori    r3, r3, MSR_RI | MSR_IR | MSR_DR
171        mtmsr   r3
172        SYNC
173        /*
174         * Restore rfi related settings
175         */
176
177        lwz     r3, SRR1_FRAME_OFFSET(r1)
178        mtsrr1  r3
179        lwz     r3, SRR0_FRAME_OFFSET(r1)
180        mtsrr0  r3
181
182        lwz     r3, GPR3_OFFSET(r1)
183        /* DONT add back the frame size but reload the value
184         * stored in the frame -- maybe the exception handler
185         * changed it with good reason (e.g., gdb pushed a dummy frame)
186         */
187        lwz r1, GPR1_OFFSET(r1)
188        SYNC
189        rfi
Note: See TracBrowser for help on using the repository browser.