source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_naked.S @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ppc_exc
5 *
6 * @brief PowerPC Exceptions implementation.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.org/license/LICENSE.
20 */
21
22#include "ppc_exc_asm_macros.h"
23
24        .global ppc_exc_min_prolog_tmpl_naked
25
26ppc_exc_min_prolog_tmpl_naked:
27
28        stwu    r1, -EXCEPTION_FRAME_END(r1)
29        stw     VECTOR_REGISTER, VECTOR_OFFSET(r1)
30        li      VECTOR_REGISTER, 0
31
32        /*
33         * We store the absolute branch target address here.  It will be used
34         * to generate the branch operation in ppc_exc_make_prologue().
35         */
36        .int    ppc_exc_wrap_naked
37
38        .global ppc_exc_wrap_naked
39ppc_exc_wrap_naked:
40
41        /* Save scratch registers */
42        stw     SCRATCH_REGISTER_0, SCRATCH_REGISTER_0_OFFSET(r1)
43        stw     SCRATCH_REGISTER_1, SCRATCH_REGISTER_1_OFFSET(r1)
44        stw     SCRATCH_REGISTER_2, SCRATCH_REGISTER_2_OFFSET(r1)
45
46        /* Save volatile registers */
47        stw     r0, GPR0_OFFSET(r1)
48        stw     r3, GPR3_OFFSET(r1)
49        stw     r8, GPR8_OFFSET(r1)
50        stw     r9, GPR9_OFFSET(r1)
51        stw     r10, GPR10_OFFSET(r1)
52        stw     r11, GPR11_OFFSET(r1)
53        stw     r12, GPR12_OFFSET(r1)
54
55        /* Save CR */
56        mfcr    SCRATCH_REGISTER_0
57        stw     SCRATCH_REGISTER_0, EXC_CR_OFFSET(r1)
58
59        /* Save SRR0 */
60        mfspr   SCRATCH_REGISTER_0, srr0
61        stw     SCRATCH_REGISTER_0, SRR0_FRAME_OFFSET(r1)
62
63        /* Save SRR1 */
64        mfspr   SCRATCH_REGISTER_0, srr1
65        stw     SCRATCH_REGISTER_0, SRR1_FRAME_OFFSET(r1)
66
67        /* Save CTR */
68        mfctr   SCRATCH_REGISTER_0
69        stw     SCRATCH_REGISTER_0, EXC_CTR_OFFSET(r1)
70
71        /* Save XER */
72        mfxer   SCRATCH_REGISTER_0
73        stw     SCRATCH_REGISTER_0, EXC_XER_OFFSET(r1)
74
75        /* Save LR */
76        mflr    SCRATCH_REGISTER_0
77        stw     SCRATCH_REGISTER_0, EXC_LR_OFFSET(r1)
78
79#ifndef PPC_EXC_CONFIG_BOOKE_ONLY
80
81        /* Load MSR bit mask */
82        lwz     SCRATCH_REGISTER_0, ppc_exc_msr_bits@sdarel(r13)
83
84        /*
85         * Change the MSR if necessary (MMU, RI), remember decision in
86         * non-volatile CR_MSR.
87         */
88        cmpwi   CR_MSR, SCRATCH_REGISTER_0, 0
89        bne     CR_MSR, wrap_change_msr_naked
90
91wrap_change_msr_done_naked:
92
93#endif /* PPC_EXC_CONFIG_BOOKE_ONLY */
94
95        /*
96         * Call high level exception handler
97         */
98
99        /*
100         * Get the handler table index from the vector number.  We have to
101         * discard the exception type.  Take only the least significant five
102         * bits (= LAST_VALID_EXC + 1) from the vector register.  Multiply by
103         * four (= size of function pointer).
104         */
105        rlwinm  SCRATCH_REGISTER_1, VECTOR_REGISTER, 2, 25, 29
106
107        /* Load handler table address */
108        LA      SCRATCH_REGISTER_0, ppc_exc_handler_table
109
110        /* Load handler address */
111        lwzx    SCRATCH_REGISTER_0, SCRATCH_REGISTER_0, SCRATCH_REGISTER_1
112
113        /*
114         * First parameter = exception frame pointer + FRAME_LINK_SPACE
115         *
116         * We add FRAME_LINK_SPACE to the frame pointer because the high level
117         * handler expects a BSP_Exception_frame structure.
118         */
119        addi    r3, r1, FRAME_LINK_SPACE
120
121        /*
122         * Second parameter = vector number (r4 is the VECTOR_REGISTER)
123         *
124         * Discard the exception type and store the vector number
125         * in the vector register.  Take only the least significant
126         * five bits (= LAST_VALID_EXC + 1).
127         */
128        rlwinm  VECTOR_REGISTER, VECTOR_REGISTER, 0, 27, 31
129
130        /* Call handler */
131        mtctr   SCRATCH_REGISTER_0
132        bctrl
133
134#ifndef PPC_EXC_CONFIG_BOOKE_ONLY
135
136        /* Restore MSR? */
137        bne     CR_MSR, wrap_restore_msr_naked
138
139wrap_restore_msr_done_naked:
140
141#endif /* PPC_EXC_CONFIG_BOOKE_ONLY */
142
143        /* Restore XER and CTR */
144        lwz     SCRATCH_REGISTER_0, EXC_XER_OFFSET(r1)
145        lwz     SCRATCH_REGISTER_1, EXC_CTR_OFFSET(r1)
146        mtxer   SCRATCH_REGISTER_0
147        mtctr   SCRATCH_REGISTER_1
148
149        /* Restore CR and LR */
150        lwz     SCRATCH_REGISTER_0, EXC_CR_OFFSET(r1)
151        lwz     SCRATCH_REGISTER_1, EXC_LR_OFFSET(r1)
152        mtcr    SCRATCH_REGISTER_0
153        mtlr    SCRATCH_REGISTER_1
154
155        /* Restore volatile registers */
156        lwz     r0, GPR0_OFFSET(r1)
157        lwz     r3, GPR3_OFFSET(r1)
158        lwz     r8, GPR8_OFFSET(r1)
159        lwz     r9, GPR9_OFFSET(r1)
160        lwz     r10, GPR10_OFFSET(r1)
161        lwz     r11, GPR11_OFFSET(r1)
162        lwz     r12, GPR12_OFFSET(r1)
163
164        /* Restore vector register */
165        lwz     VECTOR_REGISTER, VECTOR_OFFSET(r1)
166
167        /* Restore scratch registers and SRRs */
168        lwz     SCRATCH_REGISTER_0, SRR0_FRAME_OFFSET(r1)
169        lwz     SCRATCH_REGISTER_1, SRR1_FRAME_OFFSET(r1)
170        lwz     SCRATCH_REGISTER_2, SCRATCH_REGISTER_2_OFFSET(r1)
171        mtspr   srr0, SCRATCH_REGISTER_0
172        lwz     SCRATCH_REGISTER_0, SCRATCH_REGISTER_0_OFFSET(r1)
173        mtspr   srr1, SCRATCH_REGISTER_1
174        lwz     SCRATCH_REGISTER_1, SCRATCH_REGISTER_1_OFFSET(r1)
175
176        /*
177         * We restore r1 from the frame rather than just popping (adding to
178         * current r1) since the exception handler might have done strange
179         * things (e.g. a debugger moving and relocating the stack).
180         */
181        lwz     r1, 0(r1)
182
183        /* Return */
184        rfi
185
186#ifndef PPC_EXC_CONFIG_BOOKE_ONLY
187
188wrap_change_msr_naked:
189
190        mfmsr   SCRATCH_REGISTER_1
191        or      SCRATCH_REGISTER_1, SCRATCH_REGISTER_1, SCRATCH_REGISTER_0
192        mtmsr   SCRATCH_REGISTER_1
193        sync
194        isync
195        b       wrap_change_msr_done_naked
196
197wrap_restore_msr_naked:
198
199        lwz     SCRATCH_REGISTER_0, ppc_exc_msr_bits@sdarel(r13)
200        mfmsr   SCRATCH_REGISTER_1
201        andc    SCRATCH_REGISTER_1, SCRATCH_REGISTER_1, SCRATCH_REGISTER_0
202        mtmsr   SCRATCH_REGISTER_1
203        sync
204        isync
205        b       wrap_restore_msr_done_naked
206
207#endif /* PPC_EXC_CONFIG_BOOKE_ONLY */
Note: See TracBrowser for help on using the repository browser.