source: trunk/libs/newlib/src/libgloss/or1k/exceptions-asm.S @ 684

Last change on this file since 684 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 6.9 KB
Line 
1/* exceptions-asm.S -- exception handling for OpenRISC 1000.
2 *
3 * Copyright (c) 2011, 2014 Authors
4 *
5 * Contributor Julius Baxter <juliusbaxter@gmail.com>
6 * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de>
7 *
8 * The authors hereby grant permission to use, copy, modify, distribute,
9 * and license this software and its documentation for any purpose, provided
10 * that existing copyright notices are retained in all copies and that this
11 * notice is included verbatim in any distributions. No written agreement,
12 * license, or royalty fee is required for any of the authorized uses.
13 * Modifications to this software may be copyrighted by their authors
14 * and need not follow the licensing terms described here, provided that
15 * the new terms are clearly indicated on the first page of each file where
16 * they apply.
17 */
18
19#include "include/or1k-asm.h"
20#include "include/or1k-sprs.h"
21
22/* -------------------------------------------------------------------------- */
23/*!Generic exception handler function
24                                                                              */
25/* -------------------------------------------------------------------------- */
26// Warning - this must be the same as specified in crt0.S
27#define EXCEPTION_STACK_SIZE 136
28
29        .extern _or1k_exception_handler_table
30        .extern _or1k_exception_level
31
32/* -------------------------------------------------------------------------- */
33/*!Function to call appropriate exception handler
34                                                                              */
35/* -------------------------------------------------------------------------- */
36        .section .text
37        .global _or1k_exception_handler
38        .type   _or1k_exception_handler,@function
39
40        /*
41        r3 = address of exception vector
42        r4 = address where exception occurred
43        */
44
45#define GPR_BUF_OFFSET(x) (x << 2)
46
47_or1k_exception_handler:
48        /* Store remainder of state (r3,r4 stored in vector entry)*/
49        l.sw    GPR_BUF_OFFSET(2)(r1),r2
50        l.sw    GPR_BUF_OFFSET(5)(r1),r5
51        l.sw    GPR_BUF_OFFSET(6)(r1),r6
52        l.sw    GPR_BUF_OFFSET(7)(r1),r7
53        l.sw    GPR_BUF_OFFSET(8)(r1),r8
54        l.sw    GPR_BUF_OFFSET(9)(r1),r9
55        l.sw    GPR_BUF_OFFSET(10)(r1),r10
56        l.sw    GPR_BUF_OFFSET(11)(r1),r11
57        l.sw    GPR_BUF_OFFSET(12)(r1),r12
58        l.sw    GPR_BUF_OFFSET(13)(r1),r13
59        l.sw    GPR_BUF_OFFSET(14)(r1),r14
60        l.sw    GPR_BUF_OFFSET(15)(r1),r15
61        l.sw    GPR_BUF_OFFSET(16)(r1),r16
62        l.sw    GPR_BUF_OFFSET(17)(r1),r17
63        l.sw    GPR_BUF_OFFSET(18)(r1),r18
64        l.sw    GPR_BUF_OFFSET(19)(r1),r19
65        l.sw    GPR_BUF_OFFSET(20)(r1),r20
66        l.sw    GPR_BUF_OFFSET(21)(r1),r21
67        l.sw    GPR_BUF_OFFSET(22)(r1),r22
68        l.sw    GPR_BUF_OFFSET(23)(r1),r23
69        l.sw    GPR_BUF_OFFSET(24)(r1),r24
70        l.sw    GPR_BUF_OFFSET(25)(r1),r25
71        l.sw    GPR_BUF_OFFSET(26)(r1),r26
72        l.sw    GPR_BUF_OFFSET(27)(r1),r27
73        l.sw    GPR_BUF_OFFSET(28)(r1),r28
74        l.sw    GPR_BUF_OFFSET(29)(r1),r29
75        l.sw    GPR_BUF_OFFSET(30)(r1),r30
76        l.sw    GPR_BUF_OFFSET(31)(r1),r31
77        l.mfspr r14,r0,OR1K_SPR_SYS_EPCR_BASE
78        l.sw    0x80(r1),r14
79        l.mfspr r14,r0,OR1K_SPR_SYS_ESR_BASE
80        l.sw    0x84(r1),r14
81
82        /* Replace impure pointer for exception */
83        l.movhi r20,hi(_or1k_exception_impure_ptr)
84        l.ori   r20,r20,lo(_or1k_exception_impure_ptr)
85#ifdef __OR1K_MULTICORE__
86        l.lwz   r20,0(r20)
87        l.mfspr r22,r0,OR1K_SPR_SYS_COREID_ADDR
88        l.slli  r22,r22,2
89        l.add   r20,r20,r22
90#endif
91        l.lwz   r20,0(r20)
92
93        l.movhi r21,hi(_or1k_current_impure_ptr)
94        l.ori   r21,r21,lo(_or1k_current_impure_ptr)
95#ifdef __OR1K_MULTICORE__
96        l.lwz   r21,0(r21)
97        l.add   r21,r21,r22
98#endif
99        l.sw    0(r21),r20
100
101        /* Determine offset in table of exception handler using r3*/
102        l.andi  r13,r3,0xff00
103        l.srli  r13,r13,6
104        /* Substract 2 words, as we have no vector at 0 and no reset handler */
105        l.addi  r13,r13,-8
106        /* r13 now contains offset in or1k_exception_handler_table for
107           function
108        */
109        /* Get or1k_exception_handler_table address */
110        l.movhi r14,hi(_or1k_exception_handler_table)
111        l.ori   r14,r14,lo(_or1k_exception_handler_table)
112#ifdef __OR1K_MULTICORE__
113        /* Read the address of the array of cores */
114        /* r14 = (*or1k_exception_handler_table)  */
115        l.lwz   r14,0(r14)
116        /* Generate core offset in array (off = coreid*30*4 = coreid*120) */
117        /* r15 = coreid */
118        l.mfspr r15,r0,OR1K_SPR_SYS_COREID_ADDR
119        /* r16 = coreid * 128 */
120        l.slli  r16,r15,7
121        /* r15 = coreid * 8 */
122        l.slli  r15,r15,3
123        /* r15 = coreid*128 - coreid*8 = coreid*120 = off */
124        l.sub   r15,r16,r15
125        /* r14 = (*or1k_exception_handler_table)[coreid] =  r14 + off */
126        l.add   r14,r14,r15
127#endif
128        /* r14 now contains base of exception handler table */
129        /* add offset of exception vector */
130        l.add   r14,r14,r13
131        /* load handler address from table */
132        l.lwz   r13, 0(r14)
133
134        /* Check to see if this handler has been set yet */
135        l.sfne  r13,r0
136        OR1K_DELAYED_NOP(OR1K_INST(l.bnf exception_exit))
137
138        /* Call exception handler, copy EPCR to r3 */
139        OR1K_DELAYED(
140                OR1K_INST(l.or   r3,r4,r4),
141                OR1K_INST(l.jalr r13)
142        )
143
144        /* Restore impure pointer */
145        l.movhi r20,hi(_or1k_impure_ptr)
146        l.ori   r20,r20,lo(_or1k_impure_ptr)
147#ifdef __OR1K_MULTICORE__
148        l.lwz   r20,0(r20)
149        l.mfspr r22,r0,OR1K_SPR_SYS_COREID_ADDR
150        l.slli  r22,r22,2
151        l.add   r20,r20,r22
152#endif
153        l.lwz   r20,0(r20)
154
155        l.movhi r21,hi(_or1k_current_impure_ptr)
156        l.ori   r21,r21,lo(_or1k_current_impure_ptr)
157#ifdef __OR1K_MULTICORE__
158        l.lwz   r21,0(r21)
159        l.add   r21,r21,r22
160#endif
161        l.sw    0(r21),r20
162
163        /* Decrement the exception nesting level */
164        // Load the exception level entry
165        l.movhi r2,hi(_or1k_exception_level)
166        l.ori   r2,r2,lo(_or1k_exception_level)
167#ifdef __OR1K_MULTICORE__
168        // In multicore this is the pointer to an array
169        // Load pointer value
170        l.lwz   r2,0(r2)
171        // Add word offset of this core's nesting level
172        l.add   r2,r2,r22
173#endif
174        // Load the nesting level entry
175        l.lwz   r3,0(r2)
176        // Decrement nesting level
177        l.addi  r3,r3,-1
178        // Store back the nesting level
179        l.sw    0(r2),r3
180
181        /* Restore state */
182        l.lwz   r2,0x80(r1)
183        l.mtspr r0,r2,OR1K_SPR_SYS_EPCR_BASE
184
185        l.lwz   r2,0x84(r1)
186        l.mtspr r0,r2,OR1K_SPR_SYS_ESR_BASE
187
188        l.lwz   r2,GPR_BUF_OFFSET(2)(r1)
189        l.lwz   r3,GPR_BUF_OFFSET(3)(r1)
190        l.lwz   r4,GPR_BUF_OFFSET(4)(r1)
191        l.lwz   r5,GPR_BUF_OFFSET(5)(r1)
192        l.lwz   r6,GPR_BUF_OFFSET(6)(r1)
193        l.lwz   r7,GPR_BUF_OFFSET(7)(r1)
194        l.lwz   r8,GPR_BUF_OFFSET(8)(r1)
195        l.lwz   r9,GPR_BUF_OFFSET(9)(r1)
196        l.lwz   r10,GPR_BUF_OFFSET(10)(r1)
197        l.lwz   r11,GPR_BUF_OFFSET(11)(r1)
198        l.lwz   r12,GPR_BUF_OFFSET(12)(r1)
199        l.lwz   r13,GPR_BUF_OFFSET(13)(r1)
200        l.lwz   r14,GPR_BUF_OFFSET(14)(r1)
201        l.lwz   r15,GPR_BUF_OFFSET(15)(r1)
202        l.lwz   r16,GPR_BUF_OFFSET(16)(r1)
203        l.lwz   r17,GPR_BUF_OFFSET(17)(r1)
204        l.lwz   r18,GPR_BUF_OFFSET(18)(r1)
205        l.lwz   r19,GPR_BUF_OFFSET(19)(r1)
206        l.lwz   r20,GPR_BUF_OFFSET(20)(r1)
207        l.lwz   r21,GPR_BUF_OFFSET(21)(r1)
208        l.lwz   r22,GPR_BUF_OFFSET(22)(r1)
209        l.lwz   r23,GPR_BUF_OFFSET(23)(r1)
210        l.lwz   r24,GPR_BUF_OFFSET(24)(r1)
211        l.lwz   r25,GPR_BUF_OFFSET(25)(r1)
212        l.lwz   r26,GPR_BUF_OFFSET(26)(r1)
213        l.lwz   r27,GPR_BUF_OFFSET(27)(r1)
214        l.lwz   r28,GPR_BUF_OFFSET(28)(r1)
215        l.lwz   r29,GPR_BUF_OFFSET(29)(r1)
216        l.lwz   r30,GPR_BUF_OFFSET(30)(r1)
217        l.lwz   r31,GPR_BUF_OFFSET(31)(r1)
218
219        // Restore original stack
220        l.lwz   r1,GPR_BUF_OFFSET(1)(r1)
221
222        l.rfe
223        l.nop
224
225exception_exit:
226        /* Exception handler not set, exit */
227        OR1K_DELAYED(
228                OR1K_INST(l.or  r3,r4,r4),
229                OR1K_INST(l.jal exit)
230        )
Note: See TracBrowser for help on using the repository browser.