xref: /plan9/sys/src/9/rb/l.s (revision 51f48f69b4c3e5c9d9f7955d28612ef2d4048ccc)
1f43f8ee6SDavid du Colombier/*
2f43f8ee6SDavid du Colombier * mips 24k machine assist for routerboard rb450g
3f43f8ee6SDavid du Colombier */
4f43f8ee6SDavid du Colombier#include "mem.h"
5f43f8ee6SDavid du Colombier#include "mips.s"
6f43f8ee6SDavid du Colombier
7f43f8ee6SDavid du Colombier#define SANITY 0x12345678
8f43f8ee6SDavid du Colombier
9f43f8ee6SDavid du Colombier	NOSCHED
10f43f8ee6SDavid du Colombier
11f43f8ee6SDavid du Colombier/*
12f43f8ee6SDavid du Colombier * Boot only processor
13f43f8ee6SDavid du Colombier */
14f43f8ee6SDavid du ColombierTEXT	start(SB), $-4
15f43f8ee6SDavid du Colombier	MOVW	$setR30(SB), R30
16f43f8ee6SDavid du Colombier
17f43f8ee6SDavid du ColombierPUTC('9', R1, R2)
18f43f8ee6SDavid du Colombier	DI(0)
19f43f8ee6SDavid du Colombier
20f43f8ee6SDavid du Colombier	MOVW	sanity(SB), R1
21f43f8ee6SDavid du Colombier	CONST(SANITY, R2)
22f43f8ee6SDavid du Colombier	SUBU	R1, R2, R2
23f43f8ee6SDavid du Colombier	BNE	R2, insane
24f43f8ee6SDavid du Colombier	NOP
25f43f8ee6SDavid du Colombier
26f43f8ee6SDavid du Colombier	MOVW	R0, M(COMPARE)
27f43f8ee6SDavid du Colombier	EHB
28f43f8ee6SDavid du Colombier
29f43f8ee6SDavid du Colombier	/* don't enable any interrupts nor FP, but leave BEV on. */
30f43f8ee6SDavid du Colombier	MOVW	$BEV,R1
31f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)
32f43f8ee6SDavid du Colombier	UBARRIERS(7, R7, stshb)		/* returns to kseg1 space */
33f43f8ee6SDavid du Colombier	MOVW	R0, M(CAUSE)
34f43f8ee6SDavid du Colombier	EHB
35f43f8ee6SDavid du Colombier
36f43f8ee6SDavid du Colombier	/* silence the atheros watchdog */
37f43f8ee6SDavid du Colombier	MOVW	$(KSEG1|0x18060008), R1
38f43f8ee6SDavid du Colombier	MOVW	R0, (R1)			/* set no action */
39f43f8ee6SDavid du Colombier	SYNC
40f43f8ee6SDavid du Colombier
41f43f8ee6SDavid du Colombier	MOVW	$PE, R1
42f43f8ee6SDavid du Colombier	MOVW	R1, M(CACHEECC)		/* aka ErrCtl */
43f43f8ee6SDavid du Colombier	EHB
44f43f8ee6SDavid du Colombier	JAL	cleancache(SB)
45f43f8ee6SDavid du Colombier	NOP
46f43f8ee6SDavid du Colombier
47f43f8ee6SDavid du Colombier	MOVW	$TLBROFF, R1
48f43f8ee6SDavid du Colombier	MOVW	R1, M(WIRED)
49f43f8ee6SDavid du Colombier
50f43f8ee6SDavid du Colombier	MOVW	R0, M(CONTEXT)
51f43f8ee6SDavid du Colombier	EHB
52f43f8ee6SDavid du Colombier
53f43f8ee6SDavid du Colombier	/* set KSEG0 cachability before trying LL/SC in lock code */
54f43f8ee6SDavid du Colombier	MOVW	M(CONFIG), R1
55f43f8ee6SDavid du Colombier	AND	$~CFG_K0, R1
56f43f8ee6SDavid du Colombier	/* make kseg0 cachable, enable write-through merging */
57f43f8ee6SDavid du Colombier	OR	$((PTECACHABILITY>>3)|CFG_MM), R1
58f43f8ee6SDavid du Colombier	MOVW	R1, M(CONFIG)
59f43f8ee6SDavid du Colombier	BARRIERS(7, R7, cfghb)			/* back to kseg0 space */
60f43f8ee6SDavid du Colombier
61f43f8ee6SDavid du Colombier	MOVW	$setR30(SB), R30		/* again */
62f43f8ee6SDavid du Colombier
63f43f8ee6SDavid du Colombier	/* initialize Mach, including stack */
64f43f8ee6SDavid du Colombier	MOVW	$MACHADDR, R(MACH)
65f43f8ee6SDavid du Colombier	ADDU	$(MACHSIZE-BY2V), R(MACH), SP
66f43f8ee6SDavid du Colombier	MOVW	R(MACH), R1
67f43f8ee6SDavid du Colombierclrmach:
68f43f8ee6SDavid du Colombier	MOVW	R0, (R1)
69f43f8ee6SDavid du Colombier	ADDU	$BY2WD, R1
70f43f8ee6SDavid du Colombier	BNE	R1, SP, clrmach
71f43f8ee6SDavid du Colombier	NOP
72f43f8ee6SDavid du Colombier	MOVW	R0, 0(R(MACH))			/* m->machno = 0 */
73f43f8ee6SDavid du Colombier	MOVW	R0, R(USER)			/* up = nil */
74f43f8ee6SDavid du Colombier
75f43f8ee6SDavid du Colombier	/* zero bss, byte-by-byte */
76f43f8ee6SDavid du Colombier	MOVW	$edata(SB), R1
77f43f8ee6SDavid du Colombier	MOVW	$end(SB), R2
78f43f8ee6SDavid du Colombierclrbss:
79f43f8ee6SDavid du Colombier	MOVB	R0, (R1)
80f43f8ee6SDavid du Colombier	ADDU	$1, R1
81f43f8ee6SDavid du Colombier	BNE	R1, R2, clrbss
82f43f8ee6SDavid du Colombier	NOP
83f43f8ee6SDavid du Colombier
84f43f8ee6SDavid du Colombier	MOVW	$0x16, R16
85f43f8ee6SDavid du Colombier	MOVW	$0x17, R17
86f43f8ee6SDavid du Colombier	MOVW	$0x18, R18
87f43f8ee6SDavid du Colombier	MOVW	$0x19, R19
88f43f8ee6SDavid du Colombier	MOVW	$0x20, R20
89f43f8ee6SDavid du Colombier	MOVW	$0x21, R21
90f43f8ee6SDavid du Colombier	MOVW	$0x22, R22
91f43f8ee6SDavid du Colombier	MOVW	$0x23, R23
92f43f8ee6SDavid du Colombier
93f43f8ee6SDavid du Colombier	MOVW	R0, HI
94f43f8ee6SDavid du Colombier	MOVW	R0, LO
95f43f8ee6SDavid du Colombier
96f43f8ee6SDavid du ColombierPUTC('\r', R1, R2)
97f43f8ee6SDavid du ColombierPUTC('\n', R1, R2)
98f43f8ee6SDavid du Colombier	JAL	main(SB)
99f43f8ee6SDavid du Colombier	NOP
100f43f8ee6SDavid du Colombier	CONST(ROM, R1)
101f43f8ee6SDavid du Colombier	JMP	(R1)			/* back to the rom */
102f43f8ee6SDavid du Colombier
103f43f8ee6SDavid du Colombier#define PUT(c) PUTC(c, R1, R2)
104f43f8ee6SDavid du Colombier#define DELAY(lab) \
105f43f8ee6SDavid du Colombier	CONST(34000000, R3); \
106f43f8ee6SDavid du Colombierlab:	SUBU	$1, R3; \
107f43f8ee6SDavid du Colombier	BNE	R3, lab; \
108f43f8ee6SDavid du Colombier	NOP
109f43f8ee6SDavid du Colombier
110f43f8ee6SDavid du Colombierinsane:
111f43f8ee6SDavid du Colombier	/*
112f43f8ee6SDavid du Colombier	 * data segment is misaligned; kernel needs vl -R4096 or -R16384,
113f43f8ee6SDavid du Colombier	 * as appropriate, for reboot.
114f43f8ee6SDavid du Colombier	 */
115f43f8ee6SDavid du Colombier	PUT('?'); PUT('d'); PUT('a'); PUT('t'); PUT('a'); PUT(' '); DELAY(dl1)
116f43f8ee6SDavid du Colombier	PUT('s'); PUT('e'); PUT('g'); PUT('m'); PUT('e'); PUT('n'); DELAY(dl2)
117f43f8ee6SDavid du Colombier	PUT('t'); PUT(' '); PUT('m'); PUT('i'); PUT('s'); PUT('a'); DELAY(dl3)
118f43f8ee6SDavid du Colombier	PUT('l'); PUT('i'); PUT('g'); PUT('n'); PUT('e'); PUT('d'); DELAY(dl4)
119f43f8ee6SDavid du Colombier	PUT('\r'); PUT('\n'); DELAY(dl5)
120f43f8ee6SDavid du Colombier	CONST(ROM, R1)
121f43f8ee6SDavid du Colombier	JMP	(R1)			/* back to the rom */
122f43f8ee6SDavid du Colombier	NOP
123f43f8ee6SDavid du Colombier
124f43f8ee6SDavid du Colombier/* target for JALRHB in BARRIERS */
125f43f8ee6SDavid du ColombierTEXT ret(SB), $-4
126f43f8ee6SDavid du Colombier	JMP	(R22)
127f43f8ee6SDavid du Colombier	NOP
128f43f8ee6SDavid du Colombier
129f43f8ee6SDavid du Colombier/* print R1 in hex; clobbers R3—8 */
130f43f8ee6SDavid du ColombierTEXT printhex(SB), $-4
131f43f8ee6SDavid du Colombier	MOVW	$32, R5
132f43f8ee6SDavid du Colombier	MOVW	$9, R7
133f43f8ee6SDavid du Colombierprtop:
134f43f8ee6SDavid du Colombier	SUB	$4, R5
135f43f8ee6SDavid du Colombier	MOVW	R1, R6
136f43f8ee6SDavid du Colombier	SRL	R5, R6
137f43f8ee6SDavid du Colombier	AND	$0xf, R6
138f43f8ee6SDavid du Colombier	SGTU	R6, R7, R8
139f43f8ee6SDavid du Colombier	BEQ	R8, prdec		/* branch if R6 <= 9 */
140f43f8ee6SDavid du Colombier	NOP
141f43f8ee6SDavid du Colombier	ADD	$('a'-10), R6
142f43f8ee6SDavid du Colombier	JMP	prchar
143f43f8ee6SDavid du Colombier	NOP
144f43f8ee6SDavid du Colombierprdec:
145f43f8ee6SDavid du Colombier	ADD	$'0', R6
146f43f8ee6SDavid du Colombierprchar:
147f43f8ee6SDavid du Colombier	PUTC(R6, R3, R4)
148f43f8ee6SDavid du Colombier	BNE	R5, prtop
149f43f8ee6SDavid du Colombier	NOP
150f43f8ee6SDavid du Colombier	RETURN
151f43f8ee6SDavid du Colombier
152f43f8ee6SDavid du Colombier/*
153f43f8ee6SDavid du Colombier * Take first processor into user mode
154f43f8ee6SDavid du Colombier * 	- argument is stack pointer to user
155f43f8ee6SDavid du Colombier */
156f43f8ee6SDavid du ColombierTEXT	touser(SB), $-4
157f43f8ee6SDavid du Colombier	MOVW	R1, SP
158f43f8ee6SDavid du Colombier	MOVW	$(UTZERO+32), R2	/* header appears in text */
159f43f8ee6SDavid du Colombier	MOVW	R2, M(EPC)
160f43f8ee6SDavid du Colombier	EHB
161f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R4
162f43f8ee6SDavid du Colombier	AND	$(~KMODEMASK), R4
163f43f8ee6SDavid du Colombier	OR	$(KUSER|IE|EXL), R4	/* switch to user mode, intrs on, exc */
164f43f8ee6SDavid du Colombier	MOVW	R4, M(STATUS)		/* " */
165f43f8ee6SDavid du Colombier	ERET				/* clears EXL */
166f43f8ee6SDavid du Colombier
167f43f8ee6SDavid du Colombier/*
168f43f8ee6SDavid du Colombier * manipulate interrupts
169f43f8ee6SDavid du Colombier */
170f43f8ee6SDavid du Colombier
171f43f8ee6SDavid du Colombier/* enable an interrupt; bit is in R1 */
172f43f8ee6SDavid du ColombierTEXT	intron(SB), $0
173f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R2
174f43f8ee6SDavid du Colombier	OR	R1, R2
175f43f8ee6SDavid du Colombier	MOVW	R2, M(STATUS)
176f43f8ee6SDavid du Colombier	EHB
177f43f8ee6SDavid du Colombier	RETURN
178f43f8ee6SDavid du Colombier
179f43f8ee6SDavid du Colombier/* disable an interrupt; bit is in R1 */
180f43f8ee6SDavid du ColombierTEXT	introff(SB), $0
181f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R2
182f43f8ee6SDavid du Colombier	XOR	$-1, R1
183f43f8ee6SDavid du Colombier	AND	R1, R2
184f43f8ee6SDavid du Colombier	MOVW	R2, M(STATUS)
185f43f8ee6SDavid du Colombier	EHB
186f43f8ee6SDavid du Colombier	RETURN
187f43f8ee6SDavid du Colombier
188f43f8ee6SDavid du Colombier/* on our 24k, wait instructions are not interruptible, alas. */
189f43f8ee6SDavid du ColombierTEXT	idle(SB), $-4
190f43f8ee6SDavid du Colombier	EI(1)				/* old M(STATUS) into R1 */
191f43f8ee6SDavid du Colombier	EHB
192f43f8ee6SDavid du Colombier	/* fall through */
193f43f8ee6SDavid du Colombier
194f43f8ee6SDavid du ColombierTEXT	wait(SB), $-4
195f43f8ee6SDavid du Colombier	WAIT
196f43f8ee6SDavid du Colombier	NOP
197f43f8ee6SDavid du Colombier
198f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)		/* interrupts restored */
199f43f8ee6SDavid du Colombier	EHB
200f43f8ee6SDavid du Colombier	RETURN
201f43f8ee6SDavid du Colombier
202f43f8ee6SDavid du ColombierTEXT	splhi(SB), $0
203f43f8ee6SDavid du Colombier	EHB
204f43f8ee6SDavid du Colombier	MOVW	R31, 12(R(MACH))	/* save PC in m->splpc */
205f43f8ee6SDavid du Colombier	DI(1)				/* old M(STATUS) into R1 */
206f43f8ee6SDavid du Colombier	EHB
207f43f8ee6SDavid du Colombier	RETURN
208f43f8ee6SDavid du Colombier
209f43f8ee6SDavid du ColombierTEXT	splx(SB), $0
210f43f8ee6SDavid du Colombier	EHB
211f43f8ee6SDavid du Colombier	MOVW	R31, 12(R(MACH))	/* save PC in m->splpc */
212f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R2
213f43f8ee6SDavid du Colombier	AND	$IE, R1
214f43f8ee6SDavid du Colombier	AND	$~IE, R2
215f43f8ee6SDavid du Colombier	OR	R2, R1
216f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)
217f43f8ee6SDavid du Colombier	EHB
218f43f8ee6SDavid du Colombier	RETURN
219f43f8ee6SDavid du Colombier
220f43f8ee6SDavid du ColombierTEXT	spllo(SB), $0
221f43f8ee6SDavid du Colombier	EHB
222f43f8ee6SDavid du Colombier	EI(1)				/* old M(STATUS) into R1 */
223f43f8ee6SDavid du Colombier	EHB
224f43f8ee6SDavid du Colombier	RETURN
225f43f8ee6SDavid du Colombier
226f43f8ee6SDavid du ColombierTEXT	spldone(SB), $0
227f43f8ee6SDavid du Colombier	RETURN
228f43f8ee6SDavid du Colombier
229f43f8ee6SDavid du ColombierTEXT	islo(SB), $0
230f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R1
231f43f8ee6SDavid du Colombier	AND	$IE, R1
232f43f8ee6SDavid du Colombier	RETURN
233f43f8ee6SDavid du Colombier
234f43f8ee6SDavid du ColombierTEXT	coherence(SB), $-4
235f43f8ee6SDavid du Colombier	BARRIERS(7, R7, cohhb)
236f43f8ee6SDavid du Colombier	SYNC
237f43f8ee6SDavid du Colombier	EHB
238f43f8ee6SDavid du Colombier	RETURN
239f43f8ee6SDavid du Colombier
240f43f8ee6SDavid du Colombier/*
241f43f8ee6SDavid du Colombier * process switching
242f43f8ee6SDavid du Colombier */
243f43f8ee6SDavid du Colombier
244f43f8ee6SDavid du ColombierTEXT	setlabel(SB), $-4
245f43f8ee6SDavid du Colombier	MOVW	R29, 0(R1)
246f43f8ee6SDavid du Colombier	MOVW	R31, 4(R1)
247f43f8ee6SDavid du Colombier	MOVW	R0, R1
248f43f8ee6SDavid du Colombier	RETURN
249f43f8ee6SDavid du Colombier
250f43f8ee6SDavid du ColombierTEXT	gotolabel(SB), $-4
251f43f8ee6SDavid du Colombier	MOVW	0(R1), R29
252f43f8ee6SDavid du Colombier	MOVW	4(R1), R31
253f43f8ee6SDavid du Colombier	MOVW	$1, R1
254f43f8ee6SDavid du Colombier	RETURN
255f43f8ee6SDavid du Colombier
256f43f8ee6SDavid du Colombier/*
257f43f8ee6SDavid du Colombier * the tlb routines need to be called at splhi.
258f43f8ee6SDavid du Colombier */
259f43f8ee6SDavid du Colombier
260f43f8ee6SDavid du ColombierTEXT	puttlb(SB), $0			/* puttlb(virt, phys0, phys1) */
261f43f8ee6SDavid du Colombier	EHB
262f43f8ee6SDavid du Colombier	MOVW	R1, M(TLBVIRT)
263f43f8ee6SDavid du Colombier	EHB
264f43f8ee6SDavid du Colombier	MOVW	4(FP), R2		/* phys0 */
265f43f8ee6SDavid du Colombier	MOVW	8(FP), R3		/* phys1 */
266f43f8ee6SDavid du Colombier	MOVW	R2, M(TLBPHYS0)
267f43f8ee6SDavid du Colombier	EHB
268f43f8ee6SDavid du Colombier	MOVW	$PGSZ, R1
269f43f8ee6SDavid du Colombier	MOVW	R3, M(TLBPHYS1)
270f43f8ee6SDavid du Colombier	EHB
271f43f8ee6SDavid du Colombier	MOVW	R1, M(PAGEMASK)
272f43f8ee6SDavid du Colombier	OR	R2, R3, R4		/* MTC0 delay slot */
273f43f8ee6SDavid du Colombier	AND	$PTEVALID, R4		/* MTC0 delay slot */
274f43f8ee6SDavid du Colombier	EHB
275f43f8ee6SDavid du Colombier	TLBP				/* tlb probe */
276f43f8ee6SDavid du Colombier	EHB
277f43f8ee6SDavid du Colombier	MOVW	M(INDEX), R1
278f43f8ee6SDavid du Colombier	BGEZ	R1, index		/* if tlb entry found, use it */
279f43f8ee6SDavid du Colombier	NOP
280f43f8ee6SDavid du Colombier	BEQ	R4, dont		/* not valid? cf. kunmap */
281f43f8ee6SDavid du Colombier	NOP
282f43f8ee6SDavid du Colombier	MOVW	M(RANDOM), R1		/* write random tlb entry */
283f43f8ee6SDavid du Colombier	MOVW	R1, M(INDEX)
284f43f8ee6SDavid du Colombierindex:
285f43f8ee6SDavid du Colombier	EHB
286f43f8ee6SDavid du Colombier	TLBWI				/* write indexed tlb entry */
287f43f8ee6SDavid du Colombier	JRHB(31)			/* return and clear all hazards */
288f43f8ee6SDavid du Colombierdont:
289f43f8ee6SDavid du Colombier	RETURN
290f43f8ee6SDavid du Colombier
291f43f8ee6SDavid du ColombierTEXT	getwired(SB),$0
292f43f8ee6SDavid du Colombier	MOVW	M(WIRED), R1
293f43f8ee6SDavid du Colombier	RETURN
294f43f8ee6SDavid du Colombier
295f43f8ee6SDavid du ColombierTEXT	setwired(SB),$0
296f43f8ee6SDavid du Colombier	MOVW	R1, M(WIRED)
297f43f8ee6SDavid du Colombier	EHB
298f43f8ee6SDavid du Colombier	RETURN
299f43f8ee6SDavid du Colombier
300f43f8ee6SDavid du ColombierTEXT	getrandom(SB),$0
301f43f8ee6SDavid du Colombier	MOVW	M(RANDOM), R1
302f43f8ee6SDavid du Colombier	RETURN
303f43f8ee6SDavid du Colombier
304f43f8ee6SDavid du ColombierTEXT	getpagemask(SB),$0
305f43f8ee6SDavid du Colombier	MOVW	M(PAGEMASK), R1
306f43f8ee6SDavid du Colombier	RETURN
307f43f8ee6SDavid du Colombier
308f43f8ee6SDavid du ColombierTEXT	setpagemask(SB),$0
309f43f8ee6SDavid du Colombier	EHB
310f43f8ee6SDavid du Colombier	MOVW	R1, M(PAGEMASK)
311f43f8ee6SDavid du Colombier	EHB
312f43f8ee6SDavid du Colombier	MOVW	R0, R1			/* prevent accidents */
313f43f8ee6SDavid du Colombier	RETURN
314f43f8ee6SDavid du Colombier
315f43f8ee6SDavid du ColombierTEXT	puttlbx(SB), $0	/* puttlbx(index, virt, phys0, phys1, pagemask) */
316f43f8ee6SDavid du Colombier	MOVW	4(FP), R2
317f43f8ee6SDavid du Colombier	MOVW	8(FP), R3
318f43f8ee6SDavid du Colombier	MOVW	12(FP), R4
319f43f8ee6SDavid du Colombier	MOVW	16(FP), R5
320f43f8ee6SDavid du Colombier	EHB
321f43f8ee6SDavid du Colombier	MOVW	R2, M(TLBVIRT)
322f43f8ee6SDavid du Colombier	EHB
323f43f8ee6SDavid du Colombier	MOVW	R3, M(TLBPHYS0)
324f43f8ee6SDavid du Colombier	MOVW	R4, M(TLBPHYS1)
325f43f8ee6SDavid du Colombier	MOVW	R5, M(PAGEMASK)
326f43f8ee6SDavid du Colombier	EHB
327f43f8ee6SDavid du Colombier	MOVW	R1, M(INDEX)
328f43f8ee6SDavid du Colombier	EHB
329f43f8ee6SDavid du Colombier	TLBWI				/* write indexed tlb entry */
330f43f8ee6SDavid du Colombier	JRHB(31)			/* return and clear all hazards */
331f43f8ee6SDavid du Colombier
332f43f8ee6SDavid du ColombierTEXT	tlbvirt(SB), $0
333f43f8ee6SDavid du Colombier	EHB
334f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R1
335f43f8ee6SDavid du Colombier	EHB
336f43f8ee6SDavid du Colombier	RETURN
337f43f8ee6SDavid du Colombier
338f43f8ee6SDavid du ColombierTEXT	gettlbx(SB), $0			/* gettlbx(index, &entry) */
339f43f8ee6SDavid du Colombier	MOVW	4(FP), R5
340f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R10		/* save our asid */
341f43f8ee6SDavid du Colombier	EHB
342f43f8ee6SDavid du Colombier	MOVW	R1, M(INDEX)
343f43f8ee6SDavid du Colombier	EHB
344f43f8ee6SDavid du Colombier	TLBR				/* read indexed tlb entry */
345f43f8ee6SDavid du Colombier	EHB
346f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R2
347f43f8ee6SDavid du Colombier	MOVW	M(TLBPHYS0), R3
348f43f8ee6SDavid du Colombier	MOVW	M(TLBPHYS1), R4
349f43f8ee6SDavid du Colombier	MOVW	R2, 0(R5)
350f43f8ee6SDavid du Colombier	MOVW	R3, 4(R5)
351f43f8ee6SDavid du Colombier	MIPS24KNOP
352f43f8ee6SDavid du Colombier	MOVW	R4, 8(R5)
353f43f8ee6SDavid du Colombier	EHB
354f43f8ee6SDavid du Colombier	MOVW	R10, M(TLBVIRT)		/* restore our asid */
355f43f8ee6SDavid du Colombier	EHB
356f43f8ee6SDavid du Colombier	RETURN
357f43f8ee6SDavid du Colombier
358f43f8ee6SDavid du ColombierTEXT	gettlbp(SB), $0			/* gettlbp(tlbvirt, &entry) */
359f43f8ee6SDavid du Colombier	MOVW	4(FP), R5
360f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R10		/* save our asid */
361f43f8ee6SDavid du Colombier	EHB
362f43f8ee6SDavid du Colombier	MOVW	R1, M(TLBVIRT)
363f43f8ee6SDavid du Colombier	EHB
364f43f8ee6SDavid du Colombier	TLBP				/* probe tlb */
365f43f8ee6SDavid du Colombier	EHB
366f43f8ee6SDavid du Colombier	MOVW	M(INDEX), R1
367f43f8ee6SDavid du Colombier	BLTZ	R1, gettlbp1		/* if no tlb entry found, return */
368f43f8ee6SDavid du Colombier	NOP
369f43f8ee6SDavid du Colombier	EHB
370f43f8ee6SDavid du Colombier	TLBR				/* read indexed tlb entry */
371f43f8ee6SDavid du Colombier	EHB
372f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R2
373f43f8ee6SDavid du Colombier	MOVW	M(TLBPHYS0), R3
374f43f8ee6SDavid du Colombier	MOVW	M(TLBPHYS1), R4
375f43f8ee6SDavid du Colombier	MOVW	M(PAGEMASK), R6
376f43f8ee6SDavid du Colombier	MOVW	R2, 0(R5)
377f43f8ee6SDavid du Colombier	MOVW	R3, 4(R5)
378f43f8ee6SDavid du Colombier	MIPS24KNOP
379f43f8ee6SDavid du Colombier	MOVW	R4, 8(R5)
380f43f8ee6SDavid du Colombier	MOVW	R6, 12(R5)
381f43f8ee6SDavid du Colombiergettlbp1:
382f43f8ee6SDavid du Colombier	EHB
383f43f8ee6SDavid du Colombier	MOVW	R10, M(TLBVIRT)		/* restore our asid */
384f43f8ee6SDavid du Colombier	EHB
385f43f8ee6SDavid du Colombier	RETURN
386f43f8ee6SDavid du Colombier
387f43f8ee6SDavid du ColombierTEXT	gettlbvirt(SB), $0		/* gettlbvirt(index) */
388f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R10		/* save our asid */
389f43f8ee6SDavid du Colombier	EHB
390f43f8ee6SDavid du Colombier	MOVW	R1, M(INDEX)
391f43f8ee6SDavid du Colombier	EHB
392f43f8ee6SDavid du Colombier	TLBR				/* read indexed tlb entry */
393f43f8ee6SDavid du Colombier	EHB
394f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R1
395f43f8ee6SDavid du Colombier	EHB
396f43f8ee6SDavid du Colombier	MOVW	R10, M(TLBVIRT)		/* restore our asid */
397f43f8ee6SDavid du Colombier	EHB
398f43f8ee6SDavid du Colombier	RETURN
399f43f8ee6SDavid du Colombier
400f43f8ee6SDavid du Colombier/*
401f43f8ee6SDavid du Colombier * exceptions.
402f43f8ee6SDavid du Colombier * mips promises that there will be no current hazards upon entry
403f43f8ee6SDavid du Colombier * to exception handlers.
404f43f8ee6SDavid du Colombier */
405f43f8ee6SDavid du Colombier
406f43f8ee6SDavid du ColombierTEXT	vector0(SB), $-4
407f43f8ee6SDavid du Colombier	MOVW	$utlbmiss(SB), R26
408f43f8ee6SDavid du Colombier	JMP	(R26)
409f43f8ee6SDavid du Colombier	NOP
410f43f8ee6SDavid du Colombier
411f43f8ee6SDavid du Colombier/*
412f43f8ee6SDavid du Colombier * compute stlb hash index.
413f43f8ee6SDavid du Colombier * must match index calculation in mmu.c/putstlb()
414f43f8ee6SDavid du Colombier *
415f43f8ee6SDavid du Colombier * M(TLBVIRT) [page & asid] in arg, result in arg.
416f43f8ee6SDavid du Colombier * stir in swizzled asid; we get best results with asid in both high & low bits.
417f43f8ee6SDavid du Colombier *
418f43f8ee6SDavid du Colombier * page = tlbvirt >> (PGSHIFT+1);	// ignoring even/odd bit
419f43f8ee6SDavid du Colombier * R27 = ((tlbvirt<<(STLBLOG-8) ^ (uchar)tlbvirt ^ page ^
420f43f8ee6SDavid du Colombier *	((page & (MASK(HIPFNBITS) << STLBLOG)) >> HIPFNBITS)) &
421f43f8ee6SDavid du Colombier *	(STLBSIZE-1)) * 12;
422f43f8ee6SDavid du Colombier */
423f43f8ee6SDavid du Colombier#define STLBHASH(arg, tmp, tmp2) \
424f43f8ee6SDavid du Colombier	MOVW	arg, tmp2; \
425f43f8ee6SDavid du Colombier	SRL	$(PGSHIFT+1), arg;	/* move low page # bits to low bits */ \
426f43f8ee6SDavid du Colombier	CONST	((MASK(HIPFNBITS) << STLBLOG), tmp); \
427f43f8ee6SDavid du Colombier	AND	arg, tmp;		/* extract high page # bits */ \
428f43f8ee6SDavid du Colombier	SRL	$HIPFNBITS, tmp;	/* position them */ \
429f43f8ee6SDavid du Colombier	XOR	tmp, arg;		/* include them */ \
430f43f8ee6SDavid du Colombier	MOVW	tmp2, tmp;		/* asid in low byte */ \
431f43f8ee6SDavid du Colombier	SLL	$(STLBLOG-8), tmp;	/* move asid to high bits */ \
432f43f8ee6SDavid du Colombier	XOR	tmp, arg;		/* include asid in high bits too */ \
433f43f8ee6SDavid du Colombier	AND	$0xff, tmp2, tmp;	/* asid in low byte */ \
434f43f8ee6SDavid du Colombier	XOR	tmp, arg;		/* include asid in low bits */ \
435f43f8ee6SDavid du Colombier	CONST	(STLBSIZE-1, tmp); \
436f43f8ee6SDavid du Colombier	AND	tmp, arg		/* chop to fit */
437f43f8ee6SDavid du Colombier
438f43f8ee6SDavid du ColombierTEXT	utlbmiss(SB), $-4
439f43f8ee6SDavid du Colombier	/*
440f43f8ee6SDavid du Colombier	 * don't use R28 by using constants that span both word halves,
441f43f8ee6SDavid du Colombier	 * it's unsaved so far.  avoid R24 (up in kernel) and R25 (m in kernel).
442f43f8ee6SDavid du Colombier	 */
443f43f8ee6SDavid du Colombier	/* update statistics */
444f43f8ee6SDavid du Colombier	CONST	(MACHADDR, R26)		/* R26 = m-> */
445f43f8ee6SDavid du Colombier	MOVW	16(R26), R27
446f43f8ee6SDavid du Colombier	ADDU	$1, R27
447f43f8ee6SDavid du Colombier	MOVW	R27, 16(R26)		/* m->tlbfault++ */
448f43f8ee6SDavid du Colombier
449f43f8ee6SDavid du Colombier	MOVW	R23, M(DESAVE)		/* save R23 */
450f43f8ee6SDavid du Colombier
451f43f8ee6SDavid du Colombier#ifdef	KUTLBSTATS
452f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R23
453f43f8ee6SDavid du Colombier	AND	$KUSER, R23
454f43f8ee6SDavid du Colombier	BEQ	R23, kmiss
455f43f8ee6SDavid du Colombier
456f43f8ee6SDavid du Colombier	MOVW	24(R26), R27
457f43f8ee6SDavid du Colombier	ADDU	$1, R27
458f43f8ee6SDavid du Colombier	MOVW	R27, 24(R26)		/* m->utlbfault++ */
459f43f8ee6SDavid du Colombier	JMP	either
460f43f8ee6SDavid du Colombierkmiss:
461f43f8ee6SDavid du Colombier	MOVW	20(R26), R27
462f43f8ee6SDavid du Colombier	ADDU	$1, R27
463f43f8ee6SDavid du Colombier	MOVW	R27, 20(R26)		/* m->ktlbfault++ */
464f43f8ee6SDavid du Colombiereither:
465f43f8ee6SDavid du Colombier#endif
466f43f8ee6SDavid du Colombier
467f43f8ee6SDavid du Colombier	/* compute stlb index */
468f43f8ee6SDavid du Colombier	EHB
469f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R27		/* asid in low byte */
470f43f8ee6SDavid du Colombier	STLBHASH(R27, R26, R23)
471f43f8ee6SDavid du Colombier	MOVW	M(DESAVE), R23		/* restore R23 */
472f43f8ee6SDavid du Colombier
473f43f8ee6SDavid du Colombier	/* scale to a byte index (multiply by 12) */
474f43f8ee6SDavid du Colombier	SLL	$1, R27, R26		/* × 2 */
475f43f8ee6SDavid du Colombier	ADDU	R26, R27		/* × 3 */
476f43f8ee6SDavid du Colombier	SLL	$2, R27			/* × 12 */
477f43f8ee6SDavid du Colombier
478f43f8ee6SDavid du Colombier	CONST	(MACHADDR, R26)		/* R26 = m-> */
479f43f8ee6SDavid du Colombier	MOVW	4(R26), R26		/* R26 = m->stb */
480f43f8ee6SDavid du Colombier	ADDU	R26, R27		/* R27 = &m->stb[hash] */
481f43f8ee6SDavid du Colombier
482f43f8ee6SDavid du Colombier	MOVW	M(BADVADDR), R26
483f43f8ee6SDavid du Colombier	AND	$BY2PG, R26
484f43f8ee6SDavid du Colombier	BNE	R26, utlbodd		/* odd page? */
485f43f8ee6SDavid du Colombier	NOP
486f43f8ee6SDavid du Colombier
487f43f8ee6SDavid du Colombierutlbeven:
488f43f8ee6SDavid du Colombier	MOVW	4(R27), R26		/* R26 = m->stb[hash].phys0 */
489f43f8ee6SDavid du Colombier	BEQ	R26, stlbm		/* nothing cached? do it the hard way */
490f43f8ee6SDavid du Colombier	NOP
491f43f8ee6SDavid du Colombier	MOVW	R26, M(TLBPHYS0)
492f43f8ee6SDavid du Colombier	EHB
493f43f8ee6SDavid du Colombier	MOVW	8(R27), R26		/* R26 = m->stb[hash].phys1 */
494f43f8ee6SDavid du Colombier	JMP	utlbcom
495f43f8ee6SDavid du Colombier	MOVW	R26, M(TLBPHYS1)	/* branch delay slot */
496f43f8ee6SDavid du Colombier
497f43f8ee6SDavid du Colombierutlbodd:
498f43f8ee6SDavid du Colombier	MOVW	8(R27), R26		/* R26 = m->stb[hash].phys1 */
499f43f8ee6SDavid du Colombier	BEQ	R26, stlbm		/* nothing cached? do it the hard way */
500f43f8ee6SDavid du Colombier	NOP
501f43f8ee6SDavid du Colombier	MOVW	R26, M(TLBPHYS1)
502f43f8ee6SDavid du Colombier	EHB
503f43f8ee6SDavid du Colombier	MOVW	4(R27), R26		/* R26 = m->stb[hash].phys0 */
504f43f8ee6SDavid du Colombier	MOVW	R26, M(TLBPHYS0)
505f43f8ee6SDavid du Colombier
506f43f8ee6SDavid du Colombierutlbcom:
507f43f8ee6SDavid du Colombier	EHB				/* MTC0/MFC0 hazard */
508f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R26
509f43f8ee6SDavid du Colombier	MOVW	(R27), R27		/* R27 = m->stb[hash].virt */
510f43f8ee6SDavid du Colombier	BEQ	R27, stlbm		/* nothing cached? do it the hard way */
511f43f8ee6SDavid du Colombier	NOP
512f43f8ee6SDavid du Colombier	/* is the stlb entry for the right virtual address? */
513f43f8ee6SDavid du Colombier	BNE	R26, R27, stlbm		/* M(TLBVIRT) != m->stb[hash].virt? */
514f43f8ee6SDavid du Colombier	NOP
515f43f8ee6SDavid du Colombier
516f43f8ee6SDavid du Colombier	/* if an entry exists, overwrite it, else write a random one */
517f43f8ee6SDavid du Colombier	CONST	(PGSZ, R27)
518f43f8ee6SDavid du Colombier	MOVW	R27, M(PAGEMASK)	/* select page size */
519f43f8ee6SDavid du Colombier	EHB
520f43f8ee6SDavid du Colombier	TLBP				/* probe tlb */
521f43f8ee6SDavid du Colombier	EHB
522f43f8ee6SDavid du Colombier	MOVW	M(INDEX), R26
523f43f8ee6SDavid du Colombier	BGEZ	R26, utlindex		/* if tlb entry found, rewrite it */
524f43f8ee6SDavid du Colombier	EHB				/* delay slot */
525f43f8ee6SDavid du Colombier	TLBWR				/* else write random tlb entry */
526f43f8ee6SDavid du Colombier	ERET
527f43f8ee6SDavid du Colombierutlindex:
528f43f8ee6SDavid du Colombier	TLBWI				/* write indexed tlb entry */
529f43f8ee6SDavid du Colombier	ERET
530f43f8ee6SDavid du Colombier
531f43f8ee6SDavid du Colombier/* not in the stlb either; make trap.c figure it out */
532f43f8ee6SDavid du Colombierstlbm:
533f43f8ee6SDavid du Colombier	MOVW	$exception(SB), R26
534f43f8ee6SDavid du Colombier	JMP	(R26)
535f43f8ee6SDavid du Colombier	NOP
536f43f8ee6SDavid du Colombier
537f43f8ee6SDavid du ColombierTEXT	stlbhash(SB), $-4
538f43f8ee6SDavid du Colombier	STLBHASH(R1, R2, R3)
539f43f8ee6SDavid du Colombier	RETURN
540f43f8ee6SDavid du Colombier
541f43f8ee6SDavid du ColombierTEXT	vector100(SB), $-4
542f43f8ee6SDavid du Colombier	MOVW	$exception(SB), R26
543f43f8ee6SDavid du Colombier	JMP	(R26)
544f43f8ee6SDavid du Colombier	NOP
545f43f8ee6SDavid du Colombier
546f43f8ee6SDavid du ColombierTEXT	vector180(SB), $-4
547f43f8ee6SDavid du Colombier	MOVW	$exception(SB), R26
548f43f8ee6SDavid du Colombier	JMP	(R26)
549f43f8ee6SDavid du Colombier	NOP
550f43f8ee6SDavid du Colombier
551f43f8ee6SDavid du ColombierTEXT	exception(SB), $-4
552f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R26
553f43f8ee6SDavid du Colombier	AND	$KUSER, R26, R27
554f43f8ee6SDavid du Colombier	BEQ	R27, waskernel
555f43f8ee6SDavid du Colombier	MOVW	SP, R27			/* delay slot */
556f43f8ee6SDavid du Colombier
557f43f8ee6SDavid du Colombierwasuser:
558f43f8ee6SDavid du Colombier	CONST	(MACHADDR, SP)		/*  m-> */
559f43f8ee6SDavid du Colombier	MOVW	8(SP), SP		/*  m->proc */
560f43f8ee6SDavid du Colombier	MOVW	8(SP), SP		/*  m->proc->kstack */
561f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R26		/* redundant load */
562f43f8ee6SDavid du Colombier	ADDU	$(KSTACK-UREGSIZE), SP
563f43f8ee6SDavid du Colombier	MOVW	R31, Ureg_r31(SP)
564f43f8ee6SDavid du Colombier
565f43f8ee6SDavid du Colombier	JAL	savereg1(SB)
566f43f8ee6SDavid du Colombier	NOP
567f43f8ee6SDavid du Colombier
568f43f8ee6SDavid du Colombier	MOVW	R30, Ureg_r30(SP)
569f43f8ee6SDavid du Colombier	MOVW	R(MACH), Ureg_r25(SP)
570f43f8ee6SDavid du Colombier	MIPS24KNOP
571f43f8ee6SDavid du Colombier	MOVW	R(USER), Ureg_r24(SP)
572f43f8ee6SDavid du Colombier
573f43f8ee6SDavid du Colombier	MOVW	$setR30(SB), R30
574f43f8ee6SDavid du Colombier	CONST	(MACHADDR, R(MACH))		/* R(MACH) = m-> */
575f43f8ee6SDavid du Colombier	MOVW	8(R(MACH)), R(USER)		/* up = m->proc */
576f43f8ee6SDavid du Colombier
577f43f8ee6SDavid du Colombier	AND	$(EXCMASK<<2), R26, R1
578f43f8ee6SDavid du Colombier	SUBU	$(CSYS<<2), R1
579f43f8ee6SDavid du Colombier	BNE	R1, notsys
580f43f8ee6SDavid du Colombier	NOP
581f43f8ee6SDavid du Colombier
582f43f8ee6SDavid du Colombier	/* the carrera does this: */
583f43f8ee6SDavid du Colombier//	ADDU	$8, SP, R1			/* first arg for syscall */
584f43f8ee6SDavid du Colombier
585f43f8ee6SDavid du Colombier	MOVW	SP, R1				/* first arg for syscall */
586f43f8ee6SDavid du Colombier	JAL	syscall(SB)
587f43f8ee6SDavid du Colombier	SUBU	$Notuoffset, SP			/* delay slot */
588f43f8ee6SDavid du Colombiersysrestore:
589f43f8ee6SDavid du Colombier	JAL	restreg1(SB)
590f43f8ee6SDavid du Colombier	ADDU	$Notuoffset, SP			/* delay slot */
591f43f8ee6SDavid du Colombier
592f43f8ee6SDavid du Colombier	MOVW	Ureg_r31(SP), R31
593f43f8ee6SDavid du Colombier	MOVW	Ureg_status(SP), R26
594f43f8ee6SDavid du Colombier	MOVW	Ureg_r30(SP), R30
595f43f8ee6SDavid du Colombier	MOVW	R26, M(STATUS)
596f43f8ee6SDavid du Colombier	EHB
597f43f8ee6SDavid du Colombier	MOVW	Ureg_pc(SP), R26		/* old pc */
598f43f8ee6SDavid du Colombier	MOVW	Ureg_sp(SP), SP
599f43f8ee6SDavid du Colombier	MOVW	R26, M(EPC)
600f43f8ee6SDavid du Colombier	ERET
601f43f8ee6SDavid du Colombier
602f43f8ee6SDavid du Colombiernotsys:
603f43f8ee6SDavid du Colombier	JAL	savereg2(SB)
604f43f8ee6SDavid du Colombier	NOP
605f43f8ee6SDavid du Colombier
606f43f8ee6SDavid du Colombier	/* the carrera does this: */
607f43f8ee6SDavid du Colombier//	ADDU	$8, SP, R1			/* first arg for trap */
608f43f8ee6SDavid du Colombier
609f43f8ee6SDavid du Colombier	MOVW	SP, R1				/* first arg for trap */
610f43f8ee6SDavid du Colombier	JAL	trap(SB)
611f43f8ee6SDavid du Colombier	SUBU	$Notuoffset, SP			/* delay slot */
612f43f8ee6SDavid du Colombier
613f43f8ee6SDavid du Colombier	ADDU	$Notuoffset, SP
614f43f8ee6SDavid du Colombier
615f43f8ee6SDavid du Colombierrestore:
616f43f8ee6SDavid du Colombier	JAL	restreg1(SB)
617f43f8ee6SDavid du Colombier	NOP
618f43f8ee6SDavid du Colombier	JAL	restreg2(SB)		/* restores R28, among others */
619f43f8ee6SDavid du Colombier	NOP
620f43f8ee6SDavid du Colombier
621f43f8ee6SDavid du Colombier	MOVW	Ureg_r30(SP), R30
622f43f8ee6SDavid du Colombier	MOVW	Ureg_r31(SP), R31
623f43f8ee6SDavid du Colombier	MOVW	Ureg_r25(SP), R(MACH)
624f43f8ee6SDavid du Colombier	MOVW	Ureg_r24(SP), R(USER)
625f43f8ee6SDavid du Colombier	MOVW	Ureg_sp(SP), SP
626f43f8ee6SDavid du Colombier	MOVW	R26, M(EPC)
627f43f8ee6SDavid du Colombier	ERET
628f43f8ee6SDavid du Colombier
629f43f8ee6SDavid du Colombierwaskernel:
630f43f8ee6SDavid du Colombier	SUBU	$UREGSIZE, SP
631f43f8ee6SDavid du Colombier	OR	$7, SP				/* conservative rounding */
632f43f8ee6SDavid du Colombier	XOR	$7, SP
633f43f8ee6SDavid du Colombier	MOVW	R31, Ureg_r31(SP)
634f43f8ee6SDavid du Colombier
635f43f8ee6SDavid du Colombier	JAL	savereg1(SB)
636f43f8ee6SDavid du Colombier	NOP
637f43f8ee6SDavid du Colombier	JAL	savereg2(SB)
638f43f8ee6SDavid du Colombier	NOP
639f43f8ee6SDavid du Colombier
640f43f8ee6SDavid du Colombier	/* the carrera does this: */
641f43f8ee6SDavid du Colombier//	ADDU	$8, SP, R1			/* first arg for trap */
642f43f8ee6SDavid du Colombier
643f43f8ee6SDavid du Colombier	MOVW	SP, R1			/* first arg for trap */
644f43f8ee6SDavid du Colombier	JAL	trap(SB)
645f43f8ee6SDavid du Colombier	SUBU	$Notuoffset, SP			/* delay slot */
646f43f8ee6SDavid du Colombier
647f43f8ee6SDavid du Colombier	ADDU	$Notuoffset, SP
648f43f8ee6SDavid du Colombier
649f43f8ee6SDavid du Colombier	JAL	restreg1(SB)
650f43f8ee6SDavid du Colombier	NOP
651f43f8ee6SDavid du Colombier
652f43f8ee6SDavid du Colombier	/*
653f43f8ee6SDavid du Colombier	 * if about to return to `wait', interrupt arrived just before
654f43f8ee6SDavid du Colombier	 * executing wait, so move saved pc past it.
655f43f8ee6SDavid du Colombier	 */
656f43f8ee6SDavid du Colombier	MOVW	Ureg_pc(SP), R26
657f43f8ee6SDavid du Colombier	MOVW	R26, R31
658f43f8ee6SDavid du Colombier	MOVW	$wait(SB), R1
659f43f8ee6SDavid du Colombier	SUBU	R1, R31
660f43f8ee6SDavid du Colombier	BNE	R31, notwait
661f43f8ee6SDavid du Colombier	NOP
662f43f8ee6SDavid du Colombier	ADD	$BY2WD, R26		/* advance saved pc */
663f43f8ee6SDavid du Colombier	MOVW	R26, Ureg_pc(SP)
664f43f8ee6SDavid du Colombiernotwait:
665f43f8ee6SDavid du Colombier	JAL	restreg2(SB)		/* restores R28, among others */
666f43f8ee6SDavid du Colombier	NOP
667f43f8ee6SDavid du Colombier
668f43f8ee6SDavid du Colombier	MOVW	Ureg_r31(SP), R31
669f43f8ee6SDavid du Colombier	MOVW	Ureg_sp(SP), SP
670f43f8ee6SDavid du Colombier	MOVW	R26, M(EPC)
671f43f8ee6SDavid du Colombier	ERET
672f43f8ee6SDavid du Colombier
673f43f8ee6SDavid du ColombierTEXT	forkret(SB), $0
674f43f8ee6SDavid du Colombier	JMP	sysrestore
675f43f8ee6SDavid du Colombier	MOVW	R0, R1			/* delay slot; child returns 0 */
676f43f8ee6SDavid du Colombier
677f43f8ee6SDavid du Colombier/*
678f43f8ee6SDavid du Colombier * save mandatory registers.
679f43f8ee6SDavid du Colombier * called with old M(STATUS) in R26.
680f43f8ee6SDavid du Colombier * called with old SP in R27
681f43f8ee6SDavid du Colombier * returns with M(CAUSE) in R26
682f43f8ee6SDavid du Colombier */
683f43f8ee6SDavid du ColombierTEXT	savereg1(SB), $-4
684f43f8ee6SDavid du Colombier	MOVW	R1, Ureg_r1(SP)
685f43f8ee6SDavid du Colombier
686f43f8ee6SDavid du Colombier	MOVW	$(~KMODEMASK),R1	/* don't use R28, it's unsaved so far */
687f43f8ee6SDavid du Colombier	AND	R26, R1
688f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)
689f43f8ee6SDavid du Colombier	EHB
690f43f8ee6SDavid du Colombier
691f43f8ee6SDavid du Colombier	MOVW	R26, Ureg_status(SP)	/* status */
692f43f8ee6SDavid du Colombier	MOVW	R27, Ureg_sp(SP)	/* user SP */
693f43f8ee6SDavid du Colombier
694f43f8ee6SDavid du Colombier	MOVW	M(EPC), R1
695f43f8ee6SDavid du Colombier	MOVW	M(CAUSE), R26
696f43f8ee6SDavid du Colombier
697f43f8ee6SDavid du Colombier	MOVW	R23, Ureg_r23(SP)
698f43f8ee6SDavid du Colombier	MOVW	R22, Ureg_r22(SP)
699f43f8ee6SDavid du Colombier	MIPS24KNOP
700f43f8ee6SDavid du Colombier	MOVW	R21, Ureg_r21(SP)
701f43f8ee6SDavid du Colombier	MOVW	R20, Ureg_r20(SP)
702f43f8ee6SDavid du Colombier	MIPS24KNOP
703f43f8ee6SDavid du Colombier	MOVW	R19, Ureg_r19(SP)
704f43f8ee6SDavid du Colombier	MOVW	R1, Ureg_pc(SP)
705f43f8ee6SDavid du Colombier	RETURN
706f43f8ee6SDavid du Colombier
707f43f8ee6SDavid du Colombier/*
708f43f8ee6SDavid du Colombier * all other registers.
709f43f8ee6SDavid du Colombier * called with M(CAUSE) in R26
710f43f8ee6SDavid du Colombier */
711f43f8ee6SDavid du ColombierTEXT	savereg2(SB), $-4
712f43f8ee6SDavid du Colombier	MOVW	R2, Ureg_r2(SP)
713f43f8ee6SDavid du Colombier
714f43f8ee6SDavid du Colombier	MOVW	M(BADVADDR), R2
715f43f8ee6SDavid du Colombier	MOVW	R26, Ureg_cause(SP)
716f43f8ee6SDavid du Colombier	MOVW	M(TLBVIRT), R1
717f43f8ee6SDavid du Colombier	MOVW	R2, Ureg_badvaddr(SP)
718f43f8ee6SDavid du Colombier	MOVW	R1, Ureg_tlbvirt(SP)
719f43f8ee6SDavid du Colombier	MOVW	HI, R1
720f43f8ee6SDavid du Colombier	MOVW	LO, R2
721f43f8ee6SDavid du Colombier	MOVW	R1, Ureg_hi(SP)
722f43f8ee6SDavid du Colombier	MOVW	R2, Ureg_lo(SP)
723f43f8ee6SDavid du Colombier	MIPS24KNOP
724f43f8ee6SDavid du Colombier					/* LINK,SB,SP missing */
725f43f8ee6SDavid du Colombier	MOVW	R28, Ureg_r28(SP)
726f43f8ee6SDavid du Colombier					/* R27, R26 not saved */
727f43f8ee6SDavid du Colombier					/* R25, R24 missing */
728f43f8ee6SDavid du Colombier					/* R23- R19 saved in save1 */
729f43f8ee6SDavid du Colombier	MOVW	R18, Ureg_r18(SP)
730f43f8ee6SDavid du Colombier	MIPS24KNOP
731f43f8ee6SDavid du Colombier	MOVW	R17, Ureg_r17(SP)
732f43f8ee6SDavid du Colombier	MOVW	R16, Ureg_r16(SP)
733f43f8ee6SDavid du Colombier	MIPS24KNOP
734f43f8ee6SDavid du Colombier	MOVW	R15, Ureg_r15(SP)
735f43f8ee6SDavid du Colombier	MOVW	R14, Ureg_r14(SP)
736f43f8ee6SDavid du Colombier	MIPS24KNOP
737f43f8ee6SDavid du Colombier	MOVW	R13, Ureg_r13(SP)
738f43f8ee6SDavid du Colombier	MOVW	R12, Ureg_r12(SP)
739f43f8ee6SDavid du Colombier	MIPS24KNOP
740f43f8ee6SDavid du Colombier	MOVW	R11, Ureg_r11(SP)
741f43f8ee6SDavid du Colombier	MOVW	R10, Ureg_r10(SP)
742f43f8ee6SDavid du Colombier	MIPS24KNOP
743f43f8ee6SDavid du Colombier	MOVW	R9, Ureg_r9(SP)
744f43f8ee6SDavid du Colombier	MOVW	R8, Ureg_r8(SP)
745f43f8ee6SDavid du Colombier	MIPS24KNOP
746f43f8ee6SDavid du Colombier	MOVW	R7, Ureg_r7(SP)
747f43f8ee6SDavid du Colombier	MOVW	R6, Ureg_r6(SP)
748f43f8ee6SDavid du Colombier	MIPS24KNOP
749f43f8ee6SDavid du Colombier	MOVW	R5, Ureg_r5(SP)
750f43f8ee6SDavid du Colombier	MOVW	R4, Ureg_r4(SP)
751f43f8ee6SDavid du Colombier	MIPS24KNOP
752f43f8ee6SDavid du Colombier	MOVW	R3, Ureg_r3(SP)
753f43f8ee6SDavid du Colombier	RETURN
754f43f8ee6SDavid du Colombier
755f43f8ee6SDavid du ColombierTEXT	restreg1(SB), $-4
756f43f8ee6SDavid du Colombier	MOVW	Ureg_r23(SP), R23
757f43f8ee6SDavid du Colombier	MOVW	Ureg_r22(SP), R22
758f43f8ee6SDavid du Colombier	MOVW	Ureg_r21(SP), R21
759f43f8ee6SDavid du Colombier	MOVW	Ureg_r20(SP), R20
760f43f8ee6SDavid du Colombier	MOVW	Ureg_r19(SP), R19
761f43f8ee6SDavid du Colombier	RETURN
762f43f8ee6SDavid du Colombier
763f43f8ee6SDavid du ColombierTEXT	restreg2(SB), $-4
764f43f8ee6SDavid du Colombier					/* LINK,SB,SP missing */
765f43f8ee6SDavid du Colombier	MOVW	Ureg_r28(SP), R28
766f43f8ee6SDavid du Colombier					/* R27, R26 not saved */
767f43f8ee6SDavid du Colombier					/* R25, R24 missing */
768f43f8ee6SDavid du Colombier					/* R19- R23 restored in rest1 */
769f43f8ee6SDavid du Colombier	MOVW	Ureg_r18(SP), R18
770f43f8ee6SDavid du Colombier	MOVW	Ureg_r17(SP), R17
771f43f8ee6SDavid du Colombier	MOVW	Ureg_r16(SP), R16
772f43f8ee6SDavid du Colombier	MOVW	Ureg_r15(SP), R15
773f43f8ee6SDavid du Colombier	MOVW	Ureg_r14(SP), R14
774f43f8ee6SDavid du Colombier	MOVW	Ureg_r13(SP), R13
775f43f8ee6SDavid du Colombier	MOVW	Ureg_r12(SP), R12
776f43f8ee6SDavid du Colombier	MOVW	Ureg_r11(SP), R11
777f43f8ee6SDavid du Colombier	MOVW	Ureg_r10(SP), R10
778f43f8ee6SDavid du Colombier	MOVW	Ureg_r9(SP), R9
779f43f8ee6SDavid du Colombier	MOVW	Ureg_r8(SP), R8
780f43f8ee6SDavid du Colombier	MOVW	Ureg_r7(SP), R7
781f43f8ee6SDavid du Colombier	MOVW	Ureg_r6(SP), R6
782f43f8ee6SDavid du Colombier	MOVW	Ureg_r5(SP), R5
783f43f8ee6SDavid du Colombier	MOVW	Ureg_r4(SP), R4
784f43f8ee6SDavid du Colombier	MOVW	Ureg_r3(SP), R3
785f43f8ee6SDavid du Colombier	MOVW	Ureg_lo(SP), R2
786f43f8ee6SDavid du Colombier	MOVW	Ureg_hi(SP), R1
787f43f8ee6SDavid du Colombier	MOVW	R2, LO
788f43f8ee6SDavid du Colombier	MOVW	R1, HI
789f43f8ee6SDavid du Colombier
790f43f8ee6SDavid du Colombier	MOVW	Ureg_status(SP), R1
791f43f8ee6SDavid du Colombier	MOVW	Ureg_r2(SP), R2
792f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)		/* could change interruptibility */
793f43f8ee6SDavid du Colombier	EHB
794f43f8ee6SDavid du Colombier	MOVW	Ureg_r1(SP), R1	/* BOTCH */
795f43f8ee6SDavid du Colombier	MOVW	Ureg_pc(SP), R26
796f43f8ee6SDavid du Colombier	RETURN
797f43f8ee6SDavid du Colombier
798f43f8ee6SDavid du Colombier#ifdef OLD_MIPS_EXAMPLE
799f43f8ee6SDavid du Colombier/* this appears to be a dreg from the distant past */
800f43f8ee6SDavid du ColombierTEXT	rfnote(SB), $0
801f43f8ee6SDavid du Colombier	MOVW	R1, R26			/* 1st arg is &uregpointer */
802f43f8ee6SDavid du Colombier	JMP	restore
803f43f8ee6SDavid du Colombier	SUBU	$(BY2WD), R26, SP	/* delay slot: pc hole */
804f43f8ee6SDavid du Colombier#endif
805f43f8ee6SDavid du Colombier
806f43f8ee6SDavid du Colombier/*
807f43f8ee6SDavid du Colombier * degenerate floating-point stuff
808f43f8ee6SDavid du Colombier */
809f43f8ee6SDavid du Colombier
810f43f8ee6SDavid du ColombierTEXT	clrfpintr(SB), $0
811f43f8ee6SDavid du Colombier	RETURN
812f43f8ee6SDavid du Colombier
813f43f8ee6SDavid du ColombierTEXT	savefpregs(SB), $0
814f43f8ee6SDavid du Colombier	RETURN
815f43f8ee6SDavid du Colombier
816f43f8ee6SDavid du ColombierTEXT	restfpregs(SB), $0
817f43f8ee6SDavid du Colombier	RETURN
818f43f8ee6SDavid du Colombier
819f43f8ee6SDavid du ColombierTEXT	fcr31(SB), $0			/* fp csr */
820f43f8ee6SDavid du Colombier	MOVW	R0, R1
821f43f8ee6SDavid du Colombier	RETURN
822f43f8ee6SDavid du Colombier
823f43f8ee6SDavid du Colombier/*
824f43f8ee6SDavid du Colombier * Emulate 68020 test and set: load linked / store conditional
825f43f8ee6SDavid du Colombier */
826f43f8ee6SDavid du Colombier
827f43f8ee6SDavid du ColombierTEXT	tas(SB), $0
828f43f8ee6SDavid du Colombier	MOVW	R1, R2		/* address of key */
829f43f8ee6SDavid du Colombiertas1:
830f43f8ee6SDavid du Colombier	MOVW	$1, R3
831f43f8ee6SDavid du Colombier	LL(2, 1)
832f43f8ee6SDavid du Colombier	NOP
833f43f8ee6SDavid du Colombier	SC(2, 3)
834f43f8ee6SDavid du Colombier	NOP
835f43f8ee6SDavid du Colombier	BEQ	R3, tas1
836f43f8ee6SDavid du Colombier	NOP
837f43f8ee6SDavid du Colombier	RETURN
838f43f8ee6SDavid du Colombier
839f43f8ee6SDavid du ColombierTEXT	_xinc(SB), $0
840f43f8ee6SDavid du Colombier	MOVW	R1, R2		/* address of counter */
841f43f8ee6SDavid du Colombierloop:
842f43f8ee6SDavid du Colombier	MOVW	$1, R3
843f43f8ee6SDavid du Colombier	LL(2, 1)
844f43f8ee6SDavid du Colombier	NOP
845*51f48f69SDavid du Colombier	ADDU	R1, R3
846*51f48f69SDavid du Colombier	MOVW	R3, R1		/* return new value */
847f43f8ee6SDavid du Colombier	SC(2, 3)
848f43f8ee6SDavid du Colombier	NOP
849f43f8ee6SDavid du Colombier	BEQ	R3, loop
850f43f8ee6SDavid du Colombier	NOP
851f43f8ee6SDavid du Colombier	RETURN
852f43f8ee6SDavid du Colombier
853f43f8ee6SDavid du ColombierTEXT	_xdec(SB), $0
854f43f8ee6SDavid du Colombier	SYNC
855f43f8ee6SDavid du Colombier	MOVW	R1, R2		/* address of counter */
856f43f8ee6SDavid du Colombierloop1:
857f43f8ee6SDavid du Colombier	MOVW	$-1, R3
858f43f8ee6SDavid du Colombier	LL(2, 1)
859f43f8ee6SDavid du Colombier	NOP
860*51f48f69SDavid du Colombier	ADDU	R1, R3
861*51f48f69SDavid du Colombier	MOVW	R3, R1		/* return new value */
862f43f8ee6SDavid du Colombier	SC(2, 3)
863f43f8ee6SDavid du Colombier	NOP
864f43f8ee6SDavid du Colombier	BEQ	R3, loop1
865f43f8ee6SDavid du Colombier	NOP
866f43f8ee6SDavid du Colombier	RETURN
867f43f8ee6SDavid du Colombier
868*51f48f69SDavid du Colombier/* used by the semaphore implementation */
869f43f8ee6SDavid du ColombierTEXT cmpswap(SB), $0
870f43f8ee6SDavid du Colombier	MOVW	R1, R2		/* address of key */
871f43f8ee6SDavid du Colombier	MOVW	old+4(FP), R3	/* old value */
872f43f8ee6SDavid du Colombier	MOVW	new+8(FP), R4	/* new value */
873f43f8ee6SDavid du Colombier	LL(2, 1)		/* R1 = (R2) */
874f43f8ee6SDavid du Colombier	NOP
875f43f8ee6SDavid du Colombier	BNE	R1, R3, fail
876f43f8ee6SDavid du Colombier	NOP
877f43f8ee6SDavid du Colombier	MOVW	R4, R1
878f43f8ee6SDavid du Colombier	SC(2, 1)	/* (R2) = R1 if (R2) hasn't changed; R1 = success */
879f43f8ee6SDavid du Colombier	NOP
880f43f8ee6SDavid du Colombier	RETURN
881f43f8ee6SDavid du Colombierfail:
882f43f8ee6SDavid du Colombier	MOVW	R0, R1
883f43f8ee6SDavid du Colombier	RETURN
884f43f8ee6SDavid du Colombier
885f43f8ee6SDavid du Colombier/*
886f43f8ee6SDavid du Colombier *  cache manipulation
887f43f8ee6SDavid du Colombier */
888f43f8ee6SDavid du Colombier
889f43f8ee6SDavid du Colombier/*
890f43f8ee6SDavid du Colombier *  we avoided using R4, R5, R6, and R7 so gotopc can call us without saving
891f43f8ee6SDavid du Colombier *  them, but gotopc is now gone.
892f43f8ee6SDavid du Colombier */
893f43f8ee6SDavid du ColombierTEXT	icflush(SB), $-4			/* icflush(virtaddr, count) */
894f43f8ee6SDavid du Colombier	MOVW	4(FP), R9
895f43f8ee6SDavid du Colombier	DI(10)				/* intrs off, old status -> R10 */
896f43f8ee6SDavid du Colombier	UBARRIERS(7, R7, ichb);		/* return to kseg1 (uncached) */
897f43f8ee6SDavid du Colombier	ADDU	R1, R9			/* R9 = last address */
898f43f8ee6SDavid du Colombier	MOVW	$(~(CACHELINESZ-1)), R8
899f43f8ee6SDavid du Colombier	AND	R1, R8			/* R8 = first address, rounded down */
900f43f8ee6SDavid du Colombier	ADDU	$(CACHELINESZ-1), R9
901f43f8ee6SDavid du Colombier	AND	$(~(CACHELINESZ-1)), R9	/* round last address up */
902f43f8ee6SDavid du Colombier	SUBU	R8, R9			/* R9 = revised count */
903f43f8ee6SDavid du Colombiericflush1:
904f43f8ee6SDavid du Colombier//	CACHE	PD+HWB, (R8)		/* flush D to ram */
905f43f8ee6SDavid du Colombier	CACHE	PI+HINV, (R8)		/* invalidate in I */
906f43f8ee6SDavid du Colombier	SUBU	$CACHELINESZ, R9
907f43f8ee6SDavid du Colombier	BGTZ	R9, icflush1
908f43f8ee6SDavid du Colombier	ADDU	$CACHELINESZ, R8	/* delay slot */
909f43f8ee6SDavid du Colombier
910f43f8ee6SDavid du Colombier	BARRIERS(7, R7, ic2hb);		/* return to kseg0 (cached) */
911f43f8ee6SDavid du Colombier	MOVW	R10, M(STATUS)
912f43f8ee6SDavid du Colombier	JRHB(31)			/* return and clear all hazards */
913f43f8ee6SDavid du Colombier
914f43f8ee6SDavid du ColombierTEXT	dcflush(SB), $-4			/* dcflush(virtaddr, count) */
915f43f8ee6SDavid du Colombier	MOVW	4(FP), R9
916f43f8ee6SDavid du Colombier	DI(10)				/* intrs off, old status -> R10 */
917f43f8ee6SDavid du Colombier	SYNC
918f43f8ee6SDavid du Colombier	EHB
919f43f8ee6SDavid du Colombier	ADDU	R1, R9			/* R9 = last address */
920f43f8ee6SDavid du Colombier	MOVW	$(~(CACHELINESZ-1)), R8
921f43f8ee6SDavid du Colombier	AND	R1, R8			/* R8 = first address, rounded down */
922f43f8ee6SDavid du Colombier	ADDU	$(CACHELINESZ-1), R9
923f43f8ee6SDavid du Colombier	AND	$(~(CACHELINESZ-1)), R9	/* round last address up */
924f43f8ee6SDavid du Colombier	SUBU	R8, R9			/* R9 = revised count */
925f43f8ee6SDavid du Colombierdcflush1:
926f43f8ee6SDavid du Colombier//	CACHE	PI+HINV, (R8)		/* invalidate in I */
927f43f8ee6SDavid du Colombier	CACHE	PD+HWBI, (R8)		/* flush & invalidate in D */
928f43f8ee6SDavid du Colombier	SUBU	$CACHELINESZ, R9
929f43f8ee6SDavid du Colombier	BGTZ	R9, dcflush1
930f43f8ee6SDavid du Colombier	ADDU	$CACHELINESZ, R8	/* delay slot */
931f43f8ee6SDavid du Colombier	SYNC
932f43f8ee6SDavid du Colombier	EHB
933f43f8ee6SDavid du Colombier	MOVW	R10, M(STATUS)
934f43f8ee6SDavid du Colombier	JRHB(31)			/* return and clear all hazards */
935f43f8ee6SDavid du Colombier
936f43f8ee6SDavid du Colombier/* the i and d caches may be different sizes, so clean them separately */
937f43f8ee6SDavid du ColombierTEXT	cleancache(SB), $-4
938f43f8ee6SDavid du Colombier	DI(10)				/* intrs off, old status -> R10 */
939f43f8ee6SDavid du Colombier
940f43f8ee6SDavid du Colombier	UBARRIERS(7, R7, cchb);		/* return to kseg1 (uncached) */
941f43f8ee6SDavid du Colombier	MOVW	R0, R1			/* index, not address */
942f43f8ee6SDavid du Colombier	MOVW	$ICACHESIZE, R9
943f43f8ee6SDavid du Colombiericcache:
944f43f8ee6SDavid du Colombier	CACHE	PI+IWBI, (R1)		/* flush & invalidate I by index */
945f43f8ee6SDavid du Colombier	SUBU	$CACHELINESZ, R9
946f43f8ee6SDavid du Colombier	BGTZ	R9, iccache
947f43f8ee6SDavid du Colombier	ADDU	$CACHELINESZ, R1	/* delay slot */
948f43f8ee6SDavid du Colombier
949f43f8ee6SDavid du Colombier	BARRIERS(7, R7, cc2hb);		/* return to kseg0 (cached) */
950f43f8ee6SDavid du Colombier
951f43f8ee6SDavid du Colombier	MOVW	R0, R1			/* index, not address */
952f43f8ee6SDavid du Colombier	MOVW	$DCACHESIZE, R9
953f43f8ee6SDavid du Colombierdccache:
954f43f8ee6SDavid du Colombier	CACHE	PD+IWBI, (R1)		/* flush & invalidate D by index */
955f43f8ee6SDavid du Colombier	SUBU	$CACHELINESZ, R9
956f43f8ee6SDavid du Colombier	BGTZ	R9, dccache
957f43f8ee6SDavid du Colombier	ADDU	$CACHELINESZ, R1	/* delay slot */
958f43f8ee6SDavid du Colombier
959f43f8ee6SDavid du Colombier	SYNC
960f43f8ee6SDavid du Colombier	MOVW	R10, M(STATUS)
961f43f8ee6SDavid du Colombier	JRHB(31)			/* return and clear all hazards */
962f43f8ee6SDavid du Colombier
963f43f8ee6SDavid du Colombier/*
964f43f8ee6SDavid du Colombier * access to CP0 registers
965f43f8ee6SDavid du Colombier */
966f43f8ee6SDavid du Colombier
967f43f8ee6SDavid du ColombierTEXT	prid(SB), $0
968f43f8ee6SDavid du Colombier	MOVW	M(PRID), R1
969f43f8ee6SDavid du Colombier	RETURN
970f43f8ee6SDavid du Colombier
971f43f8ee6SDavid du ColombierTEXT	rdcount(SB), $0
972f43f8ee6SDavid du Colombier	MOVW	M(COUNT), R1
973f43f8ee6SDavid du Colombier	RETURN
974f43f8ee6SDavid du Colombier
975f43f8ee6SDavid du ColombierTEXT	wrcount(SB), $0
976f43f8ee6SDavid du Colombier	MOVW	R1, M(COUNT)
977f43f8ee6SDavid du Colombier	EHB
978f43f8ee6SDavid du Colombier	RETURN
979f43f8ee6SDavid du Colombier
980f43f8ee6SDavid du ColombierTEXT	wrcompare(SB), $0
981f43f8ee6SDavid du Colombier	MOVW	R1, M(COMPARE)
982f43f8ee6SDavid du Colombier	EHB
983f43f8ee6SDavid du Colombier	RETURN
984f43f8ee6SDavid du Colombier
985f43f8ee6SDavid du ColombierTEXT	rdcompare(SB), $0
986f43f8ee6SDavid du Colombier	MOVW	M(COMPARE), R1
987f43f8ee6SDavid du Colombier	RETURN
988f43f8ee6SDavid du Colombier
989f43f8ee6SDavid du ColombierTEXT	getconfig(SB), $-4
990f43f8ee6SDavid du Colombier	MOVW	M(CONFIG), R1
991f43f8ee6SDavid du Colombier	RETURN
992f43f8ee6SDavid du Colombier
993f43f8ee6SDavid du ColombierTEXT	getconfig1(SB), $-4
994f43f8ee6SDavid du Colombier	MFC0(CONFIG, 1, 1)
995f43f8ee6SDavid du Colombier	RETURN
996f43f8ee6SDavid du Colombier
997f43f8ee6SDavid du ColombierTEXT	getconfig2(SB), $-4
998f43f8ee6SDavid du Colombier	MFC0(CONFIG, 2, 1)
999f43f8ee6SDavid du Colombier	RETURN
1000f43f8ee6SDavid du Colombier
1001f43f8ee6SDavid du ColombierTEXT	getconfig3(SB), $-4
1002f43f8ee6SDavid du Colombier	MFC0(CONFIG, 3, 1)
1003f43f8ee6SDavid du Colombier	RETURN
1004f43f8ee6SDavid du Colombier
1005f43f8ee6SDavid du ColombierTEXT	getconfig4(SB), $-4
1006f43f8ee6SDavid du Colombier	MFC0(CONFIG, 4, 1)
1007f43f8ee6SDavid du Colombier	RETURN
1008f43f8ee6SDavid du Colombier
1009f43f8ee6SDavid du ColombierTEXT	getconfig7(SB), $-4
1010f43f8ee6SDavid du Colombier	MFC0(CONFIG, 7, 1)
1011f43f8ee6SDavid du Colombier	RETURN
1012f43f8ee6SDavid du Colombier
1013f43f8ee6SDavid du ColombierTEXT	gethwreg3(SB), $-4
1014f43f8ee6SDavid du Colombier	RDHWR(3, 1)
1015f43f8ee6SDavid du Colombier	RETURN
1016f43f8ee6SDavid du Colombier
1017f43f8ee6SDavid du ColombierTEXT	getcause(SB), $-4
1018f43f8ee6SDavid du Colombier	MOVW	M(CAUSE), R1
1019f43f8ee6SDavid du Colombier	RETURN
1020f43f8ee6SDavid du Colombier
1021f43f8ee6SDavid du ColombierTEXT	C_fcr0(SB), $-4		/* fp implementation */
1022f43f8ee6SDavid du Colombier	MOVW	$0x500, R1	/* claim to be an r4k, thus have ll/sc */
1023f43f8ee6SDavid du Colombier	RETURN
1024f43f8ee6SDavid du Colombier
1025f43f8ee6SDavid du ColombierTEXT	getstatus(SB), $0
1026f43f8ee6SDavid du Colombier	MOVW	M(STATUS), R1
1027f43f8ee6SDavid du Colombier	RETURN
1028f43f8ee6SDavid du Colombier
1029f43f8ee6SDavid du ColombierTEXT	setstatus(SB), $0
1030f43f8ee6SDavid du Colombier	MOVW	R1, M(STATUS)
1031f43f8ee6SDavid du Colombier	EHB
1032f43f8ee6SDavid du Colombier	RETURN
1033f43f8ee6SDavid du Colombier
1034f43f8ee6SDavid du ColombierTEXT	setwatchhi0(SB), $0
1035f43f8ee6SDavid du Colombier	MOVW	R1, M(WATCHHI)
1036f43f8ee6SDavid du Colombier	EHB
1037f43f8ee6SDavid du Colombier	RETURN
1038f43f8ee6SDavid du Colombier
1039f43f8ee6SDavid du Colombier/*
1040f43f8ee6SDavid du Colombier * beware that the register takes a double-word address, so it's not
1041f43f8ee6SDavid du Colombier * precise to the individual instruction.
1042f43f8ee6SDavid du Colombier */
1043f43f8ee6SDavid du ColombierTEXT	setwatchlo0(SB), $0
1044f43f8ee6SDavid du Colombier	MOVW	R1, M(WATCHLO)
1045f43f8ee6SDavid du Colombier	EHB
1046f43f8ee6SDavid du Colombier	RETURN
1047f43f8ee6SDavid du Colombier
1048f43f8ee6SDavid du ColombierTEXT	setsp(SB), $-4
1049f43f8ee6SDavid du Colombier	MOVW	R1, SP
1050f43f8ee6SDavid du Colombier	RETURN
1051f43f8ee6SDavid du Colombier
1052f43f8ee6SDavid du ColombierTEXT	getintctl(SB), $-4
1053f43f8ee6SDavid du Colombier	MFC0(STATUS, 1, 1)
1054f43f8ee6SDavid du Colombier	RETURN
1055f43f8ee6SDavid du Colombier
1056f43f8ee6SDavid du ColombierTEXT	getsrsctl(SB), $-4
1057f43f8ee6SDavid du Colombier	MFC0(STATUS, 2, 1)
1058f43f8ee6SDavid du Colombier	RETURN
1059f43f8ee6SDavid du Colombier
1060f43f8ee6SDavid du ColombierTEXT	getsrsmap(SB), $-4
1061f43f8ee6SDavid du Colombier	MFC0(STATUS, 3, 1)
1062f43f8ee6SDavid du Colombier	RETURN
1063f43f8ee6SDavid du Colombier
1064f43f8ee6SDavid du ColombierTEXT	getperfctl0(SB), $-4
1065f43f8ee6SDavid du Colombier	MFC0(PERFCOUNT, 0, 1)
1066f43f8ee6SDavid du Colombier	RETURN
1067f43f8ee6SDavid du Colombier
1068f43f8ee6SDavid du ColombierTEXT	getperfctl1(SB), $-4
1069f43f8ee6SDavid du Colombier	MFC0(PERFCOUNT, 2, 1)
1070f43f8ee6SDavid du Colombier	RETURN
1071f43f8ee6SDavid du Colombier
1072f43f8ee6SDavid du Colombier	GLOBL	sanity(SB), $4
1073f43f8ee6SDavid du Colombier	DATA	sanity(SB)/4, $SANITY
1074f43f8ee6SDavid du Colombier
1075f43f8ee6SDavid du Colombier	SCHED
1076