Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * arm exception handlers
3
 */
4
#include "arm.s"
5
 
6
/*
7
 *  exception vectors, copied by trapinit() to somewhere useful
8
 */
9
TEXT vectors(SB), 1, $-4
10
	MOVW	0x18(R15), R15		/* reset */
11
	MOVW	0x18(R15), R15		/* undefined instr. */
12
	MOVW	0x18(R15), R15		/* SWI & SMC */
13
	MOVW	0x18(R15), R15		/* prefetch abort */
14
	MOVW	0x18(R15), R15		/* data abort */
15
	MOVW	0x18(R15), R15		/* reserved */
16
	MOVW	0x18(R15), R15		/* IRQ */
17
	MOVW	0x18(R15), R15		/* FIQ */
18
 
19
TEXT vtable(SB), 1, $-4
20
	WORD	$_vsvc(SB)		/* reset, in svc mode already */
21
	WORD	$_vund(SB)		/* undefined, switch to svc mode */
22
	WORD	$_vsvc(SB)		/* swi, in svc mode already */
23
	WORD	$_vpabt(SB)		/* prefetch abort, switch to svc mode */
24
	WORD	$_vdabt(SB)		/* data abort, switch to svc mode */
25
	WORD	$_vsvc(SB)		/* reserved */
26
	WORD	$_virq(SB)		/* IRQ, switch to svc mode */
27
	WORD	$_vfiq(SB)		/* FIQ, switch to svc mode */
28
 
29
TEXT _vsvc(SB), 1, $-4			/* SWI */
30
	MOVW.W	R14, -4(R13)		/* ureg->pc = interrupted PC */
31
	MOVW	SPSR, R14		/* ureg->psr = SPSR */
32
	MOVW.W	R14, -4(R13)		/* ... */
33
	MOVW	$PsrMsvc, R14		/* ureg->type = PsrMsvc */
34
	MOVW.W	R14, -4(R13)		/* ... */
35
 
36
	/* avoid the ambiguity described in notes/movm.w. */
37
	MOVM.DB.S [R0-R14], (R13)	/* save user level registers */
38
	SUB	$(15*4), R13		/* r13 now points to ureg */
39
 
40
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
41
 
42
//	MOVW	$(KSEG0+16*KiB-MACHSIZE), R10	/* m */
43
	MOVW	$(MACHADDR), R10	/* m */
44
	MOVW	8(R10), R9		/* up */
45
 
46
	MOVW	R13, R0			/* first arg is pointer to ureg */
47
	SUB	$8, R13			/* space for argument+link */
48
 
49
	BL	syscall(SB)
50
 
51
	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */
52
	MOVW	8(R13), R14		/* restore link */
53
	MOVW	4(R13), R0		/* restore SPSR */
54
	MOVW	R0, SPSR		/* ... */
55
	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
56
	ADD	$8, R13			/* pop past ureg->{type+psr} */
57
	RFE				/* MOVM.IA.S.W (R13), [R15] */
58
 
59
TEXT _vund(SB), 1, $-4			/* undefined */
60
	MOVM.IA	[R0-R4], (R13)		/* free some working space */
61
	MOVW	$PsrMund, R0
62
	B	_vswitch
63
 
64
TEXT _vpabt(SB), 1, $-4			/* prefetch abort */
65
	MOVM.IA	[R0-R4], (R13)		/* free some working space */
66
	MOVW	$PsrMabt, R0		/* r0 = type */
67
	B	_vswitch
68
 
69
TEXT _vdabt(SB), 1, $-4			/* data abort */
70
	MOVM.IA	[R0-R4], (R13)		/* free some working space */
71
	MOVW	$(PsrMabt+1), R0	/* r0 = type */
72
	B	_vswitch
73
 
74
TEXT _virq(SB), 1, $-4			/* IRQ */
75
	MOVM.IA	[R0-R4], (R13)		/* free some working space */
76
	MOVW	$PsrMirq, R0		/* r0 = type */
77
	B	_vswitch
78
 
79
	/*
80
	 *  come here with type in R0 and R13 pointing above saved [r0-r4].
81
	 *  we'll switch to SVC mode and then call trap.
82
	 */
83
_vswitch:
84
	MOVW	SPSR, R1		/* save SPSR for ureg */
85
	MOVW	R14, R2			/* save interrupted pc for ureg */
86
	MOVW	R13, R3			/* save pointer to where the original [R0-R4] are */
87
 
88
	/*
89
	 * switch processor to svc mode.  this switches the banked registers
90
	 * (r13 [sp] and r14 [link]) to those of svc mode.
91
	 */
92
	MOVW	CPSR, R14
93
	BIC	$PsrMask, R14
94
	ORR	$(PsrDirq|PsrMsvc), R14
95
	MOVW	R14, CPSR		/* switch! */
96
 
97
	AND.S	$0xf, R1, R4		/* interrupted code kernel or user? */
98
	BEQ	_userexcep
99
 
100
	/* here for trap from SVC mode */
101
	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */
102
	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */
103
 
104
	/*
105
	 * avoid the ambiguity described in notes/movm.w.
106
	 * In order to get a predictable value in R13 after the stores,
107
	 * separate the store-multiple from the stack-pointer adjustment.
108
	 * We'll assume that the old value of R13 should be stored on the stack.
109
	 */
110
	/* save kernel level registers, at end r13 points to ureg */
111
	MOVM.DB	[R0-R14], (R13)
112
	SUB	$(15*4), R13		/* SP now points to saved R0 */
113
 
114
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
115
 
116
	MOVW	R13, R0			/* first arg is pointer to ureg */
117
	SUB	$(4*2), R13		/* space for argument+link (for debugger) */
118
	MOVW	$0xdeaddead, R11	/* marker */
119
 
120
	BL	trap(SB)
121
 
122
	ADD	$(4*2+4*15), R13	/* make r13 point to ureg->type */
123
	MOVW	8(R13), R14		/* restore link */
124
	MOVW	4(R13), R0		/* restore SPSR */
125
	MOVW	R0, SPSR		/* ... */
126
 
127
	MOVM.DB (R13), [R0-R14]		/* restore registers */
128
 
129
	ADD	$(4*2), R13		/* pop past ureg->{type+psr} to pc */
130
	RFE				/* MOVM.IA.S.W (R13), [R15] */
131
 
132
	/* here for trap from USER mode */
133
_userexcep:
134
	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */
135
	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */
136
 
137
	/* avoid the ambiguity described in notes/movm.w. */
138
	MOVM.DB.S [R0-R14], (R13)	/* save kernel level registers */
139
	SUB	$(15*4), R13		/* r13 now points to ureg */
140
 
141
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
142
 
143
//	MOVW	$(KSEG0+16*KiB-MACHSIZE), R10	/* m */
144
	MOVW	$(MACHADDR), R10	/* m */
145
	MOVW	8(R10), R9		/* up */
146
 
147
	MOVW	R13, R0			/* first arg is pointer to ureg */
148
	SUB	$(4*2), R13		/* space for argument+link (for debugger) */
149
 
150
	BL	trap(SB)
151
 
152
	ADD	$(4*2+4*15), R13	/* make r13 point to ureg->type */
153
	MOVW	8(R13), R14		/* restore link */
154
	MOVW	4(R13), R0		/* restore SPSR */
155
	MOVW	R0, SPSR		/* ... */
156
	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
157
	ADD	$(4*2), R13		/* pop past ureg->{type+psr} */
158
	RFE				/* MOVM.IA.S.W (R13), [R15] */
159
 
160
TEXT _vfiq(SB), 1, $-4			/* FIQ */
161
	MOVW	$PsrMfiq, R8		/* trap type */
162
	MOVW	SPSR, R9		/* interrupted psr */
163
	MOVW	R14, R10		/* interrupted pc */
164
	MOVM.DB.W [R8-R10], (R13)	/* save in ureg */
165
	MOVM.DB.W.S [R0-R14], (R13)	/* save interrupted regs */
166
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
167
	MOVW	$(MACHADDR), R10	/* m */
168
	MOVW	8(R10), R9		/* up */
169
	MOVW	R13, R0			/* first arg is pointer to ureg */
170
	SUB	$(4*2), R13		/* space for argument+link (for debugger) */
171
 
172
	BL	fiq(SB)
173
 
174
	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */
175
	MOVW	8(R13), R14		/* restore link */
176
	MOVW	4(R13), R0		/* restore SPSR */
177
	MOVW	R0, SPSR		/* ... */
178
	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
179
	ADD	$8, R13			/* pop past ureg->{type+psr} */
180
	RFE				/* MOVM.IA.S.W (R13), [R15] */
181
 
182
/*
183
 *  set the stack value for the mode passed in R0
184
 */
185
TEXT setr13(SB), 1, $-4
186
	MOVW	4(FP), R1
187
 
188
	MOVW	CPSR, R2
189
	BIC	$PsrMask, R2, R3
190
	ORR	R0, R3
191
	MOVW	R3, CPSR		/* switch to new mode */
192
 
193
	MOVW	R13, R0			/* return old sp */
194
	MOVW	R1, R13			/* install new one */
195
 
196
	MOVW	R2, CPSR		/* switch back to old mode */
197
	RET