locore_mips3.S revision 1.110
1/*	$NetBSD: locore_mips3.S,v 1.110 2015/06/16 18:12:18 macallan Exp $	*/
2
3/*
4 * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by Jonathan R. Stone for
18 *      the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * Copyright (c) 1992, 1993
37 *	The Regents of the University of California.  All rights reserved.
38 *
39 * This code is derived from software contributed to Berkeley by
40 * Digital Equipment Corporation and Ralph Campbell.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 *    notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 *    notice, this list of conditions and the following disclaimer in the
49 *    documentation and/or other materials provided with the distribution.
50 * 3. Neither the name of the University nor the names of its contributors
51 *    may be used to endorse or promote products derived from this software
52 *    without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * Copyright (C) 1989 Digital Equipment Corporation.
67 * Permission to use, copy, modify, and distribute this software and
68 * its documentation for any purpose and without fee is hereby granted,
69 * provided that the above copyright notice appears in all copies.
70 * Digital Equipment Corporation makes no representations about the
71 * suitability of this software for any purpose.  It is provided "as is"
72 * without express or implied warranty.
73 *
74 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
75 *	v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
76 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
77 *	v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
78 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
79 *	v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
80 *
81 *	@(#)locore.s	8.5 (Berkeley) 1/4/94
82 */
83#include "opt_cputype.h"
84#include "opt_ddb.h"
85#include "opt_lockdebug.h"
86#include "opt_multiprocessor.h"
87#include "opt_kgdb.h"
88
89#include <sys/cdefs.h>
90#include <sys/endian.h>
91
92#include <mips/asm.h>
93#include <mips/cpuregs.h>
94
95#include "assym.h"
96
97/*
98 * XXX We need a cleaner way of handling the instruction hazards of
99 * the various processors.  Here are the relevant rules for the QED 52XX:
100 *	tlbw[ri]	-- two integer ops beforehand
101 *	tlbr		-- two integer ops beforehand
102 *	tlbp		-- two integer ops beforehand
103 *	mtc0	[PageMask,EntryHi,Cp0] -- two integer ops afterwards
104 *	changing JTLB	-- two integer ops afterwards
105 *	mtc0	[EPC,ErrorEPC,Status] -- two int ops afterwards before eret
106 *	config.k0	-- five int ops before kseg0, ckseg0 memref
107 *
108 * For the IDT R4000, some hazards are:
109 *	mtc0/mfc0	one integer op before and after
110 *	tlbp		-- one integer op afterwards
111 * Obvious solution is to take least common denominator.
112 */
113
114/*
115 *============================================================================
116 *
117 *  MIPS III ISA support, part 1: locore exception vectors.
118 *  The following code is copied to the vector locations to which
119 *  the CPU jumps in response to an exception or a TLB miss.
120 *
121 *============================================================================
122 */
123	.set	noreorder
124#if (__mips < 3) || __mips_o32
125	.set	mips3
126#endif
127
128#ifdef _LP64
129#define	_MFC0	dmfc0
130#define	_MTC0	dmtc0
131#else
132#define	_MFC0	mfc0
133#define	_MTC0	mtc0
134#endif
135
136	.text
137
138/*----------------------------------------------------------------------------
139 *
140 * mips3_wbflush --
141 *
142 *	Return when the write buffer is empty.
143 *
144 *	Common for all MIPS3 and greater ISAs
145 *
146 * Results:
147 *	None.
148 *
149 * Side effects:
150 *	None.
151 *
152 *----------------------------------------------------------------------------
153 */
154LEAF(mips3_wbflush)
155XLEAF(loongson2_wbflush)
156XLEAF(mips32_wbflush)
157XLEAF(mips32r2_wbflush)
158XLEAF(mips64_wbflush)
159XLEAF(mips64r2_wbflush)
160	nop
161	sync
162	jr	ra
163	 nop
164END(mips3_wbflush)
165
166
167/*
168 * mips_wait_idle:
169 *
170 *	When no processes are on the runq, cpu_idle branches to
171 *	mips_wait_idle to save power.
172 */
173LEAF(mips_wait_idle)
174	mfc0	v0, MIPS_COP_0_STATUS
175	andi	v1, v0, MIPS_SR_INT_IE
176#if __mips >= 32
177	teqi	v1, 0
178#else
179	beqz	v1, 1f
180	 nop
181#endif
182	andi	v1, v0, MIPS_INT_MASK
183#if __mips >= 32
184	teqi	v1, 0
185#else
186	bnez	v1, 2f
187	 nop
1881:
189	move	a1, v0
190	PANIC("mips_wait_idle: interrupts disabled status=%#x")
191#endif
192
1932:	wait
194	nop
195	nop
196	nop
197	mfc0	v0, MIPS_COP_0_STATUS
198	andi	v1, v0, MIPS_SR_INT_IE
199#if __mips >= 32
200	teqi	v1, 0
201#else
202	beqz	v1, 1b
203	 nop
204#endif
205	andi	v1, v0, MIPS_INT_MASK
206#if __mips >= 32
207	teqi	v1, 0
208#else
209	bnez	v1, 2b
210	 nop
211#endif
212	jr	ra
213	 nop
214END(mips_wait_idle)
215
216/*
217 * uint32_t mips3_cp0_compare_read(void)
218 *
219 *	Return the current value of the CP0 Compare register.
220 */
221LEAF(mips3_cp0_compare_read)
222	mfc0	v0, MIPS_COP_0_COMPARE
223	jr	ra
224	 nop
225END(mips3_cp0_compare_read)
226
227/*
228 * void mips3_cp0_compare_write(uint32_t)
229 *
230 *	Set the value of the CP0 Compare register.
231 */
232LEAF(mips3_cp0_compare_write)
233	mtc0	a0, MIPS_COP_0_COMPARE
234	JR_HB_RA
235END(mips3_cp0_compare_write)
236
237/*
238 * uint32_t mips3_cp0_config_read(void)
239 *
240 *	Return the current value of the CP0 Config register.
241 */
242LEAF(mips3_cp0_config_read)
243	mfc0	v0, MIPS_COP_0_CONFIG
244	jr	ra
245	 nop
246END(mips3_cp0_config_read)
247
248/*
249 * void mips3_cp0_config_write(uint32_t)
250 *
251 *	Set the value of the CP0 Config register.
252 */
253LEAF(mips3_cp0_config_write)
254	mtc0	a0, MIPS_COP_0_CONFIG
255	JR_HB_RA
256END(mips3_cp0_config_write)
257
258#if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
259	.set push
260#ifdef __mips_o32
261	.set mips32
262#else
263	.set mips64
264#endif
265/*
266 * uint32_t mipsNN_cp0_config1_read(void)
267 *
268 *	Return the current value of the CP0 Config (Select 1) register.
269 */
270LEAF(mipsNN_cp0_config1_read)
271	mfc0	v0, MIPS_COP_0_CONFIG, 1
272	jr	ra
273	 nop
274END(mipsNN_cp0_config1_read)
275
276/*
277 * uint32_t mipsNN_cp0_config1_write(uint32_t)
278 *
279 *	Set the current value of the CP0 Config (Select 1) register.
280 */
281LEAF(mipsNN_cp0_config1_write)
282	mtc0	v0, MIPS_COP_0_CONFIG, 1
283	JR_HB_RA
284END(mipsNN_cp0_config1_write)
285
286/*
287 * uint32_t mipsNN_cp0_config2_read(void)
288 *
289 *	Return the current value of the CP0 Config (Select 2) register.
290 */
291LEAF(mipsNN_cp0_config2_read)
292	mfc0	v0, MIPS_COP_0_CONFIG, 2
293	jr	ra
294	 nop
295END(mipsNN_cp0_config2_read)
296
297/*
298 * uint32_t mipsNN_cp0_config3_read(void)
299 *
300 *	Return the current value of the CP0 Config (Select 3) register.
301 */
302LEAF(mipsNN_cp0_config3_read)
303	mfc0	v0, MIPS_COP_0_CONFIG, 3
304	jr	ra
305	 nop
306END(mipsNN_cp0_config3_read)
307
308/*
309 * uintptr_t mipsNN_cp0_watchlo_read(u_int sel)
310 *
311 *	Return the current value of the selected CP0 Watchlo register.
312 */
313LEAF(mipsNN_cp0_watchlo_read)
314	sll	a0, 2
315	PTR_LA	t9, 1f
316	PTR_ADDU t9, a0
317	jr	t9
318	 nop
3191:
320	jr	ra
321	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 0
322	jr	ra
323	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 1
324	jr	ra
325	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 2
326	jr	ra
327	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 3
328	jr	ra
329	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 4
330	jr	ra
331	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 5
332	jr	ra
333	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 6
334	jr	ra
335	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 7
336END(mipsNN_cp0_watchlo_read)
337
338/*
339 * void mipsNN_cp0_watchlo_write(u_int sel, uintptr_t val)
340 *
341 *	Set the current value of the selected CP0 WatchLo register.
342 */
343LEAF(mipsNN_cp0_watchlo_write)
344	sll	a0, 2
345	PTR_LA	t9, 1f
346	PTR_ADDU t9, a0
347	jr	t9
348	 nop
3491:
350	jr	ra
351	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 0
352	jr	ra
353	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 1
354	jr	ra
355	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 2
356	jr	ra
357	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 3
358	jr	ra
359	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 4
360	jr	ra
361	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 5
362	jr	ra
363	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 6
364	jr	ra
365	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 7
366END(mipsNN_cp0_watchlo_write)
367
368/*
369 * uint32_t mipsNN_cp0_watchhi_read(u_int sel)
370 *
371 *	Return the current value of the selected CP0 WatchHi register.
372 */
373LEAF(mipsNN_cp0_watchhi_read)
374	sll	a0, 2
375	PTR_LA	t9, 1f
376	PTR_ADDU t9, a0
377	jr	t9
378	 nop
3791:
380	jr	ra
381	 mfc0	v0, MIPS_COP_0_WATCH_HI, 0
382	jr	ra
383	 mfc0	v0, MIPS_COP_0_WATCH_HI, 1
384	jr	ra
385	 mfc0	v0, MIPS_COP_0_WATCH_HI, 2
386	jr	ra
387	 mfc0	v0, MIPS_COP_0_WATCH_HI, 3
388	jr	ra
389	 mfc0	v0, MIPS_COP_0_WATCH_HI, 4
390	jr	ra
391	 mfc0	v0, MIPS_COP_0_WATCH_HI, 5
392	jr	ra
393	 mfc0	v0, MIPS_COP_0_WATCH_HI, 6
394	jr	ra
395	 mfc0	v0, MIPS_COP_0_WATCH_HI, 7
396END(mipsNN_cp0_watchhi_read)
397
398/*
399 * void mipsNN_cp0_watchhi_write(u_int sel, uint32_t val)
400 *
401 *	Set the current value of the selected CP0 WatchHi register.
402 */
403LEAF(mipsNN_cp0_watchhi_write)
404	sll	a0, 2
405	PTR_LA	t9, 1f
406	PTR_ADDU t9, a0
407	jr	t9
408	 nop
4091:
410	jr	ra
411	 mtc0	a1, MIPS_COP_0_WATCH_HI, 0
412	jr	ra
413	 mtc0	a1, MIPS_COP_0_WATCH_HI, 1
414	jr	ra
415	 mtc0	a1, MIPS_COP_0_WATCH_HI, 2
416	jr	ra
417	 mtc0	a1, MIPS_COP_0_WATCH_HI, 3
418	jr	ra
419	 mtc0	a1, MIPS_COP_0_WATCH_HI, 4
420	jr	ra
421	 mtc0	a1, MIPS_COP_0_WATCH_HI, 5
422	jr	ra
423	 mtc0	a1, MIPS_COP_0_WATCH_HI, 6
424	jr	ra
425	 mtc0	a1, MIPS_COP_0_WATCH_HI, 7
426END(mipsNN_cp0_watchhi_write)
427
428/*
429 * void mipsNN_cp0_ebase_read(void *);
430 *	Get the value of the CP0 EBASE (PRID, select 1) register.
431 */
432LEAF(mipsNN_cp0_ebase_read)
433	jr	ra
434	 mfc0	v0, MIPS_COP_0_EBASE
435END(mipsNN_cp0_ebase_read)
436
437/*
438 * void mipsNN_cp0_ebase_write(void *);
439 *	Set the value of the CP0 EBASE (PRID, select 1) register.
440 */
441LEAF(mipsNN_cp0_ebase_write)
442	and	v0, v0, 0x1ff
443	xor	v0, v0, a0
444	jr	ra
445	 mtc0	v0, MIPS_COP_0_EBASE
446END(mipsNN_cp0_ebase_write)
447
448#if (MIPS32R2 + MIPS64R2) > 0
449/*
450 * void mipsNN_cp0_hwrena_write(void *);
451 *	Set the value of the CP0 HWRENA register.
452 */
453LEAF(mipsNN_cp0_hwrena_write)
454	jr	ra
455	 mtc0	a0, MIPS_COP_0_HWRENA
456END(mipsNN_cp0_hwrena_write)
457
458/*
459 * void mipsNN_cp0_userlocal_write(void *);
460 *	Set the value of the CP0 USERLOCAL (TLB_CONTEXT, select 2) register.
461 */
462LEAF(mipsNN_cp0_userlocal_write)
463	jr	ra
464	 _MTC0	a0, MIPS_COP_0_USERLOCAL
465END(mipsNN_cp0_userlocal_write)
466#endif /* (MIPS32R2 + MIPS64R2) > 0 */
467	.set	pop
468#endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */
469
470/*
471 * uint32_t mips3_cp0_count_read(void)
472 *
473 *	Return the current value of the CP0 Count register.
474 */
475LEAF(mips3_cp0_count_read)
476	mfc0	v0, MIPS_COP_0_COUNT
477	jr	ra
478	 nop
479END(mips3_cp0_count_read)
480WEAK_ALIAS(cpu_counter32, mips3_cp0_count_read)
481
482/*
483 * void mips3_cp0_count_write(uint32_t)
484 *
485 *	Set the value of the CP0 Count register.
486 */
487LEAF(mips3_cp0_count_write)
488	mtc0	a0, MIPS_COP_0_COUNT
489	JR_HB_RA
490END(mips3_cp0_count_write)
491
492/*
493 * uint32_t mips3_cp0_wired_read(void)
494 *
495 *	Return the current value of the CP0 Wired register.
496 */
497LEAF(mips3_cp0_wired_read)
498	mfc0	v0, MIPS_COP_0_TLB_WIRED
499	jr	ra
500	 nop
501END(mips3_cp0_wired_read)
502
503/*
504 * void mips3_cp0_wired_write(uint32_t)
505 *
506 *	Set the value of the CP0 Wired register.
507 */
508LEAF(mips3_cp0_wired_write)
509	mtc0	a0, MIPS_COP_0_TLB_WIRED
510	JR_HB_RA
511END(mips3_cp0_wired_write)
512
513/*
514 * void mips3_cp0_pg_mask_write(uint32_t)
515 *
516 *	Set the value of the CP0 PG_MASK register.
517 */
518LEAF(mips3_cp0_pg_mask_write)
519	mtc0	a0, MIPS_COP_0_TLB_PG_MASK
520	JR_HB_RA
521END(mips3_cp0_pg_mask_write)
522
523#if __mips != 32
524LEAF(mips3_ld)
525#if defined(__mips_o32)
526	mfc0	t0, MIPS_COP_0_STATUS		# turn off interrupts
527	and	t1, t0, ~(MIPS_SR_INT_IE)
528	mtc0	t1, MIPS_COP_0_STATUS
529	COP0_SYNC
530
531	ld	v0, 0(a0)
532#if defined(_MIPS_BSD_API) && \
533    (_MIPS_BSD_API == _MIPS_BSD_API_N32 || _MIPS_BSD_API == _MIPS_BSD_API_LP64)
534	# nothing to do
535#else
536#if _BYTE_ORDER == _BIG_ENDIAN
537	dsll	v1, v0, 32
538	dsra	v1, v1, 32			# low word in v1
539	dsra	v0, v0, 32			# high word in v0
540#else
541	dsra	v1, v0, 32			# high word in v1
542	dsll	v0, v0, 32
543	dsra	v0, v0, 32			# low word in v0
544#endif
545#endif
546
547	mtc0	t0, MIPS_COP_0_STATUS		# restore intr status.
548	JR_HB_RA
549#else /* !__mips_o32 */
550	ld	v0, 0(a0)
551	jr	ra
552	 nop
553#endif /* !__mips_o32 */
554END(mips3_ld)
555
556LEAF(mips3_sd)
557#if defined(__mips_o32)
558	mfc0	t0, MIPS_COP_0_STATUS		# turn off interrupts
559	and	t1, t0, ~(MIPS_SR_INT_IE)
560	mtc0	t1, MIPS_COP_0_STATUS
561	COP0_SYNC
562
563#if defined(_MIPS_BSD_API) && \
564    (_MIPS_BSD_API == _MIPS_BSD_API_N32 || _MIPS_BSD_API == _MIPS_BSD_API_LP64)
565	# nothing to do
566#else
567	# NOTE: a1 is padding!
568
569#if _BYTE_ORDER == _BIG_ENDIAN
570	dsll	a2, a2, 32			# high word in a2
571	dsll	a3, a3, 32			# low word in a3
572	dsrl	a3, a3, 32
573#else
574	dsll	a2, a2, 32			# low word in a2
575	dsrl	a2, a2, 32
576	dsll	a3, a3, 32			# high word in a3
577#endif
578	or	a1, a2, a3
579#endif
580	sd	a1, 0(a0)
581
582	mtc0	t0, MIPS_COP_0_STATUS		# restore intr status.
583	JR_HB_RA
584#else /* !__mips_o32 */
585	sd	a1, 0(a0)
586	jr	ra
587	 nop
588#endif /* !__mips_o32 */
589
590END(mips3_sd)
591
592/*
593 * int badaddr64(uint64_t addr, int len)
594 * See if access to addr with a len type instruction causes a machine check.
595 * len is length of access in bytes (can be 1, 2, 4, or 8).
596 */
597LEAF(badaddr64)
598	PTR_L	v1, L_PCB(MIPS_CURLWP)
599	PTR_LA	v0, _C_LABEL(baderr64)
600
601	/* Enable KX */
602	mfc0	t0, MIPS_COP_0_STATUS
603	or	t1, t0, MIPS3_SR_KX
604#ifdef __mips_o32
605	and	t2, t0, MIPS_SR_INT_IE	# disable interrupts
606	xor	t1, t2
607#endif
608	mtc0	t1, MIPS_COP_0_STATUS
609	COP0_SYNC
610
611#ifdef __mips_o32
612#ifdef __MIPSEB__
613	dsll	a0, a0, 32	# MSW
614	dsll	a1, a1, 32	# LSW
615	dsrl	a1, a1, 32
616#else
617	dsll	a1, a1, 32	# MSW
618	dsll	a0, a0, 32	# LSW
619	dsrl	a0, a0, 32
620#endif
621	or	a0, a1		# combine
622	move	a1, a2		# move up length argument
623#endif /* __mips_o32 */
624
625	bne	a1, 1, 2f
626	 PTR_S	v0, PCB_ONFAULT(v1)
627	b	9f
628	 lbu	v0, (a0)
6292:
630	bne	a1, 2, 4f
631	 nop
632	b	9f
633	 lhu	v0, (a0)
6344:
635	bne	a1, 4, 8f
636	 nop
637	b	9f
638	 INT_L	v0, (a0)
6398:
640	REG_L	v0, (a0)
6419:
642	sync
643	mtc0	t0, MIPS_COP_0_STATUS           # Restore KX
644	COP0_SYNC
645	PTR_S	zero, PCB_ONFAULT(v1)
646	jr	ra
647	 move	v0, zero			# made it w/o errors
648END(badaddr64)
649
650LEAF(baderr64)
651	mtc0	t0, MIPS_COP_0_STATUS		# Restore KX
652	COP0_SYNC
653	PTR_S	zero, PCB_ONFAULT(v1)
654	jr	ra
655	 li	v0, -1
656END(baderr64)
657
658/*
659 * uint64_t mips3_cp0_tlb_entry_hi_probe(void);
660 *
661 * Write 1s to the VPN and ASID fields of Entry_Hi0 to see how many VA bits
662 * and ASID bits are implemented.  Assumes that interrupts are disabled.
663 */
664LEAF(mips3_cp0_tlb_entry_hi_probe)
665	dmfc0	t0, MIPS_COP_0_TLB_HI
666	li	v0, -1		/* all 1s */
667#if defined(__mips_isa_rev) && __mips_isa_rev >= 2
668	dinsu	v0, zero, 62, 2
669#else
670	dsll	v0, v0, 2	/* except the top 2 */
671	dsrl	v0, v0, 2
672#endif
673	dmtc0	v0, MIPS_COP_0_TLB_HI
674	COP0_SYNC
675	dmfc0	v0, MIPS_COP_0_TLB_HI
676	dmtc0	t0, MIPS_COP_0_TLB_HI
677	COP0_SYNC
678	nop
679#ifdef __mips_o32
680	nop
681#if BYTE_ORDER == BIG_ENDIAN
682	srl	v1, v0, 0
683	dsra	v0, v0, 32
684#endif
685#if BYTE_ORDER == LITTLE_ENDIAN
686	dsra	v1, v0, 32
687	srl	v0, v0, 0
688#endif
689#endif /* __mips_o32 */
690	jr	ra
691	 nop
692END(mips3_cp0_tlb_entry_hi_probe)
693
694/*
695 * uint64_t mips3_cp0_tlb_entry_lo_probe(void);
696 *
697 * Write 1s to the PFN field of Entry_Lo0 to see how many
698 * PA bits are implemented.  Assumes that interrupts are disabled.
699 */
700LEAF(mips3_cp0_tlb_entry_lo_probe)
701	dmfc0	t0, MIPS_COP_0_TLB_LO0
702	li	v0, -64		/* all 1s except low 6 bits */
703	dmtc0	v0, MIPS_COP_0_TLB_LO0
704	COP0_SYNC
705	dmfc0	v0, MIPS_COP_0_TLB_LO0
706	dmtc0	t0, MIPS_COP_0_TLB_LO0
707	COP0_SYNC
708#ifdef __mips_o32
709#if BYTE_ORDER == BIG_ENDIAN
710	srl	v1, v0, 0
711	dsra	v0, v0, 32
712#endif
713#if BYTE_ORDER == LITTLE_ENDIAN
714	dsra	v1, v0, 32
715	srl	v0, v0, 0
716#endif
717#endif /* __mips_o32 */
718	jr	ra
719	 nop
720END(mips3_cp0_tlb_entry_lo_probe)
721#endif /* __mips != 32 */
722
723/*
724 * uint32_t mips3_cp0_tlb_page_mask_probe(void);
725 *
726 * Write 1s to the RPN field of Entry_Lo0 to see how many PA bits are implemented.
727 * Assumes that interrupts are disabled.
728 */
729LEAF(mips3_cp0_tlb_page_mask_probe)
730	mfc0	t0, MIPS_COP_0_TLB_PG_MASK
731	lui	v0, 0xffff
732	srl	v0, v0, 3
733	mtc0	v0, MIPS_COP_0_TLB_PG_MASK
734	COP0_SYNC
735	mfc0	v0, MIPS_COP_0_TLB_PG_MASK
736	mtc0	t0, MIPS_COP_0_TLB_PG_MASK
737	JR_HB_RA
738END(mips3_cp0_tlb_page_mask_probe)
739
740#ifdef MULTIPROCESSOR
741/*
742 * The presence of this routine here will causes MIPS1 MULTIPROCESSOR kernels
743 * to fail, as they should since we won't support such abominations.
744 *
745 * MD code calls/jumps to this with the pointer to this CPU's cpu_info in a1,
746 * sp set to ci->ci_data.cpu_idlelwp->l_md.md_utf.  gp will be overridden so
747 * 0 can be supplied if needed.  (This happens to match what CFE wants)
748 */
749NESTED_NOPROFILE(cpu_trampoline, 0, ra)
750	/*
751	 * We act as the idle lwp so make it CURLWP.  When know
752	 * that the cpu_info is a KSEG0 address.
753	 */
754	move	a0, a1
755	// Loop until idlelwp is filled in.
7561:	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
757	nop
758	beqz	MIPS_CURLWP, 1b
759	 nop
760	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
761
762#ifdef _LP64
763	li	v0, MIPS_SR_KX | MIPS_SR_UX	# allow 64bit addressing
764#else
765	li	v0, 0
766#endif
767	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
768	COP0_SYNC
769
770	PTR_L	sp, L_MD_UTF(MIPS_CURLWP)	# fetch KSP
771
772	/*
773	 * Indicate that no one has called us.
774	 */
775	move	ra, zero
776	REG_S	ra, CALLFRAME_RA(sp)
777
778#ifdef __GP_SUPPORT__
779	/*
780	 * New execution constant needs GP to be loaded.
781	 */
782	PTR_LA	gp, _C_LABEL(_gp)
783#endif
784
785#if 0
786	LONG_L	t0, CPU_INFO_FLAGS(a0)
787	or	t0, t0, CPUF_PRESENT
788	LONG_S	t0, CPU_INFO_FLAGS(a0)
789	sync
790#endif
791
792	/*
793	 * and off we go.
794	 */
795	j	_C_LABEL(cpu_hatch)		# does everything
796	 nop
797END(cpu_trampoline)
798#endif /* MULTIPROCESSOR */
799