source: rtems/bsps/powerpc/shared/exceptions/ppc_exc.S @ 9964895

5
Last change on this file since 9964895 was bd150801, checked in by Sebastian Huber <sebastian.huber@…>, on 03/13/18 at 15:24:16

bsps/powerpc: Move exceptions support to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * (c) 1999, Eric Valette valette@crf.canon.fr
3 *
4 * Modified and partially rewritten by Till Straumann, 2007
5 *
6 * Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>, 2008.
7 *
8 * Low-level assembly code for PPC exceptions.
9 *
10 * This file was written with the goal to eliminate
11 * ALL #ifdef <cpu_flavor> conditionals -- please do not
12 * reintroduce such statements.
13 */
14
15/* Load macro definitions */
16#include <rtems/asm.h>
17#include <rtems/system.h>
18#include <rtems/score/percpu.h>
19
20/*
21 * This code uses the small-data area which is not available in the 64-bit
22 * PowerPC ELFv2 ABI.
23 */
24#ifndef __powerpc64__
25
26#include "ppc_exc_asm_macros.h"
27
28/******************************************************/
29/*  PROLOGUES                                         */
30/******************************************************/
31
32        /*
33         * Expand prologue snippets for classic, ppc405-critical, bookE-critical
34         * and E500 machine-check, synchronous and asynchronous exceptions
35         */
36        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_std        _VEC=0 _PRI=std  _FLVR=std
37        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_p405_crit  _VEC=0 _PRI=crit _FLVR=p405_crit
38        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_bookE_crit _VEC=0 _PRI=crit _FLVR=bookE_crit
39        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_e500_mchk  _VEC=0 _PRI=mchk _FLVR=e500_mchk
40
41        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_std        _VEC=0 _PRI=std  _FLVR=std
42        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_p405_crit  _VEC=0 _PRI=crit _FLVR=p405_crit
43        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_bookE_crit _VEC=0 _PRI=crit _FLVR=bookE_crit
44        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_e500_mchk  _VEC=0 _PRI=mchk _FLVR=e500_mchk
45
46        .global ppc_exc_min_prolog_size
47ppc_exc_min_prolog_size      = 4 * 4
48
49/* Special prologue for 603e-style CPUs.
50 *
51 * 603e shadows GPR0..GPR3 for certain exceptions. We must switch
52 * that off before we can use the stack pointer. Note that this is
53 * ONLY safe if the shadowing is actually active -- otherwise, r1
54 * is destroyed. We deliberately use r1 so problems become obvious
55 * if this is misused!
56 */
57        .global ppc_exc_tgpr_clr_prolog
58ppc_exc_tgpr_clr_prolog:
59        mfmsr   r1
60        rlwinm  r1,r1,0,15,13
61        mtmsr   r1
62        isync
63        /* FALL THRU TO 'auto' PROLOG */
64
65/* Determine vector dynamically/automatically
66 *
67 * BUT: - only standard exceptions (no critical ones)
68 *      - vector offset must be on 256 Byte boundary.
69 */
70        .global ppc_exc_min_prolog_auto
71ppc_exc_min_prolog_auto:
72        stwu    r1, -EXCEPTION_FRAME_END(r1)
73        stw     VECTOR_REGISTER, VECTOR_OFFSET(r1)
74        mflr    VECTOR_REGISTER
75
76        /*
77         * We store the absolute branch target address here.  It will be used
78         * to generate the branch operation in ppc_exc_make_prologue().
79         *
80         * We add one to request the link in the generated branch instruction.
81         */
82        .int    ppc_exc_wrap_auto + 1
83
84        .global ppc_exc_tgpr_clr_prolog_size
85ppc_exc_tgpr_clr_prolog_size = . - ppc_exc_tgpr_clr_prolog
86
87/*
88 * Automatic vector, asynchronous exception; however,
89 * automatic vector calculation is less efficient than
90 * using an explicit vector in a minimal prolog snippet.
91 * The latter method is preferable since there usually
92 * are few asynchronous exceptions.
93 *
94 * For generic exceptions (which are the bulk) using
95 * the 'auto' prologue is OK since performance is not
96 * really an issue.
97 */
98        .global ppc_exc_min_prolog_auto_async
99ppc_exc_min_prolog_auto_async:
100        stw     r1, ppc_exc_lock_std@sdarel(r13)
101        stw     VECTOR_REGISTER, ppc_exc_vector_register_std@sdarel(r13)
102        mflr    VECTOR_REGISTER
103
104        /*
105         * We store the absolute branch target address here.  It will be used
106         * to generate the branch operation in ppc_exc_make_prologue().
107         *
108         * We add one to request the link in the generated branch instruction.
109         */
110        .int    ppc_exc_wrap_auto_async + 1
111
112/******************************************************/
113/*  WRAPPERS                                          */
114/******************************************************/
115
116        /* Tag start and end of the wrappers.
117         * If exceptions are installed farther removed
118         * from the text area than 32M then the wrappers
119         * must be moved to an area that is reachable
120         * from where the prologues reside. Branches into
121         * C-code are far.
122         */
123
124        .global __ppc_exc_wrappers_start
125__ppc_exc_wrappers_start = .
126
127        /* Expand wrappers for different exception flavors */
128
129        /* Standard/classic powerpc */
130        WRAP    _FLVR=std _PRI=std _SRR0=srr0 _SRR1=srr1 _RFI=rfi
131
132        /* ppc405 has a critical exception using srr2/srr3 */
133        WRAP    _FLVR=p405_crit _PRI=crit _SRR0=srr2 _SRR1=srr3 _RFI=rfci
134
135        /* bookE has critical exception using csrr0 cssr1 */
136        WRAP    _FLVR=bookE_crit _PRI=crit _SRR0=csrr0 _SRR1=csrr1 _RFI=rfci
137
138        /* e500 has machine-check exception using mcsrr0 mcssr1 */
139        WRAP    _FLVR=e500_mchk _PRI=mchk _SRR0=mcsrr0 _SRR1=mcsrr1 _RFI=rfmci
140
141        /* LR holds vector, VECTOR_REGISTER holds orig. LR */
142        .global ppc_exc_wrap_auto
143ppc_exc_wrap_auto:
144        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
145
146        /* Find address where we jumped from */
147        mflr    FRAME_REGISTER
148
149        /* Restore LR */
150        mtlr    VECTOR_REGISTER
151
152        /* Compute vector into R3 */
153        rlwinm  VECTOR_REGISTER, FRAME_REGISTER, 24, 26, 31
154
155        /*
156         * We're now in almost the same state as if called by
157         * min_prolog_std but we must skip saving FRAME_REGISTER
158         * since that's done already
159         */
160        b       wrap_no_save_frame_register_std
161
162        .global ppc_exc_wrap_auto_async
163ppc_exc_wrap_auto_async:
164        stwu    r1, -EXCEPTION_FRAME_END(r1)
165        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
166        /* find address where we jumped from */
167        mflr    FRAME_REGISTER
168        /* restore LR     */
169        mtlr    VECTOR_REGISTER
170        /* set upper bits to indicate that non-volatile
171         * registers should not be saved/restored.
172         */
173        li      VECTOR_REGISTER, 0xffff8000
174        /* compute vector into R3 */
175        rlwimi  VECTOR_REGISTER, FRAME_REGISTER, 24, 26, 31
176        /* we're now in almost the same state as if called by
177         * min_prolog_std but we must skip saving FRAME_REGISTER
178         * since that's done already
179         */
180        b       wrap_no_save_frame_register_std
181
182        .global __ppc_exc_wrappers_end
183__ppc_exc_wrappers_end = .
184
185#endif /* !__powerpc64__ */
Note: See TracBrowser for help on using the repository browser.