source: mainline/kernel/arch/mips32/src/start.S@ 0af7a09

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0af7a09 was 11675207, checked in by jermar <jermar@…>, 17 years ago

Move everything to kernel/.

  • Property mode set to 100644
File size: 7.5 KB
RevLine 
[a5d1331]1#
[178ec7b]2# Copyright (C) 2003-2004 Jakub Jermar
[f761f1eb]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
[e84439a]29#include <arch/asm/regname.h>
30#include <arch/mm/page.h>
31#include <arch/asm/boot.h>
[909c6e3]32#include <arch/context_offset.h>
[e84439a]33
[f761f1eb]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
[2bd4fdf]44.global userspace_asm
[f761f1eb]45
[1b109cb]46# Which status bits should are thread-local
47#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
48
[2bd4fdf]49# Save registers to space defined by \r
[1b109cb]50# We will change status: Disable ERL,EXL,UM,IE
51# These changes will be automatically reversed in REGISTER_LOAD
[741ade3f]52# SP is NOT saved as part of these registers
[1b109cb]53.macro REGISTERS_STORE_AND_EXC_RESET r
[e84439a]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)
[909c6e3]61 sw $t0,EOFFSET_T0(\r)
[e84439a]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)
[2bd4fdf]71
72 mflo $at
73 sw $at, EOFFSET_LO(\r)
74 mfhi $at
75 sw $at, EOFFSET_HI(\r)
76
[8d25b44]77#ifdef CONFIG_DEBUG_ALLREGS
[e84439a]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)
[8d25b44]86 sw $s8,EOFFSET_S8(\r)
87#endif
88
[e84439a]89 sw $gp,EOFFSET_GP(\r)
90 sw $ra,EOFFSET_RA(\r)
[741ade3f]91 sw $k1,EOFFSET_K1(\r)
[2bd4fdf]92
[1b109cb]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
[e84439a]103.endm
104
105.macro REGISTERS_LOAD r
[1b109cb]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
[e84439a]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)
[909c6e3]123 lw $t0,EOFFSET_T0(\r)
[e84439a]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)
[8d25b44]133
134#ifdef CONFIG_DEBUG_ALLREGS
[e84439a]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)
[8d25b44]144#endif
[e84439a]145 lw $gp,EOFFSET_GP(\r)
146 lw $ra,EOFFSET_RA(\r)
[741ade3f]147 lw $k1,EOFFSET_K1(\r)
[e84439a]148
[2bd4fdf]149 lw $at,EOFFSET_LO(\r)
150 mtlo $at
151 lw $at,EOFFSET_HI(\r)
152 mthi $at
153
[909c6e3]154 lw $at,EOFFSET_EPC(\r)
155 mtc0 $at, $epc
[2bd4fdf]156
157 lw $at,EOFFSET_AT(\r)
158 lw $sp,EOFFSET_SP(\r)
[e84439a]159.endm
160
[2bd4fdf]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
[e84439a]171
[2bd4fdf]172 # Move $k0 pointer to kernel stack
173 lui $k0, %hi(supervisor_sp)
[85ddc05]174 ori $k0, $k0, %lo(supervisor_sp)
[2bd4fdf]175 # Move $k0 (superveisor_sp)
176 lw $k0, 0($k0)
1771:
178.endm
179
[f761f1eb]180.org 0x0
[e84439a]181kernel_image_start:
182 /* Load temporary stack */
[2bd4fdf]183 lui $sp, %hi(end_stack)
[85ddc05]184 ori $sp, $sp, %lo(end_stack)
[971cf31f]185
186 /* $a1 contains physical address of bootinfo_t */
187 /* $a2 contains size of bootinfo_t */
188
189 beq $a2, $0, bootinfo_end
190
[e84439a]191 /* Not sure about this, but might be needed for PIC code???? */
192 lui $gp, 0x8000
193
[971cf31f]194 lui $a3, %hi(bootinfo)
195 ori $a3, $a3, %lo(bootinfo)
196
197 bootinfo_loop:
198
199 lw $v0, 0($a1)
200 sw $v0, 0($a3)
201
202 addi $a1, $a1, 4
203 addi $a3, $a3, 4
204 addi $a2, $a2, -4
205
206 bgtz $a2, bootinfo_loop
207 nop
208
209 bootinfo_end:
210
[12c7f27]211 jal arch_pre_main
212 nop
213
214 j main_bsp
[e84439a]215 nop
[2bd4fdf]216
[e84439a]217 .space TEMP_STACK_SIZE
[ffc277e]218end_stack:
219
220tlb_refill_entry:
221 j tlb_refill_handler
222 nop
223
224cache_error_entry:
225 j cache_error_handler
226 nop
227
228exception_entry:
229 j exception_handler
230 nop
231
232
[2bd4fdf]233
234exception_handler:
235 KERNEL_STACK_TO_K0
236 sub $k0, REGISTER_SPACE
[741ade3f]237 sw $sp,EOFFSET_SP($k0)
238 move $sp, $k0
[1b109cb]239
[741ade3f]240 mfc0 $k0, $cause
[1b109cb]241
[741ade3f]242 sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
243 andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
244 sub $k0, 8 # 8=SYSCALL
[1b109cb]245
[741ade3f]246 beqz $k0, syscall_shortcut
[7ca8b36b]247 add $k0, 8 # Revert $k0 back to correct exc number
[741ade3f]248
249 REGISTERS_STORE_AND_EXC_RESET $sp
[1b109cb]250
251 move $a1, $sp
252 jal exc_dispatch # exc_dispatch(excno, register_space)
[741ade3f]253 move $a0, $k0
[2bd4fdf]254
255 REGISTERS_LOAD $sp
256 # The $sp is automatically restored to former value
257 eret
[1b109cb]258
259# it seems that mips reserves some space on stack for varfuncs???
260#define SS_ARG4 16
[741ade3f]261#define SS_SP EOFFSET_SP
262#define SS_STATUS EOFFSET_STATUS
263#define SS_EPC EOFFSET_EPC
[7ca8b36b]264#define SS_K1 EOFFSET_K1
[53f9821]265syscall_shortcut:
[1b109cb]266 # We have a lot of space on the stack, with free use
267 mfc0 $t1, $epc
268 mfc0 $t0, $status
269 sw $t1,SS_EPC($sp) # Save EPC
[7ca8b36b]270 sw $k1,SS_K1($sp) # Save k1, which is not saved during context switch
[1b109cb]271
272 and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
273 li $t3, ~(0x1f)
274 and $t0, $t0, $t3 # Clear KSU,EXL,ERL
275 ori $t0, $t0, 0x1 # Set IE
276
277 sw $t2,SS_STATUS($sp)
278 mtc0 $t0, $status
279
[5201199]280 # CALL Syscall handler
[1b109cb]281 jal syscall_handler
282 sw $v0, SS_ARG4($sp) # save v0 - arg4 to stack
283
284 # restore status
285 mfc0 $t0, $status
286 lw $t1,SS_STATUS($sp)
287
[5201199]288 # Change back to EXL=1(from last exception), otherwise
289 # an interrupt could rewrite the CP0-EPC
[1b109cb]290 li $t2, ~REG_SAVE_MASK # Mask UM,EXL,ERL,IE
291 and $t0, $t0, $t2
292 or $t0, $t0, $t1 # Copy UM,EXL,ERL,IE from saved status
293 mtc0 $t0, $status
294
[5201199]295 # restore epc+4
296 lw $t0,SS_EPC($sp)
[7ca8b36b]297 lw $k1,SS_K1($sp)
[5201199]298 addi $t0, $t0, 4
299 mtc0 $t0, $epc
300
[1b109cb]301 lw $sp,SS_SP($sp) # restore sp
302
303 eret
[738ad2e]304
[f761f1eb]305tlb_refill_handler:
[2bd4fdf]306 KERNEL_STACK_TO_K0
307 sub $k0, REGISTER_SPACE
[1b109cb]308 REGISTERS_STORE_AND_EXC_RESET $k0
[741ade3f]309 sw $sp,EOFFSET_SP($k0)
[2bd4fdf]310 add $sp, $k0, 0
[76cec1e]311
[2f40fe4]312 jal tlb_refill
[f58af46]313 add $a0, $sp, 0
[76cec1e]314
[e84439a]315 REGISTERS_LOAD $sp
[76cec1e]316
[4e1d008]317 eret
[f761f1eb]318
319cache_error_handler:
[2bd4fdf]320 KERNEL_STACK_TO_K0
[741ade3f]321 sub $k0, REGISTER_SPACE
322 REGISTERS_STORE_AND_EXC_RESET $k0
323 sw $sp,EOFFSET_SP($k0)
[2bd4fdf]324 add $sp, $k0, 0
[f761f1eb]325
[4e1d008]326 jal cache_error
[2f40fe4]327 add $a0, $sp, 0
[76cec1e]328
[e84439a]329 REGISTERS_LOAD $sp
[f761f1eb]330
[4e1d008]331 eret
[2bd4fdf]332
333userspace_asm:
334 add $sp, $a0, 0
[9cbd27b]335 add $v0, $a1, 0
336 add $t9, $a2, 0 # Set up correct entry into PIC code
[2bd4fdf]337 eret
Note: See TracBrowser for help on using the repository browser.