tinysmb devoptab fix - allow fread sizes > 7236
[libogc.git] / libogc / exception_handler.S
blob772c97d3e982b4b54eed20dfac189ce5444f6a70
1 /*-------------------------------------------------------------
3 exception_handler.S -- PPC exception handling support
5 Copyright (C) 2004
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
26 distribution.
28 -------------------------------------------------------------*/
31 #include <asm.h>
33 #define EXCEPTION_PROLOG                        \
34         mfspr    r0,912;                                \
35         stw      r0,GQR0_OFFSET(sp);    \
36         mfspr    r0,913;                                \
37         stw      r0,GQR1_OFFSET(sp);    \
38         mfspr    r0,914;                                \
39         stw      r0,GQR2_OFFSET(sp);    \
40         mfspr    r0,915;                                \
41         stw      r0,GQR3_OFFSET(sp);    \
42         mfspr    r0,916;                                \
43         stw      r0,GQR4_OFFSET(sp);    \
44         mfspr    r0,917;                                \
45         stw      r0,GQR5_OFFSET(sp);    \
46         mfspr    r0,918;                                \
47         stw      r0,GQR6_OFFSET(sp);    \
48         mfspr    r0,919;                                \
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);
60         
61 #define EXCEPTION_EPILOG                        \
62         lwz             r4,GQR0_OFFSET(sp);             \
63         mtspr   912,r4;                                 \
64         lwz             r4,GQR1_OFFSET(sp);             \
65         mtspr   913,r4;                                 \
66         lwz             r4,GQR2_OFFSET(sp);             \
67         mtspr   914,r4;                                 \
68         lwz             r4,GQR3_OFFSET(sp);             \
69         mtspr   915,r4;                                 \
70         lwz             r4,GQR4_OFFSET(sp);             \
71         mtspr   916,r4;                                 \
72         lwz             r4,GQR5_OFFSET(sp);             \
73         mtspr   917,r4;                                 \
74         lwz             r4,GQR6_OFFSET(sp);             \
75         mtspr   918,r4;                                 \
76         lwz             r4,GQR7_OFFSET(sp);             \
77         mtspr   919,r4;                                 \
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:
93         mtspr           SPRG3,r4
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)
100         mfspr           r3,SPRG3
101         stw                     r3,GPR4_OFFSET(r4)
102         stw                     r5,GPR5_OFFSET(r4)
103         mfcr            r3
104         stw                     r3,CR_OFFSET(r4)
105         mflr            r3
106         stw                     r3,LR_OFFSET(r4)
107         mfctr           r3
108         stw                     r3,CTR_OFFSET(r4)
109         mfxer           r3
110         stw                     r3,XER_OFFSET(r4)
111         mfmsr           r3
112         stw                     r3,MSR_OFFSET(r4)
113         mfdar           r3
114         stw                     r3,DAR_OFFSET(r4)
115         mfsrr0          r3
116         stw                     r3,SRR0_OFFSET(r4)
117         mfsrr1          r3
118         stw                     r3,SRR1_OFFSET(r4)
119         mr                      r5,r3
120         nop             
121         mfmsr           r3
122         ori                     r3,r3,MSR_IR|MSR_DR|MSR_FP
123         mtsrr1          r3
124         
125 exceptionhandler_patch:
126         li                      r3,0
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
132         beq                     1f
133         lis                     r5,_exceptionhandlertable@h
134         ori                     r5,r5,_exceptionhandlertable@l
135         clrlwi          r5,r5,2
136         clrlslwi        r3,r3,24,2
137         lwzx            r5,r3,r5
138 1:      
139         mtsrr0          r5
140         rfi
141 exceptionhandler_end:
142         nop
143         
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
149         EXCEPTION_PROLOG
150         
151         stmw            r16,GPR16_OFFSET(sp)
153         addi            r3,sp,0x08
154         bl                      c_default_exceptionhandler
156         lwz                     r4,CR_OFFSET(sp)
157         mtcr            r4
158         lwz                     r4,LR_OFFSET(sp)
159         mtlr            r4
160         lwz                     r4,CTR_OFFSET(sp)
161         mtctr           r4
162         lwz                     r4,XER_OFFSET(sp)
163         mtxer           r4
165         EXCEPTION_EPILOG
167         lmw                     r16,GPR16_OFFSET(sp)
169         mfmsr           r4
170         rlwinm          r4,r4,0,19,17
171         mtmsr           r4
172         isync
174         lwz                     toc,GPR2_OFFSET(sp)
175         lwz                     r0,GPR0_OFFSET(sp)
177         lwz                     r4,SRR0_OFFSET(sp)
178         mtsrr0          r4
179         lwz                     r4,SRR1_OFFSET(sp)
180         mtsrr1          r4
182         lwz                     r4,GPR4_OFFSET(sp)
183         lwz                     r3,GPR3_OFFSET(sp)
184         addi            sp,sp,EXCEPTION_FRAME_END
185         rfi
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
192         EXCEPTION_PROLOG
194         bl                      __thread_dispatch_fp
196         lwz                     r4,CR_OFFSET(sp)
197         mtcr            r4
198         lwz                     r4,LR_OFFSET(sp)
199         mtlr            r4
200         lwz                     r4,CTR_OFFSET(sp)
201         mtctr           r4
202         lwz                     r4,XER_OFFSET(sp)
203         mtxer           r4
205         EXCEPTION_EPILOG
207         mfmsr           r4
208         rlwinm          r4,r4,0,19,17
209         mtmsr           r4
210         isync
212         lwz                     toc,GPR2_OFFSET(sp)
213         lwz                     r0,GPR0_OFFSET(sp)
215         lwz                     r4,SRR0_OFFSET(sp)
216         mtsrr0          r4
217         lwz                     r4,SRR1_OFFSET(sp)
218         ori                     r4,r4,MSR_FP
219         mtsrr1          r4
221         lwz                     r4,GPR4_OFFSET(sp)
222         lwz                     r3,GPR3_OFFSET(sp)
223         addi            sp,sp,EXCEPTION_FRAME_END
224         rfi
226         .global systemcallhandler_start,systemcallhandler_end
227 systemcallhandler_start:
228         mtspr   SPRG2,r9
229         mtspr   SPRG3,r10
230         mfspr   r9,HID0
231         ori             r10,r9,0x0008
232         mtspr   HID0,r10
233         isync
234         sync
235         mtspr   HID0,r9
236         mfspr   r9,SPRG2
237         mfspr   r10,SPRG3
238         rfi
239 systemcallhandler_end:
240         nop