1 /*        $NetBSD: mips_machdep.c,v 1.308 2025/04/24 23:55:18 riastradh 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.  The "Broadcom Corporation" name may not be
54  *    used to endorse or promote products derived from this software
55  *    without the prior written permission of Broadcom Corporation.
56  *
57  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
58  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
59  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
60  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
61  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
62  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
65  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
66  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
67  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68  */
69 
70 /*-
71  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
72  * All rights reserved.
73  *
74  * This code is derived from software contributed to The NetBSD Foundation
75  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
76  * NASA Ames Research Center and by Chris Demetriou.
77  *
78  * Redistribution and use in source and binary forms, with or without
79  * modification, are permitted provided that the following conditions
80  * are met:
81  * 1. Redistributions of source code must retain the above copyright
82  *    notice, this list of conditions and the following disclaimer.
83  * 2. Redistributions in binary form must reproduce the above copyright
84  *    notice, this list of conditions and the following disclaimer in the
85  *    documentation and/or other materials provided with the distribution.
86  *
87  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
88  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
89  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
91  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
92  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
93  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
94  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
95  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
96  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
97  * POSSIBILITY OF SUCH DAMAGE.
98  */
99 
100 /*
101  * Copyright 1996 The Board of Trustees of The Leland Stanford
102  * Junior University. All Rights Reserved.
103  *
104  * Permission to use, copy, modify, and distribute this
105  * software and its documentation for any purpose and without
106  * fee is hereby granted, provided that the above copyright
107  * notice appear in all copies.  Stanford University
108  * makes no representations about the suitability of this
109  * software for any purpose.  It is provided "as is" without
110  * express or implied warranty.
111  */
112 
113 #include <sys/cdefs.h>                            /* RCS ID & Copyright macro defns */
114 __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.308 2025/04/24 23:55:18 riastradh Exp $");
115 
116 #define __INTR_PRIVATE
117 #include "opt_cputype.h"
118 #include "opt_compat_netbsd32.h"
119 #include "opt_multiprocessor.h"
120 
121 #include <sys/param.h>
122 #include <sys/systm.h>
123 #include <sys/proc.h>
124 #include <sys/intr.h>
125 #include <sys/exec.h>
126 #include <sys/reboot.h>
127 #include <sys/module.h>
128 #include <sys/mount.h>                            /* fsid_t for syscallargs */
129 #include <sys/lwp.h>
130 #include <sys/sysctl.h>
131 #include <sys/msgbuf.h>
132 #include <sys/conf.h>
133 #include <sys/core.h>
134 #include <sys/device.h>
135 #include <sys/kcore.h>
136 #include <sys/kmem.h>
137 #include <sys/ras.h>
138 #include <sys/cpu.h>
139 #include <sys/atomic.h>
140 #include <sys/ucontext.h>
141 #include <sys/bitops.h>
142 
143 #include <mips/kcore.h>
144 
145 #ifdef COMPAT_NETBSD32
146 #include <compat/netbsd32/netbsd32.h>
147 #endif
148 
149 #include <uvm/uvm.h>
150 #include <uvm/uvm_physseg.h>
151 
152 #include <dev/cons.h>
153 #include <dev/mm.h>
154 
155 #include <mips/pcb.h>
156 #include <mips/cache.h>
157 #include <mips/frame.h>
158 #include <mips/regnum.h>
159 #include <mips/mips_opcode.h>
160 
161 #include <mips/cpu.h>
162 #include <mips/locore.h>
163 #include <mips/psl.h>
164 #include <mips/pte.h>
165 #include <mips/userret.h>
166 
167 #ifdef __HAVE_BOOTINFO_H
168 #include <machine/bootinfo.h>
169 #endif
170 
171 #ifdef MIPS64_OCTEON
172 #include <mips/cavium/octeonvar.h>
173 #endif
174 
175 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
176 #include <mips/mipsNN.h>                /* MIPS32/MIPS64 registers */
177 
178 #define   _MKINSN(a,b,c,d,e) ((uint32_t)(((a) << 26)|((b) << 21)|((c) << 16)|((d) << 11)|(e)))
179 
180 #ifdef _LP64
181 #define   _LOAD_V0_L_PRIVATE_A0         _MKINSN(OP_LD, _R_A0, _R_V0, 0, offsetof(lwp_t, l_private))
182 #define   _MTC0_V0_USERLOCAL  _MKINSN(OP_COP0, OP_DMT, _R_V0, MIPS_COP_0_TLB_CONTEXT, 2)
183 #else
184 #define   _LOAD_V0_L_PRIVATE_A0         _MKINSN(OP_LW, _R_A0, _R_V0, 0, offsetof(lwp_t, l_private))
185 #define   _MTC0_V0_USERLOCAL  _MKINSN(OP_COP0, OP_MT, _R_V0, MIPS_COP_0_TLB_CONTEXT, 2)
186 #endif
187 #define   JR_RA                         _MKINSN(OP_SPECIAL, _R_RA, 0, 0, OP_JR)
188 
189 #endif
190 
191 /* Internal routines. */
192 int       cpu_dumpsize(void);
193 u_long    cpu_dump_mempagecnt(void);
194 int       cpu_dump(void);
195 
196 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
197 static void mips_watchpoint_init(void);
198 #endif
199 
200 #if defined(_LP64) && defined(ENABLE_MIPS_16KB_PAGE)
201 vaddr_t mips_vm_maxuser_address = MIPS_VM_MAXUSER_ADDRESS;
202 #endif
203 
204 #if defined(MIPS3_PLUS)
205 uint32_t mips3_cp0_tlb_page_mask_probe(void);
206 uint64_t mips3_cp0_tlb_entry_hi_probe(void);
207 uint64_t mips3_cp0_tlb_entry_lo_probe(void);
208 
209 static void mips3_tlb_probe(void);
210 #endif
211 
212 #if defined(MIPS1)
213 static void         mips1_vector_init(const struct splsw *);
214 extern const struct locoresw mips1_locoresw;
215 extern const mips_locore_jumpvec_t mips1_locore_vec;
216 #endif
217 
218 #if defined(MIPS3)
219 static void         mips3_vector_init(const struct splsw *);
220 extern const struct locoresw mips3_locoresw;
221 extern const mips_locore_jumpvec_t mips3_locore_vec;
222 #endif
223 
224 #if defined(MIPS3_LOONGSON2)
225 static void         loongson2_vector_init(const struct splsw *);
226 extern const struct locoresw loongson2_locoresw;
227 extern const mips_locore_jumpvec_t loongson2_locore_vec;
228 #endif
229 
230 #if defined(MIPS32)
231 static void         mips32_vector_init(const struct splsw *);
232 extern const struct locoresw mips32_locoresw;
233 extern const mips_locore_jumpvec_t mips32_locore_vec;
234 #endif
235 
236 #if defined(MIPS32R2)
237 static void         mips32r2_vector_init(const struct splsw *);
238 extern const struct locoresw mips32r2_locoresw;
239 extern const mips_locore_jumpvec_t mips32r2_locore_vec;
240 #endif
241 
242 #if defined(MIPS64)
243 static void         mips64_vector_init(const struct splsw *);
244 extern const struct locoresw mips64_locoresw;
245 extern const mips_locore_jumpvec_t mips64_locore_vec;
246 #endif
247 
248 #if defined(MIPS64R2)
249 extern const struct locoresw mips64r2_locoresw;
250 extern const mips_locore_jumpvec_t mips64r2_locore_vec;
251 #endif
252 
253 #if defined(PARANOIA)
254 void std_splsw_test(void);
255 #endif
256 
257 mips_locore_jumpvec_t mips_locore_jumpvec;
258 
259 struct locoresw mips_locoresw;
260 
261 extern const struct splsw std_splsw;
262 struct splsw mips_splsw;
263 
264 struct mips_options mips_options = {
265           .mips_cpu_id = 0xffffffff,
266           .mips_fpu_id = 0xffffffff,
267 };
268 
269 void *    msgbufaddr;
270 
271 /* the following is used by DDB to reset the system */
272 void      (*cpu_reset_address)(void);
273 
274 /* the following is used externally (sysctl_hw) */
275 char      machine[] = MACHINE;                    /* from <machine/param.h> */
276 char      machine_arch[] = MACHINE_ARCH;          /* from <machine/param.h> */
277 
278 /*
279  * Assumptions:
280  *  - All MIPS3+ have an r4k-style MMU.  _Many_ assumptions throughout
281  *    much of the mips code about this.  Includes overloaded usage of
282  *    MIPS3_PLUS.
283  *  - All MIPS3+ use the same exception model (cp0 status, cause bits,
284  *    etc).  _Many_ assumptions throughout much of the mips code about
285  *    this.  Includes overloaded usage of MIPS3_PLUS.
286  *  - All MIPS3+ have a count register.  MIPS_HAS_CLOCK in <mips/cpu.h>
287  *    will need to be revised if this is false.
288  */
289 #define   MIPS32_FLAGS        CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_USE_WAIT
290 #define   MIPS64_FLAGS        MIPS32_FLAGS        /* same as MIPS32 flags (for now) */
291 
292 static const struct pridtab cputab[] = {
293           { 0, MIPS_R2000, -1, -1,                CPU_ARCH_MIPS1, 64,
294             CPU_MIPS_NO_LLSC, 0, 0,               "MIPS R2000 CPU"    },
295           { 0, MIPS_R3000, MIPS_REV_R2000A, -1,   CPU_ARCH_MIPS1, 64,
296             CPU_MIPS_NO_LLSC, 0, 0,               "MIPS R2000A CPU"   },
297           { 0, MIPS_R3000, MIPS_REV_R3000, -1,    CPU_ARCH_MIPS1, 64,
298             CPU_MIPS_NO_LLSC, 0, 0,               "MIPS R3000 CPU"    },
299           { 0, MIPS_R3000, MIPS_REV_R3000A, -1,   CPU_ARCH_MIPS1, 64,
300             CPU_MIPS_NO_LLSC, 0, 0,               "MIPS R3000A CPU"   },
301           { 0, MIPS_R6000, -1, -1,                CPU_ARCH_MIPS2, 32,
302             MIPS_NOT_SUPP, 0, 0,                            "MIPS R6000 CPU"    },
303 
304           /*
305            * rev 0x00, 0x22 and 0x30 are R4000, 0x40, 0x50 and 0x60 are R4400.
306            * should we allow ranges and use 0x00 - 0x3f for R4000 and
307            * 0x40 - 0xff for R4400?
308            */
309           { 0, MIPS_R4000, MIPS_REV_R4000_A, -1,  CPU_ARCH_MIPS3, 48,
310             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
311                                                             "MIPS R4000 CPU"    },
312           { 0, MIPS_R4000, MIPS_REV_R4000_B, -1,  CPU_ARCH_MIPS3, 48,
313             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
314                                                             "MIPS R4000 CPU"    },
315           { 0, MIPS_R4000, MIPS_REV_R4000_C, -1,  CPU_ARCH_MIPS3, 48,
316             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
317                                                             "MIPS R4000 CPU"    },
318           { 0, MIPS_R4000, MIPS_REV_R4400_A, -1,  CPU_ARCH_MIPS3, 48,
319             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
320                                                             "MIPS R4400 CPU"    },
321           { 0, MIPS_R4000, MIPS_REV_R4400_B, -1,  CPU_ARCH_MIPS3, 48,
322             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
323                                                             "MIPS R4400 CPU"    },
324           { 0, MIPS_R4000, MIPS_REV_R4400_C, -1,  CPU_ARCH_MIPS3, 48,
325             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
326                                                             "MIPS R4400 CPU"    },
327 
328           { 0, MIPS_R3LSI, -1, -1,                CPU_ARCH_MIPS1, -1,
329             MIPS_NOT_SUPP, 0, 0,                            "LSI Logic R3000 derivative" },
330           { 0, MIPS_R6000A, -1, -1,               CPU_ARCH_MIPS2, 32,
331             MIPS_NOT_SUPP, 0, 0,                            "MIPS R6000A CPU"   },
332           { 0, MIPS_R3IDT, -1, -1,                CPU_ARCH_MIPS1, -1,
333             MIPS_NOT_SUPP, 0, 0,                            "IDT R3041 or RC36100 CPU" },
334           { 0, MIPS_R4100, -1, -1,                CPU_ARCH_MIPS3, 32,
335             CPU_MIPS_R4K_MMU | CPU_MIPS_NO_LLSC, 0, 0,
336                                                             "NEC VR4100 CPU"    },
337           { 0, MIPS_R4200, -1, -1,                CPU_ARCH_MIPS3, -1,
338             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
339                                                             "NEC VR4200 CPU"    },
340           { 0, MIPS_R4300, -1, -1,                CPU_ARCH_MIPS3, 32,
341             CPU_MIPS_R4K_MMU, 0, 0,               "NEC VR4300 CPU"    },
342           { 0, MIPS_R4600, -1, -1,                CPU_ARCH_MIPS3, 48,
343             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
344                                                             "QED R4600 Orion CPU"         },
345           { 0, MIPS_R4700, -1, -1,                CPU_ARCH_MIPS3, 48,
346             CPU_MIPS_R4K_MMU, 0, 0,               "QED R4700 Orion CPU"         },
347 
348           { 0, MIPS_R8000, -1, -1,                CPU_ARCH_MIPS4, 384,
349             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
350                                                    "MIPS R8000 Blackbird/TFP CPU" },
351           { 0, MIPS_R10000, -1, -1,               CPU_ARCH_MIPS4, 64,
352             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
353                                                             "MIPS R10000 CPU"   },
354           { 0, MIPS_R12000, -1, -1,               CPU_ARCH_MIPS4, 64,
355             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
356                                                             "MIPS R12000 CPU"   },
357           { 0, MIPS_R14000, -1, -1,               CPU_ARCH_MIPS4, 64,
358             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
359                                                             "MIPS R14000 CPU"   },
360 
361           /* XXX
362            * If the Processor Revision ID of the 4650 isn't 0, the following
363            * entry needs to be adjusted.  Can't use a wildcard match because
364            * the TX39 series processors share the same Processor ID value.
365            * Or maybe put TX39 CPUs first if the revid doesn't overlap with
366            * the 4650...
367            */
368           { 0, MIPS_R4650, 0, -1,                           CPU_ARCH_MIPS3, -1,
369             MIPS_NOT_SUPP /* no MMU! */, 0, 0,    "QED R4650 CPU"     },
370           { 0, MIPS_TX3900, MIPS_REV_TX3912, -1,  CPU_ARCH_MIPS1, 32,
371             CPU_MIPS_NO_LLSC, 0, 0,               "Toshiba TX3912 CPU"          },
372           { 0, MIPS_TX3900, MIPS_REV_TX3922, -1,  CPU_ARCH_MIPS1, 64,
373             CPU_MIPS_NO_LLSC, 0, 0,               "Toshiba TX3922 CPU"          },
374           { 0, MIPS_TX3900, MIPS_REV_TX3927, -1,  CPU_ARCH_MIPS1, 64,
375             CPU_MIPS_NO_LLSC, 0, 0,               "Toshiba TX3927 CPU"          },
376           { 0, MIPS_R5000, -1, -1,                CPU_ARCH_MIPS4, 48,
377             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
378                                                             "MIPS R5000 CPU"    },
379           { 0, MIPS_RM5200, -1, -1,               CPU_ARCH_MIPS4, 48,
380             CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT |
381             CPU_MIPS_USE_WAIT, 0, 0,              "QED RM5200 CPU"    },
382 
383           /* XXX
384            * The rm7000 rev 2.0 can have 64 tlbs, and has 6 extra interrupts.  See
385            *    "Migrating to the RM7000 from other MIPS Microprocessors"
386            * for more details.
387            */
388           { 0, MIPS_RM7000, -1, -1,               CPU_ARCH_MIPS4, 48,
389             MIPS_NOT_SUPP | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT |
390             CPU_MIPS_USE_WAIT, 0, 0,              "QED RM7000 CPU"    },
391 
392           /*
393            * IDT RC32300 core is a 32 bit MIPS2 processor with
394            * MIPS3/MIPS4 extensions. It has an R4000-style TLB,
395            * while all registers are 32 bits and any 64 bit
396            * instructions like ld/sd/dmfc0/dmtc0 are not allowed.
397            *
398            * note that the Config register has a non-standard base
399            * for IC and DC (2^9 instead of 2^12).
400            *
401            */
402           { 0, MIPS_RC32300, -1, -1,              CPU_ARCH_MIPS3, 16,
403             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
404                                                             "IDT RC32300 CPU"   },
405           { 0, MIPS_RC32364, -1, -1,              CPU_ARCH_MIPS3, 16,
406             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
407                                                             "IDT RC32364 CPU"   },
408           { 0, MIPS_RC64470, -1, -1,              CPU_ARCH_MIPSx, -1,
409             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
410                                                             "IDT RC64474/RC64475 CPU" },
411 
412           { 0, MIPS_R5400, -1, -1,                CPU_ARCH_MIPSx, -1,
413             MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0,
414                                                             "NEC VR5400 CPU"    },
415           { 0, MIPS_R5900, -1, -1,                CPU_ARCH_MIPS3, 48,
416             CPU_MIPS_NO_LLSC | CPU_MIPS_R4K_MMU, 0, 0,
417                                                             "Toshiba R5900 CPU" },
418 
419           { 0, MIPS_TX4900, MIPS_REV_TX4927, -1,  CPU_ARCH_MIPS3, 48,
420             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
421                                                             "Toshiba TX4927 CPU"          },
422 
423           { 0, MIPS_TX4900, -1, -1,               CPU_ARCH_MIPS3, 48,
424             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0,
425                                                             "Toshiba TX4900 CPU"          },
426 
427           /*
428            * ICT Loongson2 is a MIPS64 CPU with a few quirks.  For some reason
429            * the virtual aliases present with 4KB pages make the caches misbehave
430            * so we make all accesses uncached.  With 16KB pages, no virtual
431            * aliases are possible so we can use caching.
432            */
433 #ifdef ENABLE_MIPS_16KB_PAGE
434 #define   MIPS_LOONGSON2_CCA  0
435 #else
436 #define   MIPS_LOONGSON2_CCA  (CPU_MIPS_HAVE_SPECIAL_CCA | \
437                                         (2 << CPU_MIPS_CACHED_CCA_SHIFT))
438 #endif
439           { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2E, -1, CPU_ARCH_MIPS3, 64,
440             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2
441             | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2E CPU"         },
442           { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2F, -1, CPU_ARCH_MIPS3, 64,
443             CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2
444             | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2F CPU"         },
445 
446 #if 0 /* ID collisions : can we use a CU1 test or similar? */
447           { 0, MIPS_R3SONY, -1, -1,               CPU_ARCH_MIPS1, -1,
448             MIPS_NOT_SUPP, 0, 0,                            "SONY R3000 derivative"       },        /* 0x21; crash R4700? */
449           { 0, MIPS_R3NKK, -1, -1,                CPU_ARCH_MIPS1, -1,
450             MIPS_NOT_SUPP, 0, 0,                            "NKK R3000 derivative"        },        /* 0x23; crash R5000? */
451 #endif
452 
453           { MIPS_PRID_CID_MTI, MIPS_4Kc, -1, -1,  -1, 0,
454             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4Kc"                   },
455           { MIPS_PRID_CID_MTI, MIPS_4KEc, -1, -1, -1, 0,
456             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KEc"                  },
457           { MIPS_PRID_CID_MTI, MIPS_4KEc_R2, -1, -1, -1, 0,
458             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KEc (Rev 2)"          },
459           { MIPS_PRID_CID_MTI, MIPS_4KSc, -1, -1, -1, 0,
460             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KSc"                  },
461           { MIPS_PRID_CID_MTI, MIPS_5Kc, -1, -1,  -1, 0,
462             MIPS64_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "5Kc"                   },
463           { MIPS_PRID_CID_MTI, MIPS_20Kc, -1, -1, -1, 0,
464             MIPS64_FLAGS,                                   0, 0, "20Kc"                  },
465           { MIPS_PRID_CID_MTI, MIPS_25Kf, -1, -1, -1, 0,
466             MIPS64_FLAGS,                                   0, 0, "25Kf"                  },
467           { MIPS_PRID_CID_MTI, MIPS_24K, -1, -1,  -1, 0,
468             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
469             MIPS_CP0FL_USE |
470             MIPS_CP0FL_EBASE |
471             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
472             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7,
473             0, "24K" },
474           { MIPS_PRID_CID_MTI, MIPS_24KE, -1, -1, -1, 0,
475             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
476             MIPS_CP0FL_USE |
477             MIPS_CP0FL_EBASE |
478             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
479             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7,
480             0, "24KE" },
481           { MIPS_PRID_CID_MTI, MIPS_34K, -1, -1,  -1, 0,
482             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
483             MIPS_CP0FL_USE |
484             MIPS_CP0FL_EBASE |
485             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
486             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7,
487             0, "34K" },
488           { MIPS_PRID_CID_MTI, MIPS_74K, -1, -1,  -1, 0,
489             CPU_MIPS_HAVE_SPECIAL_CCA | (0 << CPU_MIPS_CACHED_CCA_SHIFT) |
490             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
491             MIPS_CP0FL_USE |
492             MIPS_CP0FL_EBASE |
493             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
494             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7,
495             0, "74K" },
496           { MIPS_PRID_CID_MTI, MIPS_1004K, -1, -1,          -1, 0,
497             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
498             MIPS_CP0FL_USE |
499             MIPS_CP0FL_EBASE |
500             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
501             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7,
502             0, "1004K" },
503           { MIPS_PRID_CID_MTI, MIPS_1074K, -1, -1,          -1, 0,
504             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT,
505             MIPS_CP0FL_USE |
506             MIPS_CP0FL_EBASE |
507             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
508             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7,
509             0, "1074K" },
510 
511           { MIPS_PRID_CID_BROADCOM, MIPS_BCM3302, -1, -1, -1, 0,
512             MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "BCM3302"     },
513 
514           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1000, -1, 0,
515             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
516                                                             "Au1000 (Rev 1 core)"         },
517           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1000, -1, 0,
518             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
519                                                             "Au1000 (Rev 2 core)"         },
520 
521           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1100, -1, 0,
522             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
523                                                             "Au1100 (Rev 1 core)"         },
524           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1100, -1, 0,
525             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
526                                                             "Au1100 (Rev 2 core)"         },
527 
528           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1500, -1, 0,
529             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
530                                                             "Au1500 (Rev 1 core)"         },
531           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1500, -1, 0,
532             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
533                                                             "Au1500 (Rev 2 core)"         },
534 
535           { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1550, -1, 0,
536             MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0,
537                                                             "Au1550 (Rev 2 core)"         },
538 
539           /* The SB-1 CPU uses a CCA of 5 - "Cacheable Coherent Shareable" */
540           { MIPS_PRID_CID_SIBYTE, MIPS_SB1, -1,   -1, -1, 0,
541             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT |
542             CPU_MIPS_HAVE_SPECIAL_CCA |
543             (CCA_SB_CACHEABLE_COHERENT << CPU_MIPS_CACHED_CCA_SHIFT), 0, 0,
544                                                             "SB-1"                        },
545           { MIPS_PRID_CID_SIBYTE, MIPS_SB1_11, -1,          -1, -1, 0,
546             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT |
547             CPU_MIPS_HAVE_SPECIAL_CCA |
548             (CCA_SB_CACHEABLE_COHERENT << CPU_MIPS_CACHED_CCA_SHIFT), 0, 0,
549                                                             "SB-1 (0x11)"                 },
550 
551           { MIPS_PRID_CID_RMI, MIPS_XLR732B, -1,  -1, -1, 0,
552             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
553             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
554             MIPS_CP0FL_USE |
555             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
556             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
557             CIDFL_RMI_TYPE_XLR|MIPS_CIDFL_RMI_CPUS(8,4)|MIPS_CIDFL_RMI_L2(2MB),
558             "XLR732B"                   },
559 
560           { MIPS_PRID_CID_RMI, MIPS_XLR732C, -1,  -1, -1, 0,
561             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
562             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
563             MIPS_CP0FL_USE |
564             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
565             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
566             CIDFL_RMI_TYPE_XLR|MIPS_CIDFL_RMI_CPUS(8,4)|MIPS_CIDFL_RMI_L2(2MB),
567             "XLR732C"                   },
568 
569           { MIPS_PRID_CID_RMI, MIPS_XLS616, -1,   -1, -1, 0,
570             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
571             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
572             MIPS_CP0FL_USE |
573             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
574             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
575             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(4,4)|MIPS_CIDFL_RMI_L2(1MB),
576             "XLS616"                    },
577 
578           { MIPS_PRID_CID_RMI, MIPS_XLS416, -1,   -1, -1, 0,
579             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
580             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
581             MIPS_CP0FL_USE |
582             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
583             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
584             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(4,4)|MIPS_CIDFL_RMI_L2(1MB),
585             "XLS416"                    },
586 
587           { MIPS_PRID_CID_RMI, MIPS_XLS408, -1,   -1, -1, 0,
588             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
589             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
590             MIPS_CP0FL_USE |
591             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
592             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
593             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(1MB),
594             "XLS408"                    },
595 
596           { MIPS_PRID_CID_RMI, MIPS_XLS408LITE, -1, -1, -1, 0,
597             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
598             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
599             MIPS_CP0FL_USE |
600             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
601             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
602             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(1MB),
603             "XLS408lite"                },
604 
605           { MIPS_PRID_CID_RMI, MIPS_XLS404LITE, -1, -1, -1, 0,
606             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
607             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
608             MIPS_CP0FL_USE |
609             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
610             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
611             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(512KB),
612             "XLS404lite"                },
613 
614           { MIPS_PRID_CID_RMI, MIPS_XLS208, -1,   -1, -1, 0,
615             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
616             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
617             MIPS_CP0FL_USE |
618             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
619             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
620             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(512KB),
621             "XLS208"                    },
622 
623           { MIPS_PRID_CID_RMI, MIPS_XLS204, -1,   -1, -1, 0,
624             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
625             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
626             MIPS_CP0FL_USE |
627             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
628             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
629             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(256KB),
630             "XLS204"                    },
631 
632           { MIPS_PRID_CID_RMI, MIPS_XLS108, -1,   -1, -1, 0,
633             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
634             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
635             MIPS_CP0FL_USE |
636             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
637             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
638             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(512KB),
639             "XLS108"                    },
640 
641           { MIPS_PRID_CID_RMI, MIPS_XLS104, -1,   -1, -1, 0,
642             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR |
643             CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR,
644             MIPS_CP0FL_USE |
645             MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE |
646             MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7,
647             CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(256KB),
648             "XLS104"                    },
649 
650           { MIPS_PRID_CID_CAVIUM, MIPS_CN31XX, -1, -1, -1, 0,
651             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR,
652             MIPS_CP0FL_USE |
653             MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG |
654             MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3,
655             0,
656             "CN31xx"                    },
657 
658           { MIPS_PRID_CID_CAVIUM, MIPS_CN30XX, -1, -1, -1, 0,
659             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR,
660             MIPS_CP0FL_USE |
661             MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG |
662             MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3,
663             0,
664             "CN30xx"                    },
665 
666           { MIPS_PRID_CID_CAVIUM, MIPS_CN50XX, -1, -1, -1, 0,
667             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR,
668             MIPS_CP0FL_USE |
669             MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG |
670             MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3,
671             0,
672             "CN50xx"                    },
673 
674           { MIPS_PRID_CID_CAVIUM, MIPS_CN68XX, -1, -1, -1, 0,
675             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR,
676             MIPS_CP0FL_USE |
677             MIPS_CP0FL_CONFIG  | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
678             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG4,
679             0,
680             "CN68xx"                    },
681 
682           { MIPS_PRID_CID_CAVIUM, MIPS_CN70XX, -1, -1, -1, 0,
683             MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR,
684             MIPS_CP0FL_USE | MIPS_CP0FL_EBASE |
685             MIPS_CP0FL_CONFIG  | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 |
686             MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG4 | MIPS_CP0FL_CONFIG5 |
687             MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7,
688             0,
689             "CN70xx/CN71xx"   },
690 
691           /* Microsoft Research' extensible MIPS */
692           { MIPS_PRID_CID_MICROSOFT, MIPS_eMIPS, 1, -1, CPU_ARCH_MIPS1, 64,
693             CPU_MIPS_NO_WAIT, 0, 0,               "eMIPS CPU"                   },
694 
695           /* Ingenic XBurst */
696           { MIPS_PRID_CID_INGENIC, MIPS_XBURST,  -1, -1,    -1, 0,
697             MIPS32_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_DOUBLE_COUNT,
698             0, 0, "XBurst"              },
699 
700           { 0, 0, 0,                                        0, 0, 0,
701             0, 0, 0,                                        NULL                          }
702 };
703 
704 static const struct pridtab fputab[] = {
705     { 0, MIPS_SOFT,  -1, 0, 0, 0, 0, 0, 0, "software emulated floating point" },
706     { 0, MIPS_R2360, -1, 0, 0, 0, 0, 0, 0, "MIPS R2360 Floating Point Board" },
707     { 0, MIPS_R2010, -1, 0, 0, 0, 0, 0, 0, "MIPS R2010 FPC" },
708     { 0, MIPS_R3010, -1, 0, 0, 0, 0, 0, 0, "MIPS R3010 FPC" },
709     { 0, MIPS_R6010, -1, 0, 0, 0, 0, 0, 0, "MIPS R6010 FPC" },
710     { 0, MIPS_R4010, -1, 0, 0, 0, 0, 0, 0, "MIPS R4010 FPC" },
711 };
712 
713 /*
714  * Company ID's are not sparse (yet), this array is indexed directly
715  * by pridtab->cpu_cid.
716  */
717 static const char * const cidnames[] = {
718           "Prehistoric",
719           "MIPS",             /* or "MIPS Technologies, Inc.          */
720           "Broadcom",         /* or "Broadcom Corp."                  */
721           "Alchemy",          /* or "Alchemy Semiconductor" */
722           "SiByte", /* or "Broadcom Corp. (SiByte)"         */
723           "SandCraft",
724           "Phillips",
725           "Toshiba or Microsoft",
726           "LSI",
727           "(unannounced)",
728           "(unannounced)",
729           "Lexra",
730           "RMI",
731           "Cavium",
732 };
733 #define   ncidnames __arraycount(cidnames)
734 
735 #if defined(MIPS1)
736 /*
737  * MIPS-I locore function vector
738  */
739 
740 static void
mips1_vector_init(const struct splsw * splsw)741 mips1_vector_init(const struct splsw *splsw)
742 {
743           extern char mips1_utlb_miss[], mips1_utlb_miss_end[];
744           extern char mips1_exception[], mips1_exception_end[];
745 
746           /*
747            * Copy down exception vector code.
748            */
749           if (mips1_utlb_miss_end - mips1_utlb_miss > 0x80)
750                     panic("startup: UTLB vector code too large");
751           if (mips1_exception_end - mips1_exception > 0x80)
752                     panic("startup: general exception vector code too large");
753           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips1_utlb_miss,
754                     mips1_exception_end - mips1_utlb_miss);
755 
756           /*
757            * Copy locore-function vector.
758            */
759           mips_locore_jumpvec = mips1_locore_vec;
760 
761           /*
762            * Clear out the I and D caches.
763            */
764           mips_icache_sync_all();
765           mips_dcache_wbinv_all();
766 }
767 #endif /* MIPS1 */
768 
769 #if defined(MIPS3)
770 static void
mips3_vector_init(const struct splsw * splsw)771 mips3_vector_init(const struct splsw *splsw)
772 {
773           /* r4000 exception handler address and end */
774           extern char mips3_exception[], mips3_exception_end[];
775 
776           /* TLB miss handler address and end */
777           extern char mips3_tlb_miss[];
778           extern char mips3_xtlb_miss[];
779 
780           /* Cache error handler */
781           extern char mips3_cache[];
782           /*
783            * Copy down exception vector code.
784            */
785 
786           if (mips3_xtlb_miss - mips3_tlb_miss != 0x80)
787                     panic("startup: %s vector code not 128 bytes in length",
788                         "UTLB");
789           if (mips3_cache - mips3_xtlb_miss != 0x80)
790                     panic("startup: %s vector code not 128 bytes in length",
791                         "XTLB");
792           if (mips3_exception - mips3_cache != 0x80)
793                     panic("startup: %s vector code not 128 bytes in length",
794                         "Cache error");
795           if (mips3_exception_end - mips3_exception > 0x80)
796                     panic("startup: %s vector code too large",
797                         "General exception");
798 
799           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips3_tlb_miss,
800                 mips3_exception_end - mips3_tlb_miss);
801 
802           /*
803            * Copy locore-function vector.
804            */
805           mips_locore_jumpvec = mips3_locore_vec;
806 
807           mips_icache_sync_all();
808           mips_dcache_wbinv_all();
809 
810           /* Clear BEV in SR so we start handling our own exceptions */
811           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
812 }
813 #endif /* MIPS3 */
814 
815 #if defined(MIPS3_LOONGSON2)
816 static void
loongson2_vector_init(const struct splsw * splsw)817 loongson2_vector_init(const struct splsw *splsw)
818 {
819           /* r4000 exception handler address and end */
820           extern char loongson2_exception[], loongson2_exception_end[];
821 
822           /* TLB miss handler address and end */
823           extern char loongson2_tlb_miss[];
824           extern char loongson2_xtlb_miss[];
825 
826           /* Cache error handler */
827           extern char loongson2_cache[];
828 
829           /*
830            * Copy down exception vector code.
831            */
832 
833           if (loongson2_xtlb_miss - loongson2_tlb_miss != 0x80)
834                     panic("startup: %s vector code not 128 bytes in length",
835                         "UTLB");
836           if (loongson2_cache - loongson2_xtlb_miss != 0x80)
837                     panic("startup: %s vector code not 128 bytes in length",
838                         "XTLB");
839           if (loongson2_exception - loongson2_cache != 0x80)
840                     panic("startup: %s vector code not 128 bytes in length",
841                         "Cache error");
842           if (loongson2_exception_end - loongson2_exception > 0x80)
843                     panic("startup: %s vector code too large",
844                         "General exception");
845 
846           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, loongson2_tlb_miss,
847                 loongson2_exception_end - loongson2_tlb_miss);
848 
849           /*
850            * Copy locore-function vector.
851            */
852           mips_locore_jumpvec = loongson2_locore_vec;
853 
854           mips_icache_sync_all();
855           mips_dcache_wbinv_all();
856 
857           /* Clear BEV in SR so we start handling our own exceptions */
858           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
859 }
860 #endif /* MIPS3_LOONGSON2 */
861 
862 #if defined(MIPS32)
863 static void
mips32_vector_init(const struct splsw * splsw)864 mips32_vector_init(const struct splsw *splsw)
865 {
866           /* r4000 exception handler address */
867           extern char mips32_exception[];
868 
869           /* TLB miss handler addresses */
870           extern char mips32_tlb_miss[];
871 
872           /* Cache error handler */
873           extern char mips32_cache[];
874 
875           /* MIPS32 interrupt exception handler */
876           extern char mips32_intr[], mips32_intr_end[];
877 
878           /*
879            * Copy down exception vector code.
880            */
881 
882           if (mips32_cache - mips32_tlb_miss != 0x100)
883                     panic("startup: %s vector code not 128 bytes in length",
884                         "UTLB");
885           if (mips32_exception - mips32_cache != 0x80)
886                     panic("startup: %s vector code not 128 bytes in length",
887                         "Cache error");
888           if (mips32_intr - mips32_exception != 0x80)
889                     panic("startup: %s vector code not 128 bytes in length",
890                         "General exception");
891           if (mips32_intr_end - mips32_intr > 0x80)
892                     panic("startup: %s vector code too large",
893                         "interrupt exception");
894 
895           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32_tlb_miss,
896                 mips32_intr_end - mips32_tlb_miss);
897 
898           /*
899            * Copy locore-function vector.
900            */
901           mips_locore_jumpvec = mips32_locore_vec;
902 
903           mips_icache_sync_all();
904           mips_dcache_wbinv_all();
905 
906           /* Clear BEV in SR so we start handling our own exceptions */
907           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
908 
909           mips_watchpoint_init();
910 }
911 #endif /* MIPS32 */
912 
913 #if defined(MIPS32R2)
914 static void
mips32r2_vector_init(const struct splsw * splsw)915 mips32r2_vector_init(const struct splsw *splsw)
916 {
917           /* r4000 exception handler address */
918           extern char mips32r2_exception[];
919 
920           /* TLB miss handler addresses */
921           extern char mips32r2_tlb_miss[];
922 
923           /* Cache error handler */
924           extern char mips32r2_cache[];
925 
926           /* MIPS32 interrupt exception handler */
927           extern char mips32r2_intr[], mips32r2_intr_end[];
928 
929           /*
930            * Copy down exception vector code.
931            */
932           if (mips32r2_cache - mips32r2_tlb_miss != 0x100)
933                     panic("startup: %s vector code not 128 bytes in length",
934                         "UTLB");
935           if (mips32r2_exception - mips32r2_cache != 0x80)
936                     panic("startup: %s vector code not 128 bytes in length",
937                         "Cache error");
938           if (mips32r2_intr - mips32r2_exception != 0x80)
939                     panic("startup: %s vector code not 128 bytes in length",
940                         "General exception");
941           if (mips32r2_intr_end - mips32r2_intr > 0x80)
942                     panic("startup: %s vector code too large",
943                         "interrupt exception");
944 
945           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32r2_tlb_miss,
946                 mips32r2_intr_end - mips32r2_tlb_miss);
947 
948           /*
949            * Let's see if this cpu has USERLOCAL or DSP V2 ASE...
950            */
951           if (mipsNN_cp0_config2_read() & MIPSNN_CFG2_M) {
952                     const uint32_t cfg3 = mipsNN_cp0_config3_read();
953                     if (cfg3 & MIPSNN_CFG3_ULRI) {
954                               mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_USERLOCAL;
955                     }
956                     if (cfg3 & MIPSNN_CFG3_DSP2P) {
957                               mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_DSP;
958                     }
959           }
960 
961           /*
962            * If this CPU doesn't have a COP0 USERLOCAL register, at the end
963            * of cpu_switch resume overwrite the instructions which update it.
964            */
965           if (!MIPS_HAS_USERLOCAL) {
966                     extern uint32_t mips32r2_cpu_switch_resume[];
967                     for (uint32_t *insnp = mips32r2_cpu_switch_resume;; insnp++) {
968                               KASSERT(insnp[0] != JR_RA);
969                               if (insnp[0] == _LOAD_V0_L_PRIVATE_A0
970                                   && insnp[1] == _MTC0_V0_USERLOCAL) {
971                                         insnp[0] = JR_RA;
972                                         insnp[1] = 0;                 /* NOP */
973                                         break;
974                               }
975                     }
976           }
977 
978           /*
979            * Copy locore-function vector.
980            */
981           mips_locore_jumpvec = mips32r2_locore_vec;
982 
983           mips_icache_sync_all();
984           mips_dcache_wbinv_all();
985 
986           /* Clear BEV in SR so we start handling our own exceptions */
987           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
988 
989           mips_watchpoint_init();
990 }
991 #endif /* MIPS32R2 */
992 
993 #if defined(MIPS64)
994 static void
mips64_vector_init(const struct splsw * splsw)995 mips64_vector_init(const struct splsw *splsw)
996 {
997           /* r4000 exception handler address */
998           extern char mips64_exception[];
999 
1000           /* TLB miss handler addresses */
1001           extern char mips64_tlb_miss[];
1002           extern char mips64_xtlb_miss[];
1003 
1004           /* Cache error handler */
1005           extern char mips64_cache[];
1006 
1007           /* MIPS64 interrupt exception handler */
1008           extern char mips64_intr[], mips64_intr_end[];
1009 
1010           /*
1011            * Copy down exception vector code.
1012            */
1013 
1014           if (mips64_xtlb_miss - mips64_tlb_miss != 0x80)
1015                     panic("startup: %s vector code not 128 bytes in length",
1016                         "UTLB");
1017           if (mips64_cache - mips64_xtlb_miss != 0x80)
1018                     panic("startup: %s vector code not 128 bytes in length",
1019                         "XTLB");
1020           if (mips64_exception - mips64_cache != 0x80)
1021                     panic("startup: %s vector code not 128 bytes in length",
1022                         "Cache error");
1023           if (mips64_intr - mips64_exception != 0x80)
1024                     panic("startup: %s vector code not 128 bytes in length",
1025                         "General exception");
1026           if (mips64_intr_end - mips64_intr > 0x80)
1027                     panic("startup: %s vector code too large",
1028                         "interrupt exception");
1029 
1030           memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips64_tlb_miss,
1031                 mips64_intr_end - mips64_tlb_miss);
1032 
1033           /*
1034            * Copy locore-function vector.
1035            */
1036           mips_locore_jumpvec = mips64_locore_vec;
1037 
1038           mips_icache_sync_all();
1039           mips_dcache_wbinv_all();
1040 
1041           /* Clear BEV in SR so we start handling our own exceptions */
1042           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
1043 
1044           mips_watchpoint_init();
1045 }
1046 #endif /* MIPS64 */
1047 
1048 #if defined(MIPS64R2)
1049 void
mips64r2_vector_init(const struct splsw * splsw)1050 mips64r2_vector_init(const struct splsw *splsw)
1051 {
1052           /* r4000 exception handler address */
1053           extern char mips64r2_exception[];
1054 
1055           /* TLB miss handler addresses */
1056           extern char mips64r2_tlb_miss[];
1057           extern char mips64r2_xtlb_miss[];
1058 
1059           /* Cache error handler */
1060           extern char mips64r2_cache[];
1061 
1062           /* MIPS64 interrupt exception handler */
1063           extern char mips64r2_intr[], mips64r2_intr_end[];
1064 
1065           /*
1066            * Copy down exception vector code.
1067            */
1068 
1069           if (mips64r2_xtlb_miss - mips64r2_tlb_miss != 0x80)
1070                     panic("startup: %s vector code not 128 bytes in length",
1071                         "UTLB");
1072           if (mips64r2_cache - mips64r2_xtlb_miss != 0x80)
1073                     panic("startup: %s vector code not 128 bytes in length",
1074                         "XTLB");
1075           if (mips64r2_exception - mips64r2_cache != 0x80)
1076                     panic("startup: %s vector code not 128 bytes in length",
1077                         "Cache error");
1078           if (mips64r2_intr - mips64r2_exception != 0x80)
1079                     panic("startup: %s vector code not 128 bytes in length",
1080                         "General exception");
1081           if (mips64r2_intr_end - mips64r2_intr > 0x80)
1082                     panic("startup: %s vector code too large",
1083                         "interrupt exception");
1084 
1085           const intptr_t ebase = (intptr_t)mipsNN_cp0_ebase_read();
1086           const int cpunum = ebase & MIPS_EBASE_CPUNUM;
1087 
1088           // This may need to be on CPUs other CPU0 so use EBASE to fetch
1089           // the appropriate address for exception code.  EBASE also contains
1090           // the cpunum so remove that.
1091           memcpy((void *)(intptr_t)(ebase & ~MIPS_EBASE_CPUNUM), mips64r2_tlb_miss,
1092                 mips64r2_intr_end - mips64r2_tlb_miss);
1093 
1094           /*
1095            * Let's see if this cpu has USERLOCAL or DSP V2 ASE...
1096            */
1097           if (mipsNN_cp0_config2_read() & MIPSNN_CFG2_M) {
1098                     const uint32_t cfg3 = mipsNN_cp0_config3_read();
1099                     if (cfg3 & MIPSNN_CFG3_ULRI) {
1100                               mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_USERLOCAL;
1101                     }
1102                     if (cfg3 & MIPSNN_CFG3_DSP2P) {
1103                               mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_DSP;
1104                     }
1105           }
1106 
1107           /*
1108            * If this CPU doesn't have a COP0 USERLOCAL register, at the end
1109            * of cpu_switch resume overwrite the instructions which update it.
1110            */
1111           if (!MIPS_HAS_USERLOCAL && cpunum == 0) {
1112                     extern uint32_t mips64r2_cpu_switch_resume[];
1113                     for (uint32_t *insnp = mips64r2_cpu_switch_resume;; insnp++) {
1114                               KASSERT(insnp[0] != JR_RA);
1115                               if (insnp[0] == _LOAD_V0_L_PRIVATE_A0
1116                                   && insnp[1] == _MTC0_V0_USERLOCAL) {
1117                                         insnp[0] = JR_RA;
1118                                         insnp[1] = 0;                 /* NOP */
1119                                         break;
1120                               }
1121                     }
1122           }
1123 
1124           /*
1125            * Copy locore-function vector.
1126            */
1127           if (cpunum == 0)
1128                     mips_locore_jumpvec = mips64r2_locore_vec;
1129 
1130           mips_icache_sync_all();
1131           mips_dcache_wbinv_all();
1132 
1133           /* Clear BEV in SR so we start handling our own exceptions */
1134           mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
1135 
1136           mips_watchpoint_init();
1137 }
1138 #endif /* MIPS64R2 */
1139 
1140 /*
1141  * Do all the stuff that locore normally does before calling main(),
1142  * that is common to all mips-CPU NetBSD ports.
1143  *
1144  * The principal purpose of this function is to examine the
1145  * variable cpu_id, into which the kernel locore start code
1146  * writes the CPU ID register, and to then copy appropriate
1147  * code into the CPU exception-vector entries and the jump tables
1148  * used to hide the differences in cache and TLB handling in
1149  * different MIPS CPUs.
1150  *
1151  * This should be the very first thing called by each port's
1152  * init_main() function.
1153  */
1154 
1155 /*
1156  * Initialize the hardware exception vectors, and the jump table used to
1157  * call locore cache and TLB management functions, based on the kind
1158  * of CPU the kernel is running on.
1159  */
1160 void
mips_vector_init(const struct splsw * splsw,bool multicpu_p)1161 mips_vector_init(const struct splsw *splsw, bool multicpu_p)
1162 {
1163           struct mips_options * const opts = &mips_options;
1164           const struct pridtab *ct;
1165           const mips_prid_t cpu_id = opts->mips_cpu_id;
1166 
1167           for (ct = cputab; ct->cpu_name != NULL; ct++) {
1168                     if (MIPS_PRID_CID(cpu_id) != ct->cpu_cid ||
1169                         MIPS_PRID_IMPL(cpu_id) != ct->cpu_pid)
1170                               continue;
1171                     if (ct->cpu_rev >= 0 &&
1172                         MIPS_PRID_REV(cpu_id) != ct->cpu_rev)
1173                               continue;
1174                     if (ct->cpu_copts >= 0 &&
1175                         MIPS_PRID_COPTS(cpu_id) != ct->cpu_copts)
1176                               continue;
1177 
1178                     opts->mips_cpu = ct;
1179                     opts->mips_cpu_arch = ct->cpu_isa;
1180                     opts->mips_num_tlb_entries = ct->cpu_ntlb;
1181                     break;
1182           }
1183 
1184           if (opts->mips_cpu == NULL)
1185                     panic("CPU type (0x%x) not supported", cpu_id);
1186 
1187 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1188           if (MIPS_PRID_CID(cpu_id) != 0) {
1189                     /* MIPS32/MIPS64, use coprocessor 0 config registers */
1190                     uint32_t cfg, cfg1, cfg4;
1191 
1192                     cfg = mips3_cp0_config_read();
1193                     cfg1 = mipsNN_cp0_config1_read();
1194                     if (opts->mips_cpu->cpu_cp0flags & MIPS_CP0FL_CONFIG4)
1195                               cfg4 = mipsNN_cp0_config4_read();
1196                     else
1197                               cfg4 = 0;
1198 
1199                     /* pick CPU type */
1200                     switch (MIPSNN_GET(CFG_AT, cfg)) {
1201                     case MIPSNN_CFG_AT_MIPS32:
1202                               opts->mips_cpu_arch = CPU_ARCH_MIPS32;
1203                               break;
1204                     case MIPSNN_CFG_AT_MIPS64:
1205                               opts->mips_cpu_arch = CPU_ARCH_MIPS64;
1206                               break;
1207                     case MIPSNN_CFG_AT_MIPS64S:
1208                     default:
1209                               panic("MIPS32/64 architecture type %d not supported",
1210                                   MIPSNN_GET(CFG_AT, cfg));
1211                     }
1212 
1213                     switch (MIPSNN_GET(CFG_AR, cfg)) {
1214                     case MIPSNN_CFG_AR_REV1:
1215                               break;
1216                     case MIPSNN_CFG_AR_REV2:
1217                               switch (opts->mips_cpu_arch) {
1218                               case CPU_ARCH_MIPS32:
1219                                         opts->mips_cpu_arch = CPU_ARCH_MIPS32R2;
1220                                         break;
1221                               case CPU_ARCH_MIPS64:
1222                                         opts->mips_cpu_arch = CPU_ARCH_MIPS64R2;
1223                                         break;
1224                               default:
1225                                         printf("WARNING: MIPS32/64 arch %d revision %d "
1226                                             "unknown!\n", opts->mips_cpu_arch,
1227                                             MIPSNN_GET(CFG_AR, cfg));
1228                                         break;
1229                               }
1230                               break;
1231                     default:
1232                               printf("WARNING: MIPS32/64 arch revision %d "
1233                                   "unknown!\n", MIPSNN_GET(CFG_AR, cfg));
1234                               break;
1235                     }
1236 
1237                     /* figure out MMU type (and number of TLB entries) */
1238                     switch (MIPSNN_GET(CFG_MT, cfg)) {
1239                     case MIPSNN_CFG_MT_TLB:
1240                               /*
1241                                * Config1[MMUSize-1] defines the number of TLB
1242                                * entries minus 1, allowing up to 64 TLBs to be
1243                                * defined.  For MIPS32R2 and MIPS64R2 and later
1244                                * if the Config4[MMUExtDef] field is 1 then the
1245                                * Config4[MMUSizeExt] field is an extension of
1246                                * Config1[MMUSize-1] field.
1247                                */
1248                               opts->mips_num_tlb_entries = MIPSNN_CFG1_MS(cfg1);
1249                               if (__SHIFTOUT(cfg4, MIPSNN_CFG4_MMU_EXT_DEF) ==
1250                                   MIPSNN_CFG4_MMU_EXT_DEF_MMU) {
1251                                         opts->mips_num_tlb_entries +=
1252                                         __SHIFTOUT(cfg4, MIPSNN_CFG4_MMU_SIZE_EXT) <<
1253                                             popcount(MIPSNN_CFG1_MS_MASK);
1254                               }
1255                               break;
1256                     case MIPSNN_CFG_MT_NONE:
1257                     case MIPSNN_CFG_MT_BAT:
1258                     case MIPSNN_CFG_MT_FIXED:
1259                     default:
1260                               panic("MIPS32/64 MMU type %d not supported",
1261                                   MIPSNN_GET(CFG_MT, cfg));
1262                     }
1263           }
1264 #endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */
1265 
1266           if (opts->mips_cpu_arch < 1)
1267                     panic("Unknown CPU ISA for CPU type 0x%x", cpu_id);
1268           if (opts->mips_num_tlb_entries < 1)
1269                     panic("Unknown number of TLBs for CPU type 0x%x", cpu_id);
1270 
1271           /*
1272            * Check CPU-specific flags.
1273            */
1274           opts->mips_cpu_flags = opts->mips_cpu->cpu_flags;
1275           opts->mips_has_r4k_mmu = (opts->mips_cpu_flags & CPU_MIPS_R4K_MMU) != 0;
1276           opts->mips_has_llsc = (opts->mips_cpu_flags & CPU_MIPS_NO_LLSC) == 0;
1277 #if defined(MIPS3_4100)
1278           if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100)
1279                     opts->mips3_pg_shift = MIPS3_4100_PG_SHIFT;
1280           else
1281 #endif
1282                     opts->mips3_pg_shift = MIPS3_DEFAULT_PG_SHIFT;
1283 
1284           opts->mips3_cca_devmem = CCA_UNCACHED;
1285           if (opts->mips_cpu_flags & CPU_MIPS_HAVE_SPECIAL_CCA) {
1286                     uint32_t cca;
1287 
1288                     cca = (opts->mips_cpu_flags & CPU_MIPS_CACHED_CCA_MASK) >>
1289                         CPU_MIPS_CACHED_CCA_SHIFT;
1290                     opts->mips3_pg_cached = MIPS3_CCA_TO_PG(cca);
1291 #ifndef __mips_o32
1292                     opts->mips3_xkphys_cached = MIPS_PHYS_TO_XKPHYS(cca, 0);
1293 #endif
1294           } else {
1295                     opts->mips3_pg_cached = MIPS3_DEFAULT_PG_CACHED;
1296 #ifndef __mips_o32
1297                     opts->mips3_xkphys_cached = MIPS3_DEFAULT_XKPHYS_CACHED;
1298 #endif
1299           }
1300 
1301 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
1302           mips_machdep_cache_config();
1303 #endif
1304 
1305           /*
1306            * if 'splsw' is NULL, use standard SPL with COP0 status/cause
1307            * otherwise use chip-specific splsw
1308            */
1309           if (splsw == NULL) {
1310                     mips_splsw = std_splsw;
1311 #ifdef PARANOIA
1312                     std_splsw_test();   /* only works with std_splsw */
1313 #endif
1314           } else {
1315                     mips_splsw = *splsw;
1316           }
1317 
1318           /*
1319            * Determine cache configuration and initialize our cache
1320            * frobbing routine function pointers.
1321            */
1322           mips_config_cache();
1323 
1324           /*
1325            * We default to RAS atomic ops since they are the lowest overhead.
1326            */
1327 #ifdef MULTIPROCESSOR
1328           if (multicpu_p) {
1329                     /*
1330                      * If we could have multiple CPUs active,
1331                      * use the ll/sc variants.
1332                      */
1333                     mips_locore_atomicvec = mips_llsc_locore_atomicvec;
1334           }
1335 #endif
1336           /*
1337            * Now initialize our ISA-dependent function vector.
1338            */
1339           switch (opts->mips_cpu_arch) {
1340 #if defined(MIPS1)
1341           case CPU_ARCH_MIPS1:
1342                     (*mips1_locore_vec.ljv_tlb_invalidate_all)();
1343                     mips1_vector_init(splsw);
1344                     mips_locoresw = mips1_locoresw;
1345                     break;
1346 #endif
1347 #if defined(MIPS3)
1348           case CPU_ARCH_MIPS3:
1349           case CPU_ARCH_MIPS4:
1350                     mips3_tlb_probe();
1351 #if defined(MIPS3_4100)
1352                     if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100)
1353                               mips3_cp0_pg_mask_write(MIPS4100_PG_SIZE_TO_MASK(PAGE_SIZE));
1354                     else
1355 #endif
1356                     mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE));
1357                     mips3_cp0_wired_write(0);
1358 #if defined(MIPS3_LOONGSON2)
1359                     if (opts->mips_cpu_flags & CPU_MIPS_LOONGSON2) {
1360                               (*loongson2_locore_vec.ljv_tlb_invalidate_all)();
1361                               mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1362                               loongson2_vector_init(splsw);
1363                               mips_locoresw = loongson2_locoresw;
1364                               opts->mips3_cca_devmem = CCA_ACCEL;
1365                               break;
1366                     }
1367 #endif /* MIPS3_LOONGSON2 */
1368                     (*mips3_locore_vec.ljv_tlb_invalidate_all)();
1369                     mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1370                     mips3_vector_init(splsw);
1371                     mips_locoresw = mips3_locoresw;
1372                     break;
1373 
1374 #endif /* MIPS3 */
1375 #if defined(MIPS32)
1376           case CPU_ARCH_MIPS32:
1377                     mips3_tlb_probe();
1378                     mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE));
1379                     mips3_cp0_wired_write(0);
1380                     (*mips32_locore_vec.ljv_tlb_invalidate_all)();
1381                     mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1382                     mips32_vector_init(splsw);
1383                     mips_locoresw = mips32_locoresw;
1384                     break;
1385 #endif
1386 #if defined(MIPS32R2)
1387           case CPU_ARCH_MIPS32R2:
1388                     mips3_tlb_probe();
1389                     mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE));
1390                     mips3_cp0_wired_write(0);
1391                     (*mips32r2_locore_vec.ljv_tlb_invalidate_all)();
1392                     mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1393                     mips32r2_vector_init(splsw);
1394                     mips_locoresw = mips32r2_locoresw;
1395                     break;
1396 #endif
1397 #if defined(MIPS64)
1398           case CPU_ARCH_MIPS64: {
1399                     mips3_tlb_probe();
1400                     mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE));
1401                     mips3_cp0_wired_write(0);
1402                     (*mips64_locore_vec.ljv_tlb_invalidate_all)();
1403                     mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1404                     mips64_vector_init(splsw);
1405                     mips_locoresw = mips64_locoresw;
1406                     break;
1407           }
1408 #endif
1409 #if defined(MIPS64R2)
1410           case CPU_ARCH_MIPS64R2: {
1411                     mips3_tlb_probe();
1412                     mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE));
1413                     mips3_cp0_wired_write(0);
1414                     (*mips64r2_locore_vec.ljv_tlb_invalidate_all)();
1415                     mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
1416                     mips64r2_vector_init(splsw);
1417                     mips_locoresw = mips64r2_locoresw;
1418                     break;
1419           }
1420 #endif
1421           default:
1422                     printf("cpu_arch 0x%x: not supported\n", opts->mips_cpu_arch);
1423                     cpu_reboot(RB_HALT, NULL);
1424           }
1425 
1426           /*
1427            * Now that the splsw and locoresw have been filled in, fixup the
1428            * jumps to any stubs to actually jump to the real routines.
1429            */
1430           extern uint32_t _ftext[];
1431           extern uint32_t _etext[];
1432           mips_fixup_stubs(_ftext, _etext);
1433 
1434 #if (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1435           /*
1436            * Install power-saving idle routines.
1437            */
1438           if ((opts->mips_cpu_flags & CPU_MIPS_USE_WAIT) &&
1439               !(opts->mips_cpu_flags & CPU_MIPS_NO_WAIT))
1440                     mips_locoresw.lsw_cpu_idle = mips_wait_idle;
1441 #endif /* (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */
1442 }
1443 
1444 void
mips_set_wbflush(void (* flush_fn)(void))1445 mips_set_wbflush(void (*flush_fn)(void))
1446 {
1447           mips_locoresw.lsw_wbflush = flush_fn;
1448           (*flush_fn)();
1449 }
1450 
1451 #if defined(MIPS3_PLUS)
1452 static void
mips3_tlb_probe(void)1453 mips3_tlb_probe(void)
1454 {
1455           struct mips_options * const opts = &mips_options;
1456           opts->mips3_tlb_pg_mask = mips3_cp0_tlb_page_mask_probe();
1457           if (CPUIS64BITS) {
1458                     opts->mips3_tlb_vpn_mask = mips3_cp0_tlb_entry_hi_probe();
1459                     opts->mips3_tlb_vpn_mask |= PAGE_MASK;
1460                     opts->mips3_tlb_vpn_mask <<= 2;
1461                     opts->mips3_tlb_vpn_mask >>= 2;
1462                     opts->mips3_tlb_pfn_mask = mips3_cp0_tlb_entry_lo_probe();
1463 #if defined(_LP64) && defined(ENABLE_MIPS_16KB_PAGE)
1464                     /*
1465                      * 16KB pages could cause our page table being able to address
1466                      * a larger address space than the actual chip supports.  So
1467                      * we need to limit the address space to what it can really
1468                      * address.
1469                      */
1470                     if (mips_vm_maxuser_address > opts->mips3_tlb_vpn_mask + 1)
1471                               mips_vm_maxuser_address = opts->mips3_tlb_vpn_mask + 1;
1472 #endif
1473           }
1474 }
1475 #endif
1476 
1477 static const char *
wayname(int ways)1478 wayname(int ways)
1479 {
1480           static char buf[sizeof("xxx-way set-associative")];
1481 
1482 #ifdef DIAGNOSTIC
1483           if (ways > 999)
1484                     panic("mips cache - too many ways (%d)", ways);
1485 #endif
1486 
1487           switch (ways) {
1488           case 0:
1489                     return "fully set-associative";
1490           case 1:
1491                     return "direct-mapped";
1492           default:
1493                     snprintf(buf, sizeof(buf), "%d-way set-associative", ways);
1494                     return buf;
1495           }
1496 }
1497 
1498 /*
1499  * Identify product revision IDs of CPU and FPU.
1500  */
1501 void
cpu_identify(device_t dev)1502 cpu_identify(device_t dev)
1503 {
1504           const struct mips_options * const opts = &mips_options;
1505           const struct mips_cache_info * const mci = &mips_cache_info;
1506           const mips_prid_t cpu_id = opts->mips_cpu_id;
1507           const mips_prid_t fpu_id = opts->mips_fpu_id;
1508           static const char * const wtnames[] = {
1509                     "write-back",
1510                     "write-through",
1511           };
1512           const char *cpuname, *fpuname;
1513           int i;
1514 
1515           cpuname = opts->mips_cpu->cpu_name;
1516 #ifdef MIPS64_OCTEON
1517           if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_CAVIUM) {
1518                     cpuname = octeon_cpu_model(cpu_id);
1519           }
1520 #endif
1521 
1522           fpuname = NULL;
1523           for (i = 0; i < sizeof(fputab)/sizeof(fputab[0]); i++) {
1524                     if (MIPS_PRID_CID(fpu_id) == fputab[i].cpu_cid &&
1525                         MIPS_PRID_IMPL(fpu_id) == fputab[i].cpu_pid) {
1526                               fpuname = fputab[i].cpu_name;
1527                               break;
1528                     }
1529           }
1530           if (fpuname == NULL && MIPS_PRID_IMPL(fpu_id) == MIPS_PRID_IMPL(cpu_id))
1531                     fpuname = "built-in FPU";
1532           if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4700)         /* FPU PRid is 0x20 */
1533                     fpuname = "built-in FPU";
1534           if (MIPS_PRID_IMPL(cpu_id) == MIPS_RC64470)       /* FPU PRid is 0x21 */
1535                     fpuname = "built-in FPU";
1536 #ifdef MIPSNN
1537           if (CPUISMIPSNN) {
1538                     uint32_t cfg1;
1539 
1540                     switch (MIPS_PRID_CID(cpu_id)) {
1541                     /*
1542                      * CPUs from the following companies have a built-in
1543                      * FPU if Config1[FP] is set.
1544                      */
1545                     case MIPS_PRID_CID_SIBYTE:
1546                     case MIPS_PRID_CID_CAVIUM:
1547                               cfg1 = mipsNN_cp0_config1_read();
1548                               if (cfg1 & MIPSNN_CFG1_FP)
1549                                         fpuname = "built-in FPU";
1550                               break;
1551                     }
1552           }
1553 #endif
1554 
1555           if (opts->mips_cpu->cpu_cid != 0) {
1556                     if (opts->mips_cpu->cpu_cid <= ncidnames)
1557                               aprint_normal("%s ", cidnames[opts->mips_cpu->cpu_cid]);
1558                     else if (opts->mips_cpu->cpu_cid == MIPS_PRID_CID_INGENIC) {
1559                               aprint_normal("Ingenic ");
1560                     } else {
1561                               aprint_normal("Unknown Company ID - 0x%x",
1562                                   opts->mips_cpu->cpu_cid);
1563                               aprint_normal_dev(dev, "");
1564                     }
1565           }
1566           if (cpuname != NULL)
1567                     aprint_normal("%s (0x%x)", cpuname, cpu_id);
1568           else
1569                     aprint_normal("unknown CPU type (0x%x)", cpu_id);
1570           if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
1571                     aprint_normal(" Rev. %d.%d", MIPS_PRID_REV_MAJ(cpu_id),
1572                         MIPS_PRID_REV_MIN(cpu_id));
1573           else
1574                     aprint_normal(" Rev. %d", MIPS_PRID_REV(cpu_id));
1575 
1576           if (fpuname != NULL)
1577                     aprint_normal(" with %s", fpuname);
1578           else
1579                     aprint_normal(" with unknown FPC type (0x%x)", fpu_id);
1580           if (opts->mips_fpu_id != 0) {
1581                     if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC)
1582                               aprint_normal(" Rev. %d.%d", MIPS_PRID_REV_MAJ(fpu_id),
1583                                   MIPS_PRID_REV_MIN(fpu_id));
1584                     else
1585                               aprint_normal(" Rev. %d", MIPS_PRID_REV(fpu_id));
1586           }
1587           if (opts->mips_cpu_flags & MIPS_HAS_DSP) {
1588                     aprint_normal(" and DSPv2");
1589           }
1590           aprint_normal("\n");
1591 
1592           if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC &&
1593               MIPS_PRID_RSVD(cpu_id) != 0) {
1594                     aprint_normal_dev(dev,
1595                         "NOTE: top 8 bits of prehistoric PRID not 0!\n");
1596                     aprint_normal_dev(dev, "Please mail port-mips@NetBSD.org "
1597                         "with %s dmesg lines.\n", device_xname(dev));
1598           }
1599 
1600           switch (opts->mips_cpu_arch) {
1601 #if defined(MIPS1)
1602           case CPU_ARCH_MIPS1:
1603                     if (mci->mci_picache_size)
1604                               aprint_normal_dev(dev, "%dKB/%dB %s Instruction cache, "
1605                                   "%d TLB entries\n", mci->mci_picache_size / 1024,
1606                                   mci->mci_picache_line_size,
1607                                   wayname(mci->mci_picache_ways),
1608                                   opts->mips_num_tlb_entries);
1609                     else
1610                               aprint_normal_dev(dev, "%d TLB entries\n",
1611                                   opts->mips_num_tlb_entries);
1612                     if (mci->mci_pdcache_size)
1613                               aprint_normal_dev(dev, "%dKB/%dB %s %s Data cache\n",
1614                                   mci->mci_pdcache_size / 1024,
1615                                   mci->mci_pdcache_line_size,
1616                                   wayname(mci->mci_pdcache_ways),
1617                                   wtnames[mci->mci_pdcache_write_through]);
1618                     break;
1619 #endif /* MIPS1 */
1620 #if (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
1621           case CPU_ARCH_MIPS3:
1622           case CPU_ARCH_MIPS4:
1623           case CPU_ARCH_MIPS32:
1624           case CPU_ARCH_MIPS32R2:
1625           case CPU_ARCH_MIPS64:
1626           case CPU_ARCH_MIPS64R2: {
1627                     const char *sufx = "KMGTPE";
1628                     uint32_t pg_mask;
1629                     aprint_normal_dev(dev, "%d TLB entries",
1630                         opts->mips_num_tlb_entries);
1631 #if !defined(__mips_o32)
1632                     if (CPUIS64BITS) {
1633                               int64_t pfn_mask;
1634                               i = ffs(~(opts->mips3_tlb_vpn_mask >> 31)) + 30;
1635                               aprint_normal(", %d%cB (%d-bit) VAs",
1636                                   1 << (i % 10), sufx[(i / 10) - 1], i);
1637                               for (i = 64, pfn_mask = opts->mips3_tlb_pfn_mask << 6;
1638                                    pfn_mask > 0; i--, pfn_mask <<= 1)
1639                                         ;
1640                               aprint_normal(", %d%cB (%d-bit) PAs",
1641                                     1 << (i % 10), sufx[(i / 10) - 1], i);
1642                     }
1643 #endif
1644                     for (i = 4, pg_mask = opts->mips3_tlb_pg_mask >> 13;
1645                          pg_mask != 0; ) {
1646                               if ((pg_mask & 3) != 3)
1647                                         break;
1648                               pg_mask >>= 2;
1649                               i *= 4;
1650                               if (i == 1024) {
1651                                         i = 1;
1652                                         sufx++;
1653                               }
1654                     }
1655                     aprint_normal(", %d%cB max page size\n", i, sufx[0]);
1656                     if (mci->mci_picache_size)
1657                               aprint_normal_dev(dev,
1658                                   "%dKB/%dB %s L1 instruction cache\n",
1659                                   mci->mci_picache_size / 1024,
1660                                   mci->mci_picache_line_size,
1661                                   wayname(mci->mci_picache_ways));
1662                     if (mci->mci_pdcache_size)
1663                               aprint_normal_dev(dev,
1664                                   "%dKB/%dB %s %s %sL1 data cache\n",
1665                                   mci->mci_pdcache_size / 1024,
1666                                   mci->mci_pdcache_line_size,
1667                                   wayname(mci->mci_pdcache_ways),
1668                                   wtnames[mci->mci_pdcache_write_through],
1669                                   ((opts->mips_cpu_flags & CPU_MIPS_D_CACHE_COHERENT)
1670                                         ? "coherent " : ""));
1671                     if (mci->mci_sdcache_line_size)
1672                               aprint_normal_dev(dev,
1673                                   "%dKB/%dB %s %s L2 %s cache\n",
1674                                   mci->mci_sdcache_size / 1024,
1675                                   mci->mci_sdcache_line_size,
1676                                   wayname(mci->mci_sdcache_ways),
1677                                   wtnames[mci->mci_sdcache_write_through],
1678                                   mci->mci_scache_unified ? "unified" : "data");
1679                     break;
1680           }
1681 #endif /* (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */
1682           default:
1683                     panic("cpu_identify: impossible");
1684           }
1685 }
1686 
1687 /*
1688  * Set registers on exec.
1689  * Clear all registers except sp, pc, and t9.
1690  * $sp is set to the stack pointer passed in.  $pc is set to the entry
1691  * point given by the exec_package passed in, as is $t9 (used for PIC
1692  * code by the MIPS elf abi).
1693  */
1694 void
setregs(struct lwp * l,struct exec_package * pack,vaddr_t stack)1695 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
1696 {
1697           struct trapframe * const tf = l->l_md.md_utf;
1698           struct proc * const p = l->l_proc;
1699 
1700           KASSERTMSG((stack & STACK_ALIGNBYTES) == 0, "stack=%"PRIxVADDR, stack);
1701 
1702           memset(tf, 0, sizeof(*tf));
1703           tf->tf_regs[_R_SP] = (intptr_t)stack & ~STACK_ALIGNBYTES;
1704           tf->tf_regs[_R_PC] = (intptr_t)pack->ep_entry & ~3;
1705           tf->tf_regs[_R_T9] = (intptr_t)pack->ep_entry & ~3; /* abicall requirement */
1706           tf->tf_regs[_R_SR] = PSL_USERSET;
1707 #if !defined(__mips_o32)
1708           /*
1709            * allow 64bit ops in userland for non-O32 ABIs
1710            */
1711           if (p->p_md.md_abi == _MIPS_BSD_API_N32
1712               && (CPUISMIPS64 || CPUISMIPS64R2)) {
1713                     tf->tf_regs[_R_SR] |= MIPS_SR_PX;
1714           } else if (p->p_md.md_abi != _MIPS_BSD_API_O32) {
1715                     tf->tf_regs[_R_SR] |= MIPS_SR_UX;
1716           }
1717           if (_MIPS_SIM_NEWABI_P(p->p_md.md_abi))
1718                     tf->tf_regs[_R_SR] |= MIPS3_SR_FR;
1719 #endif
1720 #ifdef _LP64
1721           /*
1722            * If we are using a 32-bit ABI on a 64-bit kernel, mark the process
1723            * that way.  If we aren't, clear it.
1724            */
1725           if (p->p_md.md_abi == _MIPS_BSD_API_N32
1726               || p->p_md.md_abi == _MIPS_BSD_API_O32) {
1727                     p->p_flag |= PK_32;
1728           } else {
1729                     p->p_flag &= ~PK_32;
1730           }
1731 #endif
1732           /*
1733            * Set up arguments for _start():
1734            *        _start(stack, obj, cleanup, ps_strings);
1735            *
1736            * Notes:
1737            *        - obj and cleanup are the auxiliary and termination
1738            *          vectors.  They are fixed up by ld.elf_so.
1739            *        - ps_strings is a NetBSD extension.
1740            */
1741           tf->tf_regs[_R_A0] = (intptr_t)stack;
1742           tf->tf_regs[_R_A1] = 0;
1743           tf->tf_regs[_R_A2] = 0;
1744           tf->tf_regs[_R_A3] = p->p_psstrp;
1745 
1746           l->l_md.md_ss_addr = 0;
1747 }
1748 
1749 #ifdef __HAVE_BOOTINFO_H
1750 /*
1751  * Machine dependent system variables.
1752  */
1753 static int
sysctl_machdep_booted_kernel(SYSCTLFN_ARGS)1754 sysctl_machdep_booted_kernel(SYSCTLFN_ARGS)
1755 {
1756           struct btinfo_bootpath *bibp;
1757           struct sysctlnode node;
1758 
1759           bibp = lookup_bootinfo(BTINFO_BOOTPATH);
1760           if(!bibp)
1761                     return(ENOENT); /* ??? */
1762 
1763           node = *rnode;
1764           node.sysctl_data = bibp->bootpath;
1765           node.sysctl_size = sizeof(bibp->bootpath);
1766           return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1767 }
1768 #endif
1769 
1770 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
1771 {
1772 
1773           sysctl_createv(clog, 0, NULL, NULL,
1774                            CTLFLAG_PERMANENT,
1775                            CTLTYPE_NODE, "machdep", NULL,
1776                            NULL, 0, NULL, 0,
1777                            CTL_MACHDEP, CTL_EOL);
1778 
1779           sysctl_createv(clog, 0, NULL, NULL,
1780                            CTLFLAG_PERMANENT,
1781                            CTLTYPE_STRUCT, "console_device", NULL,
1782                            sysctl_consdev, 0, NULL, sizeof(dev_t),
1783                            CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
1784 #ifdef __HAVE_BOOTINFO_H
1785           sysctl_createv(clog, 0, NULL, NULL,
1786                            CTLFLAG_PERMANENT,
1787                            CTLTYPE_STRING, "booted_kernel", NULL,
1788                            sysctl_machdep_booted_kernel, 0, NULL, 0,
1789                            CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL);
1790 #endif
1791           sysctl_createv(clog, 0, NULL, NULL,
1792                            CTLFLAG_PERMANENT,
1793                            CTLTYPE_STRING, "root_device", NULL,
1794                            sysctl_root_device, 0, NULL, 0,
1795                            CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL);
1796           sysctl_createv(clog, 0, NULL, NULL,
1797                            CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1798                            CTLTYPE_INT, "llsc", NULL,
1799                            NULL, MIPS_HAS_LLSC, NULL, 0,
1800                            CTL_MACHDEP, CPU_LLSC, CTL_EOL);
1801 #ifdef MIPS3_LOONGSON2
1802           sysctl_createv(clog, 0, NULL, NULL,
1803                            CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1804                            CTLTYPE_INT, "loongson-mmi", NULL,
1805                            NULL, MIPS_HAS_LMMI, NULL, 0,
1806                            CTL_MACHDEP, CPU_LMMI, CTL_EOL);
1807 #endif
1808           sysctl_createv(clog, 0, NULL, NULL,
1809                            CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1810                            CTLTYPE_INT, "fpu_present", NULL,
1811                            NULL,
1812 #ifdef NOFPU
1813                            0,
1814 #else
1815                            1,
1816 #endif
1817                            NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1818 }
1819 
1820 /*
1821  * These are imported from platform-specific code.
1822  * XXX Should be declared in a header file.
1823  */
1824 extern phys_ram_seg_t mem_clusters[];
1825 extern int mem_cluster_cnt;
1826 
1827 /*
1828  * These variables are needed by /sbin/savecore.
1829  */
1830 u_int32_t dumpmag = 0x8fca0101;         /* magic number */
1831 int       dumpsize = 0;                 /* pages */
1832 long      dumplo = 0;                   /* blocks */
1833 
1834 struct pcb dumppcb;
1835 
1836 /*
1837  * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
1838  */
1839 int
cpu_dumpsize(void)1840 cpu_dumpsize(void)
1841 {
1842           int size;
1843 
1844           size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) +
1845               ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t));
1846           if (roundup(size, dbtob(1)) != dbtob(1))
1847                     return (-1);
1848 
1849           return (1);
1850 }
1851 
1852 /*
1853  * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped.
1854  */
1855 u_long
cpu_dump_mempagecnt(void)1856 cpu_dump_mempagecnt(void)
1857 {
1858           u_long i, n;
1859 
1860           n = 0;
1861           for (i = 0; i < mem_cluster_cnt; i++)
1862                     n += atop(mem_clusters[i].size);
1863           return (n);
1864 }
1865 
1866 /*
1867  * cpu_dump: dump machine-dependent kernel core dump headers.
1868  */
1869 int
cpu_dump(void)1870 cpu_dump(void)
1871 {
1872           int (*dump)(dev_t, daddr_t, void *, size_t);
1873           char buf[dbtob(1)];
1874           kcore_seg_t *segp;
1875           cpu_kcore_hdr_t *cpuhdrp;
1876           phys_ram_seg_t *memsegp;
1877           const struct bdevsw *bdev;
1878           int i;
1879 
1880           bdev = bdevsw_lookup(dumpdev);
1881           if (bdev == NULL)
1882                     return (ENXIO);
1883 
1884           dump = bdev->d_dump;
1885 
1886           memset(buf, 0, sizeof buf);
1887           segp = (kcore_seg_t *)buf;
1888           cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))];
1889           memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) +
1890               ALIGN(sizeof(*cpuhdrp))];
1891 
1892           /*
1893            * Generate a segment header.
1894            */
1895           CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
1896           segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
1897 
1898           /*
1899            * Add the machine-dependent header info.
1900            */
1901           if (MIPS_HAS_R4K_MMU) {
1902                     cpuhdrp->archlevel = 3;
1903                     cpuhdrp->pg_shift  = MIPS3_PG_SHIFT;
1904                     cpuhdrp->pg_frame  = MIPS3_PG_FRAME;
1905                     cpuhdrp->pg_v      = MIPS3_PG_V;
1906           } else {
1907                     cpuhdrp->archlevel = 1;
1908                     cpuhdrp->pg_shift  = MIPS1_PG_SHIFT;
1909                     cpuhdrp->pg_frame  = MIPS1_PG_FRAME;
1910                     cpuhdrp->pg_v      = MIPS1_PG_V;
1911           }
1912           cpuhdrp->sysmappa   = MIPS_KSEG0_TO_PHYS(curcpu()->ci_pmap_kern_segtab);
1913           cpuhdrp->nmemsegs   = mem_cluster_cnt;
1914 
1915           /*
1916            * Fill in the memory segment descriptors.
1917            */
1918           for (i = 0; i < mem_cluster_cnt; i++) {
1919                     memsegp[i].start = mem_clusters[i].start;
1920                     memsegp[i].size = mem_clusters[i].size;
1921           }
1922 
1923           return (dump(dumpdev, dumplo, (void *)buf, dbtob(1)));
1924 }
1925 
1926 /*
1927  * This is called by main to set dumplo and dumpsize.
1928  * Dumps always skip the first CLBYTES of disk space
1929  * in case there might be a disk label stored there.
1930  * If there is extra space, put dump at the end to
1931  * reduce the chance that swapping trashes it.
1932  */
1933 void
cpu_dumpconf(void)1934 cpu_dumpconf(void)
1935 {
1936           int nblks, dumpblks;          /* size of dump area */
1937 
1938           if (dumpdev == NODEV)
1939                     goto bad;
1940           nblks = bdev_size(dumpdev);
1941           if (nblks <= ctod(1))
1942                     goto bad;
1943 
1944           dumpblks = cpu_dumpsize();
1945           if (dumpblks < 0)
1946                     goto bad;
1947           dumpblks += ctod(cpu_dump_mempagecnt());
1948 
1949           /* If dump won't fit (incl. room for possible label), punt. */
1950           if (dumpblks > (nblks - ctod(1)))
1951                     goto bad;
1952 
1953           /* Put dump at end of partition */
1954           dumplo = nblks - dumpblks;
1955 
1956           /* dumpsize is in page units, and doesn't include headers. */
1957           dumpsize = cpu_dump_mempagecnt();
1958           return;
1959 
1960  bad:
1961           dumpsize = 0;
1962 }
1963 
1964 /*
1965  * Dump the kernel's image to the swap partition.
1966  */
1967 #define   BYTES_PER_DUMP      PAGE_SIZE
1968 
1969 void
dumpsys(void)1970 dumpsys(void)
1971 {
1972           u_long totalbytesleft, bytes, i, n, memcl;
1973           u_long maddr;
1974           int psize;
1975           daddr_t blkno;
1976           const struct bdevsw *bdev;
1977           int (*dump)(dev_t, daddr_t, void *, size_t);
1978           int error;
1979 
1980           /* Save registers. */
1981           savectx(&dumppcb);
1982 
1983           if (dumpdev == NODEV)
1984                     return;
1985           bdev = bdevsw_lookup(dumpdev);
1986           if (bdev == NULL || bdev->d_psize == NULL)
1987                     return;
1988 
1989           /*
1990            * For dumps during autoconfiguration,
1991            * if dump device has already configured...
1992            */
1993           if (dumpsize == 0)
1994                     cpu_dumpconf();
1995           if (dumplo <= 0) {
1996                     printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
1997                         minor(dumpdev));
1998                     return;
1999           }
2000           printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
2001               minor(dumpdev), dumplo);
2002 
2003           psize = bdev_size(dumpdev);
2004           printf("dump ");
2005           if (psize == -1) {
2006                     printf("area unavailable\n");
2007                     return;
2008           }
2009 
2010           /* XXX should purge all outstanding keystrokes. */
2011 
2012           if ((error = cpu_dump()) != 0)
2013                     goto err;
2014 
2015           totalbytesleft = ptoa(cpu_dump_mempagecnt());
2016           blkno = dumplo + cpu_dumpsize();
2017           dump = bdev->d_dump;
2018           error = 0;
2019 
2020           for (memcl = 0; memcl < mem_cluster_cnt; memcl++) {
2021                     maddr = mem_clusters[memcl].start;
2022                     bytes = mem_clusters[memcl].size;
2023 
2024                     for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
2025                               void *maddr_va;
2026 
2027                               /* Print out how many MBs we have left to go. */
2028                               if ((totalbytesleft % (1024*1024)) == 0)
2029                                         printf_nolog("%ld ",
2030                                             totalbytesleft / (1024 * 1024));
2031 
2032                               /* Limit size for next transfer. */
2033                               n = bytes - i;
2034                               if (n > BYTES_PER_DUMP)
2035                                         n = BYTES_PER_DUMP;
2036 
2037 #ifdef _LP64
2038                               maddr_va = (void *)MIPS_PHYS_TO_XKPHYS_CACHED(maddr);
2039 #else
2040                               maddr_va = (void *)MIPS_PHYS_TO_KSEG0(maddr);
2041 #endif
2042                               error = (*dump)(dumpdev, blkno, maddr_va, n);
2043                               if (error)
2044                                         goto err;
2045                               maddr += n;
2046                               blkno += btodb(n);            /* XXX? */
2047 
2048                               /* XXX should look for keystrokes, to cancel. */
2049                     }
2050           }
2051 
2052  err:
2053           switch (error) {
2054 
2055           case ENXIO:
2056                     printf("device bad\n");
2057                     break;
2058 
2059           case EFAULT:
2060                     printf("device not ready\n");
2061                     break;
2062 
2063           case EINVAL:
2064                     printf("area improper\n");
2065                     break;
2066 
2067           case EIO:
2068                     printf("i/o error\n");
2069                     break;
2070 
2071           case EINTR:
2072                     printf("aborted from console\n");
2073                     break;
2074 
2075           case 0:
2076                     printf("succeeded\n");
2077                     break;
2078 
2079           default:
2080                     printf("error %d\n", error);
2081                     break;
2082           }
2083           printf("\n\n");
2084           delay(5000000);               /* 5 seconds */
2085 }
2086 
2087 void
mips_init_msgbuf(void)2088 mips_init_msgbuf(void)
2089 {
2090           vsize_t sz = (vsize_t)round_page(MSGBUFSIZE);
2091           vsize_t reqsz = sz;
2092           uvm_physseg_t bank = uvm_physseg_get_last();
2093 #ifndef _LP64
2094           /*
2095            * First the physical segment that can be mapped to KSEG0
2096            */
2097           for (; uvm_physseg_valid_p(bank); bank = uvm_physseg_get_prev(bank)) {
2098                     if (uvm_physseg_get_avail_start(bank) + atop(sz) <= atop(MIPS_PHYS_MASK))
2099                               break;
2100           }
2101 #endif
2102 
2103           paddr_t start = uvm_physseg_get_start(bank);
2104           paddr_t end = uvm_physseg_get_end(bank);
2105 
2106           /* shrink so that it'll fit in the last segment */
2107           if ((end - start) < atop(sz))
2108                     sz = ptoa(end - start);
2109 
2110           end -= atop(sz);
2111           uvm_physseg_unplug(end, atop(sz));
2112 
2113 #ifdef _LP64
2114           msgbufaddr = (void *) MIPS_PHYS_TO_XKPHYS_CACHED(ptoa(end));
2115 #else
2116           msgbufaddr = (void *) MIPS_PHYS_TO_KSEG0(ptoa(end));
2117 #endif
2118           initmsgbuf(msgbufaddr, sz);
2119 
2120           /* warn if the message buffer had to be shrunk */
2121           if (sz != reqsz)
2122                     printf("WARNING: %"PRIdVSIZE" bytes not available for msgbuf "
2123                         "in last cluster (%"PRIdVSIZE" used)\n", reqsz, sz);
2124 }
2125 
2126 void
mips_init_lwp0_uarea(void)2127 mips_init_lwp0_uarea(void)
2128 {
2129           struct lwp * const l = &lwp0;
2130           vaddr_t v;
2131 
2132           if (l->l_addr == NULL) {
2133                     v = uvm_pageboot_alloc(USPACE);
2134                     uvm_lwp_setuarea(&lwp0, v);
2135           } else {
2136                     v = (vaddr_t)l->l_addr;
2137           }
2138 
2139           l->l_md.md_utf = (struct trapframe *)(v + USPACE) - 1;
2140           struct pcb * const pcb = lwp_getpcb(l);
2141           /*
2142            * Now zero out the only two areas of the uarea that we care about.
2143            */
2144           memset(l->l_md.md_utf, 0, sizeof(*l->l_md.md_utf));
2145           memset(pcb, 0, sizeof(*pcb));
2146 
2147           pcb->pcb_context.val[_L_SR] = MIPS_SR_INT_IE
2148               | (ipl_sr_map.sr_bits[IPL_SCHED] ^ MIPS_INT_MASK);
2149 #ifdef __mips_n32
2150           pcb->pcb_context.val[_L_SR] |= MIPS_SR_KX;
2151           l->l_md.md_utf->tf_regs[_R_SR] = MIPS_SR_KX;
2152 #endif
2153 #ifdef _LP64
2154           pcb->pcb_context.val[_L_SR] |= MIPS_SR_KX | MIPS_SR_UX;
2155           l->l_md.md_utf->tf_regs[_R_SR] = MIPS_SR_KX | MIPS_SR_UX;
2156 #endif
2157 }
2158 
2159 int mips_poolpage_vmfreelist = VM_FREELIST_DEFAULT;
2160 
2161 #define   HALFGIG             ((paddr_t)512 * 1024 * 1024)
2162 #define   FOURGIG             ((paddr_t)4 * 1024 * 1024 * 1024)
2163 
2164 void
mips_page_physload(vaddr_t vkernstart,vaddr_t vkernend,const phys_ram_seg_t * segs,size_t nseg,const struct mips_vmfreelist * flp,size_t nfl)2165 mips_page_physload(vaddr_t vkernstart, vaddr_t vkernend,
2166           const phys_ram_seg_t *segs, size_t nseg,
2167           const struct mips_vmfreelist *flp, size_t nfl)
2168 {
2169           const paddr_t kernstart = MIPS_KSEG0_TO_PHYS(trunc_page(vkernstart));
2170           const paddr_t kernend = MIPS_KSEG0_TO_PHYS(round_page(vkernend));
2171 #if defined(VM_FREELIST_FIRST4G) || defined(VM_FREELIST_FIRST512M)
2172 #ifdef VM_FREELIST_FIRST512M
2173           bool need512m = false;
2174 #endif
2175 #ifdef VM_FREELIST_FIRST4G
2176           bool need4g = false;
2177 #endif
2178 
2179           /*
2180            * Do a first pass and see what ranges memory we have to deal with.
2181            */
2182           for (size_t i = 0; i < nseg; i++) {
2183 #ifdef VM_FREELIST_FIRST4G
2184                     if (round_page(segs[i].start + segs[i].size) > FOURGIG) {
2185                               need4g = true;
2186                     }
2187 #endif
2188 #ifdef VM_FREELIST_FIRST512M
2189                     if (round_page(segs[i].start + segs[i].size) > HALFGIG) {
2190                               need512m = true;
2191 #if !defined(_LP64)
2192                               mips_poolpage_vmfreelist = VM_FREELIST_FIRST512M;
2193 #endif
2194                     }
2195 #endif
2196           }
2197 #endif /* VM_FREELIST_FIRST512M || VM_FREELIST_FIRST4G */
2198 
2199           for (; nseg-- > 0; segs++) {
2200                     /*
2201                      * Make sure everything is in page units.
2202                      */
2203                     paddr_t segstart = round_page(segs->start);
2204                     const paddr_t segfinish = trunc_page(segs->start + segs->size);
2205 
2206                     if (segstart >= segfinish) {
2207                               /*
2208                                * This is purely cosmetic, to avoid output like
2209                                *    phys segment: 0xffffffffffffe000 @ 0xffb6000
2210                                * when a segment starts and finishes in the same page.
2211                                */
2212                               printf("phys segment: %#"PRIxPADDR" @ %#"PRIxPADDR
2213                                   " (short)\n", (paddr_t)segs->size, segstart);
2214                               continue;
2215                     }
2216 
2217                     printf("phys segment: %#"PRIxPADDR" @ %#"PRIxPADDR"\n",
2218                         segfinish - segstart, segstart);
2219 
2220                     /*
2221                      * Page 0 is reserved for exception vectors.
2222                      */
2223                     if (segstart == 0) {
2224                               segstart = PAGE_SIZE;
2225                     }
2226                     while (segstart < segfinish) {
2227                               int freelist = -1;  /* unknown freelist */
2228                               paddr_t segend = segfinish;
2229                               for (size_t i = 0; i < nfl; i++) {
2230                                         /*
2231                                          * If this segment doesn't overlap the freelist
2232                                          * at all, skip it.
2233                                          */
2234                                         if (segstart >= flp[i].fl_end
2235                                             || segend <= flp[i].fl_start)
2236                                                   continue;
2237                                         /*
2238                                          * If the start of this segment starts before
2239                                          * the start of the freelist, then limit the
2240                                          * segment to loaded to the part that doesn't
2241                                          * match this freelist and fall back to normal
2242                                          * freelist matching.
2243                                          */
2244                                         if (segstart < flp[i].fl_start) {
2245                                                   segstart = flp[i].fl_start;
2246                                                   break;
2247                                         }
2248 
2249                                         /*
2250                                          * We've matched this freelist so remember it.
2251                                          */
2252                                         freelist = flp->fl_freelist;
2253 
2254                                         /*
2255                                          * If this segment extends past the end of this
2256                                          * freelist, bound to segment to the freelist.
2257                                          */
2258                                         if (segend > flp[i].fl_end)
2259                                                   segend = flp[i].fl_end;
2260                                         break;
2261                               }
2262                               /*
2263                                * If we didn't match one of the port dependent
2264                                * freelists, let's try the common ones.
2265                                */
2266                               if (freelist == -1) {
2267 #ifdef VM_FREELIST_FIRST512M
2268                                         if (need512m && segstart < HALFGIG) {
2269                                                   freelist = VM_FREELIST_FIRST512M;
2270                                                   if (segend > HALFGIG)
2271                                                             segend = HALFGIG;
2272                                         } else
2273 #endif
2274 #ifdef VM_FREELIST_FIRST4G
2275                                         if (need4g && segstart < FOURGIG) {
2276                                                   freelist = VM_FREELIST_FIRST4G;
2277                                                   if (segend > FOURGIG)
2278                                                             segend = FOURGIG;
2279                                         } else
2280 #endif
2281                                                   freelist = VM_FREELIST_DEFAULT;
2282                               }
2283 
2284                               /*
2285                                * Make sure the memory we provide to uvm doesn't
2286                                * include the kernel.
2287                                */
2288                               if (segstart < kernend && segend > kernstart) {
2289                                         if (segstart < kernstart) {
2290                                                   /*
2291                                                    * Only add the memory before the
2292                                                    * kernel.
2293                                                    */
2294                                                   segend = kernstart;
2295                                         } else if (segend > kernend) {
2296                                                   /*
2297                                                    * Only add the memory after the
2298                                                    * kernel.
2299                                                    */
2300                                                   segstart = kernend;
2301                                         } else {
2302                                                   /*
2303                                                    * Just skip the segment entirely since
2304                                                    * it's completely inside the kernel.
2305                                                    */
2306                                                   printf("skipping %#"PRIxPADDR" @ %#"PRIxPADDR" (kernel)\n",
2307                                                       segend - segstart, segstart);
2308                                                   break;
2309                                         }
2310                               }
2311 
2312                               /*
2313                                * Now we give this segment to uvm.
2314                                */
2315                               printf("adding %#"PRIxPADDR" @ %#"PRIxPADDR" to freelist %d\n",
2316                                   segend - segstart, segstart, freelist);
2317                               paddr_t first = atop(segstart);
2318                               paddr_t last = atop(segend);
2319                               uvm_page_physload(first, last, first, last, freelist);
2320 
2321                               /*
2322                                * Start where we finished.
2323                                */
2324                               segstart = segend;
2325                     }
2326           }
2327 }
2328 
2329 /*
2330  * Start a new LWP
2331  */
2332 void
startlwp(void * arg)2333 startlwp(void *arg)
2334 {
2335           ucontext_t * const uc = arg;
2336           lwp_t * const l = curlwp;
2337           int error __diagused;
2338 
2339           error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
2340           KASSERT(error == 0);
2341 
2342           kmem_free(uc, sizeof(ucontext_t));
2343           userret(l);
2344 }
2345 
2346 #ifdef COMPAT_NETBSD32
2347 /*
2348  * Start a new LWP
2349  */
2350 void
startlwp32(void * arg)2351 startlwp32(void *arg)
2352 {
2353           ucontext32_t * const uc = arg;
2354           lwp_t * const l = curlwp;
2355           int error __diagused;
2356 
2357           error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags);
2358           KASSERT(error == 0);
2359 
2360           /* Note: we are freeing ucontext_t, not ucontext32_t. */
2361           kmem_free(uc, sizeof(ucontext_t));
2362           userret(l);
2363 }
2364 #endif /* COMPAT_NETBSD32 */
2365 
2366 #ifdef PARANOIA
2367 void
std_splsw_test(void)2368 std_splsw_test(void)
2369 {
2370           struct cpu_info * const ci = curcpu();
2371           const uint32_t * const sr_map = ipl_sr_map.sr_bits;
2372           uint32_t status = mips_cp0_status_read();
2373           uint32_t sr_bits;
2374           int s;
2375 
2376           KASSERT((status & MIPS_SR_INT_IE) == 0);
2377 
2378           sr_bits = sr_map[IPL_NONE];
2379 
2380           splx(IPL_NONE);
2381           status = mips_cp0_status_read() & MIPS_INT_MASK;
2382           KASSERT(status == MIPS_INT_MASK);
2383           KASSERT(ci->ci_cpl == IPL_NONE);
2384 
2385           s = splsoftclock();
2386           status = mips_cp0_status_read() & MIPS_INT_MASK;
2387           KASSERT((status ^ sr_map[IPL_SOFTCLOCK]) == MIPS_INT_MASK);
2388           KASSERT(ci->ci_cpl == IPL_SOFTCLOCK);
2389           KASSERT(s == IPL_NONE);
2390 
2391           s = splsoftbio();
2392           status = mips_cp0_status_read() & MIPS_INT_MASK;
2393           KASSERT((status ^ sr_map[IPL_SOFTBIO]) == MIPS_INT_MASK);
2394           KASSERT(ci->ci_cpl == IPL_SOFTBIO);
2395           KASSERT(s == IPL_SOFTCLOCK);
2396 
2397           s = splsoftnet();
2398           status = mips_cp0_status_read() & MIPS_INT_MASK;
2399           KASSERT((status ^ sr_map[IPL_SOFTNET]) == MIPS_INT_MASK);
2400           KASSERT(ci->ci_cpl == IPL_SOFTNET);
2401           KASSERT(s == IPL_SOFTBIO);
2402 
2403           s = splsoftserial();
2404           status = mips_cp0_status_read() & MIPS_INT_MASK;
2405           KASSERT((status ^ sr_map[IPL_SOFTSERIAL]) == MIPS_INT_MASK);
2406           KASSERT(ci->ci_cpl == IPL_SOFTSERIAL);
2407           KASSERT(s == IPL_SOFTNET);
2408 
2409           s = splvm();
2410           status = mips_cp0_status_read() & MIPS_INT_MASK;
2411           KASSERT((status ^ sr_map[IPL_VM]) == MIPS_INT_MASK);
2412           KASSERT(ci->ci_cpl == IPL_VM);
2413           KASSERT(s == IPL_SOFTSERIAL);
2414 
2415           s = splsched();
2416           status = mips_cp0_status_read() & MIPS_INT_MASK;
2417           KASSERT((status ^ sr_map[IPL_SCHED]) == MIPS_INT_MASK);
2418           KASSERT(ci->ci_cpl == IPL_SCHED);
2419           KASSERT(s == IPL_VM);
2420 
2421           s = splhigh();
2422           status = mips_cp0_status_read() & MIPS_INT_MASK;
2423           KASSERT((status ^ sr_map[IPL_HIGH]) == MIPS_INT_MASK);
2424           KASSERT(ci->ci_cpl == IPL_HIGH);
2425           KASSERT(s == IPL_SCHED);
2426 
2427           splx(IPL_NONE);
2428           status = mips_cp0_status_read() & MIPS_INT_MASK;
2429           KASSERT(status == MIPS_INT_MASK);
2430           KASSERT(ci->ci_cpl == IPL_NONE);
2431 
2432           for (int r = IPL_SOFTCLOCK; r <= IPL_HIGH; r++) {
2433                     /*
2434                      * As IPL increases, more intrs may be masked but no intrs
2435                      * may become unmasked.
2436                      */
2437                     KASSERT((sr_map[r] & sr_bits) == sr_bits);
2438                     sr_bits |= sr_map[r];
2439                     s = splraise(r);
2440                     KASSERT(s == IPL_NONE);
2441 
2442                     for (int t = r; t <= IPL_HIGH; t++) {
2443                               int o = splraise(t);
2444                               status = mips_cp0_status_read() & MIPS_INT_MASK;
2445                               KASSERT((status ^ sr_map[t]) == MIPS_INT_MASK);
2446                               KASSERT(ci->ci_cpl == t);
2447                               KASSERT(o == r);
2448 
2449                               splx(o);
2450                               status = mips_cp0_status_read() & MIPS_INT_MASK;
2451                               KASSERT((status ^ sr_map[r]) == MIPS_INT_MASK);
2452                               KASSERT(ci->ci_cpl == r);
2453                     }
2454 
2455                     splx(s);
2456                     status = mips_cp0_status_read() & MIPS_INT_MASK;
2457                     KASSERT((status ^ sr_map[s]) == MIPS_INT_MASK);
2458                     KASSERT(ci->ci_cpl == s);
2459           }
2460 
2461           status = mips_cp0_status_read() & MIPS_INT_MASK;
2462           KASSERT(status == MIPS_INT_MASK);
2463           KASSERT(ci->ci_cpl == IPL_NONE);
2464 }
2465 
2466 #endif /* PARANOIA */
2467 
2468 #ifdef MODULAR
2469 /*
2470  * Push any modules loaded by the boot loader.
2471  */
2472 void
module_init_md(void)2473 module_init_md(void)
2474 {
2475 
2476           /* XXX Do something board/machine specific here one day... */
2477 }
2478 #endif /* MODULAR */
2479 
2480 bool
mm_md_direct_mapped_phys(paddr_t pa,vaddr_t * vap)2481 mm_md_direct_mapped_phys(paddr_t pa, vaddr_t *vap)
2482 {
2483 #ifdef _LP64
2484           if (MIPS_XKSEG_P(pa)) {
2485                     *vap = MIPS_PHYS_TO_XKPHYS_CACHED(pa);
2486                     return true;
2487           }
2488 #endif
2489           if (MIPS_KSEG0_P(pa)) {
2490                     *vap = MIPS_PHYS_TO_KSEG0(pa);
2491                     return true;
2492           }
2493           return false;
2494 }
2495 
2496 bool
mm_md_page_color(paddr_t pa,int * colorp)2497 mm_md_page_color(paddr_t pa, int *colorp)
2498 {
2499           if (MIPS_CACHE_VIRTUAL_ALIAS) {
2500                     struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
2501                     KASSERT(pg != NULL);
2502                     struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
2503                     *colorp = atop(mdpg->mdpg_first.pv_va);
2504                     return !mips_cache_badalias(pa, mdpg->mdpg_first.pv_va);
2505           }
2506           *colorp = 0;
2507           return true;
2508 }
2509 
2510 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)2511 mm_md_physacc(paddr_t pa, vm_prot_t prot)
2512 {
2513 
2514           return (pa < ctob(physmem)) ? 0 : EFAULT;
2515 }
2516 
2517 int
mm_md_kernacc(void * ptr,vm_prot_t prot,bool * handled)2518 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
2519 {
2520           const vaddr_t v = (vaddr_t)ptr;
2521 
2522 #ifdef _LP64
2523           extern char end[];
2524 
2525           /* For any address < XKPHYS cached address 0, fault */
2526           if (v < MIPS_PHYS_TO_XKPHYS_CACHED(0)) {
2527                     return EFAULT;
2528           }
2529 
2530           /* If address < XKPHY(end of message buffer), good! */
2531           if (v < MIPS_PHYS_TO_XKPHYS_CACHED(pmap_limits.avail_end +
2532               mips_round_page(MSGBUFSIZE))) {
2533                     /* XXX holes in RAM (eg, EdgeRouter 4) */
2534                     *handled = true;
2535                     return 0;
2536           }
2537 
2538           /* If address in KSEG0 and is before end of kernel, good! */
2539           if (MIPS_KSEG0_P(v) && v < (vaddr_t)end) {
2540                     *handled = true;
2541                     return 0;
2542           }
2543 
2544           /* Otherwise, fall back to the uvm_kernacc() check. */
2545 #else
2546           if (v < MIPS_KSEG0_START) {
2547                     return EFAULT;
2548           }
2549           if (v < MIPS_PHYS_TO_KSEG0(pmap_limits.avail_end +
2550               mips_round_page(MSGBUFSIZE))) {
2551                     *handled = true;
2552                     return 0;
2553           }
2554           if (v < MIPS_KSEG2_START) {
2555                     return EFAULT;
2556           }
2557 #endif
2558           *handled = false;
2559           return 0;
2560 }
2561 
2562 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
2563 static void
mips_watchpoint_init(void)2564 mips_watchpoint_init(void)
2565 {
2566           /*
2567            * determine number of CPU watchpoints
2568            */
2569           curcpu()->ci_cpuwatch_count = cpuwatch_discover();
2570 }
2571 #endif
2572 
2573 
2574 /*
2575  * Process the tail end of a posix_spawn() for the child.
2576  */
2577 void
cpu_spawn_return(struct lwp * l)2578 cpu_spawn_return(struct lwp *l)
2579 {
2580           userret(l);
2581 }
2582