entry.s
2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "sk.h"
.text
.align 2
.globl __start
.ent __start
__start:
/* Note below is only for dev code, since in real SK
* we could never enter here unless an NMI was the source.
* XXX: we're going to use registers (t0, t1, ...) to
* determine if this is NMI or reset. But, since we could
* be entered from interrupt code, we must store
* these regs so they can be restored before returning.
* The stack ptr cannot be used since we don't yet
* know if it is valid. Thus, we'll need to choose
* some fixed place in SRAM for this purpose.
*/
/* XXX: does continued assertion of NMI signal effectively
* disable other interrups? YES
*/
mfc0 t0,C0_SR
li t1,SR_SR
and t0,t0,t1
beqz t0,hardrst
/* could be nmi. now must distinguish nmi from soft reset */
lw t0,MI_SEC_MODE_REG
and t0,t0,MI_SEC_MODE_NMI
beqz t0,softrst
nmi:
/* setup sk stack and context switch */
/* XXX: this switch is good for arriving by SK API.
* more needs to be saved if arrive by timer since
* we are interrupting unexpectedly
mfc0 t0, C0_SR
move t1, sp /* non-SK sp */
li t2, PHYS_TO_K0(SK_STACK_INIT_ADDR)
subu sp, t2, SK_API_CONTEXT_SIZE /* sk stack */
sw t1, SK_SP_SP(sp)
sw t0, SK_SP_SR(sp) /* status register, still in t0 */
sw s0, SK_SP_S0(sp)
sw s1, SK_SP_S0(sp)
sw s2, SK_SP_S0(sp)
sw s3, SK_SP_S0(sp)
sw s4, SK_SP_S0(sp)
sw s5, SK_SP_S0(sp)
sw s6, SK_SP_S0(sp)
sw s7, SK_SP_S0(sp)
sw fp, SK_SP_GP(sp)
sw gp, SK_SP_FP(sp)
sw ra, SK_SP_RA(sp)
/* call the appropriate handler */
sll t0, v0,2
la t1, sk_call_table
addu t1, t1,t0
lw t0, (t1)
jalr t0
/* restore status register */
lw t0, SK_SP_SR(sp)
li t1, SR_SR /* unset soft-reset */
not t1
and t0, t0, t1
li t1, SR_BEV /* unset BEV (assumes not set pre-NMI) */
not t1
and t0, t0, t1
mtc0 t0, C0_SR
/* we assume SR_TS is 0, so we could not have entered here
* from a TLB exception.
*/
/* restore regs and regular stack (context switch) */
lw s0, SK_SP_S0(sp)
lw s1, SK_SP_S0(sp)
lw s2, SK_SP_S0(sp)
lw s3, SK_SP_S0(sp)
lw s4, SK_SP_S0(sp)
lw s5, SK_SP_S0(sp)
lw s6, SK_SP_S0(sp)
lw s7, SK_SP_S0(sp)
lw fp, SK_SP_GP(sp)
lw gp, SK_SP_FP(sp)
lw ra, SK_SP_RA(sp)
lw sp, SK_SP_SP(sp) /* this must be last */
/* any secure cleanup or cache setup required */
/* restore NMI_* registers */
/* XXX */
/* set mode (kernel or user), unless we assume kernel */
/* clean icache and dcache if needed */
/* must place eret and sw for MI_SEC_MODE_REG into icache */
/* eret will clear C0_SR.ERL bit */
sw zero,MI_SEC_MODE_REG
eret
hardrst:
softrst:
lui sp,0x8100
jal main
.end __start