xref: /netbsd/sys/arch/mips/mips/mips_machdep.c (revision bf9ec67e)
1 /*	$NetBSD: mips_machdep.c,v 1.129 2002/05/03 03:50:11 rafal Exp $	*/
2 
3 /*
4  * Copyright 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Simon Burge for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed for the NetBSD Project by
20  *	Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * Copyright 2000, 2001
40  * Broadcom Corporation. All rights reserved.
41  *
42  * This software is furnished under license and may be used and copied only
43  * in accordance with the following terms and conditions.  Subject to these
44  * conditions, you may download, copy, install, use, modify and distribute
45  * modified or unmodified copies of this software in source and/or binary
46  * form. No title or ownership is transferred hereby.
47  *
48  * 1) Any source code used, modified or distributed must reproduce and
49  *    retain this copyright notice and list of conditions as they appear in
50  *    the source file.
51  *
52  * 2) No right is granted to use any trade name, trademark, or logo of
53  *    Broadcom Corporation. Neither the "Broadcom Corporation" name nor any
54  *    trademark or logo of Broadcom Corporation may be used to endorse or
55  *    promote products derived from this software without the prior written
56  *    permission of Broadcom Corporation.
57  *
58  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
59  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
60  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
61  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
62  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
63  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
64  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
66  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
67  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
68  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69  */
70 
71 /*-
72  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
73  * All rights reserved.
74  *
75  * This code is derived from software contributed to The NetBSD Foundation
76  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
77  * NASA Ames Research Center and by Chris Demetriou.
78  *
79  * Redistribution and use in source and binary forms, with or without
80  * modification, are permitted provided that the following conditions
81  * are met:
82  * 1. Redistributions of source code must retain the above copyright
83  *    notice, this list of conditions and the following disclaimer.
84  * 2. Redistributions in binary form must reproduce the above copyright
85  *    notice, this list of conditions and the following disclaimer in the
86  *    documentation and/or other materials provided with the distribution.
87  * 3. All advertising materials mentioning features or use of this software
88  *    must display the following acknowledgement:
89  *	This product includes software developed by the NetBSD
90  *	Foundation, Inc. and its contributors.
91  * 4. Neither the name of The NetBSD Foundation nor the names of its
92  *    contributors may be used to endorse or promote products derived
93  *    from this software without specific prior written permission.
94  *
95  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
96  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
97  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
98  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
99  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
100  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
101  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
102  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
103  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
104  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
105  * POSSIBILITY OF SUCH DAMAGE.
106  */
107 
108 /*
109  * Copyright 1996 The Board of Trustees of The Leland Stanford
110  * Junior University. All Rights Reserved.
111  *
112  * Permission to use, copy, modify, and distribute this
113  * software and its documentation for any purpose and without
114  * fee is hereby granted, provided that the above copyright
115  * notice appear in all copies.  Stanford University
116  * makes no representations about the suitability of this
117  * software for any purpose.  It is provided "as is" without
118  * express or implied warranty.
119  */
120 
121 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
122 
123 __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.129 2002/05/03 03:50:11 rafal Exp $");
124 
125 #include "opt_cputype.h"
126 #include "opt_compat_netbsd.h"
127 #include "opt_compat_ultrix.h"
128 
129 #include <sys/param.h>
130 #include <sys/systm.h>
131 #include <sys/exec.h>
132 #include <sys/reboot.h>
133 #include <sys/mount.h>			/* fsid_t for syscallargs */
134 #include <sys/proc.h>
135 #include <sys/buf.h>
136 #include <sys/clist.h>
137 #include <sys/signal.h>
138 #include <sys/signalvar.h>
139 #include <sys/syscallargs.h>
140 #include <sys/user.h>
141 #include <sys/msgbuf.h>
142 #include <sys/conf.h>
143 #include <sys/core.h>
144 #include <sys/kcore.h>
145 #include <machine/kcore.h>
146 
147 #include <uvm/uvm_extern.h>
148 
149 #include <mips/cache.h>
150 #include <mips/regnum.h>
151 #include <mips/locore.h>
152 #include <mips/psl.h>
153 #include <mips/pte.h>
154 #include <machine/cpu.h>
155 
156 #if defined(MIPS32) || defined(MIPS64)
157 #include <mips/mipsNN.h>		/* MIPS32/MIPS64 registers */
158 #endif
159 
160 /* Internal routines. */
161 int	cpu_dumpsize(void);
162 u_long	cpu_dump_mempagecnt(void);
163 int	cpu_dump(void);
164 
165 #if defined(MIPS1)
166 static void	mips1_vector_init(void);
167 extern long	*mips1_locoresw[];
168 #endif
169 
170 #if defined(MIPS3)
171 #if defined(MIPS3_5900)
172 static void	r5900_vector_init(void);
173 extern long	*mips5900_locoresw[];
174 #else
175 static void	mips3_vector_init(void);
176 extern long	*mips3_locoresw[];
177 #endif
178 #endif
179 
180 #if defined(MIPS32)
181 static void	mips32_vector_init(void);
182 extern long	*mips32_locoresw[];
183 #endif
184 
185 #if defined(MIPS64)
186 static void	mips64_vector_init(void);
187 extern long	*mips64_locoresw[];
188 #endif
189 
190 mips_locore_jumpvec_t mips_locore_jumpvec;
191 
192 long *mips_locoresw[3];
193 
194 int cpu_arch;
195 int cpu_mhz;
196 int mips_num_tlb_entries;
197 int mips_cpu_flags;
198 int mips_has_llsc;
199 int mips_has_r4k_mmu;
200 int mips3_pg_cached;
201 
202 struct	user *proc0paddr;
203 struct	proc *fpcurproc;
204 struct	pcb  *curpcb;
205 struct	segtab *segbase;
206 
207 caddr_t	msgbufaddr;
208 
209 #ifdef MIPS3_4100			/* VR4100 core */
210 int	default_pg_mask = 0x00001800;
211 #endif
212 
213 struct pridtab {
214 	int	cpu_cid;
215 	int	cpu_pid;
216 	int	cpu_rev;	/* -1 == wildcard */
217 	int	cpu_isa;	/* -1 == probed (mips32/mips64) */
218 	int	cpu_ntlb;	/* -1 == unknown, 0 == probed */
219 	int	cpu_flags;
220 	char	*cpu_name;
221 };
222 
223 /*
224  * Assumptions:
225  *  - All MIPS3+ have an r4k-style MMU.  _Many_ assumptions throughout
226  *    much of the mips code about this.  Includes overloaded usage of
227  *    MIPS3_PLUS.
228  *  - All MIPS3+ use the same exception model (cp0 status, cause bits,
229  *    etc).  _Many_ assumptions throughout much of the mips code about
230  *    this.  Includes overloaded usage of MIPS3_PLUS.
231  *  - All MIPS3+ have a count register.  MIPS_HAS_CLOCK in <mips/cpu.h>
232  *    will need to be revised if this is false.
233  */
234 #define	MIPS32_FLAGS	CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV
235 #define	MIPS64_FLAGS	MIPS32_FLAGS	/* same as MIPS32 flags (for now) */
236 
237 static const struct pridtab *mycpu;
238 
239 static const struct pridtab cputab[] = {
240 	{ 0, MIPS_R2000, -1,			CPU_ARCH_MIPS1, 64,
241 	  0,					"MIPS R2000 CPU"	},
242 	{ 0, MIPS_R3000, MIPS_REV_R3000,	CPU_ARCH_MIPS1, 64,
243 	  0,					"MIPS R3000 CPU"	},
244 	{ 0, MIPS_R3000, MIPS_REV_R3000A,	CPU_ARCH_MIPS1, 64,
245 	  0,					"MIPS R3000A CPU"	},
246 	{ 0, MIPS_R6000, -1,			CPU_ARCH_MIPS2, 32,
247 	  MIPS_NOT_SUPP,			"MIPS R6000 CPU"	},
248 
249 	/*
250 	 * rev 0x00 and 0x30 are R4000, 0x40, 0x50 and 0x60 are R4400.
251 	 * should we allow ranges and use 0x00 - 0x3f for R4000 and
252 	 * 0x40 - 0xff for R4400?
253 	 */
254 	{ 0, MIPS_R4000, MIPS_REV_R4000_A,	CPU_ARCH_MIPS3, 48,
255 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
256 						"MIPS R4000 CPU"	},
257 	{ 0, MIPS_R4000, MIPS_REV_R4000_B,	CPU_ARCH_MIPS3, 48,
258 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
259 						"MIPS R4000 CPU"	},
260 	{ 0, MIPS_R4000, MIPS_REV_R4400_A,	CPU_ARCH_MIPS3, 48,
261 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
262 						"MIPS R4400 CPU"	},
263 	{ 0, MIPS_R4000, MIPS_REV_R4400_B,	CPU_ARCH_MIPS3, 48,
264 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
265 						"MIPS R4400 CPU"	},
266 	{ 0, MIPS_R4000, MIPS_REV_R4400_C,	CPU_ARCH_MIPS3, 48,
267 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
268 						"MIPS R4400 CPU"	},
269 
270 	{ 0, MIPS_R3LSI, -1,			CPU_ARCH_MIPS1, -1,
271 	  MIPS_NOT_SUPP,			"LSI Logic R3000 derivative" },
272 	{ 0, MIPS_R6000A, -1,			CPU_ARCH_MIPS2, 32,
273 	  MIPS_NOT_SUPP,			"MIPS R6000A CPU"	},
274 	{ 0, MIPS_R3IDT, -1,			CPU_ARCH_MIPS1, -1,
275 	  MIPS_NOT_SUPP,			"IDT R3041 or RC36100 CPU" },
276 	{ 0, MIPS_R4100, -1,			CPU_ARCH_MIPS3, 32,
277 	  CPU_MIPS_R4K_MMU | CPU_MIPS_NO_LLSC,	"NEC VR4100 CPU"	},
278 	{ 0, MIPS_R4200, -1,			CPU_ARCH_MIPS3, -1,
279 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"NEC VR4200 CPU"	},
280 	{ 0, MIPS_R4300, -1,			CPU_ARCH_MIPS3, 32,
281 	  CPU_MIPS_R4K_MMU,			"NEC VR4300 CPU"	},
282 	{ 0, MIPS_R4600, -1,			CPU_ARCH_MIPS3, 48,
283 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
284 						"QED R4600 Orion CPU"	},
285 	{ 0, MIPS_R4700, -1,			CPU_ARCH_MIPS3, 48,
286 	  CPU_MIPS_R4K_MMU,			"QED R4700 Orion CPU"	},
287 
288 	{ 0, MIPS_R8000, -1,			CPU_ARCH_MIPS4, 384,
289 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R8000 Blackbird/TFP CPU" },
290 	{ 0, MIPS_R10000, -1,			CPU_ARCH_MIPS4, 64,
291 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R10000 CPU"	},
292 	{ 0, MIPS_R12000, -1,			CPU_ARCH_MIPS4, 64,
293 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R12000 CPU"	},
294 	{ 0, MIPS_R14000, -1,			CPU_ARCH_MIPS4, 64,
295 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"MIPS R14000 CPU"	},
296 
297 	/* XXX
298 	 * If the Processor Revision ID of the 4650 isn't 0, the following
299 	 * entry needs to be adjusted.  Can't use a wildcard match because
300 	 * the TX39 series processors share the same Processor ID value.
301 	 * Or maybe put TX39 CPUs first if the revid doesn't overlap with
302 	 * the 4650...
303 	 */
304 	{ 0, MIPS_R4650, 0,			CPU_ARCH_MIPS3, -1,
305 	  MIPS_NOT_SUPP /* no MMU! */,		"QED R4650 CPU"	},
306 	{ 0, MIPS_TX3900, MIPS_REV_TX3912,	CPU_ARCH_MIPS1, 32,
307 	  0,					"Toshiba TX3912 CPU"	},
308 	{ 0, MIPS_TX3900, MIPS_REV_TX3922,	CPU_ARCH_MIPS1, 64,
309 	  0,					"Toshiba TX3922 CPU"	},
310 	{ 0, MIPS_TX3900, MIPS_REV_TX3927,	CPU_ARCH_MIPS1, 64,
311 	  0,					"Toshiba TX3927 CPU"	},
312 	{ 0, MIPS_R5000, -1,			CPU_ARCH_MIPS4, 48,
313 	  CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT,
314 						"MIPS R5000 CPU"	},
315 	{ 0, MIPS_RM5200, -1,			CPU_ARCH_MIPS4, 48,
316 	  CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT,
317 						"QED RM5200 CPU"	},
318 
319 	/* XXX
320 	 * The rm7000 rev 2.0 can have 64 tlbs, and has 6 extra interrupts.  See
321 	 *    "Migrating to the RM7000 from other MIPS Microprocessors"
322 	 * for more details.
323 	 */
324 	{ 0, MIPS_RM7000, -1,			CPU_ARCH_MIPS4, 48,
325 	  MIPS_NOT_SUPP | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT,
326 						"QED RM7000 CPU"	},
327 
328 	/*
329 	 * IDT RC32300 core is a 32 bit MIPS2 processor with
330 	 * MIPS3/MIPS4 extensions. It has an R4000-style TLB,
331 	 * while all registers are 32 bits and any 64 bit
332 	 * instructions like ld/sd/dmfc0/dmtc0 are not allowed.
333 	 *
334 	 * note that the Config register has a non-standard base
335 	 * for IC and DC (2^9 instead of 2^12).
336 	 *
337 	 */
338 	{ 0, MIPS_RC32300, -1,			CPU_ARCH_MIPS3, 16,
339 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"IDT RC32300 CPU"	},
340 	{ 0, MIPS_RC32364, -1,			CPU_ARCH_MIPS3, 16,
341 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"IDT RC32364 CPU"	},
342 	{ 0, MIPS_RC64470, -1,			CPU_ARCH_MIPSx, -1,
343 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"IDT RC64474/RC64475 CPU" },
344 
345 	{ 0, MIPS_R5400, -1,			CPU_ARCH_MIPSx, -1,
346 	  MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU,	"NEC VR5400 CPU"	},
347 	{ 0, MIPS_R5900, -1,			CPU_ARCH_MIPS3, 48,
348 	  CPU_MIPS_R4K_MMU,			"Toshiba R5900 CPU"	},
349 
350 #if 0 /* ID collisions : can we use a CU1 test or similar? */
351 	{ 0, MIPS_R3SONY, -1,			CPU_ARCH_MIPS1, -1,
352 	  MIPS_NOT_SUPP,			"SONY R3000 derivative"	},	/* 0x21; crash R4700? */
353 	{ 0, MIPS_R3NKK, -1,			CPU_ARCH_MIPS1, -1,
354 	  MIPS_NOT_SUPP,			"NKK R3000 derivative"	},	/* 0x23; crash R5000? */
355 #endif
356 
357 	{ MIPS_PRID_CID_MTI, MIPS_4Kc, -1,	-1, 0,
358 	  MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,	"4Kc"			},
359 	{ MIPS_PRID_CID_MTI, MIPS_4KEc, -1,	-1, 0,
360 	  MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,	"4KEc"			},
361 	{ MIPS_PRID_CID_MTI, MIPS_4KSc, -1,	-1, 0,
362 	  MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,	"4KSc"			},
363 	{ MIPS_PRID_CID_MTI, MIPS_5Kc, -1,	-1, 0,
364 	  MIPS64_FLAGS | CPU_MIPS_DOUBLE_COUNT,	"5Kc"			},
365 
366 	{ MIPS_PRID_CID_ALCHEMY, MIPS_AU1000_R1, -1, -1, 0,
367 	  MIPS32_FLAGS,				"Au1000 (Rev 1)"	},
368 	{ MIPS_PRID_CID_ALCHEMY, MIPS_AU1000_R2, -1, -1, 0,
369 	  MIPS32_FLAGS,				"Au1000 (Rev 2)" 	},
370 
371 	/* The SB1 CPUs use a CCA of 5 - "Cacheable Coherent Shareable" */
372 	{ MIPS_PRID_CID_SIBYTE, MIPS_SB1, -1,	-1, 0,
373 	  MIPS64_FLAGS | CPU_MIPS_HAVE_SPECIAL_CCA | \
374 	  (5 << CPU_MIPS_CACHED_CCA_SHIFT),	"SB1"			},
375 
376 	{ 0, 0, 0,				0, 64,
377 	  0,					NULL			}
378 };
379 
380 static const struct pridtab fputab[] = {
381 	{ 0, MIPS_SOFT,	-1, 0, 0, 0,	"software emulated floating point" },
382 	{ 0, MIPS_R2360, -1, 0, 0, 0,	"MIPS R2360 Floating Point Board" },
383 	{ 0, MIPS_R2010, -1, 0, 0, 0,	"MIPS R2010 FPC" },
384 	{ 0, MIPS_R3010, -1, 0, 0, 0,	"MIPS R3010 FPC" },
385 	{ 0, MIPS_R6010, -1, 0, 0, 0,	"MIPS R6010 FPC" },
386 	{ 0, MIPS_R4010, -1, 0, 0, 0,	"MIPS R4010 FPC" },
387 	{ 0, MIPS_R10000, -1, 0, 0, 0,	"built-in FPU" },
388 };
389 
390 /*
391  * Company ID's are not sparse (yet), this array is indexed directly
392  * by pridtab->cpu_cid.
393  */
394 static const char *cidnames[] = {
395 	"Prehistoric",
396 	"MIPS",		/* or "MIPS Technologies, Inc.	*/
397 	"Broadcom",	/* or "Broadcom Corp."		*/
398 	"Alchemy",	/* or "Alchemy Semiconductor"	*/
399 	"SiByte",	/* or "Broadcom Corp. (SiByte)"	*/
400 	"SandCraft",
401 };
402 #define	ncidnames (sizeof(cidnames) / sizeof(cidnames[0]))
403 
404 #ifdef MIPS1
405 /*
406  * MIPS-I locore function vector
407  */
408 static const mips_locore_jumpvec_t mips1_locore_vec =
409 {
410 	mips1_SetPID,
411 	mips1_TBIAP,
412 	mips1_TBIS,
413 	mips1_TLBUpdate,
414 	mips1_wbflush,
415 };
416 
417 static void
418 mips1_vector_init(void)
419 {
420 	extern char mips1_UTLBMiss[], mips1_UTLBMissEnd[];
421 	extern char mips1_exception[], mips1_exceptionEnd[];
422 
423 	/*
424 	 * Copy down exception vector code.
425 	 */
426 	if (mips1_UTLBMissEnd - mips1_UTLBMiss > 0x80)
427 		panic("startup: UTLB vector code too large");
428 	memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips1_UTLBMiss,
429 		mips1_UTLBMissEnd - mips1_UTLBMiss);
430 
431 	if (mips1_exceptionEnd - mips1_exception > 0x80)
432 		panic("startup: general exception vector code too large");
433 	memcpy((void *)MIPS1_GEN_EXC_VEC, mips1_exception,
434 		mips1_exceptionEnd - mips1_exception);
435 
436 	/*
437 	 * Copy locore-function vector.
438 	 */
439 	memcpy(&mips_locore_jumpvec, &mips1_locore_vec,
440 		sizeof(mips_locore_jumpvec_t));
441 
442 	/*
443 	 * Clear out the I and D caches.
444 	 */
445 	mips_icache_sync_all();
446 	mips_dcache_wbinv_all();
447 }
448 #endif /* MIPS1 */
449 
450 #if defined(MIPS3)
451 #ifndef MIPS3_5900	/* XXX */
452 /*
453  * MIPS III locore function vector
454  */
455 static const mips_locore_jumpvec_t mips3_locore_vec =
456 {
457 	mips3_SetPID,
458 	mips3_TBIAP,
459 	mips3_TBIS,
460 	mips3_TLBUpdate,
461 	mips3_wbflush,
462 };
463 
464 static void
465 mips3_vector_init(void)
466 {
467 	/* r4000 exception handler address and end */
468 	extern char mips3_exception[], mips3_exceptionEnd[];
469 
470 	/* TLB miss handler address and end */
471 	extern char mips3_TLBMiss[], mips3_TLBMissEnd[];
472 	extern char mips3_XTLBMiss[], mips3_XTLBMissEnd[];
473 
474 	/* Cache error handler */
475 	extern char mips3_cache[], mips3_cacheEnd[];
476 
477 	/*
478 	 * Copy down exception vector code.
479 	 */
480 
481 	if (mips3_TLBMissEnd - mips3_TLBMiss > 0x80)
482 		panic("startup: UTLB vector code too large");
483 	memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips3_TLBMiss,
484 	      mips3_TLBMissEnd - mips3_TLBMiss);
485 
486 	if (mips3_XTLBMissEnd - mips3_XTLBMiss > 0x80)
487 		panic("startup: XTLB vector code too large");
488 	memcpy((void *)MIPS3_XTLB_MISS_EXC_VEC, mips3_XTLBMiss,
489 	      mips3_XTLBMissEnd - mips3_XTLBMiss);
490 
491 	if (mips3_cacheEnd - mips3_cache > 0x80)
492 		panic("startup: Cache error vector code too large");
493 	memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips3_cache,
494 	      mips3_cacheEnd - mips3_cache);
495 
496 	if (mips3_exceptionEnd - mips3_exception > 0x80)
497 		panic("startup: General exception vector code too large");
498 	memcpy((void *)MIPS3_GEN_EXC_VEC, mips3_exception,
499 	      mips3_exceptionEnd - mips3_exception);
500 
501 	/*
502 	 * Copy locore-function vector.
503 	 */
504 	memcpy(&mips_locore_jumpvec, &mips3_locore_vec,
505 	      sizeof(mips_locore_jumpvec_t));
506 
507 	mips_icache_sync_all();
508 	mips_dcache_wbinv_all();
509 
510 	/* Clear BEV in SR so we start handling our own exceptions */
511 	mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
512 }
513 #endif /* !MIPS3_5900 */
514 
515 #ifdef MIPS3_5900	/* XXX */
516 /*
517  * MIPS R5900 locore function vector.
518  * Same as MIPS32 - all MMU registers are 32bit.
519  */
520 static const mips_locore_jumpvec_t r5900_locore_vec =
521 {
522 	mips5900_SetPID,
523 	mips5900_TBIAP,
524 	mips5900_TBIS,
525 	mips5900_TLBUpdate,
526 	mips5900_wbflush,
527 };
528 
529 static void
530 r5900_vector_init(void)
531 {
532 	extern char mips5900_exception[], mips5900_exceptionEnd[];
533 	extern char mips5900_TLBMiss[], mips5900_TLBMissEnd[];
534 	size_t esz = mips5900_exceptionEnd - mips5900_exception;
535 	size_t tsz = mips5900_TLBMissEnd - mips5900_TLBMiss;
536 
537 	KDASSERT(tsz <= 0x80);
538 	KDASSERT(esz <= 0x80);
539 
540 	if (tsz > 0x80)
541 		panic("startup: UTLB vector code too large");
542 	if (esz > 0x80)
543 		panic("startup: General exception vector code too large");
544 
545 	memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips5900_TLBMiss, tsz);
546 	memcpy((void *)MIPS_R5900_COUNTER_EXC_VEC, mips5900_exception, esz);
547 	memcpy((void *)MIPS_R5900_DEBUG_EXC_VEC, mips5900_exception, esz);
548 	memcpy((void *)MIPS3_GEN_EXC_VEC, mips5900_exception, esz);
549 	memcpy((void *)MIPS3_INTR_EXC_VEC, mips5900_exception, esz);
550 
551 	memcpy(&mips_locore_jumpvec, &r5900_locore_vec,
552 	    sizeof(mips_locore_jumpvec_t));
553 
554 	mips_config_cache();
555 
556 	mips_icache_sync_all();
557 	mips_dcache_wbinv_all();
558 
559 	/* Clear BEV in SR so we start handling our own exceptions */
560 	mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
561 }
562 #endif /* MIPS3_5900 */
563 #endif /* MIPS3 */
564 
565 #ifdef MIPS32
566 /*
567  * MIPS32 locore function vector
568  */
569 static const mips_locore_jumpvec_t mips32_locore_vec =
570 {
571 	mips32_SetPID,
572 	mips32_TBIAP,
573 	mips32_TBIS,
574 	mips32_TLBUpdate,
575 	mips32_wbflush,
576 };
577 
578 static void
579 mips32_vector_init(void)
580 {
581 	/* r4000 exception handler address and end */
582 	extern char mips32_exception[], mips32_exceptionEnd[];
583 
584 	/* TLB miss handler address and end */
585 	extern char mips32_TLBMiss[], mips32_TLBMissEnd[];
586 
587 	/* Cache error handler */
588 	extern char mips32_cache[], mips32_cacheEnd[];
589 
590 	/* MIPS32/MIPS64 interrupt exception handler */
591 	extern char mips32_intr[], mips32_intrEnd[];
592 
593 	/*
594 	 * Copy down exception vector code.
595 	 */
596 
597 	if (mips32_TLBMissEnd - mips32_TLBMiss > 0x80)
598 		panic("startup: UTLB vector code too large");
599 	memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32_TLBMiss,
600 		      mips32_TLBMissEnd - mips32_TLBMiss);
601 
602 	if (mips32_cacheEnd - mips32_cache > 0x80)
603 		panic("startup: Cache error vector code too large");
604 	memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips32_cache,
605 	      mips32_cacheEnd - mips32_cache);
606 
607 	if (mips32_exceptionEnd - mips32_exception > 0x80)
608 		panic("startup: General exception vector code too large");
609 	memcpy((void *)MIPS3_GEN_EXC_VEC, mips32_exception,
610 	      mips32_exceptionEnd - mips32_exception);
611 
612 	if (mips32_intrEnd - mips32_intr > 0x80)
613 		panic("startup: interrupt exception vector code too large");
614 #if 0	/* XXX - why doesn't mipsNN_intr() work? */
615 	memcpy((void *)MIPS3_INTR_EXC_VEC, mips32_intr,
616 	      mips32_intrEnd - mips32_intr);
617 #else
618 	memcpy((void *)MIPS3_INTR_EXC_VEC, mips32_exception,
619 	      mips32_exceptionEnd - mips32_exception);
620 #endif
621 
622 	/*
623 	 * Copy locore-function vector.
624 	 */
625 	memcpy(&mips_locore_jumpvec, &mips32_locore_vec,
626 		      sizeof(mips_locore_jumpvec_t));
627 
628 	mips_icache_sync_all();
629 	mips_dcache_wbinv_all();
630 
631 	/* Clear BEV in SR so we start handling our own exceptions */
632 	mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
633 }
634 #endif /* MIPS32 */
635 
636 #ifdef MIPS64
637 /*
638  * MIPS64 locore function vector
639  */
640 const mips_locore_jumpvec_t mips64_locore_vec =
641 {
642 	mips64_SetPID,
643 	mips64_TBIAP,
644 	mips64_TBIS,
645 	mips64_TLBUpdate,
646 	mips64_wbflush,
647 };
648 
649 static void
650 mips64_vector_init(void)
651 {
652 	/* r4000 exception handler address and end */
653 	extern char mips64_exception[], mips64_exceptionEnd[];
654 
655 	/* TLB miss handler address and end */
656 	extern char mips64_TLBMiss[], mips64_TLBMissEnd[];
657 	extern char mips64_XTLBMiss[], mips64_XTLBMissEnd[];
658 
659 	/* Cache error handler */
660 	extern char mips64_cache[], mips64_cacheEnd[];
661 
662 	/* MIPS32/MIPS64 interrupt exception handler */
663 	extern char mips64_intr[], mips64_intrEnd[];
664 
665 	/*
666 	 * Copy down exception vector code.
667 	 */
668 
669 	if (mips64_TLBMissEnd - mips64_TLBMiss > 0x80)
670 		panic("startup: UTLB vector code too large");
671 	memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips64_TLBMiss,
672 	      mips64_TLBMissEnd - mips64_TLBMiss);
673 
674 	if (mips64_XTLBMissEnd - mips64_XTLBMiss > 0x80)
675 		panic("startup: XTLB vector code too large");
676 	memcpy((void *)MIPS3_XTLB_MISS_EXC_VEC, mips64_XTLBMiss,
677 	      mips64_XTLBMissEnd - mips64_XTLBMiss);
678 
679 	if (mips64_cacheEnd - mips64_cache > 0x80)
680 		panic("startup: Cache error vector code too large");
681 	memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips64_cache,
682 	      mips64_cacheEnd - mips64_cache);
683 
684 	if (mips64_exceptionEnd - mips64_exception > 0x80)
685 		panic("startup: General exception vector code too large");
686 	memcpy((void *)MIPS3_GEN_EXC_VEC, mips64_exception,
687 	      mips64_exceptionEnd - mips64_exception);
688 
689 	if (mips64_intrEnd - mips64_intr > 0x80)
690 		panic("startup: interrupt exception vector code too large");
691 #if 0	/* XXX - why doesn't mipsNN_intr() work? */
692 	memcpy((void *)MIPS3_INTR_EXC_VEC, mips64_intr,
693 	      mips64_intrEnd - mips64_intr);
694 #else
695 	memcpy((void *)MIPS3_INTR_EXC_VEC, mips64_exception,
696 	      mips64_exceptionEnd - mips64_exception);
697 #endif
698 
699 	/*
700 	 * Copy locore-function vector.
701 	 */
702 	memcpy(&mips_locore_jumpvec, &mips64_locore_vec,
703 	      sizeof(mips_locore_jumpvec_t));
704 
705 	mips_icache_sync_all();
706 	mips_dcache_wbinv_all();
707 
708 	/* Clear BEV in SR so we start handling our own exceptions */
709 	mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV);
710 }
711 #endif /* MIPS64 */
712 
713 /*
714  * Do all the stuff that locore normally does before calling main(),
715  * that is common to all mips-CPU NetBSD ports.
716  *
717  * The principal purpose of this function is to examine the
718  * variable cpu_id, into which the kernel locore start code
719  * writes the cpu ID register, and to then copy appropriate
720  * code into the CPU exception-vector entries and the jump tables
721  * used to hide the differences in cache and TLB handling in
722  * different MIPS CPUs.
723  *
724  * This should be the very first thing called by each port's
725  * init_main() function.
726  */
727 
728 /*
729  * Initialize the hardware exception vectors, and the jump table used to
730  * call locore cache and TLB management functions, based on the kind
731  * of CPU the kernel is running on.
732  */
733 void
734 mips_vector_init(void)
735 {
736 	const struct pridtab *ct;
737 
738 	mycpu = NULL;
739 	for (ct = cputab; ct->cpu_name != NULL; ct++) {
740 		if (MIPS_PRID_CID(cpu_id) != ct->cpu_cid ||
741 		    MIPS_PRID_IMPL(cpu_id) != ct->cpu_pid)
742 			continue;
743 		if (ct->cpu_rev >= 0 &&
744 		    MIPS_PRID_REV(cpu_id) != ct->cpu_rev)
745 			continue;
746 
747 		mycpu = ct;
748 		cpu_arch = ct->cpu_isa;
749 		mips_num_tlb_entries = ct->cpu_ntlb;
750 
751 		break;
752 	}
753 
754 	if (mycpu == NULL)
755 		panic("CPU type (0x%x) not supported", cpu_id);
756 
757 #if defined(MIPS32) || defined(MIPS64)
758 	if (MIPS_PRID_CID(cpu_id) != 0) {
759 		/* MIPS32/MIPS64, use coprocessor 0 config registers */
760 		uint32_t cfg, cfg1;
761 
762 		cfg = mips3_cp0_config_read();
763 		cfg1 = mipsNN_cp0_config1_read();
764 
765 		/* pick CPU type */
766 		switch (MIPSNN_GET(CFG_AT, cfg)) {
767 		case MIPSNN_CFG_AT_MIPS32:
768 			cpu_arch = CPU_ARCH_MIPS32;
769 			break;
770 		case MIPSNN_CFG_AT_MIPS64:
771 			cpu_arch = CPU_ARCH_MIPS64;
772 			break;
773 		case MIPSNN_CFG_AT_MIPS64S:
774 		default:
775 			panic("MIPS32/64 architecture type %d not supported",
776 			    MIPSNN_GET(CFG_AT, cfg));
777 		}
778 
779 		if (MIPSNN_GET(CFG_AR, cfg) != MIPSNN_CFG_AR_REV1)
780 			printf("WARNING: MIPS32/64 arch revision != revision 1!\n");
781 
782 		/* figure out MMU type (and number of TLB entries) */
783 		switch (MIPSNN_GET(CFG_MT, cfg)) {
784 		case MIPSNN_CFG_MT_TLB:
785 			mips_num_tlb_entries = MIPSNN_CFG1_MS(cfg1);
786 			break;
787 		case MIPSNN_CFG_MT_NONE:
788 		case MIPSNN_CFG_MT_BAT:
789 		case MIPSNN_CFG_MT_FIXED:
790 		default:
791 			panic("MIPS32/64 MMU type %d not supported",
792 			    MIPSNN_GET(CFG_MT, cfg));
793 		}
794 	}
795 #endif /* defined(MIPS32) || defined(MIPS64) */
796 
797 	if (cpu_arch < 1)
798 		panic("Unknown CPU ISA for CPU type 0x%x\n", cpu_id);
799 	if (mips_num_tlb_entries < 1)
800 		panic("Unknown number of TLBs for CPU type 0x%x\n", cpu_id);
801 
802 	/*
803 	 * Check cpu-specific flags.
804 	 */
805 	mips_cpu_flags = mycpu->cpu_flags;
806 	mips_has_r4k_mmu = mips_cpu_flags & CPU_MIPS_R4K_MMU;
807 	mips_has_llsc = !(mips_cpu_flags & CPU_MIPS_NO_LLSC);
808 
809 	if (mycpu->cpu_flags & CPU_MIPS_HAVE_SPECIAL_CCA) {
810 		uint32_t cca;
811 
812 		cca = (ct->cpu_flags & CPU_MIPS_CACHED_CCA_MASK) >>
813 		    CPU_MIPS_CACHED_CCA_SHIFT;
814 		mips3_pg_cached = MIPS3_CCA_TO_PG(cca);
815 	} else
816 		mips3_pg_cached = MIPS3_DEFAULT_PG_CACHED;
817 
818 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
819 	mips_machdep_cache_config();
820 #endif
821 
822 	/*
823 	 * Determine cache configuration and initialize our cache
824 	 * frobbing routine function pointers.
825 	 */
826 	mips_config_cache();
827 
828 	/*
829 	 * Now initialize our ISA-dependent function vector.
830 	 */
831 	switch (cpu_arch) {
832 #ifdef MIPS1
833 	case CPU_ARCH_MIPS1:
834 		mips1_TBIA(mips_num_tlb_entries);
835 		mips1_vector_init();
836 		memcpy(mips_locoresw, mips1_locoresw, sizeof(mips_locoresw));
837 		break;
838 #endif
839 #if defined(MIPS3)
840 	case CPU_ARCH_MIPS3:
841 	case CPU_ARCH_MIPS4:
842 #ifdef MIPS3_5900	/* XXX */
843 		mips3_cp0_wired_write(0);
844 		mips5900_TBIA(mips_num_tlb_entries);
845 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
846 		r5900_vector_init();
847 		memcpy(mips_locoresw, mips5900_locoresw, sizeof(mips_locoresw));
848 #else /* MIPS3_5900 */
849 		mips3_cp0_wired_write(0);
850 		mips3_TBIA(mips_num_tlb_entries);
851 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
852 		mips3_vector_init();
853 		memcpy(mips_locoresw, mips3_locoresw, sizeof(mips_locoresw));
854 #endif /* MIPS3_5900 */
855 		break;
856 #endif
857 #ifdef MIPS32
858 	case CPU_ARCH_MIPS32:
859 		mips3_cp0_wired_write(0);
860 		mips32_TBIA(mips_num_tlb_entries);
861 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
862 		mips32_vector_init();
863 		memcpy(mips_locoresw, mips32_locoresw, sizeof(mips_locoresw));
864 		break;
865 #endif
866 #if defined(MIPS64)
867 	case CPU_ARCH_MIPS64:
868 		mips3_cp0_wired_write(0);
869 		mips64_TBIA(mips_num_tlb_entries);
870 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
871 		mips64_vector_init();
872 		memcpy(mips_locoresw, mips64_locoresw, sizeof(mips_locoresw));
873 		break;
874 #endif
875 	default:
876 		printf("cpu_arch 0x%x: not supported\n", cpu_arch);
877 		cpu_reboot(RB_HALT, NULL);
878 	}
879 
880 	/*
881 	 * Install power-saving idle routines.
882 	 */
883 	switch (MIPS_PRID_CID(cpu_id)) {
884 	case MIPS_PRID_CID_PREHISTORIC:
885 		switch (MIPS_PRID_IMPL(cpu_id)) {
886 #if defined(MIPS3) && !defined(MIPS3_5900)
887 		case MIPS_RM5200:
888 		case MIPS_RM7000:
889 		    {
890 			void rm52xx_idle(void);
891 
892 			CPU_IDLE = (long *) rm52xx_idle;
893 			break;
894 		    }
895 #endif /* MIPS3 && !MIPS3_5900 */
896 		default:
897 			/* Nothing. */
898 			break;
899 		}
900 #if defined(MIPS32) || defined(MIPS64)
901 	default:
902 	    {
903 		/*
904 		 * XXX: wait is valid on all mips32/64, but do we
905 		 *	always want to use it?
906 		 */
907 		void mipsNN_idle(void);
908 
909 		CPU_IDLE = (long *) mipsNN_idle;
910 	    }
911 #endif
912 	}
913 }
914 
915 void
916 mips_set_wbflush(flush_fn)
917 	void (*flush_fn)(void);
918 {
919 #undef wbflush
920 	mips_locore_jumpvec.wbflush = flush_fn;
921 	(*flush_fn)();
922 }
923 
924 /*
925  * Identify product revision IDs of cpu and fpu.
926  */
927 void
928 cpu_identify(void)
929 {
930 	static const char * const waynames[] = {
931 		"fully set-associative",	/* 0 */
932 		"direct-mapped",		/* 1 */
933 		"2-way set-associative",	/* 2 */
934 		NULL,				/* 3 */
935 		"4-way set-associative",	/* 4 */
936 	};
937 #define	nwaynames (sizeof(waynames) / sizeof(waynames[0]))
938 	static const char * const wtnames[] = {
939 		"write-back",
940 		"write-through",
941 	};
942 	static const char * const label = "cpu0";	/* XXX */
943 	char *cpuname, *fpuname;
944 	int i;
945 
946 	cpuname = mycpu->cpu_name;
947 
948 	fpuname = NULL;
949 	for (i = 0; i < sizeof(fputab)/sizeof(fputab[0]); i++) {
950 		if (MIPS_PRID_CID(fpu_id) == fputab[i].cpu_cid &&
951 		    MIPS_PRID_IMPL(fpu_id) == fputab[i].cpu_pid) {
952 			fpuname = fputab[i].cpu_name;
953 			break;
954 		}
955 	}
956 	if (fpuname == NULL && MIPS_PRID_IMPL(fpu_id) == MIPS_PRID_IMPL(cpu_id))
957 		fpuname = "built-in FPU";
958 	if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4700)	/* FPU PRid is 0x20 */
959 		fpuname = "built-in FPU";
960 	if (MIPS_PRID_IMPL(cpu_id) == MIPS_RC64470)	/* FPU PRid is 0x21 */
961 		fpuname = "built-in FPU";
962 
963 	if (mycpu->cpu_cid != 0) {
964 		if (mycpu->cpu_cid <= ncidnames)
965 			printf("%s ", cidnames[mycpu->cpu_cid]);
966 		else {
967 			printf("Unknown Company ID - 0x%x", mycpu->cpu_cid);
968 			printf("%s: ", label);
969 		}
970 	}
971 	if (cpuname != NULL)
972 		printf("%s (0x%x)", cpuname, cpu_id);
973 	else
974 		printf("unknown CPU type (0x%x)", cpu_id);
975 	if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
976 		printf(" Rev. %d.%d", MIPS_PRID_REV_MAJ(cpu_id),
977 		    MIPS_PRID_REV_MIN(cpu_id));
978 	else
979 		printf(" Rev. %d", MIPS_PRID_REV(cpu_id));
980 
981 	if (fpuname != NULL)
982 		printf(" with %s", fpuname);
983 	else
984 		printf(" with unknown FPC type (0x%x)", fpu_id);
985 	if (fpu_id != 0) {
986 		if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
987 			printf(" Rev. %d.%d", MIPS_PRID_REV_MAJ(fpu_id),
988 			    MIPS_PRID_REV_MIN(fpu_id));
989 		else
990 			printf(" Rev. %d", MIPS_PRID_REV(fpu_id));
991 	}
992 	printf("\n");
993 
994 	if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC &&
995 	    MIPS_PRID_RSVD(cpu_id) != 0) {
996 		printf("%s: NOTE: top 8 bits of prehistoric PRID not 0!\n",
997 		    label);
998 		printf("%s: Please mail port-mips@netbsd.org with cpu0 "
999 		    "dmesg lines.\n", label);
1000 	}
1001 
1002 	KASSERT(mips_picache_ways < nwaynames);
1003 	KASSERT(mips_pdcache_ways < nwaynames);
1004 	KASSERT(mips_sicache_ways < nwaynames);
1005 	KASSERT(mips_sdcache_ways < nwaynames);
1006 
1007 	switch (cpu_arch) {
1008 #ifdef MIPS1
1009 	case CPU_ARCH_MIPS1:
1010 		if (mips_picache_size)
1011 			printf("%s: %dKB/%dB %s Instruction cache, "
1012 			    "%d TLB entries\n", label, mips_picache_size / 1024,
1013 			    mips_picache_line_size, waynames[mips_picache_ways],
1014 			    mips_num_tlb_entries);
1015 		else
1016 			printf("%s: %d TLB entries\n", label,
1017 			    mips_num_tlb_entries);
1018 		if (mips_pdcache_size)
1019 			printf("%s: %dKB/%dB %s %s Data cache\n", label,
1020 			    mips_pdcache_size / 1024, mips_pdcache_line_size,
1021 			    waynames[mips_pdcache_ways],
1022 			    wtnames[mips_pdcache_write_through]);
1023 		break;
1024 #endif /* MIPS1 */
1025 #if defined(MIPS3) || defined(MIPS32) || defined(MIPS64)
1026 	case CPU_ARCH_MIPS3:
1027 	case CPU_ARCH_MIPS4:
1028 	case CPU_ARCH_MIPS32:
1029 	case CPU_ARCH_MIPS64:
1030 		if (mips_picache_size)
1031 			printf("%s: %dKB/%dB %s L1 Instruction cache, "
1032 			    "%d TLB entries\n", label, mips_picache_size / 1024,
1033 			    mips_picache_line_size, waynames[mips_picache_ways],
1034 			    mips_num_tlb_entries);
1035 		else
1036 			printf("%s: %d TLB entries\n", label, mips_num_tlb_entries);
1037 		if (mips_pdcache_size)
1038 			printf("%s: %dKB/%dB %s %s L1 Data cache\n", label,
1039 			    mips_pdcache_size / 1024, mips_pdcache_line_size,
1040 			    waynames[mips_pdcache_ways],
1041 			    wtnames[mips_pdcache_write_through]);
1042 		if (mips_sdcache_line_size)
1043 			printf("%s: %dKB/%dB %s %s L2 %s cache\n", label,
1044 			    mips_sdcache_size / 1024, mips_sdcache_line_size,
1045 			    waynames[mips_sdcache_ways],
1046 			    wtnames[mips_sdcache_write_through],
1047 			    mips_scache_unified ? "Unified" : "Data");
1048 		break;
1049 #endif /* MIPS3 */
1050 	default:
1051 		panic("cpu_identify: impossible");
1052 	}
1053 }
1054 
1055 /*
1056  * Set registers on exec.
1057  * Clear all registers except sp, pc, and t9.
1058  * $sp is set to the stack pointer passed in.  $pc is set to the entry
1059  * point given by the exec_package passed in, as is $t9 (used for PIC
1060  * code by the MIPS elf abi).
1061  */
1062 void
1063 setregs(p, pack, stack)
1064 	struct proc *p;
1065 	struct exec_package *pack;
1066 	u_long stack;
1067 {
1068 	struct frame *f = (struct frame *)p->p_md.md_regs;
1069 
1070 	memset(f, 0, sizeof(struct frame));
1071 	f->f_regs[SP] = (int) stack;
1072 	f->f_regs[PC] = (int) pack->ep_entry & ~3;
1073 	f->f_regs[T9] = (int) pack->ep_entry & ~3; /* abicall requirement */
1074 	f->f_regs[SR] = PSL_USERSET;
1075 	/*
1076 	 * Set up arguments for the rtld-capable crt0:
1077 	 *	a0	stack pointer
1078 	 *	a1	rtld cleanup (filled in by dynamic loader)
1079 	 *	a2	rtld object (filled in by dynamic loader)
1080 	 *	a3	ps_strings
1081 	 */
1082 	f->f_regs[A0] = (int) stack;
1083 	f->f_regs[A1] = 0;
1084 	f->f_regs[A2] = 0;
1085 	f->f_regs[A3] = (int)p->p_psstr;
1086 
1087 	if ((p->p_md.md_flags & MDP_FPUSED) && p == fpcurproc)
1088 		fpcurproc = (struct proc *)0;
1089 	memset(&p->p_addr->u_pcb.pcb_fpregs, 0, sizeof(struct fpreg));
1090 	p->p_md.md_flags &= ~MDP_FPUSED;
1091 	p->p_md.md_ss_addr = 0;
1092 }
1093 
1094 /*
1095  * WARNING: code in locore.s assumes the layout shown for sf_signum
1096  * thru sf_handler so... don't screw with them!
1097  */
1098 struct sigframe {
1099 	int	sf_signum;		/* signo for handler */
1100 	int	sf_code;		/* additional info for handler */
1101 	struct	sigcontext *sf_scp;	/* context ptr for handler */
1102 	sig_t	sf_handler;		/* handler addr for u_sigc */
1103 	struct	sigcontext sf_sc;	/* actual context */
1104 };
1105 
1106 #ifdef DEBUG
1107 int sigdebug = 0;
1108 int sigpid = 0;
1109 #define SDB_FOLLOW	0x01
1110 #define SDB_KSTACK	0x02
1111 #define SDB_FPSTATE	0x04
1112 #endif
1113 
1114 /*
1115  * Send an interrupt to process.
1116  */
1117 void
1118 sendsig(catcher, sig, mask, code)
1119 	sig_t catcher;
1120 	int sig;
1121 	sigset_t *mask;
1122 	u_long code;
1123 {
1124 	struct proc *p = curproc;
1125 	struct sigframe *fp;
1126 	struct frame *f;
1127 	int onstack;
1128 	struct sigcontext ksc;
1129 
1130 	f = (struct frame *)p->p_md.md_regs;
1131 
1132 	/* Do we need to jump onto the signal stack? */
1133 	onstack =
1134 	    (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
1135 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
1136 
1137 	/* Allocate space for the signal handler context. */
1138 	if (onstack)
1139 		fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
1140 						p->p_sigctx.ps_sigstk.ss_size);
1141 	else
1142 		/* cast for _MIPS_BSD_API == _MIPS_BSD_API_LP32_64CLEAN case */
1143 		fp = (struct sigframe *)(u_int32_t)f->f_regs[SP];
1144 	fp--;
1145 
1146 #ifdef DEBUG
1147 	if ((sigdebug & SDB_FOLLOW) ||
1148 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
1149 		printf("sendsig(%d): sig %d ssp %p usp %p scp %p\n",
1150 		       p->p_pid, sig, &onstack, fp, &fp->sf_sc);
1151 #endif
1152 
1153 	/* Build stack frame for signal trampoline. */
1154 	ksc.sc_pc = f->f_regs[PC];
1155 	ksc.mullo = f->f_regs[MULLO];
1156 	ksc.mulhi = f->f_regs[MULHI];
1157 
1158 	/* Save register context. */
1159 	ksc.sc_regs[ZERO] = 0xACEDBADE;		/* magic number */
1160 	memcpy(&ksc.sc_regs[1], &f->f_regs[1],
1161 	    sizeof(ksc.sc_regs) - sizeof(ksc.sc_regs[0]));
1162 
1163 	/* Save the floating-pointstate, if necessary, then copy it. */
1164 #ifndef SOFTFLOAT
1165 	ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
1166 	if (ksc.sc_fpused) {
1167 		/* if FPU has current state, save it first */
1168 		if (p == fpcurproc)
1169 			savefpregs(p);
1170 		*(struct fpreg *)ksc.sc_fpregs = p->p_addr->u_pcb.pcb_fpregs;
1171 	}
1172 #else
1173 	*(struct fpreg *)ksc.sc_fpregs = p->p_addr->u_pcb.pcb_fpregs;
1174 #endif
1175 
1176 	/* Save signal stack. */
1177 	ksc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
1178 
1179 	/* Save signal mask. */
1180 	ksc.sc_mask = *mask;
1181 
1182 #if defined(COMPAT_13) || defined(COMPAT_ULTRIX)
1183 	/*
1184 	 * XXX We always have to save an old style signal mask because
1185 	 * XXX we might be delivering a signal to a process which will
1186 	 * XXX escape from the signal in a non-standard way and invoke
1187 	 * XXX sigreturn() directly.
1188 	 */
1189 	native_sigset_to_sigset13(mask, &ksc.__sc_mask13);
1190 #endif
1191 
1192 	if (copyout(&ksc, &fp->sf_sc, sizeof(ksc))) {
1193 		/*
1194 		 * Process has trashed its stack; give it an illegal
1195 		 * instruction to halt it in its tracks.
1196 		 */
1197 #ifdef DEBUG
1198 		if ((sigdebug & SDB_FOLLOW) ||
1199 		    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
1200 			printf("sendsig(%d): copyout failed on sig %d\n",
1201 			    p->p_pid, sig);
1202 #endif
1203 		sigexit(p, SIGILL);
1204 		/* NOTREACHED */
1205 	}
1206 
1207 	/* Set up the registers to return to sigcode. */
1208 	f->f_regs[A0] = sig;
1209 	f->f_regs[A1] = code;
1210 	f->f_regs[A2] = (int)&fp->sf_sc;
1211 	f->f_regs[A3] = (int)catcher;
1212 
1213 	f->f_regs[PC] = (int)catcher;
1214 	f->f_regs[T9] = (int)catcher;
1215 	f->f_regs[SP] = (int)fp;
1216 
1217 	/* Signal trampoline code is at base of user stack. */
1218 	f->f_regs[RA] = (int)p->p_sigctx.ps_sigcode;
1219 
1220 	/* Remember that we're now on the signal stack. */
1221 	if (onstack)
1222 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1223 
1224 #ifdef DEBUG
1225 	if ((sigdebug & SDB_FOLLOW) ||
1226 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
1227 		printf("sendsig(%d): sig %d returns\n",
1228 		       p->p_pid, sig);
1229 #endif
1230 }
1231 
1232 /*
1233  * System call to cleanup state after a signal
1234  * has been taken.  Reset signal mask and
1235  * stack state from context left by sendsig (above).
1236  * Return to previous pc and psl as specified by
1237  * context left by sendsig. Check carefully to
1238  * make sure that the user has not modified the
1239  * psl to gain improper privileges or to cause
1240  * a machine fault.
1241  */
1242 /* ARGSUSED */
1243 int
1244 sys___sigreturn14(p, v, retval)
1245 	struct proc *p;
1246 	void *v;
1247 	register_t *retval;
1248 {
1249 	struct sys___sigreturn14_args /* {
1250 		syscallarg(struct sigcontext *) sigcntxp;
1251 	} */ *uap = v;
1252 	struct sigcontext *scp, ksc;
1253 	struct frame *f;
1254 	int error;
1255 
1256 	/*
1257 	 * The trampoline code hands us the context.
1258 	 * It is unsafe to keep track of it ourselves, in the event that a
1259 	 * program jumps out of a signal handler.
1260 	 */
1261 	scp = SCARG(uap, sigcntxp);
1262 #ifdef DEBUG
1263 	if (sigdebug & SDB_FOLLOW)
1264 		printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
1265 #endif
1266 	if ((error = copyin(scp, &ksc, sizeof(ksc))) != 0)
1267 		return (error);
1268 
1269 	if ((int) ksc.sc_regs[ZERO] != 0xACEDBADE)	/* magic number */
1270 		return (EINVAL);
1271 
1272 	/* Restore the register context. */
1273 	f = (struct frame *)p->p_md.md_regs;
1274 	f->f_regs[PC] = ksc.sc_pc;
1275 	f->f_regs[MULLO] = ksc.mullo;
1276 	f->f_regs[MULHI] = ksc.mulhi;
1277 	memcpy(&f->f_regs[1], &scp->sc_regs[1],
1278 	    sizeof(scp->sc_regs) - sizeof(scp->sc_regs[0]));
1279 #ifndef	SOFTFLOAT
1280 	if (scp->sc_fpused) {
1281 		/* Disable the FPU to fault in FP registers. */
1282 		f->f_regs[SR] &= ~MIPS_SR_COP_1_BIT;
1283 		if (p == fpcurproc) {
1284 			fpcurproc = (struct proc *)0;
1285 		}
1286 		p->p_addr->u_pcb.pcb_fpregs = *(struct fpreg *)scp->sc_fpregs;
1287 	}
1288 #else
1289 	p->p_addr->u_pcb.pcb_fpregs = *(struct fpreg *)scp->sc_fpregs;
1290 #endif
1291 
1292 	/* Restore signal stack. */
1293 	if (ksc.sc_onstack & SS_ONSTACK)
1294 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1295 	else
1296 		p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
1297 
1298 	/* Restore signal mask. */
1299 	(void) sigprocmask1(p, SIG_SETMASK, &ksc.sc_mask, 0);
1300 
1301 	return (EJUSTRETURN);
1302 }
1303 
1304 /*
1305  * These are imported from platform-specific code.
1306  * XXX Should be declared in a header file.
1307  */
1308 extern phys_ram_seg_t mem_clusters[];
1309 extern int mem_cluster_cnt;
1310 
1311 /*
1312  * These variables are needed by /sbin/savecore.
1313  */
1314 u_int32_t dumpmag = 0x8fca0101;	/* magic number */
1315 int	dumpsize = 0;		/* pages */
1316 long	dumplo = 0;		/* blocks */
1317 
1318 struct user dumppcb;		/* Actually, struct pcb would do. */
1319 
1320 /*
1321  * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
1322  */
1323 int
1324 cpu_dumpsize(void)
1325 {
1326 	int size;
1327 
1328 	size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) +
1329 	    ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t));
1330 	if (roundup(size, dbtob(1)) != dbtob(1))
1331 		return (-1);
1332 
1333 	return (1);
1334 }
1335 
1336 /*
1337  * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped.
1338  */
1339 u_long
1340 cpu_dump_mempagecnt(void)
1341 {
1342 	u_long i, n;
1343 
1344 	n = 0;
1345 	for (i = 0; i < mem_cluster_cnt; i++)
1346 		n += atop(mem_clusters[i].size);
1347 	return (n);
1348 }
1349 
1350 /*
1351  * cpu_dump: dump machine-dependent kernel core dump headers.
1352  */
1353 int
1354 cpu_dump(void)
1355 {
1356 	int (*dump)(dev_t, daddr_t, caddr_t, size_t);
1357 	char buf[dbtob(1)];
1358 	kcore_seg_t *segp;
1359 	cpu_kcore_hdr_t *cpuhdrp;
1360 	phys_ram_seg_t *memsegp;
1361 	int i;
1362 
1363 	dump = bdevsw[major(dumpdev)].d_dump;
1364 
1365 	memset(buf, 0, sizeof buf);
1366 	segp = (kcore_seg_t *)buf;
1367 	cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))];
1368 	memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) +
1369 	    ALIGN(sizeof(*cpuhdrp))];
1370 
1371 	/*
1372 	 * Generate a segment header.
1373 	 */
1374 	CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
1375 	segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
1376 
1377 	/*
1378 	 * Add the machine-dependent header info.
1379 	 */
1380 	if (MIPS_HAS_R4K_MMU) {
1381 		cpuhdrp->archlevel = 3;
1382 		cpuhdrp->pg_shift  = MIPS3_PG_SHIFT;
1383 		cpuhdrp->pg_frame  = MIPS3_PG_FRAME;
1384 		cpuhdrp->pg_v      = MIPS3_PG_V;
1385 	} else {
1386 		cpuhdrp->archlevel = 1;
1387 		cpuhdrp->pg_shift  = MIPS1_PG_SHIFT;
1388 		cpuhdrp->pg_frame  = MIPS1_PG_FRAME;
1389 		cpuhdrp->pg_v      = MIPS1_PG_V;
1390 	}
1391 	cpuhdrp->sysmappa   = MIPS_KSEG0_TO_PHYS(Sysmap);
1392 	cpuhdrp->sysmapsize = Sysmapsize;
1393 	cpuhdrp->nmemsegs   = mem_cluster_cnt;
1394 
1395 	/*
1396 	 * Fill in the memory segment descriptors.
1397 	 */
1398 	for (i = 0; i < mem_cluster_cnt; i++) {
1399 		memsegp[i].start = mem_clusters[i].start;
1400 		memsegp[i].size = mem_clusters[i].size;
1401 	}
1402 
1403 	return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
1404 }
1405 
1406 /*
1407  * This is called by main to set dumplo and dumpsize.
1408  * Dumps always skip the first CLBYTES of disk space
1409  * in case there might be a disk label stored there.
1410  * If there is extra space, put dump at the end to
1411  * reduce the chance that swapping trashes it.
1412  */
1413 void
1414 cpu_dumpconf(void)
1415 {
1416 	int nblks, dumpblks;	/* size of dump area */
1417 	int maj;
1418 
1419 	if (dumpdev == NODEV)
1420 		goto bad;
1421 	maj = major(dumpdev);
1422 	if (maj < 0 || maj >= nblkdev)
1423 		panic("dumpconf: bad dumpdev=0x%x", dumpdev);
1424 	if (bdevsw[maj].d_psize == NULL)
1425 		goto bad;
1426 	nblks = (*bdevsw[maj].d_psize)(dumpdev);
1427 	if (nblks <= ctod(1))
1428 		goto bad;
1429 
1430 	dumpblks = cpu_dumpsize();
1431 	if (dumpblks < 0)
1432 		goto bad;
1433 	dumpblks += ctod(cpu_dump_mempagecnt());
1434 
1435 	/* If dump won't fit (incl. room for possible label), punt. */
1436 	if (dumpblks > (nblks - ctod(1)))
1437 		goto bad;
1438 
1439 	/* Put dump at end of partition */
1440 	dumplo = nblks - dumpblks;
1441 
1442 	/* dumpsize is in page units, and doesn't include headers. */
1443 	dumpsize = cpu_dump_mempagecnt();
1444 	return;
1445 
1446  bad:
1447 	dumpsize = 0;
1448 }
1449 
1450 /*
1451  * Dump the kernel's image to the swap partition.
1452  */
1453 #define	BYTES_PER_DUMP	NBPG
1454 
1455 void
1456 dumpsys(void)
1457 {
1458 	u_long totalbytesleft, bytes, i, n, memcl;
1459 	u_long maddr;
1460 	int psize;
1461 	daddr_t blkno;
1462 	int (*dump)(dev_t, daddr_t, caddr_t, size_t);
1463 	int error;
1464 
1465 	/* Save registers. */
1466 	savectx(&dumppcb);
1467 
1468 	if (dumpdev == NODEV)
1469 		return;
1470 
1471 	/*
1472 	 * For dumps during autoconfiguration,
1473 	 * if dump device has already configured...
1474 	 */
1475 	if (dumpsize == 0)
1476 		cpu_dumpconf();
1477 	if (dumplo <= 0) {
1478 		printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
1479 		    minor(dumpdev));
1480 		return;
1481 	}
1482 	printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
1483 	    minor(dumpdev), dumplo);
1484 
1485 	psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
1486 	printf("dump ");
1487 	if (psize == -1) {
1488 		printf("area unavailable\n");
1489 		return;
1490 	}
1491 
1492 	/* XXX should purge all outstanding keystrokes. */
1493 
1494 	if ((error = cpu_dump()) != 0)
1495 		goto err;
1496 
1497 	totalbytesleft = ptoa(cpu_dump_mempagecnt());
1498 	blkno = dumplo + cpu_dumpsize();
1499 	dump = bdevsw[major(dumpdev)].d_dump;
1500 	error = 0;
1501 
1502 	for (memcl = 0; memcl < mem_cluster_cnt; memcl++) {
1503 		maddr = mem_clusters[memcl].start;
1504 		bytes = mem_clusters[memcl].size;
1505 
1506 		for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
1507 			/* Print out how many MBs we have left to go. */
1508 			if ((totalbytesleft % (1024*1024)) == 0)
1509 				printf("%ld ", totalbytesleft / (1024 * 1024));
1510 
1511 			/* Limit size for next transfer. */
1512 			n = bytes - i;
1513 			if (n > BYTES_PER_DUMP)
1514 				n = BYTES_PER_DUMP;
1515 
1516 			error = (*dump)(dumpdev, blkno,
1517 			    (caddr_t)MIPS_PHYS_TO_KSEG0(maddr), n);
1518 			if (error)
1519 				goto err;
1520 			maddr += n;
1521 			blkno += btodb(n);		/* XXX? */
1522 
1523 			/* XXX should look for keystrokes, to cancel. */
1524 		}
1525 	}
1526 
1527  err:
1528 	switch (error) {
1529 
1530 	case ENXIO:
1531 		printf("device bad\n");
1532 		break;
1533 
1534 	case EFAULT:
1535 		printf("device not ready\n");
1536 		break;
1537 
1538 	case EINVAL:
1539 		printf("area improper\n");
1540 		break;
1541 
1542 	case EIO:
1543 		printf("i/o error\n");
1544 		break;
1545 
1546 	case EINTR:
1547 		printf("aborted from console\n");
1548 		break;
1549 
1550 	case 0:
1551 		printf("succeeded\n");
1552 		break;
1553 
1554 	default:
1555 		printf("error %d\n", error);
1556 		break;
1557 	}
1558 	printf("\n\n");
1559 	delay(5000000);		/* 5 seconds */
1560 }
1561 
1562 void
1563 mips_init_msgbuf(void)
1564 {
1565 	vsize_t sz = (vsize_t)round_page(MSGBUFSIZE);
1566 	vsize_t reqsz = sz;
1567 	struct vm_physseg *vps;
1568 
1569 	vps = &vm_physmem[vm_nphysseg - 1];
1570 
1571 	/* shrink so that it'll fit in the last segment */
1572 	if ((vps->avail_end - vps->avail_start) < atop(sz))
1573 		sz = ptoa(vps->avail_end - vps->avail_start);
1574 
1575 	vps->end -= atop(sz);
1576 	vps->avail_end -= atop(sz);
1577 	msgbufaddr = (caddr_t) MIPS_PHYS_TO_KSEG0(ptoa(vps->end));
1578 	initmsgbuf(msgbufaddr, sz);
1579 
1580 	/* Remove the last segment if it now has no pages. */
1581 	if (vps->start == vps->end)
1582 		vm_nphysseg--;
1583 
1584 	/* warn if the message buffer had to be shrunk */
1585 	if (sz != reqsz)
1586 		printf("WARNING: %ld bytes not available for msgbuf "
1587 		    "in last cluster (%ld used)\n", reqsz, sz);
1588 }
1589 
1590 void
1591 savefpregs(p)
1592 	struct proc *p;
1593 {
1594 #ifndef NOFPU
1595 	u_int32_t status, fpcsr, *fp;
1596 	struct frame *f;
1597 
1598 	if (p == NULL)
1599 		return;
1600 	/*
1601 	 * turnoff interrupts enabling CP1 to read FPCSR register.
1602 	 */
1603 	__asm __volatile (
1604 		".set noreorder		;"
1605 		".set noat		;"
1606 		"mfc0	%0, $12		;"
1607 		"li	$1, %2		;"
1608 		"mtc0	$1, $12		;"
1609 		"nop; nop; nop; nop	;"
1610 		"cfc1	%1, $31		;"
1611 		"cfc1	%1, $31		;"
1612 		".set reorder		;"
1613 		".set at"
1614 		: "=r" (status), "=r"(fpcsr) : "i"(MIPS_SR_COP_1_BIT));
1615 	/*
1616 	 * this process yielded FPA.
1617 	 */
1618 	f = (struct frame *)p->p_md.md_regs;
1619 	f->f_regs[SR] &= ~MIPS_SR_COP_1_BIT;
1620 
1621 	/*
1622 	 * save FPCSR and 32bit FP register values.
1623 	 */
1624 	fp = (int *)p->p_addr->u_pcb.pcb_fpregs.r_regs;
1625 	fp[32] = fpcsr;
1626 	__asm __volatile (
1627 		".set noreorder		;"
1628 		"swc1	$f0, 0(%0)	;"
1629 		"swc1	$f1, 4(%0)	;"
1630 		"swc1	$f2, 8(%0)	;"
1631 		"swc1	$f3, 12(%0)	;"
1632 		"swc1	$f4, 16(%0)	;"
1633 		"swc1	$f5, 20(%0)	;"
1634 		"swc1	$f6, 24(%0)	;"
1635 		"swc1	$f7, 28(%0)	;"
1636 		"swc1	$f8, 32(%0)	;"
1637 		"swc1	$f9, 36(%0)	;"
1638 		"swc1	$f10, 40(%0)	;"
1639 		"swc1	$f11, 44(%0)	;"
1640 		"swc1	$f12, 48(%0)	;"
1641 		"swc1	$f13, 52(%0)	;"
1642 		"swc1	$f14, 56(%0)	;"
1643 		"swc1	$f15, 60(%0)	;"
1644 		"swc1	$f16, 64(%0)	;"
1645 		"swc1	$f17, 68(%0)	;"
1646 		"swc1	$f18, 72(%0)	;"
1647 		"swc1	$f19, 76(%0)	;"
1648 		"swc1	$f20, 80(%0)	;"
1649 		"swc1	$f21, 84(%0)	;"
1650 		"swc1	$f22, 88(%0)	;"
1651 		"swc1	$f23, 92(%0)	;"
1652 		"swc1	$f24, 96(%0)	;"
1653 		"swc1	$f25, 100(%0)	;"
1654 		"swc1	$f26, 104(%0)	;"
1655 		"swc1	$f27, 108(%0)	;"
1656 		"swc1	$f28, 112(%0)	;"
1657 		"swc1	$f29, 116(%0)	;"
1658 		"swc1	$f30, 120(%0)	;"
1659 		"swc1	$f31, 124(%0)	;"
1660 		".set reorder" :: "r"(fp));
1661 	/*
1662 	 * stop CP1, enable interrupts.
1663 	 */
1664 	__asm __volatile ("mtc0 %0, $12" :: "r"(status));
1665 	return;
1666 #endif
1667 }
1668 
1669 void
1670 loadfpregs(p)
1671 	struct proc *p;
1672 {
1673 #ifndef NOFPU
1674 	u_int32_t status, *fp;
1675 	struct frame *f;
1676 
1677 	if (p == NULL)
1678 		panic("loading fpregs for NULL proc");
1679 
1680 	/*
1681 	 * turnoff interrupts enabling CP1 to load FP registers.
1682 	 */
1683 	__asm __volatile(
1684 		".set noreorder		;"
1685 		".set noat		;"
1686 		"mfc0	%0, $12		;"
1687 		"li	$1, %1		;"
1688 		"mtc0	$1, $12		;"
1689 		"nop; nop; nop; nop	;"
1690 		".set reorder		;"
1691 		".set at" : "=r"(status) : "i"(MIPS_SR_COP_1_BIT));
1692 
1693 	f = (struct frame *)p->p_md.md_regs;
1694 	fp = (int *)p->p_addr->u_pcb.pcb_fpregs.r_regs;
1695 	/*
1696 	 * load 32bit FP registers and establish processes' FP context.
1697 	 */
1698 	__asm __volatile(
1699 		".set noreorder		;"
1700 		"lwc1	$f0, 0(%0)	;"
1701 		"lwc1	$f1, 4(%0)	;"
1702 		"lwc1	$f2, 8(%0)	;"
1703 		"lwc1	$f3, 12(%0)	;"
1704 		"lwc1	$f4, 16(%0)	;"
1705 		"lwc1	$f5, 20(%0)	;"
1706 		"lwc1	$f6, 24(%0)	;"
1707 		"lwc1	$f7, 28(%0)	;"
1708 		"lwc1	$f8, 32(%0)	;"
1709 		"lwc1	$f9, 36(%0)	;"
1710 		"lwc1	$f10, 40(%0)	;"
1711 		"lwc1	$f11, 44(%0)	;"
1712 		"lwc1	$f12, 48(%0)	;"
1713 		"lwc1	$f13, 52(%0)	;"
1714 		"lwc1	$f14, 56(%0)	;"
1715 		"lwc1	$f15, 60(%0)	;"
1716 		"lwc1	$f16, 64(%0)	;"
1717 		"lwc1	$f17, 68(%0)	;"
1718 		"lwc1	$f18, 72(%0)	;"
1719 		"lwc1	$f19, 76(%0)	;"
1720 		"lwc1	$f20, 80(%0)	;"
1721 		"lwc1	$f21, 84(%0)	;"
1722 		"lwc1	$f22, 88(%0)	;"
1723 		"lwc1	$f23, 92(%0)	;"
1724 		"lwc1	$f24, 96(%0)	;"
1725 		"lwc1	$f25, 100(%0)	;"
1726 		"lwc1	$f26, 104(%0)	;"
1727 		"lwc1	$f27, 108(%0)	;"
1728 		"lwc1	$f28, 112(%0)	;"
1729 		"lwc1	$f29, 116(%0)	;"
1730 		"lwc1	$f30, 120(%0)	;"
1731 		"lwc1	$f31, 124(%0)	;"
1732 		".set reorder" :: "r"(fp));
1733 	/*
1734 	 * load FPCSR and stop CP1 again while enabling interrupts.
1735 	 */
1736 	__asm __volatile(
1737 		".set noreorder		;"
1738 		".set noat		;"
1739 		"ctc1	%0, $31		;"
1740 		"mtc0	%1, $12		;"
1741 		".set reorder		;"
1742 		".set at"
1743 		:: "r"(fp[32] &~ MIPS_FPU_EXCEPTION_BITS), "r"(status));
1744 	return;
1745 #endif
1746 }
1747