1 /*-------------------------------------------------------------
3 exception_handler.S -- PPC exception handling support
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any
11 damages arising from the use of this software.
13 Permission is granted to anyone to use this software for any
14 purpose, including commercial applications, and to alter it and
15 redistribute it freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you
18 must not claim that you wrote the original software. If you use
19 this software in a product, an acknowledgment in the product
20 documentation would be appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and
23 must not be misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source
28 -------------------------------------------------------------*/
33 #define EXCEPTION_PROLOG \
35 stw r0,GQR0_OFFSET(sp); \
37 stw r0,GQR1_OFFSET(sp); \
39 stw r0,GQR2_OFFSET(sp); \
41 stw r0,GQR3_OFFSET(sp); \
43 stw r0,GQR4_OFFSET(sp); \
45 stw r0,GQR5_OFFSET(sp); \
47 stw r0,GQR6_OFFSET(sp); \
49 stw r0,GQR7_OFFSET(sp); \
50 stw r6,GPR6_OFFSET(sp); \
51 stw r7,GPR7_OFFSET(sp); \
52 stw r8,GPR8_OFFSET(sp); \
53 stw r9,GPR9_OFFSET(sp); \
54 stw r10,GPR10_OFFSET(sp); \
55 stw r11,GPR11_OFFSET(sp); \
56 stw r12,GPR12_OFFSET(sp); \
57 stw r13,GPR13_OFFSET(sp); \
58 stw r14,GPR14_OFFSET(sp); \
59 stw r15,GPR15_OFFSET(sp);
61 #define EXCEPTION_EPILOG \
62 lwz r4,GQR0_OFFSET(sp); \
64 lwz r4,GQR1_OFFSET(sp); \
66 lwz r4,GQR2_OFFSET(sp); \
68 lwz r4,GQR3_OFFSET(sp); \
70 lwz r4,GQR4_OFFSET(sp); \
72 lwz r4,GQR5_OFFSET(sp); \
74 lwz r4,GQR6_OFFSET(sp); \
76 lwz r4,GQR7_OFFSET(sp); \
78 lwz r15,GPR15_OFFSET(sp); \
79 lwz r14,GPR14_OFFSET(sp); \
80 lwz r13,GPR13_OFFSET(sp); \
81 lwz r12,GPR12_OFFSET(sp); \
82 lwz r11,GPR11_OFFSET(sp); \
83 lwz r10,GPR10_OFFSET(sp); \
84 lwz r9,GPR9_OFFSET(sp); \
85 lwz r8,GPR8_OFFSET(sp); \
86 lwz r7,GPR7_OFFSET(sp); \
87 lwz r6,GPR6_OFFSET(sp); \
88 lwz r5,GPR5_OFFSET(sp)
91 .globl exceptionhandler_start,exceptionhandler_end,exceptionhandler_patch
92 exceptionhandler_start:
94 clrlwi r4,sp,2 //make sp physical and move new value to r4
95 stwu r4,-EXCEPTION_FRAME_END(r4)
96 stw r0,GPR0_OFFSET(r4)
97 stw sp,GPR1_OFFSET(r4)
98 stw toc,GPR2_OFFSET(r4)
99 stw r3,GPR3_OFFSET(r4)
101 stw r3,GPR4_OFFSET(r4)
102 stw r5,GPR5_OFFSET(r4)
108 stw r3,CTR_OFFSET(r4)
110 stw r3,XER_OFFSET(r4)
112 stw r3,MSR_OFFSET(r4)
114 stw r3,DAR_OFFSET(r4)
116 stw r3,SRR0_OFFSET(r4)
118 stw r3,SRR1_OFFSET(r4)
122 ori r3,r3,MSR_IR|MSR_DR|MSR_FP
125 exceptionhandler_patch:
127 stw r3,EXCEPTION_NUMBER(r4)
129 rlwinm. r5,r5,0,30,30
130 lis r5,default_exceptionhandler@h
131 ori r5,r5,default_exceptionhandler@l
133 lis r5,_exceptionhandlertable@h
134 ori r5,r5,_exceptionhandlertable@l
141 exceptionhandler_end:
144 .extern c_default_exceptionhandler
145 .globl default_exceptionhandler
146 default_exceptionhandler:
147 stwu sp,-EXCEPTION_FRAME_END(sp) //now we're able to adjust the stackpointer with it's cached address
151 stmw r16,GPR16_OFFSET(sp)
154 bl c_default_exceptionhandler
160 lwz r4,CTR_OFFSET(sp)
162 lwz r4,XER_OFFSET(sp)
167 lmw r16,GPR16_OFFSET(sp)
174 lwz toc,GPR2_OFFSET(sp)
175 lwz r0,GPR0_OFFSET(sp)
177 lwz r4,SRR0_OFFSET(sp)
179 lwz r4,SRR1_OFFSET(sp)
182 lwz r4,GPR4_OFFSET(sp)
183 lwz r3,GPR3_OFFSET(sp)
184 addi sp,sp,EXCEPTION_FRAME_END
187 .extern _cpu_context_save_fp,_cpu_context_restore_fp
188 .globl fpu_exceptionhandler
189 fpu_exceptionhandler:
190 stwu sp,-EXCEPTION_FRAME_END(sp) //now we're able to adjust the stackpointer with it's cached address
194 bl __thread_dispatch_fp
200 lwz r4,CTR_OFFSET(sp)
202 lwz r4,XER_OFFSET(sp)
212 lwz toc,GPR2_OFFSET(sp)
213 lwz r0,GPR0_OFFSET(sp)
215 lwz r4,SRR0_OFFSET(sp)
217 lwz r4,SRR1_OFFSET(sp)
221 lwz r4,GPR4_OFFSET(sp)
222 lwz r3,GPR3_OFFSET(sp)
223 addi sp,sp,EXCEPTION_FRAME_END
226 .global systemcallhandler_start,systemcallhandler_end
227 systemcallhandler_start:
239 systemcallhandler_end: