source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc.S @ 2d2de4eb

4.104.115
Last change on this file since 2d2de4eb was 2d2de4eb, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 10/23/09 at 07:32:46

Update for exception support changes.

  • Property mode set to 100644
File size: 5.5 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 "ppc_exc_asm_macros.h"
17
18/******************************************************/
19/*  PROLOGUES                                         */
20/******************************************************/
21
22        /*
23         * Expand prologue snippets for classic, ppc405-critical, bookE-critical
24         * and E500 machine-check, synchronous and asynchronous exceptions
25         */
26        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_std        _VEC=0 _PRI=std  _FLVR=std
27        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_p405_crit  _VEC=0 _PRI=crit _FLVR=p405_crit
28        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_bookE_crit _VEC=0 _PRI=crit _FLVR=bookE_crit
29        PPC_EXC_MIN_PROLOG_SYNC _NAME=tmpl_e500_mchk  _VEC=0 _PRI=mchk _FLVR=e500_mchk
30
31        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_std        _VEC=0 _PRI=std  _FLVR=std
32        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_p405_crit  _VEC=0 _PRI=crit _FLVR=p405_crit
33        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_bookE_crit _VEC=0 _PRI=crit _FLVR=bookE_crit
34        PPC_EXC_MIN_PROLOG_ASYNC _NAME=tmpl_e500_mchk  _VEC=0 _PRI=mchk _FLVR=e500_mchk
35
36        .global ppc_exc_min_prolog_size
37ppc_exc_min_prolog_size      = 4 * 4
38
39/* Special prologue for 603e-style CPUs.
40 *
41 * 603e shadows GPR0..GPR3 for certain exceptions. We must switch
42 * that off before we can use the stack pointer. Note that this is
43 * ONLY safe if the shadowing is actually active -- otherwise, r1
44 * is destroyed. We deliberately use r1 so problems become obvious
45 * if this is misused!
46 */
47        .global ppc_exc_tgpr_clr_prolog
48ppc_exc_tgpr_clr_prolog:
49        mfmsr   r1
50        rlwinm  r1,r1,0,15,13
51        mtmsr   r1
52        isync
53        /* FALL THRU TO 'auto' PROLOG */
54
55/* Determine vector dynamically/automatically
56 *
57 * BUT: - only standard exceptions (no critical ones)
58 *      - vector offset must be on 256 Byte boundary.
59 */
60        .global ppc_exc_min_prolog_auto
61ppc_exc_min_prolog_auto:
62        stwu    r1, -EXCEPTION_FRAME_END(r1)
63        stw     VECTOR_REGISTER, VECTOR_OFFSET(r1)
64        mflr    VECTOR_REGISTER
65        bla     wrap_auto
66
67        .global ppc_exc_tgpr_clr_prolog_size
68ppc_exc_tgpr_clr_prolog_size = . - ppc_exc_tgpr_clr_prolog
69
70/**
71 * @brief Use vector offsets with 16 byte boundaries.
72 *
73 * @see ppc_exc_min_prolog_auto();
74 */
75        .global ppc_exc_min_prolog_auto_packed
76ppc_exc_min_prolog_auto_packed:
77        stwu    r1, -EXCEPTION_FRAME_END(r1)
78        stw     VECTOR_REGISTER, VECTOR_OFFSET(r1)
79        mflr    VECTOR_REGISTER
80        bla     wrap_auto_packed
81
82/*
83 * Automatic vector, asynchronous exception; however,
84 * automatic vector calculation is less efficient than
85 * using an explicit vector in a minimal prolog snippet.
86 * The latter method is preferable since there usually
87 * are few asynchronous exceptions.
88 *
89 * For generic exceptions (which are the bulk) using
90 * the 'auto' prologue is OK since performance is not
91 * really an issue.
92 */
93        .global ppc_exc_min_prolog_auto_async
94ppc_exc_min_prolog_auto_async:
95        stw     r1, ppc_exc_lock_std@sdarel(r13)
96        stw     VECTOR_REGISTER, ppc_exc_vector_register_std@sdarel(r13)
97        mflr    VECTOR_REGISTER
98        bla     wrap_auto_async
99
100/******************************************************/
101/*  WRAPPERS                                          */
102/******************************************************/
103
104        /* Tag start and end of the wrappers.
105         * If exceptions are installed farther removed
106         * from the text area than 32M then the wrappers
107         * must be moved to an area that is reachable
108         * from where the prologues reside. Branches into
109         * C-code are far.
110         */
111
112        .global __ppc_exc_wrappers_start
113__ppc_exc_wrappers_start = .
114
115        /* Expand wrappers for different exception flavors */
116
117        /* Standard/classic powerpc */
118        WRAP    _FLVR=std _PRI=std _SRR0=srr0 _SRR1=srr1 _RFI=rfi
119
120        /* ppc405 has a critical exception using srr2/srr3 */
121        WRAP    _FLVR=p405_crit _PRI=crit _SRR0=srr2 _SRR1=srr3 _RFI=rfci
122
123        /* bookE has critical exception using csrr0 cssr1 */
124        WRAP    _FLVR=bookE_crit _PRI=crit _SRR0=csrr0 _SRR1=csrr1 _RFI=rfci
125
126        /* e500 has machine-check exception using mcsrr0 mcssr1 */
127        WRAP    _FLVR=e500_mchk _PRI=mchk _SRR0=mcsrr0 _SRR1=mcsrr1 _RFI=rfmci
128
129        /* LR holds vector, VECTOR_REGISTER holds orig. LR */
130wrap_auto:
131        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
132
133        /* Find address where we jumped from */
134        mflr    FRAME_REGISTER
135
136        /* Restore LR */
137        mtlr    VECTOR_REGISTER
138
139        /* Compute vector into R3 */
140        rlwinm  VECTOR_REGISTER, FRAME_REGISTER, 24, 26, 31
141
142        /*
143         * We're now in almost the same state as if called by
144         * min_prolog_std but we must skip saving FRAME_REGISTER
145         * since that's done already
146         */
147        b       wrap_no_save_frame_register_std
148
149        /* See: wrap_auto */
150wrap_auto_packed:
151        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
152        mflr    FRAME_REGISTER
153        mtlr    VECTOR_REGISTER
154        rlwinm  VECTOR_REGISTER, FRAME_REGISTER, 28, 26, 31
155        b       wrap_no_save_frame_register_std
156
157wrap_auto_async:
158        stwu    r1, -EXCEPTION_FRAME_END(r1)
159        stw     FRAME_REGISTER, FRAME_OFFSET(r1)
160        /* find address where we jumped from */
161        mflr    FRAME_REGISTER
162        /* restore LR     */
163        mtlr    VECTOR_REGISTER
164        /* set upper bits to indicate that non-volatile
165         * registers should not be saved/restored.
166         */
167        li      VECTOR_REGISTER, 0xffff8000
168        /* compute vector into R3 */
169        rlwimi  VECTOR_REGISTER, FRAME_REGISTER, 24, 26, 31
170        /* we're now in almost the same state as if called by
171         * min_prolog_std but we must skip saving FRAME_REGISTER
172         * since that's done already
173         */
174        b       wrap_no_save_frame_register_std
175
176        .global __ppc_exc_wrappers_end
177__ppc_exc_wrappers_end = .
Note: See TracBrowser for help on using the repository browser.