source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.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: 9.6 KB
Line 
1/*
2 * Copyright (c) 2011-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <bspopts.h>
16#include <rtems/score/percpu.h>
17#include <bsp/vectors.h>
18
19#define VECTOR_REGISTER r4
20#define SELF_CPU_REGISTER r5
21#define ISR_NEST_REGISTER r6
22#define DISPATCH_LEVEL_REGISTER r7
23#define HANDLER_REGISTER r8
24#define SCRATCH_0_REGISTER r0
25#define SCRATCH_1_REGISTER r3
26#define SCRATCH_2_REGISTER r9
27#define SCRATCH_3_REGISTER r10
28#define SCRATCH_4_REGISTER r11
29#define SCRATCH_5_REGISTER r12
30#define FRAME_REGISTER r14
31
32#define VECTOR_OFFSET(reg) GPR4_OFFSET(reg)
33#define SELF_CPU_OFFSET(reg) GPR5_OFFSET(reg)
34#define ISR_NEST_OFFSET(reg) GPR6_OFFSET(reg)
35#define DISPATCH_LEVEL_OFFSET(reg) GPR7_OFFSET(reg)
36#define HANDLER_OFFSET(reg) GPR8_OFFSET(reg)
37#define SCRATCH_0_OFFSET(reg) GPR0_OFFSET(reg)
38#define SCRATCH_1_OFFSET(reg) GPR3_OFFSET(reg)
39#define SCRATCH_2_OFFSET(reg) GPR9_OFFSET(reg)
40#define SCRATCH_3_OFFSET(reg) GPR10_OFFSET(reg)
41#define SCRATCH_4_OFFSET(reg) GPR11_OFFSET(reg)
42#define SCRATCH_5_OFFSET(reg) GPR12_OFFSET(reg)
43
44/*
45 * The register 2 slot is free, since this is the read-only small data anchor.
46 */
47#define FRAME_OFFSET(reg) GPR2_OFFSET(reg)
48
49#ifdef RTEMS_PROFILING
50/*
51 * The PPC_EXC_MINIMAL_FRAME_SIZE is enough to store this additional register.
52 */
53#define ENTRY_INSTANT_REGISTER r15
54#define ENTRY_INSTANT_OFFSET(reg) GPR13_OFFSET(reg)
55
56.macro GET_TIME_BASE REG
57#ifdef ppc8540
58        mfspr   \REG, TBRL
59#else /* ppc8540 */
60        mftb    \REG
61#endif /* ppc8540 */
62.endm
63#endif /* RTEMS_PROFILING */
64
65#ifdef PPC_EXC_CONFIG_USE_FIXED_HANDLER
66        .global bsp_interrupt_dispatch
67#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
68
69        .global ppc_exc_min_prolog_async_tmpl_normal
70        .global ppc_exc_wrap_async_normal
71
72ppc_exc_min_prolog_async_tmpl_normal:
73
74        stwu    r1, -PPC_EXC_MINIMAL_FRAME_SIZE(r1)
75
76#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
77        stw     VECTOR_REGISTER, PPC_EXC_VECTOR_PROLOGUE_OFFSET(r1)
78        li      VECTOR_REGISTER, 0xffff8000
79#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
80
81        /*
82         * We store the absolute branch target address here.  It will be used
83         * to generate the branch operation in ppc_exc_make_prologue().
84         */
85        .int    ppc_exc_wrap_async_normal
86
87ppc_exc_wrap_async_normal:
88
89#ifdef RTEMS_PROFILING
90        /* Save non-volatile ENTRY_INSTANT_REGISTER */
91        stw     ENTRY_INSTANT_REGISTER, ENTRY_INSTANT_OFFSET(r1)
92
93        /* Get entry instant */
94        GET_TIME_BASE   ENTRY_INSTANT_REGISTER
95#endif /* RTEMS_PROFILING */
96
97        /* Save non-volatile FRAME_REGISTER */
98        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
99
100#ifdef __SPE__
101        /* Enable SPE */
102        mfmsr   FRAME_REGISTER
103        oris    FRAME_REGISTER, FRAME_REGISTER, MSR_SPE >> 16
104        mtmsr   FRAME_REGISTER
105        isync
106#endif
107
108        /* Move frame pointer to non-volatile FRAME_REGISTER */
109        mr      FRAME_REGISTER, r1
110
111        /* Load ISR nest level and thread dispatch disable level */
112        PPC_GPR_STORE   SELF_CPU_REGISTER, SELF_CPU_OFFSET(r1)
113        GET_SELF_CPU_CONTROL    SELF_CPU_REGISTER
114        PPC_GPR_STORE   ISR_NEST_REGISTER, ISR_NEST_OFFSET(r1)
115        lwz     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
116        PPC_GPR_STORE   DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_OFFSET(r1)
117        lwz     DISPATCH_LEVEL_REGISTER, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
118
119        PPC_GPR_STORE   SCRATCH_0_REGISTER, SCRATCH_0_OFFSET(r1)
120
121#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
122#ifdef __SPE__
123        /*
124         * Save high order part of VECTOR_REGISTER here.  The low order part
125         * was saved in the minimal prologue.
126         */
127        evmergehi       SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, VECTOR_REGISTER
128        stw     SCRATCH_0_REGISTER, VECTOR_OFFSET(r1)
129#endif
130#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
131        /* The vector register has no special purpose in this case */
132        PPC_GPR_STORE   VECTOR_REGISTER, VECTOR_OFFSET(r1)
133#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
134
135        PPC_GPR_STORE   HANDLER_REGISTER, HANDLER_OFFSET(r1)
136
137#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
138        /*
139         * Load the handler address.  Get the handler table index from the
140         * vector number.  We have to discard the exception type.  Take only
141         * the least significant five bits (= LAST_VALID_EXC + 1) from the
142         * vector register.  Multiply by four (= size of function pointer).
143         */
144        rlwinm  SCRATCH_0_REGISTER, VECTOR_REGISTER, 2, 25, 29
145        lis     HANDLER_REGISTER, ppc_exc_handler_table@h
146        ori     HANDLER_REGISTER, HANDLER_REGISTER, ppc_exc_handler_table@l
147        lwzx    HANDLER_REGISTER, HANDLER_REGISTER, SCRATCH_0_REGISTER
148#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
149
150        PPC_GPR_STORE   SCRATCH_1_REGISTER, SCRATCH_1_OFFSET(r1)
151        PPC_GPR_STORE   SCRATCH_2_REGISTER, SCRATCH_2_OFFSET(r1)
152        PPC_GPR_STORE   SCRATCH_3_REGISTER, SCRATCH_3_OFFSET(r1)
153        PPC_GPR_STORE   SCRATCH_4_REGISTER, SCRATCH_4_OFFSET(r1)
154        PPC_GPR_STORE   SCRATCH_5_REGISTER, SCRATCH_5_OFFSET(r1)
155
156        /* Save SRR0, SRR1, CR, CTR, XER, and LR */
157        mfsrr0  SCRATCH_0_REGISTER
158        mfsrr1  SCRATCH_1_REGISTER
159        mfcr    SCRATCH_2_REGISTER
160        mfctr   SCRATCH_3_REGISTER
161        mfxer   SCRATCH_4_REGISTER
162        mflr    SCRATCH_5_REGISTER
163        stw     SCRATCH_0_REGISTER, SRR0_FRAME_OFFSET(r1)
164        stw     SCRATCH_1_REGISTER, SRR1_FRAME_OFFSET(r1)
165        stw     SCRATCH_2_REGISTER, EXC_CR_OFFSET(r1)
166        stw     SCRATCH_3_REGISTER, EXC_CTR_OFFSET(r1)
167        stw     SCRATCH_4_REGISTER, EXC_XER_OFFSET(r1)
168        stw     SCRATCH_5_REGISTER, EXC_LR_OFFSET(r1)
169
170#ifdef __SPE__
171        /* Save SPEFSCR and ACC */
172        mfspr   SCRATCH_0_REGISTER, FSL_EIS_SPEFSCR
173        evxor   SCRATCH_1_REGISTER, SCRATCH_1_REGISTER, SCRATCH_1_REGISTER
174        evmwumiaa       SCRATCH_1_REGISTER, SCRATCH_1_REGISTER, SCRATCH_1_REGISTER
175        stw     SCRATCH_0_REGISTER, PPC_EXC_SPEFSCR_OFFSET(r1)
176        evstdd  SCRATCH_1_REGISTER, PPC_EXC_ACC_OFFSET(r1)
177#endif
178
179        /* Increment ISR nest level and thread dispatch disable level */
180        cmpwi   ISR_NEST_REGISTER, 0
181        addi    ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
182        addi    DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
183        stw     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
184        stw     DISPATCH_LEVEL_REGISTER, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
185
186        /* Switch stack if necessary */
187        mfspr   SCRATCH_0_REGISTER, SPRG1
188        iselgt  r1, r1, SCRATCH_0_REGISTER
189
190#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
191        /*
192         * Call high level exception handler.
193         *
194         * First parameter = exception frame pointer + FRAME_LINK_SPACE
195         * Second parameter = vector number (r4 is the VECTOR_REGISTER)
196         */
197        addi    r3, FRAME_REGISTER, FRAME_LINK_SPACE
198        rlwinm  VECTOR_REGISTER, VECTOR_REGISTER, 0, 27, 31
199        mtctr   HANDLER_REGISTER
200        bctrl
201#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
202        /* Call fixed high level handler */
203        bl      bsp_interrupt_dispatch
204#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
205
206        /* Load ISR nest level and thread dispatch disable level */
207        GET_SELF_CPU_CONTROL    SELF_CPU_REGISTER
208        lwz     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
209        lwz     DISPATCH_LEVEL_REGISTER, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
210
211        /*
212         * Switch back to original stack (FRAME_REGISTER == r1 if we are still
213         * on the IRQ stack) and restore FRAME_REGISTER.
214         */
215        mr      r1, FRAME_REGISTER
216        lwz     FRAME_REGISTER, FRAME_OFFSET(r1)
217
218        /* Decrement ISR nest level and thread dispatch disable level */
219#ifdef RTEMS_PROFILING
220        subic.  ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
221        subi    DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
222        cmpwi   cr2, DISPATCH_LEVEL_REGISTER, 0
223#else /* RTEMS_PROFILING */
224        subi    ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
225        subic.  DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
226#endif /* RTEMS_PROFILING */
227        stw     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
228        stw     DISPATCH_LEVEL_REGISTER, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
229
230#ifdef RTEMS_PROFILING
231        /* Store profiling data if necessary */
232        bne     profiling_done
233        mr      r3, SELF_CPU_REGISTER
234        mr      r4, ENTRY_INSTANT_REGISTER
235        GET_TIME_BASE   r5
236        bl      _Profiling_Outer_most_interrupt_entry_and_exit
237profiling_done:
238#endif /* RTEMS_PROFILING */
239
240        /* Call thread dispatcher if necessary */
241#ifdef RTEMS_PROFILING
242        bne     cr2, thread_dispatching_done
243#else /* RTEMS_PROFILING */
244        bne     thread_dispatching_done
245#endif /* RTEMS_PROFILING */
246        bl      _Thread_Dispatch
247thread_dispatching_done:
248
249#ifdef __SPE__
250        /* Load SPEFSCR and ACC */
251        lwz     DISPATCH_LEVEL_REGISTER, PPC_EXC_SPEFSCR_OFFSET(r1)
252        evldd   HANDLER_REGISTER, PPC_EXC_ACC_OFFSET(r1)
253#endif
254
255        /* Load SRR0, SRR1, CR, CTR, XER, and LR */
256        lwz     SCRATCH_0_REGISTER, SRR0_FRAME_OFFSET(r1)
257        lwz     SCRATCH_1_REGISTER, SRR1_FRAME_OFFSET(r1)
258        lwz     SCRATCH_2_REGISTER, EXC_CR_OFFSET(r1)
259        lwz     SCRATCH_3_REGISTER, EXC_CTR_OFFSET(r1)
260        lwz     SCRATCH_4_REGISTER, EXC_XER_OFFSET(r1)
261        lwz     SCRATCH_5_REGISTER, EXC_LR_OFFSET(r1)
262
263        PPC_GPR_LOAD    VECTOR_REGISTER, VECTOR_OFFSET(r1)
264        PPC_GPR_LOAD    SELF_CPU_REGISTER, SELF_CPU_OFFSET(r1)
265        PPC_GPR_LOAD    ISR_NEST_REGISTER, ISR_NEST_OFFSET(r1)
266
267#ifdef __SPE__
268        /* Restore SPEFSCR */
269        mtspr   FSL_EIS_SPEFSCR, DISPATCH_LEVEL_REGISTER
270#endif
271        PPC_GPR_LOAD    DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_OFFSET(r1)
272
273#ifdef __SPE__
274        /* Restore ACC */
275        evmra   HANDLER_REGISTER, HANDLER_REGISTER
276#endif
277        PPC_GPR_LOAD    HANDLER_REGISTER, HANDLER_OFFSET(r1)
278
279        /* Restore SRR0, SRR1, CR, CTR, XER, and LR */
280        mtsrr0  SCRATCH_0_REGISTER
281        PPC_GPR_LOAD    SCRATCH_0_REGISTER, SCRATCH_0_OFFSET(r1)
282        mtsrr1  SCRATCH_1_REGISTER
283        PPC_GPR_LOAD    SCRATCH_1_REGISTER, SCRATCH_1_OFFSET(r1)
284        mtcr    SCRATCH_2_REGISTER
285        PPC_GPR_LOAD    SCRATCH_2_REGISTER, SCRATCH_2_OFFSET(r1)
286        mtctr   SCRATCH_3_REGISTER
287        PPC_GPR_LOAD    SCRATCH_3_REGISTER, SCRATCH_3_OFFSET(r1)
288        mtxer   SCRATCH_4_REGISTER
289        PPC_GPR_LOAD    SCRATCH_4_REGISTER, SCRATCH_4_OFFSET(r1)
290        mtlr    SCRATCH_5_REGISTER
291        PPC_GPR_LOAD    SCRATCH_5_REGISTER, SCRATCH_5_OFFSET(r1)
292
293#ifdef RTEMS_PROFILING
294        /* Restore ENTRY_INSTANT_REGISTER */
295        lwz     ENTRY_INSTANT_REGISTER, ENTRY_INSTANT_OFFSET(r1)
296#endif /* RTEMS_PROFILING */
297
298        /* Pop stack */
299        addi    r1, r1, PPC_EXC_MINIMAL_FRAME_SIZE
300
301        /* Return */
302        rfi
Note: See TracBrowser for help on using the repository browser.