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

4.115
Last change on this file since 10df690 was 10df690, checked in by Sebastian Huber <sebastian.huber@…>, on 01/31/11 at 16:12:24

2011-01-31 Sebastian Huber <sebastian.huber@…>

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