Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sh/kernel/cpu/sh2a/entry.S
17305 views
1
/*
2
* arch/sh/kernel/cpu/sh2a/entry.S
3
*
4
* The SH-2A exception entry
5
*
6
* Copyright (C) 2008 Yoshinori Sato
7
* Based on arch/sh/kernel/cpu/sh2/entry.S
8
*
9
* This file is subject to the terms and conditions of the GNU General Public
10
* License. See the file "COPYING" in the main directory of this archive
11
* for more details.
12
*/
13
14
#include <linux/linkage.h>
15
#include <asm/asm-offsets.h>
16
#include <asm/thread_info.h>
17
#include <cpu/mmu_context.h>
18
#include <asm/unistd.h>
19
#include <asm/errno.h>
20
#include <asm/page.h>
21
22
/* Offsets to the stack */
23
OFF_R0 = 0 /* Return value. New ABI also arg4 */
24
OFF_R1 = 4 /* New ABI: arg5 */
25
OFF_R2 = 8 /* New ABI: arg6 */
26
OFF_R3 = 12 /* New ABI: syscall_nr */
27
OFF_R4 = 16 /* New ABI: arg0 */
28
OFF_R5 = 20 /* New ABI: arg1 */
29
OFF_R6 = 24 /* New ABI: arg2 */
30
OFF_R7 = 28 /* New ABI: arg3 */
31
OFF_SP = (15*4)
32
OFF_PC = (16*4)
33
OFF_SR = (16*4+2*4)
34
OFF_TRA = (16*4+6*4)
35
36
#include <asm/entry-macros.S>
37
38
ENTRY(exception_handler)
39
! stack
40
! r0 <- point sp
41
! r1
42
! pc
43
! sr
44
! r0 = temporary
45
! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
46
mov.l r2,@-sp
47
cli
48
mov.l $cpu_mode,r2
49
bld.b #6,@(0,r2) !previus SR.MD
50
bst.b #6,@(4*4,r15) !set cpu mode to SR.MD
51
bt 1f
52
! switch to kernel mode
53
bset.b #6,@(0,r2) !set SR.MD
54
mov.l $current_thread_info,r2
55
mov.l @r2,r2
56
mov #(THREAD_SIZE >> 8),r0
57
shll8 r0
58
add r2,r0 ! r0 = kernel stack tail
59
mov r15,r2 ! r2 = user stack top
60
mov r0,r15 ! switch kernel stack
61
mov.l r1,@-r15 ! TRA
62
sts.l macl, @-r15
63
sts.l mach, @-r15
64
stc.l gbr, @-r15
65
mov.l @(4*4,r2),r0
66
mov.l r0,@-r15 ! original SR
67
sts.l pr,@-r15
68
mov.l @(3*4,r2),r0
69
mov.l r0,@-r15 ! original PC
70
mov r2,r0
71
add #(3+2)*4,r0 ! rewind r0 - r3 + exception frame
72
lds r0,pr ! pr = original SP
73
movmu.l r3,@-r15 ! save regs
74
mov r2,r8 ! r8 = previus stack top
75
mov r1,r9 ! r9 = interrupt vector
76
! restore previous stack
77
mov.l @r8+,r2
78
mov.l @r8+,r0
79
mov.l @r8+,r1
80
bra 2f
81
movml.l r2,@-r15
82
1:
83
! in kernel exception
84
mov r15,r2
85
add #-((OFF_TRA + 4) - OFF_PC) + 5*4,r15
86
movmu.l r3,@-r15
87
mov r2,r8 ! r8 = previous stack top
88
mov r1,r9 ! r9 = interrupt vector
89
! restore exception frame & regs
90
mov.l @r8+,r2 ! old R2
91
mov.l @r8+,r0 ! old R0
92
mov.l @r8+,r1 ! old R1
93
mov.l @r8+,r10 ! old PC
94
mov.l @r8+,r11 ! old SR
95
movml.l r2,@-r15
96
mov.l r10,@(OFF_PC,r15)
97
mov.l r11,@(OFF_SR,r15)
98
mov.l r8,@(OFF_SP,r15) ! save old sp
99
mov r15,r8
100
add #OFF_TRA + 4,r8
101
mov.l r9,@-r8
102
sts.l macl,@-r8
103
sts.l mach,@-r8
104
stc.l gbr,@-r8
105
add #-4,r8
106
sts.l pr,@-r8
107
2:
108
! dispatch exception / interrupt
109
mov #64,r8
110
cmp/hs r8,r9
111
bt interrupt_entry ! vec >= 64 is interrupt
112
mov #32,r8
113
cmp/hs r8,r9
114
bt trap_entry ! 64 > vec >= 32 is trap
115
116
mov.l 4f,r8
117
mov r9,r4
118
shll2 r9
119
add r9,r8
120
mov.l @r8,r8 ! exception handler address
121
tst r8,r8
122
bf 3f
123
mov.l 8f,r8 ! unhandled exception
124
3:
125
mov.l 5f,r10
126
jmp @r8
127
lds r10,pr
128
129
interrupt_entry:
130
mov r9,r4
131
mov r15,r5
132
mov.l 7f,r8
133
mov.l 6f,r9
134
jmp @r8
135
lds r9,pr
136
137
.align 2
138
4: .long exception_handling_table
139
5: .long ret_from_exception
140
6: .long ret_from_irq
141
7: .long do_IRQ
142
8: .long exception_error
143
144
trap_entry:
145
mov #0x30,r8
146
cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
147
bt 1f
148
add #-0x10,r9 ! convert SH2 to SH3/4 ABI
149
1:
150
shll2 r9 ! TRA
151
bra system_call ! jump common systemcall entry
152
mov r9,r8
153
154
#if defined(CONFIG_SH_STANDARD_BIOS)
155
/* Unwind the stack and jmp to the debug entry */
156
ENTRY(sh_bios_handler)
157
mov r15,r0
158
add #(22-4)*4-4,r0
159
ldc.l @r0+,gbr
160
lds.l @r0+,mach
161
lds.l @r0+,macl
162
mov r15,r0
163
mov.l @(OFF_SP,r0),r1
164
mov.l @(OFF_SR,r2),r3
165
mov.l r3,@-r1
166
mov.l @(OFF_SP,r2),r3
167
mov.l r3,@-r1
168
mov r15,r0
169
add #(22-4)*4-8,r0
170
mov.l 1f,r2
171
mov.l @r2,r2
172
stc sr,r3
173
mov.l r2,@r0
174
mov.l r3,@(4,r0)
175
mov.l r1,@(8,r0)
176
movml.l @r15+,r14
177
add #8,r15
178
lds.l @r15+, pr
179
mov.l @r15+,r15
180
rte
181
nop
182
.align 2
183
1: .long gdb_vbr_vector
184
#endif /* CONFIG_SH_STANDARD_BIOS */
185
186
ENTRY(address_error_trap_handler)
187
mov r15,r4 ! regs
188
mov.l @(OFF_PC,r15),r6 ! pc
189
mov.l 1f,r0
190
jmp @r0
191
mov #0,r5 ! writeaccess is unknown
192
193
.align 2
194
1: .long do_address_error
195
196
restore_all:
197
stc sr,r0
198
or #0xf0,r0
199
ldc r0,sr ! all interrupt block (same BL = 1)
200
! restore special register
201
! overlap exception frame
202
mov r15,r0
203
add #17*4,r0
204
lds.l @r0+,pr
205
add #4,r0
206
ldc.l @r0+,gbr
207
lds.l @r0+,mach
208
lds.l @r0+,macl
209
mov r15,r0
210
mov.l $cpu_mode,r2
211
bld.b #6,@(OFF_SR,r15)
212
bst.b #6,@(0,r2) ! save CPU mode
213
mov.l @(OFF_SR,r0),r1
214
shll2 r1
215
shlr2 r1 ! clear MD bit
216
mov.l @(OFF_SP,r0),r2
217
add #-8,r2
218
mov.l r2,@(OFF_SP,r0) ! point exception frame top
219
mov.l r1,@(4,r2) ! set sr
220
mov.l @(OFF_PC,r0),r1
221
mov.l r1,@r2 ! set pc
222
get_current_thread_info r0, r1
223
mov.l $current_thread_info,r1
224
mov.l r0,@r1
225
movml.l @r15+,r14
226
mov.l @r15,r15
227
rte
228
nop
229
230
.align 2
231
$current_thread_info:
232
.long __current_thread_info
233
$cpu_mode:
234
.long __cpu_mode
235
236
! common exception handler
237
#include "../../entry-common.S"
238
239
.data
240
! cpu operation mode
241
! bit30 = MD (compatible SH3/4)
242
__cpu_mode:
243
.long 0x40000000
244
245
.section .bss
246
__current_thread_info:
247
.long 0
248
249
ENTRY(exception_handling_table)
250
.space 4*32
251
252