source: mainline/arch/mips32/src/start.S@ 41d33ac

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 41d33ac was 7ca8b36b, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Fixed mips bug fith TLS register not being properly saved on syscall context
switch.
Reverted SYS_IO, so that it could be used on machines without fb.

  • Property mode set to 100644
File size: 7.2 KB
Line 
1#
2# Copyright (C) 2003-2004 Jakub Jermar
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# - Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14# - The name of the author may not be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29#include <arch/asm/regname.h>
30#include <arch/mm/page.h>
31#include <arch/asm/boot.h>
32#include <arch/context_offset.h>
33
34.text
35
36.set noat
37.set noreorder
38.set nomacro
39
40.global kernel_image_start
41.global tlb_refill_entry
42.global cache_error_entry
43.global exception_entry
44.global userspace_asm
45
46# Which status bits should are thread-local
47#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
48
49# Save registers to space defined by \r
50# We will change status: Disable ERL,EXL,UM,IE
51# These changes will be automatically reversed in REGISTER_LOAD
52# SP is NOT saved as part of these registers
53.macro REGISTERS_STORE_AND_EXC_RESET r
54 sw $at,EOFFSET_AT(\r)
55 sw $v0,EOFFSET_V0(\r)
56 sw $v1,EOFFSET_V1(\r)
57 sw $a0,EOFFSET_A0(\r)
58 sw $a1,EOFFSET_A1(\r)
59 sw $a2,EOFFSET_A2(\r)
60 sw $a3,EOFFSET_A3(\r)
61 sw $t0,EOFFSET_T0(\r)
62 sw $t1,EOFFSET_T1(\r)
63 sw $t2,EOFFSET_T2(\r)
64 sw $t3,EOFFSET_T3(\r)
65 sw $t4,EOFFSET_T4(\r)
66 sw $t5,EOFFSET_T5(\r)
67 sw $t6,EOFFSET_T6(\r)
68 sw $t7,EOFFSET_T7(\r)
69 sw $t8,EOFFSET_T8(\r)
70 sw $t9,EOFFSET_T9(\r)
71
72 mflo $at
73 sw $at, EOFFSET_LO(\r)
74 mfhi $at
75 sw $at, EOFFSET_HI(\r)
76
77#ifdef CONFIG_DEBUG_ALLREGS
78 sw $s0,EOFFSET_S0(\r)
79 sw $s1,EOFFSET_S1(\r)
80 sw $s2,EOFFSET_S2(\r)
81 sw $s3,EOFFSET_S3(\r)
82 sw $s4,EOFFSET_S4(\r)
83 sw $s5,EOFFSET_S5(\r)
84 sw $s6,EOFFSET_S6(\r)
85 sw $s7,EOFFSET_S7(\r)
86 sw $s8,EOFFSET_S8(\r)
87#endif
88
89 sw $gp,EOFFSET_GP(\r)
90 sw $ra,EOFFSET_RA(\r)
91 sw $k1,EOFFSET_K1(\r)
92
93 mfc0 $t0, $status
94 mfc0 $t1, $epc
95
96 and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
97 li $t3, ~(0x1f)
98 and $t0, $t0, $t3 # Clear KSU,EXL,ERL,IE
99
100 sw $t2,EOFFSET_STATUS(\r)
101 sw $t1,EOFFSET_EPC(\r)
102 mtc0 $t0, $status
103.endm
104
105.macro REGISTERS_LOAD r
106 # Update only UM,EXR,IE from status, the rest
107 # is controlled by OS and not bound to task
108 mfc0 $t0, $status
109 lw $t1,EOFFSET_STATUS(\r)
110
111 li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
112 and $t0, $t0, $t2
113
114 or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
115 mtc0 $t0, $status
116
117 lw $v0,EOFFSET_V0(\r)
118 lw $v1,EOFFSET_V1(\r)
119 lw $a0,EOFFSET_A0(\r)
120 lw $a1,EOFFSET_A1(\r)
121 lw $a2,EOFFSET_A2(\r)
122 lw $a3,EOFFSET_A3(\r)
123 lw $t0,EOFFSET_T0(\r)
124 lw $t1,EOFFSET_T1(\r)
125 lw $t2,EOFFSET_T2(\r)
126 lw $t3,EOFFSET_T3(\r)
127 lw $t4,EOFFSET_T4(\r)
128 lw $t5,EOFFSET_T5(\r)
129 lw $t6,EOFFSET_T6(\r)
130 lw $t7,EOFFSET_T7(\r)
131 lw $t8,EOFFSET_T8(\r)
132 lw $t9,EOFFSET_T9(\r)
133
134#ifdef CONFIG_DEBUG_ALLREGS
135 lw $s0,EOFFSET_S0(\r)
136 lw $s1,EOFFSET_S1(\r)
137 lw $s2,EOFFSET_S2(\r)
138 lw $s3,EOFFSET_S3(\r)
139 lw $s4,EOFFSET_S4(\r)
140 lw $s5,EOFFSET_S5(\r)
141 lw $s6,EOFFSET_S6(\r)
142 lw $s7,EOFFSET_S7(\r)
143 lw $s8,EOFFSET_S8(\r)
144#endif
145 lw $gp,EOFFSET_GP(\r)
146 lw $ra,EOFFSET_RA(\r)
147 lw $k1,EOFFSET_K1(\r)
148
149 lw $at,EOFFSET_LO(\r)
150 mtlo $at
151 lw $at,EOFFSET_HI(\r)
152 mthi $at
153
154 lw $at,EOFFSET_EPC(\r)
155 mtc0 $at, $epc
156
157 lw $at,EOFFSET_AT(\r)
158 lw $sp,EOFFSET_SP(\r)
159.endm
160
161# Move kernel stack pointer address to register K0
162# - if we are in user mode, load the appropriate stack
163# address
164.macro KERNEL_STACK_TO_K0
165 # If we are in user mode
166 mfc0 $k0, $status
167 andi $k0, 0x10
168
169 beq $k0, $0, 1f
170 add $k0, $sp, 0
171
172 # Move $k0 pointer to kernel stack
173 lui $k0, %hi(supervisor_sp)
174 ori $k0, $k0, %lo(supervisor_sp)
175 # Move $k0 (superveisor_sp)
176 lw $k0, 0($k0)
1771:
178.endm
179
180.org 0x0
181kernel_image_start:
182 /* Load temporary stack */
183 lui $sp, %hi(end_stack)
184 ori $sp, $sp, %lo(end_stack)
185
186 /* Not sure about this, but might be needed for PIC code???? */
187 lui $gp, 0x8000
188
189 jal arch_pre_main
190 nop
191
192 j main_bsp
193 nop
194
195 .space TEMP_STACK_SIZE
196end_stack:
197
198tlb_refill_entry:
199 j tlb_refill_handler
200 nop
201
202cache_error_entry:
203 j cache_error_handler
204 nop
205
206exception_entry:
207 j exception_handler
208 nop
209
210
211
212exception_handler:
213 KERNEL_STACK_TO_K0
214 sub $k0, REGISTER_SPACE
215 sw $sp,EOFFSET_SP($k0)
216 move $sp, $k0
217
218 mfc0 $k0, $cause
219
220 sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
221 andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
222 sub $k0, 8 # 8=SYSCALL
223
224 beqz $k0, syscall_shortcut
225 add $k0, 8 # Revert $k0 back to correct exc number
226
227 REGISTERS_STORE_AND_EXC_RESET $sp
228
229 move $a1, $sp
230 jal exc_dispatch # exc_dispatch(excno, register_space)
231 move $a0, $k0
232
233 REGISTERS_LOAD $sp
234 # The $sp is automatically restored to former value
235 eret
236
237# it seems that mips reserves some space on stack for varfuncs???
238#define SS_ARG4 16
239#define SS_SP EOFFSET_SP
240#define SS_STATUS EOFFSET_STATUS
241#define SS_EPC EOFFSET_EPC
242#define SS_K1 EOFFSET_K1
243syscall_shortcut:
244 # We have a lot of space on the stack, with free use
245 mfc0 $t1, $epc
246 mfc0 $t0, $status
247 sw $t1,SS_EPC($sp) # Save EPC
248 sw $k1,SS_K1($sp) # Save k1, which is not saved during context switch
249
250 and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
251 li $t3, ~(0x1f)
252 and $t0, $t0, $t3 # Clear KSU,EXL,ERL
253 ori $t0, $t0, 0x1 # Set IE
254
255 sw $t2,SS_STATUS($sp)
256 mtc0 $t0, $status
257
258 # CALL Syscall handler
259 jal syscall_handler
260 sw $v0, SS_ARG4($sp) # save v0 - arg4 to stack
261
262 # restore status
263 mfc0 $t0, $status
264 lw $t1,SS_STATUS($sp)
265
266 # Change back to EXL=1(from last exception), otherwise
267 # an interrupt could rewrite the CP0-EPC
268 li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
269 and $t0, $t0, $t2
270 or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
271 mtc0 $t0, $status
272
273 # restore epc+4
274 lw $t0,SS_EPC($sp)
275 lw $k1,SS_K1($sp)
276 addi $t0, $t0, 4
277 mtc0 $t0, $epc
278
279 lw $sp,SS_SP($sp) # restore sp
280
281 eret
282
283tlb_refill_handler:
284 KERNEL_STACK_TO_K0
285 sub $k0, REGISTER_SPACE
286 REGISTERS_STORE_AND_EXC_RESET $k0
287 sw $sp,EOFFSET_SP($k0)
288 add $sp, $k0, 0
289
290 jal tlb_refill /* tlb_refill(register_space) */
291 add $a0, $sp, 0
292
293 REGISTERS_LOAD $sp
294
295 eret
296
297cache_error_handler:
298 KERNEL_STACK_TO_K0
299 sub $k0, REGISTER_SPACE
300 REGISTERS_STORE_AND_EXC_RESET $k0
301 sw $sp,EOFFSET_SP($k0)
302 add $sp, $k0, 0
303
304 jal cache_error
305 nop
306
307 REGISTERS_LOAD $sp
308
309 eret
310
311userspace_asm:
312 add $sp, $a0, 0
313 add $v0, $a1, 0
314 add $t9, $a2, 0 # Set up correct entry into PIC code
315 eret
Note: See TracBrowser for help on using the repository browser.