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

4.115
Last change on this file since edb1dd83 was edb1dd83, checked in by Sebastian Huber <sebastian.huber@…>, on 11/08/11 at 10:05:50

2011-11-08 Sebastian Huber <sebastian.huber@…>

  • new-exceptions/bspsupport/ppc_exc_async_normal.S: Bugfix for MPC5674F. Use it for all to be safe.
  • mpc55xx/include/emios.h: Fixed eMIOS module count.
  • mpc55xx/include/irq.h: Fixed CAN vector numbers. BSP_INTERRUPT_HANDLER_TABLE_SIZE is now a BSP option.
  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
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.com/license/LICENSE.
13 *
14 * $Id$
15 */
16
17#include <bspopts.h>
18#include <rtems/score/percpu.h>
19#include <bsp/vectors.h>
20
21#define VECTOR_REGISTER r4
22#define ISR_NEST_HADDR_REGISTER r5
23#define ISR_NEST_REGISTER r6
24#define DISPATCH_LEVEL_REGISTER r7
25#define HANDLER_REGISTER r8
26#define SCRATCH_0_REGISTER r0
27#define SCRATCH_1_REGISTER r3
28#define SCRATCH_2_REGISTER r9
29#define SCRATCH_3_REGISTER r10
30#define SCRATCH_4_REGISTER r11
31#define SCRATCH_5_REGISTER r12
32#define FRAME_REGISTER r14
33
34#define VECTOR_OFFSET(reg) GPR4_OFFSET(reg)
35#define ISR_NEST_HADDR_OFFSET(reg) GPR5_OFFSET(reg)
36#define ISR_NEST_OFFSET(reg) GPR6_OFFSET(reg)
37#define DISPATCH_LEVEL_OFFSET(reg) GPR7_OFFSET(reg)
38#define HANDLER_OFFSET(reg) GPR8_OFFSET(reg)
39#define SCRATCH_0_OFFSET(reg) GPR0_OFFSET(reg)
40#define SCRATCH_1_OFFSET(reg) GPR3_OFFSET(reg)
41#define SCRATCH_2_OFFSET(reg) GPR9_OFFSET(reg)
42#define SCRATCH_3_OFFSET(reg) GPR10_OFFSET(reg)
43#define SCRATCH_4_OFFSET(reg) GPR11_OFFSET(reg)
44#define SCRATCH_5_OFFSET(reg) GPR12_OFFSET(reg)
45
46/*
47 * The register 2 slot is free, since this is the read-only small data anchor.
48 */
49#define FRAME_OFFSET(reg) GPR2_OFFSET(reg)
50
51        .global ppc_exc_min_prolog_async_tmpl_normal
52        .global ppc_exc_wrap_async_normal
53
54ppc_exc_min_prolog_async_tmpl_normal:
55
56        stwu    r1, -PPC_EXC_MINIMAL_FRAME_SIZE(r1)
57        stw     VECTOR_REGISTER, PPC_EXC_VECTOR_PROLOGUE_OFFSET(r1)
58        li      VECTOR_REGISTER, 0xffff8000
59
60        /*
61         * We store the absolute branch target address here.  It will be used
62         * to generate the branch operation in ppc_exc_make_prologue().
63         */
64        .int    ppc_exc_wrap_async_normal
65
66ppc_exc_wrap_async_normal:
67
68        /* Save non-volatile FRAME_REGISTER */
69        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
70
71#ifdef __SPE__
72        /* Enable SPE */
73        mfmsr   FRAME_REGISTER
74        oris    FRAME_REGISTER, FRAME_REGISTER, MSR_SPE >> 16
75        mtmsr   FRAME_REGISTER
76        isync
77#endif
78
79        /* Move frame pointer to non-volatile FRAME_REGISTER */
80        mr      FRAME_REGISTER, r1
81
82        /* Load ISR nest level and thread dispatch disable level */
83        PPC_EXC_GPR_STORE       ISR_NEST_HADDR_REGISTER, ISR_NEST_HADDR_OFFSET(r1)
84        lis     ISR_NEST_HADDR_REGISTER, ISR_NEST_LEVEL@ha
85        PPC_EXC_GPR_STORE       ISR_NEST_REGISTER, ISR_NEST_OFFSET(r1)
86        lwz     ISR_NEST_REGISTER, ISR_NEST_LEVEL@l(ISR_NEST_HADDR_REGISTER)
87        PPC_EXC_GPR_STORE       DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_OFFSET(r1)
88        lwz     DISPATCH_LEVEL_REGISTER, _Thread_Dispatch_disable_level@sdarel(r13)
89
90        PPC_EXC_GPR_STORE       SCRATCH_0_REGISTER, SCRATCH_0_OFFSET(r1)
91
92#ifdef __SPE__
93        /*
94         * Save high order part of VECTOR_REGISTER here.  The low order part
95         * was saved in the minimal prologue.
96         */
97        evmergehi       SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, VECTOR_REGISTER
98        stw     SCRATCH_0_REGISTER, VECTOR_OFFSET(r1)
99#endif
100
101        PPC_EXC_GPR_STORE       HANDLER_REGISTER, HANDLER_OFFSET(r1)
102
103        /*
104         * Load the handler address.  Get the handler table index from the
105         * vector number.  We have to discard the exception type.  Take only
106         * the least significant five bits (= LAST_VALID_EXC + 1) from the
107         * vector register.  Multiply by four (= size of function pointer).
108         */
109        rlwinm  SCRATCH_0_REGISTER, VECTOR_REGISTER, 2, 25, 29
110        lis     HANDLER_REGISTER, ppc_exc_handler_table@h
111        ori     HANDLER_REGISTER, HANDLER_REGISTER, ppc_exc_handler_table@l
112        lwzx    HANDLER_REGISTER, HANDLER_REGISTER, SCRATCH_0_REGISTER
113
114        PPC_EXC_GPR_STORE       SCRATCH_1_REGISTER, SCRATCH_1_OFFSET(r1)
115        PPC_EXC_GPR_STORE       SCRATCH_2_REGISTER, SCRATCH_2_OFFSET(r1)
116        PPC_EXC_GPR_STORE       SCRATCH_3_REGISTER, SCRATCH_3_OFFSET(r1)
117        PPC_EXC_GPR_STORE       SCRATCH_4_REGISTER, SCRATCH_4_OFFSET(r1)
118        PPC_EXC_GPR_STORE       SCRATCH_5_REGISTER, SCRATCH_5_OFFSET(r1)
119
120        /* Save SRR0, SRR1, CR, CTR, XER, and LR */
121        mfsrr0  SCRATCH_0_REGISTER
122        mfsrr1  SCRATCH_1_REGISTER
123        mfcr    SCRATCH_2_REGISTER
124        mfctr   SCRATCH_3_REGISTER
125        mfxer   SCRATCH_4_REGISTER
126        mflr    SCRATCH_5_REGISTER
127        stw     SCRATCH_0_REGISTER, SRR0_FRAME_OFFSET(r1)
128        stw     SCRATCH_1_REGISTER, SRR1_FRAME_OFFSET(r1)
129        stw     SCRATCH_2_REGISTER, EXC_CR_OFFSET(r1)
130        stw     SCRATCH_3_REGISTER, EXC_CTR_OFFSET(r1)
131        stw     SCRATCH_4_REGISTER, EXC_XER_OFFSET(r1)
132        stw     SCRATCH_5_REGISTER, EXC_LR_OFFSET(r1)
133
134#ifdef __SPE__
135        /* Save SPEFSCR and ACC */
136        mfspr   SCRATCH_0_REGISTER, FSL_EIS_SPEFSCR
137        evxor   SCRATCH_1_REGISTER, SCRATCH_1_REGISTER, SCRATCH_1_REGISTER
138        evmwumiaa       SCRATCH_1_REGISTER, SCRATCH_1_REGISTER, SCRATCH_1_REGISTER
139        stw     SCRATCH_0_REGISTER, PPC_EXC_SPEFSCR_OFFSET(r1)
140        evstdd  SCRATCH_1_REGISTER, PPC_EXC_ACC_OFFSET(r1)
141#endif
142
143        /* Increment ISR nest level and thread dispatch disable level */
144        cmpwi   ISR_NEST_REGISTER, 0
145        addi    ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
146        addi    DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
147        stw     ISR_NEST_REGISTER, ISR_NEST_LEVEL@l(ISR_NEST_HADDR_REGISTER)
148        stw     DISPATCH_LEVEL_REGISTER, _Thread_Dispatch_disable_level@sdarel(r13)
149
150        /* Switch stack if necessary */
151        mfspr   SCRATCH_0_REGISTER, SPRG1
152        iselgt  r1, r1, SCRATCH_0_REGISTER
153
154        /*
155         * Call high level exception handler.
156         *
157         * First parameter = exception frame pointer + FRAME_LINK_SPACE
158         * Second parameter = vector number (r4 is the VECTOR_REGISTER)
159         */
160        addi    r3, FRAME_REGISTER, FRAME_LINK_SPACE
161        rlwinm  VECTOR_REGISTER, VECTOR_REGISTER, 0, 27, 31
162        mtctr   HANDLER_REGISTER
163        bctrl
164
165        /* Load ISR nest level and thread dispatch disable level */
166        lis     ISR_NEST_HADDR_REGISTER, ISR_NEST_LEVEL@ha
167        lwz     ISR_NEST_REGISTER, ISR_NEST_LEVEL@l(ISR_NEST_HADDR_REGISTER)
168        lwz     DISPATCH_LEVEL_REGISTER, _Thread_Dispatch_disable_level@sdarel(r13)
169
170        /*
171         * Switch back to original stack (FRAME_REGISTER == r1 if we are still
172         * on the IRQ stack) and restore FRAME_REGISTER.
173         */
174        mr      r1, FRAME_REGISTER
175        lwz     FRAME_REGISTER, FRAME_OFFSET(r1)
176
177        /* Decrement ISR nest level and thread dispatch disable level */
178        subi    ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
179        subic.  DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
180        stw     ISR_NEST_REGISTER, ISR_NEST_LEVEL@l(ISR_NEST_HADDR_REGISTER)
181        stw     DISPATCH_LEVEL_REGISTER, _Thread_Dispatch_disable_level@sdarel(r13)
182
183        /* Call thread dispatcher if necessary */
184        bne     thread_dispatching_done
185        bl      _Thread_Dispatch
186thread_dispatching_done:
187
188#ifdef __SPE__
189        /* Load SPEFSCR and ACC */
190        lwz     DISPATCH_LEVEL_REGISTER, PPC_EXC_SPEFSCR_OFFSET(r1)
191        evldd   HANDLER_REGISTER, PPC_EXC_ACC_OFFSET(r1)
192#endif
193
194        /* Load SRR0, SRR1, CR, CTR, XER, and LR */
195        lwz     SCRATCH_0_REGISTER, SRR0_FRAME_OFFSET(r1)
196        lwz     SCRATCH_1_REGISTER, SRR1_FRAME_OFFSET(r1)
197        lwz     SCRATCH_2_REGISTER, EXC_CR_OFFSET(r1)
198        lwz     SCRATCH_3_REGISTER, EXC_CTR_OFFSET(r1)
199        lwz     SCRATCH_4_REGISTER, EXC_XER_OFFSET(r1)
200        lwz     SCRATCH_5_REGISTER, EXC_LR_OFFSET(r1)
201
202        PPC_EXC_GPR_LOAD        VECTOR_REGISTER, VECTOR_OFFSET(r1)
203        PPC_EXC_GPR_LOAD        ISR_NEST_HADDR_REGISTER, ISR_NEST_HADDR_OFFSET(r1)
204        PPC_EXC_GPR_LOAD        ISR_NEST_REGISTER, ISR_NEST_OFFSET(r1)
205
206#ifdef __SPE__
207        /* Restore SPEFSCR */
208        mtspr   FSL_EIS_SPEFSCR, DISPATCH_LEVEL_REGISTER
209#endif
210        PPC_EXC_GPR_LOAD        DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_OFFSET(r1)
211
212#ifdef __SPE__
213        /* Restore ACC */
214        evmra   HANDLER_REGISTER, HANDLER_REGISTER
215#endif
216        PPC_EXC_GPR_LOAD        HANDLER_REGISTER, HANDLER_OFFSET(r1)
217
218        /* Restore SRR0, SRR1, CR, CTR, XER, and LR */
219        mtsrr0  SCRATCH_0_REGISTER
220        PPC_EXC_GPR_LOAD        SCRATCH_0_REGISTER, SCRATCH_0_OFFSET(r1)
221        mtsrr1  SCRATCH_1_REGISTER
222        PPC_EXC_GPR_LOAD        SCRATCH_1_REGISTER, SCRATCH_1_OFFSET(r1)
223        mtcr    SCRATCH_2_REGISTER
224        PPC_EXC_GPR_LOAD        SCRATCH_2_REGISTER, SCRATCH_2_OFFSET(r1)
225        mtctr   SCRATCH_3_REGISTER
226        PPC_EXC_GPR_LOAD        SCRATCH_3_REGISTER, SCRATCH_3_OFFSET(r1)
227        mtxer   SCRATCH_4_REGISTER
228        PPC_EXC_GPR_LOAD        SCRATCH_4_REGISTER, SCRATCH_4_OFFSET(r1)
229        mtlr    SCRATCH_5_REGISTER
230        PPC_EXC_GPR_LOAD        SCRATCH_5_REGISTER, SCRATCH_5_OFFSET(r1)
231
232        /* Pop stack */
233        addi    r1, r1, PPC_EXC_MINIMAL_FRAME_SIZE
234
235        /* Return */
236        rfi
Note: See TracBrowser for help on using the repository browser.