Subversion Repositories HelenOS

Rev

Rev 2071 | Rev 3222 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2071 Rev 2607
Line 28... Line 28...
28
 
28
 
29
#include <arch/asm/regname.h>
29
#include <arch/asm/regname.h>
30
#include <arch/mm/page.h>
30
#include <arch/mm/page.h>
31
#include <arch/asm/boot.h>
31
#include <arch/asm/boot.h>
32
#include <arch/context_offset.h>
32
#include <arch/context_offset.h>
-
 
33
#include <arch/stack.h>
33
	
34
	
34
.text
35
.text
35
 
36
 
36
.set noat
37
.set noat
37
.set noreorder
38
.set noreorder
Line 49... Line 50...
49
# Save registers to space defined by \r
50
# Save registers to space defined by \r
50
# We will change status: Disable ERL,EXL,UM,IE
51
# We will change status: Disable ERL,EXL,UM,IE
51
# These changes will be automatically reversed in REGISTER_LOAD
52
# These changes will be automatically reversed in REGISTER_LOAD
52
# SP is NOT saved as part of these registers
53
# SP is NOT saved as part of these registers
53
.macro REGISTERS_STORE_AND_EXC_RESET r
54
.macro REGISTERS_STORE_AND_EXC_RESET r
54
	sw $at,EOFFSET_AT(\r)
55
	sw $at, EOFFSET_AT(\r)
55
	sw $v0,EOFFSET_V0(\r)
56
	sw $v0, EOFFSET_V0(\r)
56
	sw $v1,EOFFSET_V1(\r)
57
	sw $v1, EOFFSET_V1(\r)
57
	sw $a0,EOFFSET_A0(\r)
58
	sw $a0, EOFFSET_A0(\r)
58
	sw $a1,EOFFSET_A1(\r)
59
	sw $a1, EOFFSET_A1(\r)
59
	sw $a2,EOFFSET_A2(\r)
60
	sw $a2, EOFFSET_A2(\r)
60
	sw $a3,EOFFSET_A3(\r)
61
	sw $a3, EOFFSET_A3(\r)
61
	sw $t0,EOFFSET_T0(\r)
62
	sw $t0, EOFFSET_T0(\r)
62
	sw $t1,EOFFSET_T1(\r)
63
	sw $t1, EOFFSET_T1(\r)
63
	sw $t2,EOFFSET_T2(\r)
64
	sw $t2, EOFFSET_T2(\r)
64
	sw $t3,EOFFSET_T3(\r)
65
	sw $t3, EOFFSET_T3(\r)
65
	sw $t4,EOFFSET_T4(\r)
66
	sw $t4, EOFFSET_T4(\r)
66
	sw $t5,EOFFSET_T5(\r)
67
	sw $t5, EOFFSET_T5(\r)
67
	sw $t6,EOFFSET_T6(\r)
68
	sw $t6, EOFFSET_T6(\r)
68
	sw $t7,EOFFSET_T7(\r)
69
	sw $t7, EOFFSET_T7(\r)
69
	sw $t8,EOFFSET_T8(\r)
70
	sw $t8, EOFFSET_T8(\r)
70
	sw $t9,EOFFSET_T9(\r)
71
	sw $t9, EOFFSET_T9(\r)
71
 
72
 
72
	mflo $at
73
	mflo $at
73
	sw $at, EOFFSET_LO(\r)
74
	sw $at, EOFFSET_LO(\r)
74
	mfhi $at
75
	mfhi $at
75
	sw $at, EOFFSET_HI(\r)
76
	sw $at, EOFFSET_HI(\r)
76
	
77
	
77
#ifdef CONFIG_DEBUG_ALLREGS	
78
#ifdef CONFIG_DEBUG_ALLREGS	
78
	sw $s0,EOFFSET_S0(\r)
79
	sw $s0, EOFFSET_S0(\r)
79
	sw $s1,EOFFSET_S1(\r)
80
	sw $s1, EOFFSET_S1(\r)
80
	sw $s2,EOFFSET_S2(\r)
81
	sw $s2, EOFFSET_S2(\r)
81
	sw $s3,EOFFSET_S3(\r)
82
	sw $s3, EOFFSET_S3(\r)
82
	sw $s4,EOFFSET_S4(\r)
83
	sw $s4, EOFFSET_S4(\r)
83
	sw $s5,EOFFSET_S5(\r)
84
	sw $s5, EOFFSET_S5(\r)
84
	sw $s6,EOFFSET_S6(\r)
85
	sw $s6, EOFFSET_S6(\r)
85
	sw $s7,EOFFSET_S7(\r)
86
	sw $s7, EOFFSET_S7(\r)
86
	sw $s8,EOFFSET_S8(\r)
87
	sw $s8, EOFFSET_S8(\r)
87
#endif
88
#endif
88
	
89
	
89
	sw $gp,EOFFSET_GP(\r)
90
	sw $gp, EOFFSET_GP(\r)
90
	sw $ra,EOFFSET_RA(\r)
91
	sw $ra, EOFFSET_RA(\r)
91
	sw $k1,EOFFSET_K1(\r)
92
	sw $k1, EOFFSET_K1(\r)
92
 
93
 
93
	mfc0 $t0, $status
94
	mfc0 $t0, $status
94
	mfc0 $t1, $epc
95
	mfc0 $t1, $epc
95
	
96
	
96
	and $t2, $t0, REG_SAVE_MASK  # Save only KSU,EXL,ERL,IE
97
	and $t2, $t0, REG_SAVE_MASK	# Save only KSU,EXL,ERL,IE
97
	li $t3, ~(0x1f)
98
	li $t3, ~(0x1f)
98
	and $t0, $t0, $t3           # Clear KSU,EXL,ERL,IE
99
	and $t0, $t0, $t3		# Clear KSU,EXL,ERL,IE
99
	
100
	
100
	sw $t2,EOFFSET_STATUS(\r)
101
	sw $t2,EOFFSET_STATUS(\r)
101
	sw $t1,EOFFSET_EPC(\r)
102
	sw $t1,EOFFSET_EPC(\r)
102
	mtc0 $t0, $status
103
	mtc0 $t0, $status
103
.endm
104
.endm
Line 106... Line 107...
106
	# Update only UM,EXR,IE from status, the rest
107
	# Update only UM,EXR,IE from status, the rest
107
	# is controlled by OS and not bound to task
108
	# is controlled by OS and not bound to task
108
	mfc0 $t0, $status
109
	mfc0 $t0, $status
109
	lw $t1,EOFFSET_STATUS(\r)
110
	lw $t1,EOFFSET_STATUS(\r)
110
 
111
 
111
	li $t2, ~REG_SAVE_MASK    # Mask UM,EXL,ERL,IE
112
	li $t2, ~REG_SAVE_MASK		# Mask UM,EXL,ERL,IE
112
	and $t0, $t0, $t2
113
	and $t0, $t0, $t2
113
	
114
	
114
	or $t0, $t0, $t1   # Copy UM,EXL,ERL,IE from saved status
115
	or $t0, $t0, $t1		# Copy UM,EXL, ERL, IE from saved status
115
	mtc0 $t0, $status
116
	mtc0 $t0, $status
116
	
117
	
117
	lw $v0,EOFFSET_V0(\r)
118
	lw $v0, EOFFSET_V0(\r)
118
	lw $v1,EOFFSET_V1(\r)
119
	lw $v1, EOFFSET_V1(\r)
119
	lw $a0,EOFFSET_A0(\r)
120
	lw $a0, EOFFSET_A0(\r)
120
	lw $a1,EOFFSET_A1(\r)
121
	lw $a1, EOFFSET_A1(\r)
121
	lw $a2,EOFFSET_A2(\r)
122
	lw $a2, EOFFSET_A2(\r)
122
	lw $a3,EOFFSET_A3(\r)
123
	lw $a3, EOFFSET_A3(\r)
123
	lw $t0,EOFFSET_T0(\r)
124
	lw $t0, EOFFSET_T0(\r)
124
	lw $t1,EOFFSET_T1(\r)
125
	lw $t1, EOFFSET_T1(\r)
125
	lw $t2,EOFFSET_T2(\r)
126
	lw $t2, EOFFSET_T2(\r)
126
	lw $t3,EOFFSET_T3(\r)
127
	lw $t3, EOFFSET_T3(\r)
127
	lw $t4,EOFFSET_T4(\r)
128
	lw $t4, EOFFSET_T4(\r)
128
	lw $t5,EOFFSET_T5(\r)
129
	lw $t5, EOFFSET_T5(\r)
129
	lw $t6,EOFFSET_T6(\r)
130
	lw $t6, EOFFSET_T6(\r)
130
	lw $t7,EOFFSET_T7(\r)
131
	lw $t7, EOFFSET_T7(\r)
131
	lw $t8,EOFFSET_T8(\r)
132
	lw $t8, EOFFSET_T8(\r)
132
	lw $t9,EOFFSET_T9(\r)
133
	lw $t9, EOFFSET_T9(\r)
133
	
134
	
134
#ifdef CONFIG_DEBUG_ALLREGS	
135
#ifdef CONFIG_DEBUG_ALLREGS	
135
	lw $s0,EOFFSET_S0(\r)
136
	lw $s0, EOFFSET_S0(\r)
136
	lw $s1,EOFFSET_S1(\r)
137
	lw $s1, EOFFSET_S1(\r)
137
	lw $s2,EOFFSET_S2(\r)
138
	lw $s2, EOFFSET_S2(\r)
138
	lw $s3,EOFFSET_S3(\r)
139
	lw $s3, EOFFSET_S3(\r)
139
	lw $s4,EOFFSET_S4(\r)
140
	lw $s4, EOFFSET_S4(\r)
140
	lw $s5,EOFFSET_S5(\r)
141
	lw $s5, EOFFSET_S5(\r)
141
	lw $s6,EOFFSET_S6(\r)
142
	lw $s6, EOFFSET_S6(\r)
142
	lw $s7,EOFFSET_S7(\r)
143
	lw $s7, EOFFSET_S7(\r)
143
	lw $s8,EOFFSET_S8(\r)
144
	lw $s8, EOFFSET_S8(\r)
144
#endif
145
#endif
145
	lw $gp,EOFFSET_GP(\r)
146
	lw $gp, EOFFSET_GP(\r)
146
	lw $ra,EOFFSET_RA(\r)
147
	lw $ra, EOFFSET_RA(\r)
147
	lw $k1,EOFFSET_K1(\r)
148
	lw $k1, EOFFSET_K1(\r)
148
	
149
	
149
	lw $at,EOFFSET_LO(\r)
150
	lw $at, EOFFSET_LO(\r)
150
	mtlo $at
151
	mtlo $at
151
	lw $at,EOFFSET_HI(\r)
152
	lw $at, EOFFSET_HI(\r)
152
	mthi $at
153
	mthi $at
153
 
154
 
154
	lw $at,EOFFSET_EPC(\r)
155
	lw $at, EOFFSET_EPC(\r)
155
	mtc0 $at, $epc
156
	mtc0 $at, $epc
156
	
157
	
157
	lw $at,EOFFSET_AT(\r)
158
	lw $at, EOFFSET_AT(\r)
158
	lw $sp,EOFFSET_SP(\r)
159
	lw $sp, EOFFSET_SP(\r)
159
.endm
160
.endm
160
 
161
 
161
# Move kernel stack pointer address to register K0
162
# Move kernel stack pointer address to register K0
162
# - if we are in user mode, load the appropriate stack
163
# - if we are in user mode, load the appropriate stack
163
# address
164
# address
Line 226... Line 227...
226
	nop
227
	nop
227
 
228
 
228
exception_entry:
229
exception_entry:
229
	j exception_handler
230
	j exception_handler
230
	nop	
231
	nop	
231
 
-
 
232
	
-
 
233
	
232
	
234
exception_handler:
233
exception_handler:
235
	KERNEL_STACK_TO_K0
234
	KERNEL_STACK_TO_K0
236
	sub $k0, REGISTER_SPACE
235
	sub $k0, REGISTER_SPACE
237
	sw $sp,EOFFSET_SP($k0)
236
	sw $sp, EOFFSET_SP($k0)
238
	move $sp, $k0
237
	move $sp, $k0
239
	
238
	
240
	mfc0 $k0, $cause
239
	mfc0 $k0, $cause
241
	
240
	
242
	sra $k0, $k0, 0x2     # cp0_exc_cause() part 1
241
	sra $k0, $k0, 0x2		# cp0_exc_cause() part 1
243
	andi $k0, $k0, 0x1f   # cp0_exc_cause() part 2
242
	andi $k0, $k0, 0x1f		# cp0_exc_cause() part 2
244
	sub $k0, 8            # 8=SYSCALL
243
	sub $k0, 8			# 8 = SYSCALL
245
	
244
	
246
	beqz $k0, syscall_shortcut
245
	beqz $k0, syscall_shortcut
247
	add $k0, 8            # Revert $k0 back to correct exc number
246
	add $k0, 8			# Revert $k0 back to correct exc number
248
	
247
	
249
	REGISTERS_STORE_AND_EXC_RESET $sp
248
	REGISTERS_STORE_AND_EXC_RESET $sp
250
	
249
	
251
	move $a1, $sp
250
	move $a1, $sp
252
	jal exc_dispatch      # exc_dispatch(excno, register_space)
251
	jal exc_dispatch		# exc_dispatch(excno, register_space)
253
	move $a0, $k0
252
	move $a0, $k0
254
 
253
 
255
	REGISTERS_LOAD $sp
254
	REGISTERS_LOAD $sp
256
	# The $sp is automatically restored to former value
255
	# The $sp is automatically restored to former value
257
	eret
256
	eret
258
 
257
 
-
 
258
## Syscall entry
-
 
259
#
-
 
260
# Registers:
-
 
261
#
-
 
262
# @param v0		Syscall number.
259
# it seems that mips reserves some space on stack for varfuncs???
263
# @param a0		1st argument.
260
#define SS_ARG4   16
264
# @param a1		2nd argument.
-
 
265
# @param a2		3rd argument.
-
 
266
# @param a3		4th argument.
-
 
267
# @param t0		5th argument.
-
 
268
# @param t1		6th argument.
-
 
269
#
-
 
270
# @return		The return value will be stored in v0.
-
 
271
#
261
#define SS_SP     EOFFSET_SP
272
#define SS_SP		EOFFSET_SP
262
#define SS_STATUS EOFFSET_STATUS
273
#define SS_STATUS	EOFFSET_STATUS
263
#define SS_EPC    EOFFSET_EPC
274
#define SS_EPC		EOFFSET_EPC
264
#define SS_K1     EOFFSET_K1
275
#define SS_K1		EOFFSET_K1
265
syscall_shortcut:
276
syscall_shortcut:
266
	# We have a lot of space on the stack, with free use
277
	# We have a lot of space on the stack, with free use
267
	mfc0 $t1, $epc
278
	mfc0 $t3, $epc
268
	mfc0 $t0, $status
279
	mfc0 $t2, $status
269
	sw $t1,SS_EPC($sp)  # Save EPC
280
	sw $t3, SS_EPC($sp)		# Save EPC
270
	sw $k1,SS_K1($sp)   # Save k1, which is not saved during context switch
281
	sw $k1, SS_K1($sp)   		# Save k1 not saved on context switch
271
	
282
	
272
	and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
283
	and $t4, $t2, REG_SAVE_MASK	# Save only KSU, EXL, ERL, IE
273
	li $t3, ~(0x1f)
284
	li $t5, ~(0x1f)
274
	and $t0, $t0, $t3           # Clear KSU,EXL,ERL
285
	and $t2, $t2, $t5		# Clear KSU, EXL, ERL
275
	ori $t0, $t0, 0x1           # Set IE
286
	ori $t2, $t2, 0x1		# Set IE
276
 
287
 
277
	sw $t2,SS_STATUS($sp)
288
	sw $t4, SS_STATUS($sp)
278
	mtc0 $t0, $status
289
	mtc0 $t2, $status
279
 
290
 
-
 
291
	#
280
	# CALL Syscall handler
292
	# Call the higher level system call handler
-
 
293
	# We are going to reuse part of the unused exception stack frame
-
 
294
	#
-
 
295
	sw $t0, STACK_ARG4($sp)		# save the 5th argument on the stack
-
 
296
	sw $t1, STACK_ARG5($sp)		# save the 6th argument on the stack
281
	jal syscall_handler
297
	jal syscall_handler
282
	sw $v0, SS_ARG4($sp)        # save v0 - arg4 to stack
298
	sw $v0, STACK_ARG6($sp)		# save the syscall number on the stack
283
 
299
 
284
	# restore status
300
	# restore status
285
	mfc0 $t0, $status
301
	mfc0 $t2, $status
286
	lw $t1,SS_STATUS($sp)
302
	lw $t3, SS_STATUS($sp)
287
 
303
 
288
	# Change back to EXL=1(from last exception), otherwise
304
	# Change back to EXL = 1 (from last exception), otherwise
289
	# an interrupt could rewrite the CP0-EPC
305
	# an interrupt could rewrite the CP0 - EPC
290
	li $t2, ~REG_SAVE_MASK      # Mask UM,EXL,ERL,IE
306
	li $t4, ~REG_SAVE_MASK		# Mask UM, EXL, ERL, IE
291
	and $t0, $t0, $t2
307
	and $t2, $t2, $t4
292
	or $t0, $t0, $t1            # Copy UM,EXL,ERL,IE from saved status
308
	or $t2, $t2, $t3		# Copy saved UM, EXL, ERL, IE
293
	mtc0 $t0, $status
309
	mtc0 $t2, $status
294
			
310
			
295
	# restore epc+4
311
	# restore epc + 4
296
	lw $t0,SS_EPC($sp)
312
	lw $t2, SS_EPC($sp)
297
	lw $k1,SS_K1($sp)
313
	lw $k1, SS_K1($sp)
298
	addi $t0, $t0, 4
314
	addi $t2, $t2, 4
299
	mtc0 $t0, $epc
315
	mtc0 $t2, $epc
300
	
316
	
301
	lw $sp,SS_SP($sp) # restore sp
317
	lw $sp, SS_SP($sp)		# restore sp
302
	
318
	
303
	eret
319
	eret
304
		
320
		
305
tlb_refill_handler:
321
tlb_refill_handler:
306
	KERNEL_STACK_TO_K0
322
	KERNEL_STACK_TO_K0
Line 331... Line 347...
331
	eret
347
	eret
332
 
348
 
333
userspace_asm:
349
userspace_asm:
334
	add $sp, $a0, 0
350
	add $sp, $a0, 0
335
	add $v0, $a1, 0 
351
	add $v0, $a1, 0 
336
	add $t9, $a2, 0   # Set up correct entry into PIC code 
352
	add $t9, $a2, 0			# Set up correct entry into PIC code 
337
	eret
353
	eret