Thu May 27 15:00:02 2021 UTC ()
Rename the unhelpfully named mips_emul_lwc0() and mips_emul_swc0() to
mips_emul_ll() and mips_emul_sc(); make these static to mips_emul.c.


(simonb)
diff -r1.118 -r1.119 src/sys/arch/mips/include/locore.h
diff -r1.28 -r1.29 src/sys/arch/mips/mips/mips_emul.c

cvs diff -r1.118 -r1.119 src/sys/arch/mips/include/locore.h (switch to unified diff)

--- src/sys/arch/mips/include/locore.h 2021/05/12 03:53:37 1.118
+++ src/sys/arch/mips/include/locore.h 2021/05/27 15:00:02 1.119
@@ -1,923 +1,921 @@ @@ -1,923 +1,921 @@
1/* $NetBSD: locore.h,v 1.118 2021/05/12 03:53:37 simonb Exp $ */ 1/* $NetBSD: locore.h,v 1.119 2021/05/27 15:00:02 simonb Exp $ */
2 2
3/* 3/*
4 * This file should not be included by MI code!!! 4 * This file should not be included by MI code!!!
5 */ 5 */
6 6
7/* 7/*
8 * Copyright 1996 The Board of Trustees of The Leland Stanford 8 * Copyright 1996 The Board of Trustees of The Leland Stanford
9 * Junior University. All Rights Reserved. 9 * Junior University. All Rights Reserved.
10 * 10 *
11 * Permission to use, copy, modify, and distribute this 11 * Permission to use, copy, modify, and distribute this
12 * software and its documentation for any purpose and without 12 * software and its documentation for any purpose and without
13 * fee is hereby granted, provided that the above copyright 13 * fee is hereby granted, provided that the above copyright
14 * notice appear in all copies. Stanford University 14 * notice appear in all copies. Stanford University
15 * makes no representations about the suitability of this 15 * makes no representations about the suitability of this
16 * software for any purpose. It is provided "as is" without 16 * software for any purpose. It is provided "as is" without
17 * express or implied warranty. 17 * express or implied warranty.
18 */ 18 */
19 19
20/* 20/*
21 * Jump table for MIPS CPU locore functions that are implemented 21 * Jump table for MIPS CPU locore functions that are implemented
22 * differently on different generations, or instruction-level 22 * differently on different generations, or instruction-level
23 * architecture (ISA) level, the Mips family. 23 * architecture (ISA) level, the Mips family.
24 * 24 *
25 * We currently provide support for MIPS I and MIPS III. 25 * We currently provide support for MIPS I and MIPS III.
26 */ 26 */
27 27
28#ifndef _MIPS_LOCORE_H 28#ifndef _MIPS_LOCORE_H
29#define _MIPS_LOCORE_H 29#define _MIPS_LOCORE_H
30 30
31#if !defined(_MODULE) && defined(_KERNEL_OPT) 31#if !defined(_MODULE) && defined(_KERNEL_OPT)
32#include "opt_cputype.h" 32#include "opt_cputype.h"
33#endif 33#endif
34 34
35#ifndef __ASSEMBLER__ 35#ifndef __ASSEMBLER__
36 36
37#include <sys/cpu.h> 37#include <sys/cpu.h>
38 38
39#include <mips/mutex.h> 39#include <mips/mutex.h>
40#include <mips/cpuregs.h> 40#include <mips/cpuregs.h>
41#include <mips/reg.h> 41#include <mips/reg.h>
42 42
43#ifndef __BSD_PTENTRY_T__ 43#ifndef __BSD_PTENTRY_T__
44#define __BSD_PTENTRY_T__ 44#define __BSD_PTENTRY_T__
45typedef uint32_t pt_entry_t; 45typedef uint32_t pt_entry_t;
46#define PRIxPTE PRIx32 46#define PRIxPTE PRIx32
47#endif 47#endif
48 48
49#include <uvm/pmap/tlb.h> 49#include <uvm/pmap/tlb.h>
50#endif /* !__ASSEMBLER__ */ 50#endif /* !__ASSEMBLER__ */
51 51
52#ifdef _KERNEL 52#ifdef _KERNEL
53 53
54#if defined(_MODULE) || defined(_STANDALONE) 54#if defined(_MODULE) || defined(_STANDALONE)
55/* Assume all CPU architectures are valid for modules and standlone progs */ 55/* Assume all CPU architectures are valid for modules and standlone progs */
56#if !defined(__mips_n32) && !defined(__mips_n64) 56#if !defined(__mips_n32) && !defined(__mips_n64)
57#define MIPS1 1 57#define MIPS1 1
58#endif 58#endif
59#define MIPS3 1 59#define MIPS3 1
60#define MIPS4 1 60#define MIPS4 1
61#if !defined(__mips_n32) && !defined(__mips_n64) 61#if !defined(__mips_n32) && !defined(__mips_n64)
62#define MIPS32 1 62#define MIPS32 1
63#define MIPS32R2 1 63#define MIPS32R2 1
64#endif 64#endif
65#define MIPS64 1 65#define MIPS64 1
66#define MIPS64R2 1 66#define MIPS64R2 1
67#endif /* _MODULE || _STANDALONE */ 67#endif /* _MODULE || _STANDALONE */
68 68
69#if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) == 0 69#if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) == 0
70#error at least one of MIPS1, MIPS3, MIPS4, MIPS32, MIPS32R2, MIPS64, or MIPS64R2 must be specified 70#error at least one of MIPS1, MIPS3, MIPS4, MIPS32, MIPS32R2, MIPS64, or MIPS64R2 must be specified
71#endif 71#endif
72 72
73/* Shortcut for MIPS3 or above defined */ 73/* Shortcut for MIPS3 or above defined */
74#if defined(MIPS3) || defined(MIPS4) \ 74#if defined(MIPS3) || defined(MIPS4) \
75 || defined(MIPS32) || defined(MIPS32R2) \ 75 || defined(MIPS32) || defined(MIPS32R2) \
76 || defined(MIPS64) || defined(MIPS64R2) 76 || defined(MIPS64) || defined(MIPS64R2)
77 77
78#define MIPS3_PLUS 1 78#define MIPS3_PLUS 1
79#if !defined(MIPS32) && !defined(MIPS32R2) 79#if !defined(MIPS32) && !defined(MIPS32R2)
80#define MIPS3_64BIT 1 80#define MIPS3_64BIT 1
81#endif 81#endif
82#if !defined(MIPS3) && !defined(MIPS4) 82#if !defined(MIPS3) && !defined(MIPS4)
83#define MIPSNN 1 83#define MIPSNN 1
84#endif 84#endif
85#if defined(MIPS32R2) || defined(MIPS64R2) 85#if defined(MIPS32R2) || defined(MIPS64R2)
86#define MIPSNNR2 1 86#define MIPSNNR2 1
87#endif 87#endif
88#else 88#else
89#undef MIPS3_PLUS 89#undef MIPS3_PLUS
90#endif 90#endif
91 91
92#if defined(MIPS1) && (ENABLE_MIPS_8KB_PAGE + ENABLE_MIPS_16KB_PAGE) > 0 92#if defined(MIPS1) && (ENABLE_MIPS_8KB_PAGE + ENABLE_MIPS_16KB_PAGE) > 0
93#error MIPS1 only supports a 4kB page size. 93#error MIPS1 only supports a 4kB page size.
94#endif 94#endif
95 95
96/* XXX some .S files look for MIPS3_PLUS */ 96/* XXX some .S files look for MIPS3_PLUS */
97#ifndef __ASSEMBLER__ 97#ifndef __ASSEMBLER__
98#ifdef _KERNEL 98#ifdef _KERNEL
99 99
100/* XXX simonb 100/* XXX simonb
101 * Should the following be in a cpu_info type structure? 101 * Should the following be in a cpu_info type structure?
102 * And how many of these are per-cpu vs. per-system? (Ie, 102 * And how many of these are per-cpu vs. per-system? (Ie,
103 * we can assume that all cpus have the same mmu-type, but 103 * we can assume that all cpus have the same mmu-type, but
104 * maybe not that all cpus run at the same clock speed. 104 * maybe not that all cpus run at the same clock speed.
105 * Some SGI's apparently support R12k and R14k in the same 105 * Some SGI's apparently support R12k and R14k in the same
106 * box.) 106 * box.)
107 */ 107 */
108struct mips_options { 108struct mips_options {
109 const struct pridtab *mips_cpu; 109 const struct pridtab *mips_cpu;
110 110
111 u_int mips_cpu_arch; 111 u_int mips_cpu_arch;
112 u_int mips_cpu_mhz; /* CPU speed in MHz, estimated by mc_cpuspeed(). */ 112 u_int mips_cpu_mhz; /* CPU speed in MHz, estimated by mc_cpuspeed(). */
113 u_int mips_cpu_flags; 113 u_int mips_cpu_flags;
114 u_int mips_num_tlb_entries; 114 u_int mips_num_tlb_entries;
115 mips_prid_t mips_cpu_id; 115 mips_prid_t mips_cpu_id;
116 mips_prid_t mips_fpu_id; 116 mips_prid_t mips_fpu_id;
117 bool mips_has_r4k_mmu; 117 bool mips_has_r4k_mmu;
118 bool mips_has_llsc; 118 bool mips_has_llsc;
119 u_int mips3_pg_shift; 119 u_int mips3_pg_shift;
120 u_int mips3_pg_cached; 120 u_int mips3_pg_cached;
121 u_int mips3_cca_devmem; 121 u_int mips3_cca_devmem;
122#ifdef MIPS3_PLUS 122#ifdef MIPS3_PLUS
123#ifndef __mips_o32 123#ifndef __mips_o32
124 uint64_t mips3_xkphys_cached; 124 uint64_t mips3_xkphys_cached;
125#endif 125#endif
126 uint64_t mips3_tlb_vpn_mask; 126 uint64_t mips3_tlb_vpn_mask;
127 uint64_t mips3_tlb_pfn_mask; 127 uint64_t mips3_tlb_pfn_mask;
128 uint32_t mips3_tlb_pg_mask; 128 uint32_t mips3_tlb_pg_mask;
129#endif 129#endif
130}; 130};
131 131
132#endif /* !__ASSEMBLER__ */ 132#endif /* !__ASSEMBLER__ */
133 133
134/* 134/*
135 * Macros to find the CPU architecture we're on at run-time, 135 * Macros to find the CPU architecture we're on at run-time,
136 * or if possible, at compile-time. 136 * or if possible, at compile-time.
137 */ 137 */
138 138
139#define CPU_ARCH_MIPSx 0 /* XXX unknown */ 139#define CPU_ARCH_MIPSx 0 /* XXX unknown */
140#define CPU_ARCH_MIPS1 (1 << 0) 140#define CPU_ARCH_MIPS1 (1 << 0)
141#define CPU_ARCH_MIPS2 (1 << 1) 141#define CPU_ARCH_MIPS2 (1 << 1)
142#define CPU_ARCH_MIPS3 (1 << 2) 142#define CPU_ARCH_MIPS3 (1 << 2)
143#define CPU_ARCH_MIPS4 (1 << 3) 143#define CPU_ARCH_MIPS4 (1 << 3)
144#define CPU_ARCH_MIPS5 (1 << 4) 144#define CPU_ARCH_MIPS5 (1 << 4)
145#define CPU_ARCH_MIPS32 (1 << 5) 145#define CPU_ARCH_MIPS32 (1 << 5)
146#define CPU_ARCH_MIPS64 (1 << 6) 146#define CPU_ARCH_MIPS64 (1 << 6)
147#define CPU_ARCH_MIPS32R2 (1 << 7) 147#define CPU_ARCH_MIPS32R2 (1 << 7)
148#define CPU_ARCH_MIPS64R2 (1 << 8) 148#define CPU_ARCH_MIPS64R2 (1 << 8)
149 149
150#define CPU_MIPS_R4K_MMU 0x00001 150#define CPU_MIPS_R4K_MMU 0x00001
151#define CPU_MIPS_NO_LLSC 0x00002 151#define CPU_MIPS_NO_LLSC 0x00002
152#define CPU_MIPS_CAUSE_IV 0x00004 152#define CPU_MIPS_CAUSE_IV 0x00004
153#define CPU_MIPS_HAVE_SPECIAL_CCA 0x00008 /* Defaults to '3' if not set. */ 153#define CPU_MIPS_HAVE_SPECIAL_CCA 0x00008 /* Defaults to '3' if not set. */
154#define CPU_MIPS_CACHED_CCA_MASK 0x00070 154#define CPU_MIPS_CACHED_CCA_MASK 0x00070
155#define CPU_MIPS_CACHED_CCA_SHIFT 4 155#define CPU_MIPS_CACHED_CCA_SHIFT 4
156#define CPU_MIPS_DOUBLE_COUNT 0x00080 /* 1 cp0 count == 2 clock cycles */ 156#define CPU_MIPS_DOUBLE_COUNT 0x00080 /* 1 cp0 count == 2 clock cycles */
157#define CPU_MIPS_USE_WAIT 0x00100 /* Use "wait"-based cpu_idle() */ 157#define CPU_MIPS_USE_WAIT 0x00100 /* Use "wait"-based cpu_idle() */
158#define CPU_MIPS_NO_WAIT 0x00200 /* Inverse of previous, for mips32/64 */ 158#define CPU_MIPS_NO_WAIT 0x00200 /* Inverse of previous, for mips32/64 */
159#define CPU_MIPS_D_CACHE_COHERENT 0x00400 /* D-cache is fully coherent */ 159#define CPU_MIPS_D_CACHE_COHERENT 0x00400 /* D-cache is fully coherent */
160#define CPU_MIPS_I_D_CACHE_COHERENT 0x00800 /* I-cache funcs don't need to flush the D-cache */ 160#define CPU_MIPS_I_D_CACHE_COHERENT 0x00800 /* I-cache funcs don't need to flush the D-cache */
161#define CPU_MIPS_NO_LLADDR 0x01000 161#define CPU_MIPS_NO_LLADDR 0x01000
162#define CPU_MIPS_HAVE_MxCR 0x02000 /* have mfcr, mtcr insns */ 162#define CPU_MIPS_HAVE_MxCR 0x02000 /* have mfcr, mtcr insns */
163#define CPU_MIPS_LOONGSON2 0x04000 163#define CPU_MIPS_LOONGSON2 0x04000
164#define MIPS_NOT_SUPP 0x08000 164#define MIPS_NOT_SUPP 0x08000
165#define CPU_MIPS_HAVE_DSP 0x10000 165#define CPU_MIPS_HAVE_DSP 0x10000
166#define CPU_MIPS_HAVE_USERLOCAL 0x20000 166#define CPU_MIPS_HAVE_USERLOCAL 0x20000
167 167
168#endif /* !_LOCORE */ 168#endif /* !_LOCORE */
169 169
170#if ((MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) == 1) || defined(_LOCORE) 170#if ((MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) == 1) || defined(_LOCORE)
171 171
172#if defined(MIPS1) 172#if defined(MIPS1)
173 173
174# define CPUISMIPS3 0 174# define CPUISMIPS3 0
175# define CPUIS64BITS 0 175# define CPUIS64BITS 0
176# define CPUISMIPS32 0 176# define CPUISMIPS32 0
177# define CPUISMIPS32R2 0 177# define CPUISMIPS32R2 0
178# define CPUISMIPS64 0 178# define CPUISMIPS64 0
179# define CPUISMIPS64R2 0 179# define CPUISMIPS64R2 0
180# define CPUISMIPSNN 0 180# define CPUISMIPSNN 0
181# define CPUISMIPSNNR2 0 181# define CPUISMIPSNNR2 0
182# define MIPS_HAS_R4K_MMU 0 182# define MIPS_HAS_R4K_MMU 0
183# define MIPS_HAS_CLOCK 0 183# define MIPS_HAS_CLOCK 0
184# define MIPS_HAS_LLSC 0 184# define MIPS_HAS_LLSC 0
185# define MIPS_HAS_LLADDR 0 185# define MIPS_HAS_LLADDR 0
186# define MIPS_HAS_LMMI 0 186# define MIPS_HAS_LMMI 0
187# define MIPS_HAS_DSP 0 187# define MIPS_HAS_DSP 0
188# define MIPS_HAS_USERLOCAL 0 188# define MIPS_HAS_USERLOCAL 0
189 189
190#elif defined(MIPS3) || defined(MIPS4) 190#elif defined(MIPS3) || defined(MIPS4)
191 191
192# define CPUISMIPS3 1 192# define CPUISMIPS3 1
193# define CPUIS64BITS 1 193# define CPUIS64BITS 1
194# define CPUISMIPS32 0 194# define CPUISMIPS32 0
195# define CPUISMIPS32R2 0 195# define CPUISMIPS32R2 0
196# define CPUISMIPS64 0 196# define CPUISMIPS64 0
197# define CPUISMIPS64R2 0 197# define CPUISMIPS64R2 0
198# define CPUISMIPSNN 0 198# define CPUISMIPSNN 0
199# define CPUISMIPSNNR2 0 199# define CPUISMIPSNNR2 0
200# define MIPS_HAS_R4K_MMU 1 200# define MIPS_HAS_R4K_MMU 1
201# define MIPS_HAS_CLOCK 1 201# define MIPS_HAS_CLOCK 1
202# if defined(_LOCORE) 202# if defined(_LOCORE)
203# if !defined(MIPS3_4100) 203# if !defined(MIPS3_4100)
204# define MIPS_HAS_LLSC 1 204# define MIPS_HAS_LLSC 1
205# else 205# else
206# define MIPS_HAS_LLSC 0 206# define MIPS_HAS_LLSC 0
207# endif 207# endif
208# else /* _LOCORE */ 208# else /* _LOCORE */
209# define MIPS_HAS_LLSC (mips_options.mips_has_llsc) 209# define MIPS_HAS_LLSC (mips_options.mips_has_llsc)
210# endif /* _LOCORE */ 210# endif /* _LOCORE */
211# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 211# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
212# if defined(MIPS3_LOONGSON2) 212# if defined(MIPS3_LOONGSON2)
213# define MIPS_HAS_LMMI ((mips_options.mips_cpu_flags & CPU_MIPS_LOONGSON2) != 0) 213# define MIPS_HAS_LMMI ((mips_options.mips_cpu_flags & CPU_MIPS_LOONGSON2) != 0)
214# else 214# else
215# define MIPS_HAS_LMMI 0 215# define MIPS_HAS_LMMI 0
216# endif 216# endif
217# define MIPS_HAS_DSP 0 217# define MIPS_HAS_DSP 0
218# define MIPS_HAS_USERLOCAL 0 218# define MIPS_HAS_USERLOCAL 0
219 219
220#elif defined(MIPS32) 220#elif defined(MIPS32)
221 221
222# define CPUISMIPS3 1 222# define CPUISMIPS3 1
223# define CPUIS64BITS 0 223# define CPUIS64BITS 0
224# define CPUISMIPS32 1 224# define CPUISMIPS32 1
225# define CPUISMIPS32R2 0 225# define CPUISMIPS32R2 0
226# define CPUISMIPS64 0 226# define CPUISMIPS64 0
227# define CPUISMIPS64R2 0 227# define CPUISMIPS64R2 0
228# define CPUISMIPSNN 1 228# define CPUISMIPSNN 1
229# define CPUISMIPSNNR2 0 229# define CPUISMIPSNNR2 0
230# define MIPS_HAS_R4K_MMU 1 230# define MIPS_HAS_R4K_MMU 1
231# define MIPS_HAS_CLOCK 1 231# define MIPS_HAS_CLOCK 1
232# define MIPS_HAS_LLSC 1 232# define MIPS_HAS_LLSC 1
233# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 233# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
234# define MIPS_HAS_LMMI 0 234# define MIPS_HAS_LMMI 0
235# define MIPS_HAS_DSP 0 235# define MIPS_HAS_DSP 0
236# define MIPS_HAS_USERLOCAL 0 236# define MIPS_HAS_USERLOCAL 0
237 237
238#elif defined(MIPS32R2) 238#elif defined(MIPS32R2)
239 239
240# define CPUISMIPS3 1 240# define CPUISMIPS3 1
241# define CPUIS64BITS 0 241# define CPUIS64BITS 0
242# define CPUISMIPS32 0 242# define CPUISMIPS32 0
243# define CPUISMIPS32R2 1 243# define CPUISMIPS32R2 1
244# define CPUISMIPS64 0 244# define CPUISMIPS64 0
245# define CPUISMIPS64R2 0 245# define CPUISMIPS64R2 0
246# define CPUISMIPSNN 1 246# define CPUISMIPSNN 1
247# define CPUISMIPSNNR2 1 247# define CPUISMIPSNNR2 1
248# define MIPS_HAS_R4K_MMU 1 248# define MIPS_HAS_R4K_MMU 1
249# define MIPS_HAS_CLOCK 1 249# define MIPS_HAS_CLOCK 1
250# define MIPS_HAS_LLSC 1 250# define MIPS_HAS_LLSC 1
251# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 251# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
252# define MIPS_HAS_LMMI 0 252# define MIPS_HAS_LMMI 0
253# define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP) 253# define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP)
254# define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL) 254# define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL)
255 255
256#elif defined(MIPS64) 256#elif defined(MIPS64)
257 257
258# define CPUISMIPS3 1 258# define CPUISMIPS3 1
259# define CPUIS64BITS 1 259# define CPUIS64BITS 1
260# define CPUISMIPS32 0 260# define CPUISMIPS32 0
261# define CPUISMIPS32R2 0 261# define CPUISMIPS32R2 0
262# define CPUISMIPS64 1 262# define CPUISMIPS64 1
263# define CPUISMIPS64R2 0 263# define CPUISMIPS64R2 0
264# define CPUISMIPSNN 1 264# define CPUISMIPSNN 1
265# define CPUISMIPSNNR2 0 265# define CPUISMIPSNNR2 0
266# define MIPS_HAS_R4K_MMU 1 266# define MIPS_HAS_R4K_MMU 1
267# define MIPS_HAS_CLOCK 1 267# define MIPS_HAS_CLOCK 1
268# define MIPS_HAS_LLSC 1 268# define MIPS_HAS_LLSC 1
269# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 269# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
270# define MIPS_HAS_LMMI 0 270# define MIPS_HAS_LMMI 0
271# define MIPS_HAS_DSP 0 271# define MIPS_HAS_DSP 0
272# define MIPS_HAS_USERLOCAL 0 272# define MIPS_HAS_USERLOCAL 0
273 273
274#elif defined(MIPS64R2) 274#elif defined(MIPS64R2)
275 275
276# define CPUISMIPS3 1 276# define CPUISMIPS3 1
277# define CPUIS64BITS 1 277# define CPUIS64BITS 1
278# define CPUISMIPS32 0 278# define CPUISMIPS32 0
279# define CPUISMIPS32R2 0 279# define CPUISMIPS32R2 0
280# define CPUISMIPS64 0 280# define CPUISMIPS64 0
281# define CPUISMIPS64R2 1 281# define CPUISMIPS64R2 1
282# define CPUISMIPSNN 1 282# define CPUISMIPSNN 1
283# define CPUISMIPSNNR2 1 283# define CPUISMIPSNNR2 1
284# define MIPS_HAS_R4K_MMU 1 284# define MIPS_HAS_R4K_MMU 1
285# define MIPS_HAS_CLOCK 1 285# define MIPS_HAS_CLOCK 1
286# define MIPS_HAS_LLSC 1 286# define MIPS_HAS_LLSC 1
287# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 287# define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
288# define MIPS_HAS_LMMI 0 288# define MIPS_HAS_LMMI 0
289# define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP) 289# define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP)
290# define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL) 290# define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL)
291 291
292#endif 292#endif
293 293
294#else /* run-time test */ 294#else /* run-time test */
295 295
296#ifdef MIPS1 296#ifdef MIPS1
297#define MIPS_HAS_R4K_MMU (mips_options.mips_has_r4k_mmu) 297#define MIPS_HAS_R4K_MMU (mips_options.mips_has_r4k_mmu)
298#define MIPS_HAS_LLSC (mips_options.mips_has_llsc) 298#define MIPS_HAS_LLSC (mips_options.mips_has_llsc)
299#else 299#else
300#define MIPS_HAS_R4K_MMU 1 300#define MIPS_HAS_R4K_MMU 1
301#if !defined(MIPS3_4100) 301#if !defined(MIPS3_4100)
302#define MIPS_HAS_LLSC 1 302#define MIPS_HAS_LLSC 1
303#else 303#else
304#define MIPS_HAS_LLSC (mips_options.mips_has_llsc) 304#define MIPS_HAS_LLSC (mips_options.mips_has_llsc)
305#endif 305#endif
306#endif 306#endif
307#define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0) 307#define MIPS_HAS_LLADDR ((mips_options.mips_cpu_flags & CPU_MIPS_NO_LLADDR) == 0)
308#define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP) 308#define MIPS_HAS_DSP (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_DSP)
309#define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL) 309#define MIPS_HAS_USERLOCAL (mips_options.mips_cpu_flags & CPU_MIPS_HAVE_USERLOCAL)
310 310
311/* This test is ... rather bogus */ 311/* This test is ... rather bogus */
312#define CPUISMIPS3 ((mips_options.mips_cpu_arch & \ 312#define CPUISMIPS3 ((mips_options.mips_cpu_arch & \
313 (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0) 313 (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS32 | CPU_ARCH_MIPS64)) != 0)
314 314
315/* And these aren't much better while the previous test exists as is... */ 315/* And these aren't much better while the previous test exists as is... */
316#define CPUISMIPS4 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS4) != 0) 316#define CPUISMIPS4 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS4) != 0)
317#define CPUISMIPS5 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS5) != 0) 317#define CPUISMIPS5 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS5) != 0)
318#define CPUISMIPS32 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS32) != 0) 318#define CPUISMIPS32 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS32) != 0)
319#define CPUISMIPS32R2 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS32R2) != 0) 319#define CPUISMIPS32R2 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS32R2) != 0)
320#define CPUISMIPS64 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS64) != 0) 320#define CPUISMIPS64 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS64) != 0)
321#define CPUISMIPS64R2 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS64R2) != 0) 321#define CPUISMIPS64R2 ((mips_options.mips_cpu_arch & CPU_ARCH_MIPS64R2) != 0)
322#define CPUISMIPSNN ((mips_options.mips_cpu_arch & \ 322#define CPUISMIPSNN ((mips_options.mips_cpu_arch & \
323 (CPU_ARCH_MIPS32 | CPU_ARCH_MIPS32R2 | CPU_ARCH_MIPS64 | CPU_ARCH_MIPS64R2)) != 0) 323 (CPU_ARCH_MIPS32 | CPU_ARCH_MIPS32R2 | CPU_ARCH_MIPS64 | CPU_ARCH_MIPS64R2)) != 0)
324#define CPUISMIPSNNR2 ((mips_options.mips_cpu_arch & \ 324#define CPUISMIPSNNR2 ((mips_options.mips_cpu_arch & \
325 (CPU_ARCH_MIPS32R2 | CPU_ARCH_MIPS64R2)) != 0) 325 (CPU_ARCH_MIPS32R2 | CPU_ARCH_MIPS64R2)) != 0)
326#define CPUIS64BITS ((mips_options.mips_cpu_arch & \ 326#define CPUIS64BITS ((mips_options.mips_cpu_arch & \
327 (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS64 | CPU_ARCH_MIPS64R2)) != 0) 327 (CPU_ARCH_MIPS3 | CPU_ARCH_MIPS4 | CPU_ARCH_MIPS64 | CPU_ARCH_MIPS64R2)) != 0)
328 328
329#define MIPS_HAS_CLOCK (mips_options.mips_cpu_arch >= CPU_ARCH_MIPS3) 329#define MIPS_HAS_CLOCK (mips_options.mips_cpu_arch >= CPU_ARCH_MIPS3)
330 330
331#endif /* run-time test */ 331#endif /* run-time test */
332 332
333#ifndef __ASSEMBLER__ 333#ifndef __ASSEMBLER__
334 334
335struct tlbmask; 335struct tlbmask;
336struct trapframe; 336struct trapframe;
337 337
338void trap(uint32_t, uint32_t, vaddr_t, vaddr_t, struct trapframe *); 338void trap(uint32_t, uint32_t, vaddr_t, vaddr_t, struct trapframe *);
339void ast(void); 339void ast(void);
340 340
341void mips_fpu_trap(vaddr_t, struct trapframe *); 341void mips_fpu_trap(vaddr_t, struct trapframe *);
342void mips_fpu_intr(vaddr_t, struct trapframe *); 342void mips_fpu_intr(vaddr_t, struct trapframe *);
343 343
344vaddr_t mips_emul_branch(struct trapframe *, vaddr_t, uint32_t, bool); 344vaddr_t mips_emul_branch(struct trapframe *, vaddr_t, uint32_t, bool);
345void mips_emul_inst(uint32_t, uint32_t, vaddr_t, struct trapframe *); 345void mips_emul_inst(uint32_t, uint32_t, vaddr_t, struct trapframe *);
346 346
347void mips_emul_fp(uint32_t, struct trapframe *, uint32_t); 347void mips_emul_fp(uint32_t, struct trapframe *, uint32_t);
348void mips_emul_branchdelayslot(uint32_t, struct trapframe *, uint32_t); 348void mips_emul_branchdelayslot(uint32_t, struct trapframe *, uint32_t);
349 349
350void mips_emul_lwc0(uint32_t, struct trapframe *, uint32_t); 
351void mips_emul_swc0(uint32_t, struct trapframe *, uint32_t); 
352void mips_emul_special(uint32_t, struct trapframe *, uint32_t); 350void mips_emul_special(uint32_t, struct trapframe *, uint32_t);
353void mips_emul_special3(uint32_t, struct trapframe *, uint32_t); 351void mips_emul_special3(uint32_t, struct trapframe *, uint32_t);
354 352
355void mips_emul_lwc1(uint32_t, struct trapframe *, uint32_t); 353void mips_emul_lwc1(uint32_t, struct trapframe *, uint32_t);
356void mips_emul_swc1(uint32_t, struct trapframe *, uint32_t); 354void mips_emul_swc1(uint32_t, struct trapframe *, uint32_t);
357void mips_emul_ldc1(uint32_t, struct trapframe *, uint32_t); 355void mips_emul_ldc1(uint32_t, struct trapframe *, uint32_t);
358void mips_emul_sdc1(uint32_t, struct trapframe *, uint32_t); 356void mips_emul_sdc1(uint32_t, struct trapframe *, uint32_t);
359 357
360void mips_emul_lb(uint32_t, struct trapframe *, uint32_t); 358void mips_emul_lb(uint32_t, struct trapframe *, uint32_t);
361void mips_emul_lbu(uint32_t, struct trapframe *, uint32_t); 359void mips_emul_lbu(uint32_t, struct trapframe *, uint32_t);
362void mips_emul_lh(uint32_t, struct trapframe *, uint32_t); 360void mips_emul_lh(uint32_t, struct trapframe *, uint32_t);
363void mips_emul_lhu(uint32_t, struct trapframe *, uint32_t); 361void mips_emul_lhu(uint32_t, struct trapframe *, uint32_t);
364void mips_emul_lw(uint32_t, struct trapframe *, uint32_t); 362void mips_emul_lw(uint32_t, struct trapframe *, uint32_t);
365void mips_emul_lwl(uint32_t, struct trapframe *, uint32_t); 363void mips_emul_lwl(uint32_t, struct trapframe *, uint32_t);
366void mips_emul_lwr(uint32_t, struct trapframe *, uint32_t); 364void mips_emul_lwr(uint32_t, struct trapframe *, uint32_t);
367#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) 365#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
368void mips_emul_lwu(uint32_t, struct trapframe *, uint32_t); 366void mips_emul_lwu(uint32_t, struct trapframe *, uint32_t);
369void mips_emul_ld(uint32_t, struct trapframe *, uint32_t); 367void mips_emul_ld(uint32_t, struct trapframe *, uint32_t);
370void mips_emul_ldl(uint32_t, struct trapframe *, uint32_t); 368void mips_emul_ldl(uint32_t, struct trapframe *, uint32_t);
371void mips_emul_ldr(uint32_t, struct trapframe *, uint32_t); 369void mips_emul_ldr(uint32_t, struct trapframe *, uint32_t);
372#endif 370#endif
373void mips_emul_sb(uint32_t, struct trapframe *, uint32_t); 371void mips_emul_sb(uint32_t, struct trapframe *, uint32_t);
374void mips_emul_sh(uint32_t, struct trapframe *, uint32_t); 372void mips_emul_sh(uint32_t, struct trapframe *, uint32_t);
375void mips_emul_sw(uint32_t, struct trapframe *, uint32_t); 373void mips_emul_sw(uint32_t, struct trapframe *, uint32_t);
376void mips_emul_swl(uint32_t, struct trapframe *, uint32_t); 374void mips_emul_swl(uint32_t, struct trapframe *, uint32_t);
377void mips_emul_swr(uint32_t, struct trapframe *, uint32_t); 375void mips_emul_swr(uint32_t, struct trapframe *, uint32_t);
378#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) 376#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
379void mips_emul_sd(uint32_t, struct trapframe *, uint32_t); 377void mips_emul_sd(uint32_t, struct trapframe *, uint32_t);
380void mips_emul_sdl(uint32_t, struct trapframe *, uint32_t); 378void mips_emul_sdl(uint32_t, struct trapframe *, uint32_t);
381void mips_emul_sdr(uint32_t, struct trapframe *, uint32_t); 379void mips_emul_sdr(uint32_t, struct trapframe *, uint32_t);
382#endif 380#endif
383 381
384uint32_t mips_cp0_cause_read(void); 382uint32_t mips_cp0_cause_read(void);
385void mips_cp0_cause_write(uint32_t); 383void mips_cp0_cause_write(uint32_t);
386uint32_t mips_cp0_status_read(void); 384uint32_t mips_cp0_status_read(void);
387void mips_cp0_status_write(uint32_t); 385void mips_cp0_status_write(uint32_t);
388 386
389void softint_process(uint32_t); 387void softint_process(uint32_t);
390void softint_fast_dispatch(struct lwp *, int); 388void softint_fast_dispatch(struct lwp *, int);
391 389
392/* 390/*
393 * Convert an address to an offset used in a MIPS jump instruction. The offset 391 * Convert an address to an offset used in a MIPS jump instruction. The offset
394 * contains the low 28 bits (allowing a jump to anywhere within the same 256MB 392 * contains the low 28 bits (allowing a jump to anywhere within the same 256MB
395 * segment of address space) of the address but since mips instructions are 393 * segment of address space) of the address but since mips instructions are
396 * always on a 4 byte boundary the low 2 bits are always zero so the 28 bits 394 * always on a 4 byte boundary the low 2 bits are always zero so the 28 bits
397 * get shifted right by 2 bits leaving us with a 26 bit result. To make the 395 * get shifted right by 2 bits leaving us with a 26 bit result. To make the
398 * offset, we shift left to clear the upper four bits and then right by 6. 396 * offset, we shift left to clear the upper four bits and then right by 6.
399 */ 397 */
400#define fixup_addr2offset(x) ((((uint32_t)(uintptr_t)(x)) << 4) >> 6) 398#define fixup_addr2offset(x) ((((uint32_t)(uintptr_t)(x)) << 4) >> 6)
401typedef bool (*mips_fixup_callback_t)(int32_t, uint32_t [2], void *); 399typedef bool (*mips_fixup_callback_t)(int32_t, uint32_t [2], void *);
402struct mips_jump_fixup_info { 400struct mips_jump_fixup_info {
403 uint32_t jfi_stub; 401 uint32_t jfi_stub;
404 uint32_t jfi_real; 402 uint32_t jfi_real;
405}; 403};
406 404
407void fixup_splcalls(void); /* splstubs.c */ 405void fixup_splcalls(void); /* splstubs.c */
408bool mips_fixup_exceptions(mips_fixup_callback_t, void *); 406bool mips_fixup_exceptions(mips_fixup_callback_t, void *);
409bool mips_fixup_zero_relative(int32_t, uint32_t [2], void *); 407bool mips_fixup_zero_relative(int32_t, uint32_t [2], void *);
410intptr_t 408intptr_t
411 mips_fixup_addr(const uint32_t *); 409 mips_fixup_addr(const uint32_t *);
412void mips_fixup_stubs(uint32_t *, uint32_t *); 410void mips_fixup_stubs(uint32_t *, uint32_t *);
413 411
414/* 412/*
415 * Define these stubs... 413 * Define these stubs...
416 */ 414 */
417void mips_cpu_switch_resume(struct lwp *); 415void mips_cpu_switch_resume(struct lwp *);
418void wbflush(void); 416void wbflush(void);
419 417
420#ifdef MIPS1 418#ifdef MIPS1
421void mips1_tlb_invalidate_all(void); 419void mips1_tlb_invalidate_all(void);
422 420
423uint32_t tx3900_cp0_config_read(void); 421uint32_t tx3900_cp0_config_read(void);
424#endif 422#endif
425 423
426#ifdef MIPS3_PLUS 424#ifdef MIPS3_PLUS
427uint32_t mips3_cp0_compare_read(void); 425uint32_t mips3_cp0_compare_read(void);
428void mips3_cp0_compare_write(uint32_t); 426void mips3_cp0_compare_write(uint32_t);
429 427
430uint32_t mips3_cp0_config_read(void); 428uint32_t mips3_cp0_config_read(void);
431void mips3_cp0_config_write(uint32_t); 429void mips3_cp0_config_write(uint32_t);
432 430
433#ifdef MIPSNN 431#ifdef MIPSNN
434uint32_t mipsNN_cp0_config1_read(void); 432uint32_t mipsNN_cp0_config1_read(void);
435void mipsNN_cp0_config1_write(uint32_t); 433void mipsNN_cp0_config1_write(uint32_t);
436uint32_t mipsNN_cp0_config2_read(void); 434uint32_t mipsNN_cp0_config2_read(void);
437uint32_t mipsNN_cp0_config3_read(void); 435uint32_t mipsNN_cp0_config3_read(void);
438uint32_t mipsNN_cp0_config4_read(void); 436uint32_t mipsNN_cp0_config4_read(void);
439uint32_t mipsNN_cp0_config5_read(void); 437uint32_t mipsNN_cp0_config5_read(void);
440uint32_t mipsNN_cp0_config6_read(void); 438uint32_t mipsNN_cp0_config6_read(void);
441uint32_t mipsNN_cp0_config7_read(void); 439uint32_t mipsNN_cp0_config7_read(void);
442 440
443intptr_t mipsNN_cp0_watchlo_read(u_int); 441intptr_t mipsNN_cp0_watchlo_read(u_int);
444void mipsNN_cp0_watchlo_write(u_int, intptr_t); 442void mipsNN_cp0_watchlo_write(u_int, intptr_t);
445uint32_t mipsNN_cp0_watchhi_read(u_int); 443uint32_t mipsNN_cp0_watchhi_read(u_int);
446void mipsNN_cp0_watchhi_write(u_int, uint32_t); 444void mipsNN_cp0_watchhi_write(u_int, uint32_t);
447 445
448int32_t mipsNN_cp0_ebase_read(void); 446int32_t mipsNN_cp0_ebase_read(void);
449void mipsNN_cp0_ebase_write(int32_t); 447void mipsNN_cp0_ebase_write(int32_t);
450 448
451uint32_t mipsNN_cp0_rdhwr_cpunum(void); 449uint32_t mipsNN_cp0_rdhwr_cpunum(void);
452 450
453#ifdef MIPSNNR2 451#ifdef MIPSNNR2
454void mipsNN_cp0_hwrena_write(uint32_t); 452void mipsNN_cp0_hwrena_write(uint32_t);
455void mipsNN_cp0_userlocal_write(void *); 453void mipsNN_cp0_userlocal_write(void *);
456#endif 454#endif
457#endif /* MIPSNN */ 455#endif /* MIPSNN */
458 456
459uint32_t mips3_cp0_count_read(void); 457uint32_t mips3_cp0_count_read(void);
460void mips3_cp0_count_write(uint32_t); 458void mips3_cp0_count_write(uint32_t);
461 459
462uint32_t mips3_cp0_wired_read(void); 460uint32_t mips3_cp0_wired_read(void);
463void mips3_cp0_wired_write(uint32_t); 461void mips3_cp0_wired_write(uint32_t);
464void mips3_cp0_pg_mask_write(uint32_t); 462void mips3_cp0_pg_mask_write(uint32_t);
465 463
466#endif /* MIPS3_PLUS */ 464#endif /* MIPS3_PLUS */
467 465
468/* 64-bit address space accessor for n32, n64 ABI */ 466/* 64-bit address space accessor for n32, n64 ABI */
469/* 32-bit address space accessor for o32 ABI */ 467/* 32-bit address space accessor for o32 ABI */
470static inline uint8_t mips_lbu(register_t addr) __unused; 468static inline uint8_t mips_lbu(register_t addr) __unused;
471static inline void mips_sb(register_t addr, uint8_t val) __unused; 469static inline void mips_sb(register_t addr, uint8_t val) __unused;
472static inline uint16_t mips_lhu(register_t addr) __unused; 470static inline uint16_t mips_lhu(register_t addr) __unused;
473static inline void mips_sh(register_t addr, uint16_t val) __unused; 471static inline void mips_sh(register_t addr, uint16_t val) __unused;
474static inline uint32_t mips_lwu(register_t addr) __unused; 472static inline uint32_t mips_lwu(register_t addr) __unused;
475static inline void mips_sw(register_t addr, uint32_t val) __unused; 473static inline void mips_sw(register_t addr, uint32_t val) __unused;
476#ifdef MIPS3_64BIT 474#ifdef MIPS3_64BIT
477#if defined(__mips_o32) 475#if defined(__mips_o32)
478uint64_t mips3_ld(register_t addr); 476uint64_t mips3_ld(register_t addr);
479void mips3_sd(register_t addr, uint64_t val); 477void mips3_sd(register_t addr, uint64_t val);
480#else 478#else
481static inline uint64_t mips3_ld(register_t addr) __unused; 479static inline uint64_t mips3_ld(register_t addr) __unused;
482static inline void mips3_sd(register_t addr, uint64_t val) __unused; 480static inline void mips3_sd(register_t addr, uint64_t val) __unused;
483#endif 481#endif
484#endif 482#endif
485 483
486static inline uint8_t 484static inline uint8_t
487mips_lbu(register_t addr) 485mips_lbu(register_t addr)
488{ 486{
489 uint8_t rv; 487 uint8_t rv;
490#if defined(__mips_n32) 488#if defined(__mips_n32)
491 __asm volatile("lbu\t%0, 0(%1)" : "=r"(rv) : "d"(addr)); 489 __asm volatile("lbu\t%0, 0(%1)" : "=r"(rv) : "d"(addr));
492#else 490#else
493 rv = *(const volatile uint8_t *)addr; 491 rv = *(const volatile uint8_t *)addr;
494#endif 492#endif
495 return rv; 493 return rv;
496} 494}
497 495
498static inline uint16_t 496static inline uint16_t
499mips_lhu(register_t addr) 497mips_lhu(register_t addr)
500{ 498{
501 uint16_t rv; 499 uint16_t rv;
502#if defined(__mips_n32) 500#if defined(__mips_n32)
503 __asm volatile("lhu\t%0, 0(%1)" : "=r"(rv) : "d"(addr)); 501 __asm volatile("lhu\t%0, 0(%1)" : "=r"(rv) : "d"(addr));
504#else 502#else
505 rv = *(const volatile uint16_t *)addr; 503 rv = *(const volatile uint16_t *)addr;
506#endif 504#endif
507 return rv; 505 return rv;
508} 506}
509 507
510static inline uint32_t 508static inline uint32_t
511mips_lwu(register_t addr) 509mips_lwu(register_t addr)
512{ 510{
513 uint32_t rv; 511 uint32_t rv;
514#if defined(__mips_n32) 512#if defined(__mips_n32)
515 __asm volatile("lwu\t%0, 0(%1)" : "=r"(rv) : "d"(addr)); 513 __asm volatile("lwu\t%0, 0(%1)" : "=r"(rv) : "d"(addr));
516#else 514#else
517 rv = *(const volatile uint32_t *)addr; 515 rv = *(const volatile uint32_t *)addr;
518#endif 516#endif
519 return (rv); 517 return (rv);
520} 518}
521 519
522#if defined(MIPS3_64BIT) && !defined(__mips_o32) 520#if defined(MIPS3_64BIT) && !defined(__mips_o32)
523static inline uint64_t 521static inline uint64_t
524mips3_ld(register_t addr) 522mips3_ld(register_t addr)
525{ 523{
526 uint64_t rv; 524 uint64_t rv;
527#if defined(__mips_n32) 525#if defined(__mips_n32)
528 __asm volatile("ld\t%0, 0(%1)" : "=r"(rv) : "d"(addr)); 526 __asm volatile("ld\t%0, 0(%1)" : "=r"(rv) : "d"(addr));
529#elif defined(_LP64) 527#elif defined(_LP64)
530 rv = *(const volatile uint64_t *)addr; 528 rv = *(const volatile uint64_t *)addr;
531#else 529#else
532#error unknown ABI 530#error unknown ABI
533#endif 531#endif
534 return (rv); 532 return (rv);
535} 533}
536#endif /* MIPS3_64BIT && !__mips_o32 */ 534#endif /* MIPS3_64BIT && !__mips_o32 */
537 535
538static inline void 536static inline void
539mips_sb(register_t addr, uint8_t val) 537mips_sb(register_t addr, uint8_t val)
540{ 538{
541#if defined(__mips_n32) 539#if defined(__mips_n32)
542 __asm volatile("sb\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory"); 540 __asm volatile("sb\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory");
543#else 541#else
544 *(volatile uint8_t *)addr = val; 542 *(volatile uint8_t *)addr = val;
545#endif 543#endif
546} 544}
547 545
548static inline void 546static inline void
549mips_sh(register_t addr, uint16_t val) 547mips_sh(register_t addr, uint16_t val)
550{ 548{
551#if defined(__mips_n32) 549#if defined(__mips_n32)
552 __asm volatile("sh\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory"); 550 __asm volatile("sh\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory");
553#else 551#else
554 *(volatile uint16_t *)addr = val; 552 *(volatile uint16_t *)addr = val;
555#endif 553#endif
556} 554}
557 555
558static inline void 556static inline void
559mips_sw(register_t addr, uint32_t val) 557mips_sw(register_t addr, uint32_t val)
560{ 558{
561#if defined(__mips_n32) 559#if defined(__mips_n32)
562 __asm volatile("sw\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory"); 560 __asm volatile("sw\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory");
563#else 561#else
564 *(volatile uint32_t *)addr = val; 562 *(volatile uint32_t *)addr = val;
565#endif 563#endif
566} 564}
567 565
568#if defined(MIPS3_64BIT) && !defined(__mips_o32) 566#if defined(MIPS3_64BIT) && !defined(__mips_o32)
569static inline void 567static inline void
570mips3_sd(register_t addr, uint64_t val) 568mips3_sd(register_t addr, uint64_t val)
571{ 569{
572#if defined(__mips_n32) 570#if defined(__mips_n32)
573 __asm volatile("sd\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory"); 571 __asm volatile("sd\t%1, 0(%0)" :: "d"(addr), "r"(val) : "memory");
574#else 572#else
575 *(volatile uint64_t *)addr = val; 573 *(volatile uint64_t *)addr = val;
576#endif 574#endif
577} 575}
578#endif /* MIPS3_64BIT && !__mips_o32 */ 576#endif /* MIPS3_64BIT && !__mips_o32 */
579 577
580/* 578/*
581 * A vector with an entry for each mips-ISA-level dependent 579 * A vector with an entry for each mips-ISA-level dependent
582 * locore function, and macros which jump through it. 580 * locore function, and macros which jump through it.
583 */ 581 */
584typedef struct { 582typedef struct {
585 void (*ljv_cpu_switch_resume)(struct lwp *); 583 void (*ljv_cpu_switch_resume)(struct lwp *);
586 intptr_t ljv_lwp_trampoline; 584 intptr_t ljv_lwp_trampoline;
587 void (*ljv_wbflush)(void); 585 void (*ljv_wbflush)(void);
588 tlb_asid_t (*ljv_tlb_get_asid)(void); 586 tlb_asid_t (*ljv_tlb_get_asid)(void);
589 void (*ljv_tlb_set_asid)(tlb_asid_t pid); 587 void (*ljv_tlb_set_asid)(tlb_asid_t pid);
590 void (*ljv_tlb_invalidate_asids)(tlb_asid_t, tlb_asid_t); 588 void (*ljv_tlb_invalidate_asids)(tlb_asid_t, tlb_asid_t);
591 void (*ljv_tlb_invalidate_addr)(vaddr_t, tlb_asid_t); 589 void (*ljv_tlb_invalidate_addr)(vaddr_t, tlb_asid_t);
592 void (*ljv_tlb_invalidate_globals)(void); 590 void (*ljv_tlb_invalidate_globals)(void);
593 void (*ljv_tlb_invalidate_all)(void); 591 void (*ljv_tlb_invalidate_all)(void);
594 u_int (*ljv_tlb_record_asids)(u_long *, tlb_asid_t); 592 u_int (*ljv_tlb_record_asids)(u_long *, tlb_asid_t);
595 int (*ljv_tlb_update_addr)(vaddr_t, tlb_asid_t, pt_entry_t, bool); 593 int (*ljv_tlb_update_addr)(vaddr_t, tlb_asid_t, pt_entry_t, bool);
596 void (*ljv_tlb_read_entry)(size_t, struct tlbmask *); 594 void (*ljv_tlb_read_entry)(size_t, struct tlbmask *);
597 void (*ljv_tlb_write_entry)(size_t, const struct tlbmask *); 595 void (*ljv_tlb_write_entry)(size_t, const struct tlbmask *);
598} mips_locore_jumpvec_t; 596} mips_locore_jumpvec_t;
599 597
600typedef struct { 598typedef struct {
601 u_int (*lav_atomic_cas_uint)(volatile u_int *, u_int, u_int); 599 u_int (*lav_atomic_cas_uint)(volatile u_int *, u_int, u_int);
602 u_long (*lav_atomic_cas_ulong)(volatile u_long *, u_long, u_long); 600 u_long (*lav_atomic_cas_ulong)(volatile u_long *, u_long, u_long);
603 int (*lav_ucas_32)(volatile uint32_t *, uint32_t, uint32_t, 601 int (*lav_ucas_32)(volatile uint32_t *, uint32_t, uint32_t,
604 uint32_t *); 602 uint32_t *);
605 int (*lav_ucas_64)(volatile uint64_t *, uint64_t, uint64_t, 603 int (*lav_ucas_64)(volatile uint64_t *, uint64_t, uint64_t,
606 uint64_t *); 604 uint64_t *);
607 void (*lav_mutex_enter)(kmutex_t *); 605 void (*lav_mutex_enter)(kmutex_t *);
608 void (*lav_mutex_exit)(kmutex_t *); 606 void (*lav_mutex_exit)(kmutex_t *);
609 void (*lav_mutex_spin_enter)(kmutex_t *); 607 void (*lav_mutex_spin_enter)(kmutex_t *);
610 void (*lav_mutex_spin_exit)(kmutex_t *); 608 void (*lav_mutex_spin_exit)(kmutex_t *);
611} mips_locore_atomicvec_t; 609} mips_locore_atomicvec_t;
612 610
613void mips_set_wbflush(void (*)(void)); 611void mips_set_wbflush(void (*)(void));
614void mips_wait_idle(void); 612void mips_wait_idle(void);
615 613
616void stacktrace(void); 614void stacktrace(void);
617void logstacktrace(void); 615void logstacktrace(void);
618 616
619struct cpu_info; 617struct cpu_info;
620struct splsw; 618struct splsw;
621 619
622struct locoresw { 620struct locoresw {
623 void (*lsw_wbflush)(void); 621 void (*lsw_wbflush)(void);
624 void (*lsw_cpu_idle)(void); 622 void (*lsw_cpu_idle)(void);
625 int (*lsw_send_ipi)(struct cpu_info *, int); 623 int (*lsw_send_ipi)(struct cpu_info *, int);
626 void (*lsw_cpu_offline_md)(void); 624 void (*lsw_cpu_offline_md)(void);
627 void (*lsw_cpu_init)(struct cpu_info *); 625 void (*lsw_cpu_init)(struct cpu_info *);
628 void (*lsw_cpu_run)(struct cpu_info *); 626 void (*lsw_cpu_run)(struct cpu_info *);
629 int (*lsw_bus_error)(unsigned int); 627 int (*lsw_bus_error)(unsigned int);
630}; 628};
631 629
632struct mips_vmfreelist { 630struct mips_vmfreelist {
633 paddr_t fl_start; 631 paddr_t fl_start;
634 paddr_t fl_end; 632 paddr_t fl_end;
635 int fl_freelist; 633 int fl_freelist;
636}; 634};
637 635
638struct cpu_info * 636struct cpu_info *
639 cpu_info_alloc(struct pmap_tlb_info *, cpuid_t, cpuid_t, cpuid_t, 637 cpu_info_alloc(struct pmap_tlb_info *, cpuid_t, cpuid_t, cpuid_t,
640 cpuid_t); 638 cpuid_t);
641void cpu_attach_common(device_t, struct cpu_info *); 639void cpu_attach_common(device_t, struct cpu_info *);
642void cpu_startup_common(void); 640void cpu_startup_common(void);
643 641
644#ifdef MULTIPROCESSOR 642#ifdef MULTIPROCESSOR
645void cpu_hatch(struct cpu_info *ci); 643void cpu_hatch(struct cpu_info *ci);
646void cpu_trampoline(void); 644void cpu_trampoline(void);
647void cpu_halt(void); 645void cpu_halt(void);
648void cpu_halt_others(void); 646void cpu_halt_others(void);
649void cpu_pause(struct reg *); 647void cpu_pause(struct reg *);
650void cpu_pause_others(void); 648void cpu_pause_others(void);
651void cpu_resume(cpuid_t); 649void cpu_resume(cpuid_t);
652void cpu_resume_others(void); 650void cpu_resume_others(void);
653bool cpu_is_paused(cpuid_t); 651bool cpu_is_paused(cpuid_t);
654void cpu_debug_dump(void); 652void cpu_debug_dump(void);
655 653
656extern kcpuset_t *cpus_running; 654extern kcpuset_t *cpus_running;
657extern kcpuset_t *cpus_hatched; 655extern kcpuset_t *cpus_hatched;
658extern kcpuset_t *cpus_paused; 656extern kcpuset_t *cpus_paused;
659extern kcpuset_t *cpus_resumed; 657extern kcpuset_t *cpus_resumed;
660extern kcpuset_t *cpus_halted; 658extern kcpuset_t *cpus_halted;
661#endif 659#endif
662 660
663/* copy.S */ 661/* copy.S */
664uint32_t mips_ufetch32(const void *); 662uint32_t mips_ufetch32(const void *);
665int mips_ustore32_isync(void *, uint32_t); 663int mips_ustore32_isync(void *, uint32_t);
666 664
667int32_t kfetch_32(volatile uint32_t *, uint32_t); 665int32_t kfetch_32(volatile uint32_t *, uint32_t);
668 666
669/* trap.c */ 667/* trap.c */
670void netintr(void); 668void netintr(void);
671 669
672/* mips_dsp.c */ 670/* mips_dsp.c */
673void dsp_init(void); 671void dsp_init(void);
674void dsp_discard(lwp_t *); 672void dsp_discard(lwp_t *);
675void dsp_load(void); 673void dsp_load(void);
676void dsp_save(lwp_t *); 674void dsp_save(lwp_t *);
677bool dsp_used_p(const lwp_t *); 675bool dsp_used_p(const lwp_t *);
678extern const pcu_ops_t mips_dsp_ops; 676extern const pcu_ops_t mips_dsp_ops;
679 677
680/* mips_fpu.c */ 678/* mips_fpu.c */
681void fpu_init(void); 679void fpu_init(void);
682void fpu_discard(lwp_t *); 680void fpu_discard(lwp_t *);
683void fpu_load(void); 681void fpu_load(void);
684void fpu_save(lwp_t *); 682void fpu_save(lwp_t *);
685bool fpu_used_p(const lwp_t *); 683bool fpu_used_p(const lwp_t *);
686extern const pcu_ops_t mips_fpu_ops; 684extern const pcu_ops_t mips_fpu_ops;
687 685
688/* mips_machdep.c */ 686/* mips_machdep.c */
689void dumpsys(void); 687void dumpsys(void);
690int savectx(struct pcb *); 688int savectx(struct pcb *);
691void cpu_identify(device_t); 689void cpu_identify(device_t);
692 690
693/* locore*.S */ 691/* locore*.S */
694int badaddr(void *, size_t); 692int badaddr(void *, size_t);
695int badaddr64(uint64_t, size_t); 693int badaddr64(uint64_t, size_t);
696 694
697/* vm_machdep.c */ 695/* vm_machdep.c */
698int ioaccess(vaddr_t, paddr_t, vsize_t); 696int ioaccess(vaddr_t, paddr_t, vsize_t);
699int iounaccess(vaddr_t, vsize_t); 697int iounaccess(vaddr_t, vsize_t);
700 698
701/* 699/*
702 * The "active" locore-function vector, and 700 * The "active" locore-function vector, and
703 */ 701 */
704extern const mips_locore_atomicvec_t mips_llsc_locore_atomicvec; 702extern const mips_locore_atomicvec_t mips_llsc_locore_atomicvec;
705 703
706extern mips_locore_atomicvec_t mips_locore_atomicvec; 704extern mips_locore_atomicvec_t mips_locore_atomicvec;
707extern mips_locore_jumpvec_t mips_locore_jumpvec; 705extern mips_locore_jumpvec_t mips_locore_jumpvec;
708extern struct locoresw mips_locoresw; 706extern struct locoresw mips_locoresw;
709 707
710extern int mips_poolpage_vmfreelist; /* freelist to allocate poolpages */ 708extern int mips_poolpage_vmfreelist; /* freelist to allocate poolpages */
711extern struct mips_options mips_options; 709extern struct mips_options mips_options;
712 710
713struct splsw; 711struct splsw;
714struct mips_vmfreelist; 712struct mips_vmfreelist;
715struct phys_ram_seg; 713struct phys_ram_seg;
716 714
717void mips64r2_vector_init(const struct splsw *); 715void mips64r2_vector_init(const struct splsw *);
718void mips_vector_init(const struct splsw *, bool); 716void mips_vector_init(const struct splsw *, bool);
719void mips_init_msgbuf(void); 717void mips_init_msgbuf(void);
720void mips_init_lwp0_uarea(void); 718void mips_init_lwp0_uarea(void);
721void mips_page_physload(vaddr_t, vaddr_t, 719void mips_page_physload(vaddr_t, vaddr_t,
722 const struct phys_ram_seg *, size_t, 720 const struct phys_ram_seg *, size_t,
723 const struct mips_vmfreelist *, size_t); 721 const struct mips_vmfreelist *, size_t);
724 722
725 723
726/* 724/*
727 * CPU identification, from PRID register. 725 * CPU identification, from PRID register.
728 */ 726 */
729#define MIPS_PRID_REV(x) (((x) >> 0) & 0x00ff) 727#define MIPS_PRID_REV(x) (((x) >> 0) & 0x00ff)
730#define MIPS_PRID_IMPL(x) (((x) >> 8) & 0x00ff) 728#define MIPS_PRID_IMPL(x) (((x) >> 8) & 0x00ff)
731 729
732/* pre-MIPS32/64 */ 730/* pre-MIPS32/64 */
733#define MIPS_PRID_RSVD(x) (((x) >> 16) & 0xffff) 731#define MIPS_PRID_RSVD(x) (((x) >> 16) & 0xffff)
734#define MIPS_PRID_REV_MIN(x) ((MIPS_PRID_REV(x) >> 0) & 0x0f) 732#define MIPS_PRID_REV_MIN(x) ((MIPS_PRID_REV(x) >> 0) & 0x0f)
735#define MIPS_PRID_REV_MAJ(x) ((MIPS_PRID_REV(x) >> 4) & 0x0f) 733#define MIPS_PRID_REV_MAJ(x) ((MIPS_PRID_REV(x) >> 4) & 0x0f)
736 734
737/* MIPS32/64 */ 735/* MIPS32/64 */
738#define MIPS_PRID_CID(x) (((x) >> 16) & 0x00ff) /* Company ID */ 736#define MIPS_PRID_CID(x) (((x) >> 16) & 0x00ff) /* Company ID */
739#define MIPS_PRID_CID_PREHISTORIC 0x00 /* Not MIPS32/64 */ 737#define MIPS_PRID_CID_PREHISTORIC 0x00 /* Not MIPS32/64 */
740#define MIPS_PRID_CID_MTI 0x01 /* MIPS Technologies, Inc. */ 738#define MIPS_PRID_CID_MTI 0x01 /* MIPS Technologies, Inc. */
741#define MIPS_PRID_CID_BROADCOM 0x02 /* Broadcom */ 739#define MIPS_PRID_CID_BROADCOM 0x02 /* Broadcom */
742#define MIPS_PRID_CID_ALCHEMY 0x03 /* Alchemy Semiconductor */ 740#define MIPS_PRID_CID_ALCHEMY 0x03 /* Alchemy Semiconductor */
743#define MIPS_PRID_CID_SIBYTE 0x04 /* SiByte */ 741#define MIPS_PRID_CID_SIBYTE 0x04 /* SiByte */
744#define MIPS_PRID_CID_SANDCRAFT 0x05 /* SandCraft */ 742#define MIPS_PRID_CID_SANDCRAFT 0x05 /* SandCraft */
745#define MIPS_PRID_CID_PHILIPS 0x06 /* Philips */ 743#define MIPS_PRID_CID_PHILIPS 0x06 /* Philips */
746#define MIPS_PRID_CID_TOSHIBA 0x07 /* Toshiba */ 744#define MIPS_PRID_CID_TOSHIBA 0x07 /* Toshiba */
747#define MIPS_PRID_CID_MICROSOFT 0x07 /* Microsoft also, sigh */ 745#define MIPS_PRID_CID_MICROSOFT 0x07 /* Microsoft also, sigh */
748#define MIPS_PRID_CID_LSI 0x08 /* LSI */ 746#define MIPS_PRID_CID_LSI 0x08 /* LSI */
749 /* 0x09 unannounced */ 747 /* 0x09 unannounced */
750 /* 0x0a unannounced */ 748 /* 0x0a unannounced */
751#define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */ 749#define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */
752#define MIPS_PRID_CID_RMI 0x0c /* RMI / NetLogic */ 750#define MIPS_PRID_CID_RMI 0x0c /* RMI / NetLogic */
753#define MIPS_PRID_CID_CAVIUM 0x0d /* Cavium */ 751#define MIPS_PRID_CID_CAVIUM 0x0d /* Cavium */
754#define MIPS_PRID_CID_INGENIC 0xe1 752#define MIPS_PRID_CID_INGENIC 0xe1
755#define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */ 753#define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */
756 754
757/* 755/*
758 * Global variables used to communicate CPU type, and parameters 756 * Global variables used to communicate CPU type, and parameters
759 * such as cache size, from locore to higher-level code (e.g., pmap). 757 * such as cache size, from locore to higher-level code (e.g., pmap).
760 */ 758 */
761void mips_pagecopy(register_t dst, register_t src); 759void mips_pagecopy(register_t dst, register_t src);
762void mips_pagezero(register_t dst); 760void mips_pagezero(register_t dst);
763 761
764#ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG 762#ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
765void mips_machdep_cache_config(void); 763void mips_machdep_cache_config(void);
766#endif 764#endif
767 765
768/* 766/*
769 * trapframe argument passed to trap() 767 * trapframe argument passed to trap()
770 */ 768 */
771 769
772#if 0 770#if 0
773#define TF_AST 0 /* really zero */ 771#define TF_AST 0 /* really zero */
774#define TF_V0 _R_V0 772#define TF_V0 _R_V0
775#define TF_V1 _R_V1 773#define TF_V1 _R_V1
776#define TF_A0 _R_A0 774#define TF_A0 _R_A0
777#define TF_A1 _R_A1 775#define TF_A1 _R_A1
778#define TF_A2 _R_A2 776#define TF_A2 _R_A2
779#define TF_A3 _R_A3 777#define TF_A3 _R_A3
780#define TF_T0 _R_T0 778#define TF_T0 _R_T0
781#define TF_T1 _R_T1 779#define TF_T1 _R_T1
782#define TF_T2 _R_T2 780#define TF_T2 _R_T2
783#define TF_T3 _R_T3 781#define TF_T3 _R_T3
784 782
785#if defined(__mips_n32) || defined(__mips_n64) 783#if defined(__mips_n32) || defined(__mips_n64)
786#define TF_A4 _R_A4 784#define TF_A4 _R_A4
787#define TF_A5 _R_A5 785#define TF_A5 _R_A5
788#define TF_A6 _R_A6 786#define TF_A6 _R_A6
789#define TF_A7 _R_A7 787#define TF_A7 _R_A7
790#else 788#else
791#define TF_T4 _R_T4 789#define TF_T4 _R_T4
792#define TF_T5 _R_T5 790#define TF_T5 _R_T5
793#define TF_T6 _R_T6 791#define TF_T6 _R_T6
794#define TF_T7 _R_T7 792#define TF_T7 _R_T7
795#endif /* __mips_n32 || __mips_n64 */ 793#endif /* __mips_n32 || __mips_n64 */
796 794
797#define TF_TA0 _R_TA0 795#define TF_TA0 _R_TA0
798#define TF_TA1 _R_TA1 796#define TF_TA1 _R_TA1
799#define TF_TA2 _R_TA2 797#define TF_TA2 _R_TA2
800#define TF_TA3 _R_TA3 798#define TF_TA3 _R_TA3
801 799
802#define TF_T8 _R_T8 800#define TF_T8 _R_T8
803#define TF_T9 _R_T9 801#define TF_T9 _R_T9
804 802
805#define TF_RA _R_RA 803#define TF_RA _R_RA
806#define TF_SR _R_SR 804#define TF_SR _R_SR
807#define TF_MULLO _R_MULLO 805#define TF_MULLO _R_MULLO
808#define TF_MULHI _R_MULHI 806#define TF_MULHI _R_MULHI
809#define TF_EPC _R_PC /* may be changed by trap() call */ 807#define TF_EPC _R_PC /* may be changed by trap() call */
810 808
811#define TF_NREGS (sizeof(struct reg) / sizeof(mips_reg_t)) 809#define TF_NREGS (sizeof(struct reg) / sizeof(mips_reg_t))
812#endif 810#endif
813 811
814struct trapframe { 812struct trapframe {
815 struct reg tf_registers; 813 struct reg tf_registers;
816#define tf_regs tf_registers.r_regs 814#define tf_regs tf_registers.r_regs
817 uint32_t tf_ppl; /* previous priority level */ 815 uint32_t tf_ppl; /* previous priority level */
818 mips_reg_t tf_pad; /* for 8 byte aligned */ 816 mips_reg_t tf_pad; /* for 8 byte aligned */
819}; 817};
820 818
821CTASSERT(sizeof(struct trapframe) % (4*sizeof(mips_reg_t)) == 0); 819CTASSERT(sizeof(struct trapframe) % (4*sizeof(mips_reg_t)) == 0);
822 820
823/* 821/*
824 * Stack frame for kernel traps. four args passed in registers. 822 * Stack frame for kernel traps. four args passed in registers.
825 * A trapframe is pointed to by the 5th arg, and a dummy sixth argument 823 * A trapframe is pointed to by the 5th arg, and a dummy sixth argument
826 * is used to avoid alignment problems 824 * is used to avoid alignment problems
827 */ 825 */
828 826
829struct kernframe { 827struct kernframe {
830#if defined(__mips_o32) || defined(__mips_o64) 828#if defined(__mips_o32) || defined(__mips_o64)
831 register_t cf_args[4 + 1]; 829 register_t cf_args[4 + 1];
832#if defined(__mips_o32) 830#if defined(__mips_o32)
833 register_t cf_pad; /* (for 8 byte alignment) */ 831 register_t cf_pad; /* (for 8 byte alignment) */
834#endif 832#endif
835#endif 833#endif
836#if defined(__mips_n32) || defined(__mips_n64) 834#if defined(__mips_n32) || defined(__mips_n64)
837 register_t cf_pad[2]; /* for 16 byte alignment */ 835 register_t cf_pad[2]; /* for 16 byte alignment */
838#endif 836#endif
839 register_t cf_sp; 837 register_t cf_sp;
840 register_t cf_ra; 838 register_t cf_ra;
841 struct trapframe cf_frame; 839 struct trapframe cf_frame;
842}; 840};
843 841
844CTASSERT(sizeof(struct kernframe) % (2*sizeof(mips_reg_t)) == 0); 842CTASSERT(sizeof(struct kernframe) % (2*sizeof(mips_reg_t)) == 0);
845 843
846/* 844/*
847 * PRocessor IDentity TABle 845 * PRocessor IDentity TABle
848 */ 846 */
849 847
850struct pridtab { 848struct pridtab {
851 int cpu_cid; 849 int cpu_cid;
852 int cpu_pid; 850 int cpu_pid;
853 int cpu_rev; /* -1 == wildcard */ 851 int cpu_rev; /* -1 == wildcard */
854 int cpu_copts; /* -1 == wildcard */ 852 int cpu_copts; /* -1 == wildcard */
855 int cpu_isa; /* -1 == probed (mips32/mips64) */ 853 int cpu_isa; /* -1 == probed (mips32/mips64) */
856 int cpu_ntlb; /* -1 == unknown, 0 == probed */ 854 int cpu_ntlb; /* -1 == unknown, 0 == probed */
857 int cpu_flags; 855 int cpu_flags;
858 u_int cpu_cp0flags; /* presence of some cp0 regs */ 856 u_int cpu_cp0flags; /* presence of some cp0 regs */
859 u_int cpu_cidflags; /* company-specific flags */ 857 u_int cpu_cidflags; /* company-specific flags */
860 const char *cpu_name; 858 const char *cpu_name;
861}; 859};
862 860
863/* 861/*
864 * bitfield defines for cpu_cp0flags 862 * bitfield defines for cpu_cp0flags
865 */ 863 */
866#define MIPS_CP0FL_USE __BIT(0) /* use these flags */ 864#define MIPS_CP0FL_USE __BIT(0) /* use these flags */
867#define MIPS_CP0FL_ECC __BIT(1) 865#define MIPS_CP0FL_ECC __BIT(1)
868#define MIPS_CP0FL_CACHE_ERR __BIT(2) 866#define MIPS_CP0FL_CACHE_ERR __BIT(2)
869#define MIPS_CP0FL_EIRR __BIT(3) 867#define MIPS_CP0FL_EIRR __BIT(3)
870#define MIPS_CP0FL_EIMR __BIT(4) 868#define MIPS_CP0FL_EIMR __BIT(4)
871#define MIPS_CP0FL_EBASE __BIT(5) /* XXX probeable - shouldn't be hard coded */ 869#define MIPS_CP0FL_EBASE __BIT(5) /* XXX probeable - shouldn't be hard coded */
872#define MIPS_CP0FL_CONFIG __BIT(6) /* XXX defined - doesn't need to be hard coded */ 870#define MIPS_CP0FL_CONFIG __BIT(6) /* XXX defined - doesn't need to be hard coded */
873#define MIPS_CP0FL_CONFIG1 __BIT(7) /* XXX probeable - shouldn't be hard coded */ 871#define MIPS_CP0FL_CONFIG1 __BIT(7) /* XXX probeable - shouldn't be hard coded */
874#define MIPS_CP0FL_CONFIG2 __BIT(8) /* XXX probeable - shouldn't be hard coded */ 872#define MIPS_CP0FL_CONFIG2 __BIT(8) /* XXX probeable - shouldn't be hard coded */
875#define MIPS_CP0FL_CONFIG3 __BIT(9) /* XXX probeable - shouldn't be hard coded */ 873#define MIPS_CP0FL_CONFIG3 __BIT(9) /* XXX probeable - shouldn't be hard coded */
876#define MIPS_CP0FL_CONFIG4 __BIT(10) /* XXX probeable - shouldn't be hard coded */ 874#define MIPS_CP0FL_CONFIG4 __BIT(10) /* XXX probeable - shouldn't be hard coded */
877#define MIPS_CP0FL_CONFIG5 __BIT(11) /* XXX probeable - shouldn't be hard coded */ 875#define MIPS_CP0FL_CONFIG5 __BIT(11) /* XXX probeable - shouldn't be hard coded */
878#define MIPS_CP0FL_CONFIG6 __BIT(12) 876#define MIPS_CP0FL_CONFIG6 __BIT(12)
879#define MIPS_CP0FL_CONFIG7 __BIT(13) 877#define MIPS_CP0FL_CONFIG7 __BIT(13)
880 878
881/* 879/*
882 * cpu_cidflags defines, by company 880 * cpu_cidflags defines, by company
883 */ 881 */
884/* 882/*
885 * RMI company-specific cpu_cidflags 883 * RMI company-specific cpu_cidflags
886 */ 884 */
887#define MIPS_CIDFL_RMI_TYPE __BITS(2,0) 885#define MIPS_CIDFL_RMI_TYPE __BITS(2,0)
888# define CIDFL_RMI_TYPE_XLR 0 886# define CIDFL_RMI_TYPE_XLR 0
889# define CIDFL_RMI_TYPE_XLS 1 887# define CIDFL_RMI_TYPE_XLS 1
890# define CIDFL_RMI_TYPE_XLP 2 888# define CIDFL_RMI_TYPE_XLP 2
891#define MIPS_CIDFL_RMI_THREADS_MASK __BITS(6,3) 889#define MIPS_CIDFL_RMI_THREADS_MASK __BITS(6,3)
892# define MIPS_CIDFL_RMI_THREADS_SHIFT 3 890# define MIPS_CIDFL_RMI_THREADS_SHIFT 3
893#define MIPS_CIDFL_RMI_CORES_MASK __BITS(10,7) 891#define MIPS_CIDFL_RMI_CORES_MASK __BITS(10,7)
894# define MIPS_CIDFL_RMI_CORES_SHIFT 7 892# define MIPS_CIDFL_RMI_CORES_SHIFT 7
895# define LOG2_1 0 893# define LOG2_1 0
896# define LOG2_2 1 894# define LOG2_2 1
897# define LOG2_4 2 895# define LOG2_4 2
898# define LOG2_8 3 896# define LOG2_8 3
899# define MIPS_CIDFL_RMI_CPUS(ncores, nthreads) \ 897# define MIPS_CIDFL_RMI_CPUS(ncores, nthreads) \
900 ((LOG2_ ## ncores << MIPS_CIDFL_RMI_CORES_SHIFT) \ 898 ((LOG2_ ## ncores << MIPS_CIDFL_RMI_CORES_SHIFT) \
901 |(LOG2_ ## nthreads << MIPS_CIDFL_RMI_THREADS_SHIFT)) 899 |(LOG2_ ## nthreads << MIPS_CIDFL_RMI_THREADS_SHIFT))
902# define MIPS_CIDFL_RMI_NTHREADS(cidfl) \ 900# define MIPS_CIDFL_RMI_NTHREADS(cidfl) \
903 (1 << (((cidfl) & MIPS_CIDFL_RMI_THREADS_MASK) \ 901 (1 << (((cidfl) & MIPS_CIDFL_RMI_THREADS_MASK) \
904 >> MIPS_CIDFL_RMI_THREADS_SHIFT)) 902 >> MIPS_CIDFL_RMI_THREADS_SHIFT))
905# define MIPS_CIDFL_RMI_NCORES(cidfl) \ 903# define MIPS_CIDFL_RMI_NCORES(cidfl) \
906 (1 << (((cidfl) & MIPS_CIDFL_RMI_CORES_MASK) \ 904 (1 << (((cidfl) & MIPS_CIDFL_RMI_CORES_MASK) \
907 >> MIPS_CIDFL_RMI_CORES_SHIFT)) 905 >> MIPS_CIDFL_RMI_CORES_SHIFT))
908#define MIPS_CIDFL_RMI_L2SZ_MASK __BITS(14,11) 906#define MIPS_CIDFL_RMI_L2SZ_MASK __BITS(14,11)
909# define MIPS_CIDFL_RMI_L2SZ_SHIFT 11 907# define MIPS_CIDFL_RMI_L2SZ_SHIFT 11
910# define RMI_L2SZ_256KB 0 908# define RMI_L2SZ_256KB 0
911# define RMI_L2SZ_512KB 1 909# define RMI_L2SZ_512KB 1
912# define RMI_L2SZ_1MB 2 910# define RMI_L2SZ_1MB 2
913# define RMI_L2SZ_2MB 3 911# define RMI_L2SZ_2MB 3
914# define RMI_L2SZ_4MB 4 912# define RMI_L2SZ_4MB 4
915# define MIPS_CIDFL_RMI_L2(l2sz) \ 913# define MIPS_CIDFL_RMI_L2(l2sz) \
916 (RMI_L2SZ_ ## l2sz << MIPS_CIDFL_RMI_L2SZ_SHIFT) 914 (RMI_L2SZ_ ## l2sz << MIPS_CIDFL_RMI_L2SZ_SHIFT)
917# define MIPS_CIDFL_RMI_L2SZ(cidfl) \ 915# define MIPS_CIDFL_RMI_L2SZ(cidfl) \
918 ((256*1024) << (((cidfl) & MIPS_CIDFL_RMI_L2SZ_MASK) \ 916 ((256*1024) << (((cidfl) & MIPS_CIDFL_RMI_L2SZ_MASK) \
919 >> MIPS_CIDFL_RMI_L2SZ_SHIFT)) 917 >> MIPS_CIDFL_RMI_L2SZ_SHIFT))
920#endif /* _KERNEL */ 918#endif /* _KERNEL */
921#endif /* !__ASSEMBLER__ */ 919#endif /* !__ASSEMBLER__ */
922 920
923#endif /* _MIPS_LOCORE_H */ 921#endif /* _MIPS_LOCORE_H */

cvs diff -r1.28 -r1.29 src/sys/arch/mips/mips/mips_emul.c (switch to unified diff)

--- src/sys/arch/mips/mips/mips_emul.c 2021/05/27 13:32:54 1.28
+++ src/sys/arch/mips/mips/mips_emul.c 2021/05/27 15:00:02 1.29
@@ -1,1221 +1,1224 @@ @@ -1,1221 +1,1224 @@
1/* $NetBSD: mips_emul.c,v 1.28 2021/05/27 13:32:54 simonb Exp $ */ 1/* $NetBSD: mips_emul.c,v 1.29 2021/05/27 15:00:02 simonb Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999 Shuichiro URATA. All rights reserved. 4 * Copyright (c) 1999 Shuichiro URATA. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products 14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission. 15 * derived from this software without specific prior written permission.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.28 2021/05/27 13:32:54 simonb Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.29 2021/05/27 15:00:02 simonb Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34#include <sys/cpu.h> 34#include <sys/cpu.h>
35#include <sys/proc.h> 35#include <sys/proc.h>
36 36
37#include <mips/locore.h> 37#include <mips/locore.h>
38#include <mips/mips_opcode.h> 38#include <mips/mips_opcode.h>
39 39
40#include <mips/reg.h> 40#include <mips/reg.h>
41#include <mips/regnum.h> /* symbolic register indices */ 41#include <mips/regnum.h> /* symbolic register indices */
42#include <mips/pcb.h> 42#include <mips/pcb.h>
43#include <mips/vmparam.h> /* for VM_MAX_ADDRESS */ 43#include <mips/vmparam.h> /* for VM_MAX_ADDRESS */
44#include <mips/trap.h> 44#include <mips/trap.h>
45 45
46static inline void send_sigsegv(intptr_t, uint32_t, struct trapframe *, 46static inline void send_sigsegv(intptr_t, uint32_t, struct trapframe *,
47 uint32_t); 47 uint32_t);
48static inline void update_pc(struct trapframe *, uint32_t); 48static inline void update_pc(struct trapframe *, uint32_t);
49 49
 50static void mips_emul_ll(uint32_t, struct trapframe *, uint32_t);
 51static void mips_emul_sc(uint32_t, struct trapframe *, uint32_t);
 52
50/* 53/*
51 * MIPS2 LL instruction emulation state 54 * MIPS2 LL instruction emulation state
52 */ 55 */
53struct { 56struct {
54 struct lwp *lwp; 57 struct lwp *lwp;
55 vaddr_t addr; 58 vaddr_t addr;
56 uint32_t value; 59 uint32_t value;
57} llstate; 60} llstate;
58 61
59/* 62/*
60 * Analyse 'next' PC address taking account of branch/jump instructions 63 * Analyse 'next' PC address taking account of branch/jump instructions
61 */ 64 */
62vaddr_t 65vaddr_t
63mips_emul_branch(struct trapframe *tf, vaddr_t instpc, uint32_t fpuCSR, 66mips_emul_branch(struct trapframe *tf, vaddr_t instpc, uint32_t fpuCSR,
64 bool allowNonBranch) 67 bool allowNonBranch)
65{ 68{
66#define BRANCHTARGET(pc, i) (4 + (pc) + ((short)(i).IType.imm << 2)) 69#define BRANCHTARGET(pc, i) (4 + (pc) + ((short)(i).IType.imm << 2))
67 InstFmt inst; 70 InstFmt inst;
68 vaddr_t nextpc; 71 vaddr_t nextpc;
69 72
70 if (instpc < MIPS_KSEG0_START) { 73 if (instpc < MIPS_KSEG0_START) {
71 inst.word = mips_ufetch32((void *)instpc); 74 inst.word = mips_ufetch32((void *)instpc);
72 } else { 75 } else {
73 inst.word = *(uint32_t *)instpc; 76 inst.word = *(uint32_t *)instpc;
74 } 77 }
75 78
76 switch ((int)inst.JType.op) { 79 switch ((int)inst.JType.op) {
77 case OP_SPECIAL: 80 case OP_SPECIAL:
78 if (inst.RType.func == OP_JR || inst.RType.func == OP_JALR) 81 if (inst.RType.func == OP_JR || inst.RType.func == OP_JALR)
79 nextpc = tf->tf_regs[inst.RType.rs]; 82 nextpc = tf->tf_regs[inst.RType.rs];
80 else if (allowNonBranch) 83 else if (allowNonBranch)
81 nextpc = instpc + 4; 84 nextpc = instpc + 4;
82 else 85 else
83 panic("%s: %s instruction %08x at pc 0x%"PRIxVADDR, 86 panic("%s: %s instruction %08x at pc 0x%"PRIxVADDR,
84 __func__, "non-branch", inst.word, instpc); 87 __func__, "non-branch", inst.word, instpc);
85 break; 88 break;
86 89
87 case OP_REGIMM: 90 case OP_REGIMM:
88 switch ((int)inst.IType.rt) { 91 switch ((int)inst.IType.rt) {
89 case OP_BLTZ: 92 case OP_BLTZ:
90 case OP_BLTZAL: 93 case OP_BLTZAL:
91 case OP_BLTZL: /* squashed */ 94 case OP_BLTZL: /* squashed */
92 case OP_BLTZALL: /* squashed */ 95 case OP_BLTZALL: /* squashed */
93 if ((int)(tf->tf_regs[inst.RType.rs]) < 0) 96 if ((int)(tf->tf_regs[inst.RType.rs]) < 0)
94 nextpc = BRANCHTARGET(instpc, inst); 97 nextpc = BRANCHTARGET(instpc, inst);
95 else 98 else
96 nextpc = instpc + 8; 99 nextpc = instpc + 8;
97 break; 100 break;
98 101
99 case OP_BGEZ: 102 case OP_BGEZ:
100 case OP_BGEZAL: 103 case OP_BGEZAL:
101 case OP_BGEZL: /* squashed */ 104 case OP_BGEZL: /* squashed */
102 case OP_BGEZALL: /* squashed */ 105 case OP_BGEZALL: /* squashed */
103 if ((int)(tf->tf_regs[inst.RType.rs]) >= 0) 106 if ((int)(tf->tf_regs[inst.RType.rs]) >= 0)
104 nextpc = BRANCHTARGET(instpc, inst); 107 nextpc = BRANCHTARGET(instpc, inst);
105 else 108 else
106 nextpc = instpc + 8; 109 nextpc = instpc + 8;
107 break; 110 break;
108 111
109 default: 112 default:
110 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR, 113 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
111 __func__, "bad branch", inst.word, instpc); 114 __func__, "bad branch", inst.word, instpc);
112 } 115 }
113 break; 116 break;
114 117
115 case OP_J: 118 case OP_J:
116 case OP_JAL: 119 case OP_JAL:
117 nextpc = (inst.JType.target << 2) | 120 nextpc = (inst.JType.target << 2) |
118 ((intptr_t)instpc & 0xF0000000); 121 ((intptr_t)instpc & 0xF0000000);
119 break; 122 break;
120 123
121 case OP_BEQ: 124 case OP_BEQ:
122 case OP_BEQL: /* squashed */ 125 case OP_BEQL: /* squashed */
123 if (tf->tf_regs[inst.RType.rs] == tf->tf_regs[inst.RType.rt]) 126 if (tf->tf_regs[inst.RType.rs] == tf->tf_regs[inst.RType.rt])
124 nextpc = BRANCHTARGET(instpc, inst); 127 nextpc = BRANCHTARGET(instpc, inst);
125 else 128 else
126 nextpc = instpc + 8; 129 nextpc = instpc + 8;
127 break; 130 break;
128 131
129 case OP_BNE: 132 case OP_BNE:
130 case OP_BNEL: /* squashed */ 133 case OP_BNEL: /* squashed */
131 if (tf->tf_regs[inst.RType.rs] != tf->tf_regs[inst.RType.rt]) 134 if (tf->tf_regs[inst.RType.rs] != tf->tf_regs[inst.RType.rt])
132 nextpc = BRANCHTARGET(instpc, inst); 135 nextpc = BRANCHTARGET(instpc, inst);
133 else 136 else
134 nextpc = instpc + 8; 137 nextpc = instpc + 8;
135 break; 138 break;
136 139
137 case OP_BLEZ: 140 case OP_BLEZ:
138 case OP_BLEZL: /* squashed */ 141 case OP_BLEZL: /* squashed */
139 if ((int)(tf->tf_regs[inst.RType.rs]) <= 0) 142 if ((int)(tf->tf_regs[inst.RType.rs]) <= 0)
140 nextpc = BRANCHTARGET(instpc, inst); 143 nextpc = BRANCHTARGET(instpc, inst);
141 else 144 else
142 nextpc = instpc + 8; 145 nextpc = instpc + 8;
143 break; 146 break;
144 147
145 case OP_BGTZ: 148 case OP_BGTZ:
146 case OP_BGTZL: /* squashed */ 149 case OP_BGTZL: /* squashed */
147 if ((int)(tf->tf_regs[inst.RType.rs]) > 0) 150 if ((int)(tf->tf_regs[inst.RType.rs]) > 0)
148 nextpc = BRANCHTARGET(instpc, inst); 151 nextpc = BRANCHTARGET(instpc, inst);
149 else 152 else
150 nextpc = instpc + 8; 153 nextpc = instpc + 8;
151 break; 154 break;
152 155
153 case OP_COP1: 156 case OP_COP1:
154 if (inst.RType.rs == OP_BCx || inst.RType.rs == OP_BCy) { 157 if (inst.RType.rs == OP_BCx || inst.RType.rs == OP_BCy) {
155 int condition = (fpuCSR & MIPS_FPU_COND_BIT) != 0; 158 int condition = (fpuCSR & MIPS_FPU_COND_BIT) != 0;
156 if ((inst.RType.rt & COPz_BC_TF_MASK) != COPz_BC_TRUE) 159 if ((inst.RType.rt & COPz_BC_TF_MASK) != COPz_BC_TRUE)
157 condition = !condition; 160 condition = !condition;
158 if (condition) 161 if (condition)
159 nextpc = BRANCHTARGET(instpc, inst); 162 nextpc = BRANCHTARGET(instpc, inst);
160 else 163 else
161 nextpc = instpc + 8; 164 nextpc = instpc + 8;
162 } 165 }
163 else if (allowNonBranch) 166 else if (allowNonBranch)
164 nextpc = instpc + 4; 167 nextpc = instpc + 4;
165 else 168 else
166 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR, 169 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
167 __func__, "bad COP1 branch", inst.word, instpc); 170 __func__, "bad COP1 branch", inst.word, instpc);
168 break; 171 break;
169 172
170 default: 173 default:
171 if (!allowNonBranch) 174 if (!allowNonBranch)
172 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR, 175 panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
173 __func__, "non-branch", inst.word, instpc); 176 __func__, "non-branch", inst.word, instpc);
174 nextpc = instpc + 4; 177 nextpc = instpc + 4;
175 } 178 }
176 KASSERT((nextpc & 0x3) == 0); 179 KASSERT((nextpc & 0x3) == 0);
177 return nextpc; 180 return nextpc;
178#undef BRANCHTARGET 181#undef BRANCHTARGET
179} 182}
180 183
181/* 184/*
182 * Emulate instructions (including floating-point instructions) 185 * Emulate instructions (including floating-point instructions)
183 */ 186 */
184void 187void
185mips_emul_inst(uint32_t status, uint32_t cause, vaddr_t opc, 188mips_emul_inst(uint32_t status, uint32_t cause, vaddr_t opc,
186 struct trapframe *tf) 189 struct trapframe *tf)
187{ 190{
188 uint32_t inst; 191 uint32_t inst;
189 ksiginfo_t ksi; 192 ksiginfo_t ksi;
190 int code = ILL_ILLOPC; 193 int code = ILL_ILLOPC;
191 194
192 /* 195 /*
193 * Fetch the instruction. 196 * Fetch the instruction.
194 */ 197 */
195 if (cause & MIPS_CR_BR_DELAY) 198 if (cause & MIPS_CR_BR_DELAY)
196 inst = mips_ufetch32((uint32_t *)opc+1); 199 inst = mips_ufetch32((uint32_t *)opc+1);
197 else 200 else
198 inst = mips_ufetch32((uint32_t *)opc); 201 inst = mips_ufetch32((uint32_t *)opc);
199 202
200 switch (((InstFmt)inst).FRType.op) { 203 switch (((InstFmt)inst).FRType.op) {
201 case OP_LWC0: 204 case OP_LL:
202 mips_emul_lwc0(inst, tf, cause); 205 mips_emul_ll(inst, tf, cause);
203 break; 206 break;
204 case OP_SWC0: 207 case OP_SC:
205 mips_emul_swc0(inst, tf, cause); 208 mips_emul_sc(inst, tf, cause);
206 break; 209 break;
207 case OP_SPECIAL: 210 case OP_SPECIAL:
208 mips_emul_special(inst, tf, cause); 211 mips_emul_special(inst, tf, cause);
209 break; 212 break;
210 case OP_SPECIAL3: 213 case OP_SPECIAL3:
211 mips_emul_special3(inst, tf, cause); 214 mips_emul_special3(inst, tf, cause);
212 break; 215 break;
213 case OP_COP1: 216 case OP_COP1:
214#if defined(FPEMUL) 217#if defined(FPEMUL)
215 mips_emul_fp(inst, tf, cause); 218 mips_emul_fp(inst, tf, cause);
216 break; 219 break;
217#endif 220#endif
218 case OP_LWC1: 221 case OP_LWC1:
219#if defined(FPEMUL) 222#if defined(FPEMUL)
220 mips_emul_lwc1(inst, tf, cause); 223 mips_emul_lwc1(inst, tf, cause);
221 break; 224 break;
222#endif 225#endif
223 case OP_LDC1: 226 case OP_LDC1:
224#if defined(FPEMUL) 227#if defined(FPEMUL)
225 mips_emul_ldc1(inst, tf, cause); 228 mips_emul_ldc1(inst, tf, cause);
226 break; 229 break;
227#endif 230#endif
228 case OP_SWC1: 231 case OP_SWC1:
229#if defined(FPEMUL) 232#if defined(FPEMUL)
230 mips_emul_swc1(inst, tf, cause); 233 mips_emul_swc1(inst, tf, cause);
231 break; 234 break;
232#endif 235#endif
233 case OP_SDC1: 236 case OP_SDC1:
234#if defined(FPEMUL) 237#if defined(FPEMUL)
235 mips_emul_sdc1(inst, tf, cause); 238 mips_emul_sdc1(inst, tf, cause);
236 break; 239 break;
237#else 240#else
238 code = ILL_COPROC; 241 code = ILL_COPROC;
239 /* FALLTHROUGH */ 242 /* FALLTHROUGH */
240#endif 243#endif
241 default: 244 default:
242#ifdef DEBUG 245#ifdef DEBUG
243 printf("pid %d (%s): trap: bad insn @ %#"PRIxVADDR 246 printf("pid %d (%s): trap: bad insn @ %#"PRIxVADDR
244 " cause %#x status %#"PRIxREGISTER" insn %#x code %d\n", 247 " cause %#x status %#"PRIxREGISTER" insn %#x code %d\n",
245 curproc->p_pid, curproc->p_comm, opc, 248 curproc->p_pid, curproc->p_comm, opc,
246 cause, tf->tf_regs[_R_SR], inst, code); 249 cause, tf->tf_regs[_R_SR], inst, code);
247#endif 250#endif
248 tf->tf_regs[_R_CAUSE] = cause; 251 tf->tf_regs[_R_CAUSE] = cause;
249 tf->tf_regs[_R_BADVADDR] = opc; 252 tf->tf_regs[_R_BADVADDR] = opc;
250 KSI_INIT_TRAP(&ksi); 253 KSI_INIT_TRAP(&ksi);
251 ksi.ksi_signo = SIGILL; 254 ksi.ksi_signo = SIGILL;
252 ksi.ksi_trap = cause; /* XXX */ 255 ksi.ksi_trap = cause; /* XXX */
253 ksi.ksi_code = code; 256 ksi.ksi_code = code;
254 ksi.ksi_addr = (void *)opc; 257 ksi.ksi_addr = (void *)opc;
255 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi); 258 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
256 break; 259 break;
257 } 260 }
258} 261}
259 262
260static inline void 263static inline void
261send_sigsegv(intptr_t vaddr, uint32_t exccode, struct trapframe *tf, 264send_sigsegv(intptr_t vaddr, uint32_t exccode, struct trapframe *tf,
262 uint32_t cause) 265 uint32_t cause)
263{ 266{
264 ksiginfo_t ksi; 267 ksiginfo_t ksi;
265 cause = (cause & ~0xFF) | (exccode << MIPS_CR_EXC_CODE_SHIFT); 268 cause = (cause & ~0xFF) | (exccode << MIPS_CR_EXC_CODE_SHIFT);
266 tf->tf_regs[_R_CAUSE] = cause; 269 tf->tf_regs[_R_CAUSE] = cause;
267 tf->tf_regs[_R_BADVADDR] = vaddr; 270 tf->tf_regs[_R_BADVADDR] = vaddr;
268 KSI_INIT_TRAP(&ksi); 271 KSI_INIT_TRAP(&ksi);
269 ksi.ksi_signo = SIGSEGV; 272 ksi.ksi_signo = SIGSEGV;
270 ksi.ksi_trap = cause; 273 ksi.ksi_trap = cause;
271 ksi.ksi_code = SEGV_MAPERR; 274 ksi.ksi_code = SEGV_MAPERR;
272 ksi.ksi_addr = (void *)vaddr; 275 ksi.ksi_addr = (void *)vaddr;
273 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi); 276 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
274} 277}
275 278
276static inline void 279static inline void
277update_pc(struct trapframe *tf, uint32_t cause) 280update_pc(struct trapframe *tf, uint32_t cause)
278{ 281{
279 282
280 if (cause & MIPS_CR_BR_DELAY) 283 if (cause & MIPS_CR_BR_DELAY)
281 tf->tf_regs[_R_PC] =  284 tf->tf_regs[_R_PC] =
282 mips_emul_branch(tf, tf->tf_regs[_R_PC], 285 mips_emul_branch(tf, tf->tf_regs[_R_PC],
283 PCB_FSR(curpcb), 0); 286 PCB_FSR(curpcb), 0);
284 else 287 else
285 tf->tf_regs[_R_PC] += 4; 288 tf->tf_regs[_R_PC] += 4;
286} 289}
287 290
288/* 291/*
289 * MIPS2 LL instruction 292 * MIPS2 LL instruction
290 */ 293 */
291void 294void
292mips_emul_lwc0(uint32_t inst, struct trapframe *tf, uint32_t cause) 295mips_emul_ll(uint32_t inst, struct trapframe *tf, uint32_t cause)
293{ 296{
294 intptr_t vaddr; 297 intptr_t vaddr;
295 int16_t offset; 298 int16_t offset;
296 void *t; 299 void *t;
297 300
298 offset = inst & 0xFFFF; 301 offset = inst & 0xFFFF;
299 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 302 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
300 303
301 /* segment and alignment check */ 304 /* segment and alignment check */
302 if (vaddr < 0 || (vaddr & 3)) { 305 if (vaddr < 0 || (vaddr & 3)) {
303 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 306 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
304 return; 307 return;
305 } 308 }
306 309
307 t = &(tf->tf_regs[(inst>>16)&0x1F]); 310 t = &(tf->tf_regs[(inst>>16)&0x1F]);
308 311
309 if (copyin((void *)vaddr, t, 4) != 0) { 312 if (copyin((void *)vaddr, t, 4) != 0) {
310 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 313 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
311 return; 314 return;
312 } 315 }
313 316
314 llstate.lwp = curlwp; 317 llstate.lwp = curlwp;
315 llstate.addr = vaddr; 318 llstate.addr = vaddr;
316 llstate.value = *((uint32_t *)t); 319 llstate.value = *((uint32_t *)t);
317 320
318 update_pc(tf, cause); 321 update_pc(tf, cause);
319} 322}
320 323
321/* 324/*
322 * MIPS2 SC instruction 325 * MIPS2 SC instruction
323 */ 326 */
324void 327void
325mips_emul_swc0(uint32_t inst, struct trapframe *tf, uint32_t cause) 328mips_emul_sc(uint32_t inst, struct trapframe *tf, uint32_t cause)
326{ 329{
327 intptr_t vaddr; 330 intptr_t vaddr;
328 uint32_t value; 331 uint32_t value;
329 int16_t offset; 332 int16_t offset;
330 mips_reg_t *t; 333 mips_reg_t *t;
331 334
332 offset = inst & 0xFFFF; 335 offset = inst & 0xFFFF;
333 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 336 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
334 337
335 /* segment and alignment check */ 338 /* segment and alignment check */
336 if (vaddr < 0 || (vaddr & 3)) { 339 if (vaddr < 0 || (vaddr & 3)) {
337 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 340 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
338 return; 341 return;
339 } 342 }
340 343
341 t = (mips_reg_t *)&(tf->tf_regs[(inst>>16)&0x1F]); 344 t = (mips_reg_t *)&(tf->tf_regs[(inst>>16)&0x1F]);
342 345
343 /* 346 /*
344 * Check that the process and address match the last 347 * Check that the process and address match the last
345 * LL instruction. 348 * LL instruction.
346 */ 349 */
347 if (curlwp == llstate.lwp && vaddr == llstate.addr) { 350 if (curlwp == llstate.lwp && vaddr == llstate.addr) {
348 llstate.lwp = NULL; 351 llstate.lwp = NULL;
349 /* 352 /*
350 * Check that the data at the address hasn't changed 353 * Check that the data at the address hasn't changed
351 * since the LL instruction. 354 * since the LL instruction.
352 */ 355 */
353 if (copyin((void *)vaddr, &value, 4) != 0) { 356 if (copyin((void *)vaddr, &value, 4) != 0) {
354 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 357 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
355 return; 358 return;
356 } 359 }
357 if (value == llstate.value) { 360 if (value == llstate.value) {
358 /* SC successful */ 361 /* SC successful */
359 if (copyout(t, (void *)vaddr, 4) != 0) { 362 if (copyout(t, (void *)vaddr, 4) != 0) {
360 send_sigsegv(vaddr, T_TLB_ST_MISS, 363 send_sigsegv(vaddr, T_TLB_ST_MISS,
361 tf, cause); 364 tf, cause);
362 return; 365 return;
363 } 366 }
364 *t = 1; 367 *t = 1;
365 update_pc(tf, cause); 368 update_pc(tf, cause);
366 return; 369 return;
367 } 370 }
368 } 371 }
369 372
370 /* SC failed */ 373 /* SC failed */
371 *t = 0; 374 *t = 0;
372 update_pc(tf, cause); 375 update_pc(tf, cause);
373} 376}
374 377
375void 378void
376mips_emul_special(uint32_t inst, struct trapframe *tf, uint32_t cause) 379mips_emul_special(uint32_t inst, struct trapframe *tf, uint32_t cause)
377{ 380{
378 ksiginfo_t ksi; 381 ksiginfo_t ksi;
379 const InstFmt instfmt = { .word = inst }; 382 const InstFmt instfmt = { .word = inst };
380 383
381 switch (instfmt.RType.func) { 384 switch (instfmt.RType.func) {
382 case OP_SYNC: 385 case OP_SYNC:
383 /* nothing */ 386 /* nothing */
384 break; 387 break;
385 default: 388 default:
386 tf->tf_regs[_R_CAUSE] = cause; 389 tf->tf_regs[_R_CAUSE] = cause;
387 tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC]; 390 tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];
388 KSI_INIT_TRAP(&ksi); 391 KSI_INIT_TRAP(&ksi);
389 ksi.ksi_signo = SIGILL; 392 ksi.ksi_signo = SIGILL;
390 ksi.ksi_trap = cause; 393 ksi.ksi_trap = cause;
391 ksi.ksi_code = ILL_ILLOPC; 394 ksi.ksi_code = ILL_ILLOPC;
392 ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC]; 395 ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC];
393 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi); 396 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
394 break; 397 break;
395 } 398 }
396 399
397 update_pc(tf, cause); 400 update_pc(tf, cause);
398} 401}
399 402
400void 403void
401mips_emul_special3(uint32_t inst, struct trapframe *tf, uint32_t cause) 404mips_emul_special3(uint32_t inst, struct trapframe *tf, uint32_t cause)
402{ 405{
403 ksiginfo_t ksi; 406 ksiginfo_t ksi;
404 const InstFmt instfmt = { .word = inst }; 407 const InstFmt instfmt = { .word = inst };
405 switch (instfmt.RType.func) { 408 switch (instfmt.RType.func) {
406 case OP_LX: { 409 case OP_LX: {
407 const intptr_t vaddr = tf->tf_regs[instfmt.RType.rs]  410 const intptr_t vaddr = tf->tf_regs[instfmt.RType.rs]
408 + tf->tf_regs[instfmt.RType.rt]; 411 + tf->tf_regs[instfmt.RType.rt];
409 mips_reg_t r; 412 mips_reg_t r;
410 int error = EFAULT; 413 int error = EFAULT;
411 if (vaddr < 0) { 414 if (vaddr < 0) {
412 addr_err: 415 addr_err:
413 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 416 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
414 return; 417 return;
415 } 418 }
416 switch (instfmt.RType.shamt) { 419 switch (instfmt.RType.shamt) {
417#if !defined(__mips_o32) 420#if !defined(__mips_o32)
418 case OP_LX_LDX: { 421 case OP_LX_LDX: {
419 uint64_t tmp64; 422 uint64_t tmp64;
420 if (vaddr & 7) 423 if (vaddr & 7)
421 goto addr_err; 424 goto addr_err;
422 error = copyin((void *)vaddr, &tmp64, sizeof(tmp64)); 425 error = copyin((void *)vaddr, &tmp64, sizeof(tmp64));
423 r = tmp64; 426 r = tmp64;
424 break; 427 break;
425 } 428 }
426#endif 429#endif
427 case OP_LX_LWX: { 430 case OP_LX_LWX: {
428 int32_t tmp32; 431 int32_t tmp32;
429 if (vaddr & 3) 432 if (vaddr & 3)
430 goto addr_err; 433 goto addr_err;
431 error = copyin((void *)vaddr, &tmp32, sizeof(tmp32)); 434 error = copyin((void *)vaddr, &tmp32, sizeof(tmp32));
432 r = tmp32; 435 r = tmp32;
433 break; 436 break;
434 } 437 }
435 case OP_LX_LHX: { 438 case OP_LX_LHX: {
436 int16_t tmp16; 439 int16_t tmp16;
437 if (vaddr & 1) 440 if (vaddr & 1)
438 goto addr_err; 441 goto addr_err;
439 error = copyin((void *)vaddr, &tmp16, sizeof(tmp16)); 442 error = copyin((void *)vaddr, &tmp16, sizeof(tmp16));
440 r = tmp16; 443 r = tmp16;
441 break; 444 break;
442 } 445 }
443 case OP_LX_LBUX: { 446 case OP_LX_LBUX: {
444 uint8_t tmp8; 447 uint8_t tmp8;
445 error = copyin((void *)vaddr, &tmp8, sizeof(tmp8)); 448 error = copyin((void *)vaddr, &tmp8, sizeof(tmp8));
446 r = tmp8; 449 r = tmp8;
447 break; 450 break;
448 } 451 }
449 default: 452 default:
450 goto illopc; 453 goto illopc;
451 } 454 }
452 if (error) { 455 if (error) {
453 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 456 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
454 return; 457 return;
455 } 458 }
456 tf->tf_regs[instfmt.RType.rd] = r; 459 tf->tf_regs[instfmt.RType.rd] = r;
457 break; 460 break;
458 } 461 }
459 case OP_RDHWR: 462 case OP_RDHWR:
460 switch (instfmt.RType.rd) { 463 switch (instfmt.RType.rd) {
461 case 29: 464 case 29:
462 tf->tf_regs[instfmt.RType.rt] = 465 tf->tf_regs[instfmt.RType.rt] =
463 (mips_reg_t)(intptr_t)curlwp->l_private; 466 (mips_reg_t)(intptr_t)curlwp->l_private;
464 goto done; 467 goto done;
465 } 468 }
466 /* FALLTHROUGH */ 469 /* FALLTHROUGH */
467 illopc: 470 illopc:
468 default: 471 default:
469 tf->tf_regs[_R_CAUSE] = cause; 472 tf->tf_regs[_R_CAUSE] = cause;
470 tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC]; 473 tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];
471 KSI_INIT_TRAP(&ksi); 474 KSI_INIT_TRAP(&ksi);
472 ksi.ksi_signo = SIGILL; 475 ksi.ksi_signo = SIGILL;
473 ksi.ksi_trap = cause; 476 ksi.ksi_trap = cause;
474 ksi.ksi_code = ILL_ILLOPC; 477 ksi.ksi_code = ILL_ILLOPC;
475 ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC]; 478 ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC];
476 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi); 479 (*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
477 return; 480 return;
478 } 481 }
479done: 482done:
480 update_pc(tf, cause); 483 update_pc(tf, cause);
481} 484}
482 485
483#if defined(FPEMUL) 486#if defined(FPEMUL)
484 487
485#define LWSWC1_MAXLOOP 12 488#define LWSWC1_MAXLOOP 12
486 489
487void 490void
488mips_emul_lwc1(uint32_t inst, struct trapframe *tf, uint32_t cause) 491mips_emul_lwc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
489{ 492{
490 intptr_t vaddr; 493 intptr_t vaddr;
491 int16_t offset; 494 int16_t offset;
492 void *t; 495 void *t;
493 mips_reg_t pc; 496 mips_reg_t pc;
494 int i; 497 int i;
495 498
496 offset = inst & 0xFFFF; 499 offset = inst & 0xFFFF;
497 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 500 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
498 501
499 /* segment and alignment check */ 502 /* segment and alignment check */
500 if (vaddr < 0 || (vaddr & 3)) { 503 if (vaddr < 0 || (vaddr & 3)) {
501 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 504 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
502 return; 505 return;
503 } 506 }
504 507
505 /* NewABI FIXME */ 508 /* NewABI FIXME */
506 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]); 509 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
507 510
508 if (copyin((void *)vaddr, t, 4) != 0) { 511 if (copyin((void *)vaddr, t, 4) != 0) {
509 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 512 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
510 return; 513 return;
511 } 514 }
512 515
513 pc = tf->tf_regs[_R_PC]; 516 pc = tf->tf_regs[_R_PC];
514 update_pc(tf, cause); 517 update_pc(tf, cause);
515 518
516 if (cause & MIPS_CR_BR_DELAY) 519 if (cause & MIPS_CR_BR_DELAY)
517 return; 520 return;
518 521
519 for (i = 1; i < LWSWC1_MAXLOOP; i++) { 522 for (i = 1; i < LWSWC1_MAXLOOP; i++) {
520 if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc)) 523 if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc))
521 return; 524 return;
522 525
523 vaddr = tf->tf_regs[_R_PC]; /* XXX truncates to 32 bits */ 526 vaddr = tf->tf_regs[_R_PC]; /* XXX truncates to 32 bits */
524 inst = mips_ufetch32((uint32_t *)vaddr); 527 inst = mips_ufetch32((uint32_t *)vaddr);
525 if (((InstFmt)inst).FRType.op != OP_LWC1) 528 if (((InstFmt)inst).FRType.op != OP_LWC1)
526 return; 529 return;
527 530
528 offset = inst & 0xFFFF; 531 offset = inst & 0xFFFF;
529 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 532 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
530 533
531 /* segment and alignment check */ 534 /* segment and alignment check */
532 if (vaddr < 0 || (vaddr & 3)) { 535 if (vaddr < 0 || (vaddr & 3)) {
533 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 536 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
534 return; 537 return;
535 } 538 }
536 539
537 /* NewABI FIXME */ 540 /* NewABI FIXME */
538 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]); 541 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
539 542
540 if (copyin((void *)vaddr, t, 4) != 0) { 543 if (copyin((void *)vaddr, t, 4) != 0) {
541 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 544 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
542 return; 545 return;
543 } 546 }
544 547
545 pc = tf->tf_regs[_R_PC]; 548 pc = tf->tf_regs[_R_PC];
546 update_pc(tf, cause); 549 update_pc(tf, cause);
547 } 550 }
548} 551}
549 552
550void 553void
551mips_emul_ldc1(uint32_t inst, struct trapframe *tf, uint32_t cause) 554mips_emul_ldc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
552{ 555{
553 intptr_t vaddr; 556 intptr_t vaddr;
554 int16_t offset; 557 int16_t offset;
555 void *t; 558 void *t;
556 559
557 offset = inst & 0xFFFF; 560 offset = inst & 0xFFFF;
558 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 561 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
559 562
560 /* segment and alignment check */ 563 /* segment and alignment check */
561 if (vaddr < 0 || (vaddr & 7)) { 564 if (vaddr < 0 || (vaddr & 7)) {
562 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 565 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
563 return; 566 return;
564 } 567 }
565 568
566 /* NewABI FIXME */ 569 /* NewABI FIXME */
567 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]); 570 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]);
568 571
569 if (copyin((void *)vaddr, t, 8) != 0) { 572 if (copyin((void *)vaddr, t, 8) != 0) {
570 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 573 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
571 return; 574 return;
572 } 575 }
573 576
574 update_pc(tf, cause); 577 update_pc(tf, cause);
575} 578}
576 579
577void 580void
578mips_emul_swc1(uint32_t inst, struct trapframe *tf, uint32_t cause) 581mips_emul_swc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
579{ 582{
580 intptr_t vaddr; 583 intptr_t vaddr;
581 int16_t offset; 584 int16_t offset;
582 void *t; 585 void *t;
583 mips_reg_t pc; 586 mips_reg_t pc;
584 int i; 587 int i;
585 588
586 offset = inst & 0xFFFF; 589 offset = inst & 0xFFFF;
587 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 590 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
588 591
589 /* segment and alignment check */ 592 /* segment and alignment check */
590 if (vaddr < 0 || (vaddr & 3)) { 593 if (vaddr < 0 || (vaddr & 3)) {
591 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 594 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
592 return; 595 return;
593 } 596 }
594 597
595 /* NewABI FIXME */ 598 /* NewABI FIXME */
596 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]); 599 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
597 600
598 if (copyout(t, (void *)vaddr, 4) != 0) { 601 if (copyout(t, (void *)vaddr, 4) != 0) {
599 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 602 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
600 return; 603 return;
601 } 604 }
602 605
603 pc = tf->tf_regs[_R_PC]; 606 pc = tf->tf_regs[_R_PC];
604 update_pc(tf, cause); 607 update_pc(tf, cause);
605 608
606 if (cause & MIPS_CR_BR_DELAY) 609 if (cause & MIPS_CR_BR_DELAY)
607 return; 610 return;
608 611
609 for (i = 1; i < LWSWC1_MAXLOOP; i++) { 612 for (i = 1; i < LWSWC1_MAXLOOP; i++) {
610 if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc)) 613 if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc))
611 return; 614 return;
612 615
613 vaddr = tf->tf_regs[_R_PC]; /* XXX truncates to 32 bits */ 616 vaddr = tf->tf_regs[_R_PC]; /* XXX truncates to 32 bits */
614 inst = mips_ufetch32((uint32_t *)vaddr); 617 inst = mips_ufetch32((uint32_t *)vaddr);
615 if (((InstFmt)inst).FRType.op != OP_SWC1) 618 if (((InstFmt)inst).FRType.op != OP_SWC1)
616 return; 619 return;
617 620
618 offset = inst & 0xFFFF; 621 offset = inst & 0xFFFF;
619 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 622 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
620 623
621 /* segment and alignment check */ 624 /* segment and alignment check */
622 if (vaddr < 0 || (vaddr & 3)) { 625 if (vaddr < 0 || (vaddr & 3)) {
623 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 626 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
624 return; 627 return;
625 } 628 }
626 629
627 /* NewABI FIXME */ 630 /* NewABI FIXME */
628 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]); 631 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
629 632
630 if (copyout(t, (void *)vaddr, 4) != 0) { 633 if (copyout(t, (void *)vaddr, 4) != 0) {
631 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 634 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
632 return; 635 return;
633 } 636 }
634 637
635 pc = tf->tf_regs[_R_PC]; 638 pc = tf->tf_regs[_R_PC];
636 update_pc(tf, cause); 639 update_pc(tf, cause);
637 } 640 }
638} 641}
639 642
640void 643void
641mips_emul_sdc1(uint32_t inst, struct trapframe *tf, uint32_t cause) 644mips_emul_sdc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
642{ 645{
643 intptr_t vaddr; 646 intptr_t vaddr;
644 int16_t offset; 647 int16_t offset;
645 void *t; 648 void *t;
646 649
647 offset = inst & 0xFFFF; 650 offset = inst & 0xFFFF;
648 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 651 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
649 652
650 /* segment and alignment check */ 653 /* segment and alignment check */
651 if (vaddr < 0 || (vaddr & 7)) { 654 if (vaddr < 0 || (vaddr & 7)) {
652 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 655 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
653 return; 656 return;
654 } 657 }
655 658
656 /* NewABI FIXME */ 659 /* NewABI FIXME */
657 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]); 660 t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]);
658 661
659 if (copyout(t, (void *)vaddr, 8) != 0) { 662 if (copyout(t, (void *)vaddr, 8) != 0) {
660 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 663 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
661 return; 664 return;
662 } 665 }
663 666
664 update_pc(tf, cause); 667 update_pc(tf, cause);
665} 668}
666 669
667void 670void
668mips_emul_lb(uint32_t inst, struct trapframe *tf, uint32_t cause) 671mips_emul_lb(uint32_t inst, struct trapframe *tf, uint32_t cause)
669{ 672{
670 intptr_t vaddr; 673 intptr_t vaddr;
671 int16_t offset; 674 int16_t offset;
672 int8_t x; 675 int8_t x;
673 676
674 offset = inst & 0xFFFF; 677 offset = inst & 0xFFFF;
675 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 678 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
676 679
677 /* segment check */ 680 /* segment check */
678 if (vaddr < 0) { 681 if (vaddr < 0) {
679 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 682 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
680 return; 683 return;
681 } 684 }
682 685
683 if (copyin((void *)vaddr, &x, 1) != 0) { 686 if (copyin((void *)vaddr, &x, 1) != 0) {
684 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 687 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
685 return; 688 return;
686 } 689 }
687 690
688 tf->tf_regs[(inst>>16)&0x1F] = x; 691 tf->tf_regs[(inst>>16)&0x1F] = x;
689 692
690 update_pc(tf, cause); 693 update_pc(tf, cause);
691} 694}
692 695
693void 696void
694mips_emul_lbu(uint32_t inst, struct trapframe *tf, uint32_t cause) 697mips_emul_lbu(uint32_t inst, struct trapframe *tf, uint32_t cause)
695{ 698{
696 intptr_t vaddr; 699 intptr_t vaddr;
697 int16_t offset; 700 int16_t offset;
698 uint8_t x; 701 uint8_t x;
699 702
700 offset = inst & 0xFFFF; 703 offset = inst & 0xFFFF;
701 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 704 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
702 705
703 /* segment check */ 706 /* segment check */
704 if (vaddr < 0) { 707 if (vaddr < 0) {
705 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 708 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
706 return; 709 return;
707 } 710 }
708 711
709 if (copyin((void *)vaddr, &x, 1) != 0) { 712 if (copyin((void *)vaddr, &x, 1) != 0) {
710 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 713 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
711 return; 714 return;
712 } 715 }
713 716
714 tf->tf_regs[(inst>>16)&0x1F] = x; 717 tf->tf_regs[(inst>>16)&0x1F] = x;
715 718
716 update_pc(tf, cause); 719 update_pc(tf, cause);
717} 720}
718 721
719void 722void
720mips_emul_lh(uint32_t inst, struct trapframe *tf, uint32_t cause) 723mips_emul_lh(uint32_t inst, struct trapframe *tf, uint32_t cause)
721{ 724{
722 intptr_t vaddr; 725 intptr_t vaddr;
723 int16_t offset; 726 int16_t offset;
724 int16_t x; 727 int16_t x;
725 728
726 offset = inst & 0xFFFF; 729 offset = inst & 0xFFFF;
727 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 730 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
728 731
729 /* segment and alignment check */ 732 /* segment and alignment check */
730 if (vaddr < 0 || (vaddr & 1)) { 733 if (vaddr < 0 || (vaddr & 1)) {
731 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 734 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
732 return; 735 return;
733 } 736 }
734 737
735 if (copyin((void *)vaddr, &x, 2) != 0) { 738 if (copyin((void *)vaddr, &x, 2) != 0) {
736 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 739 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
737 return; 740 return;
738 } 741 }
739 742
740 tf->tf_regs[(inst>>16)&0x1F] = x; 743 tf->tf_regs[(inst>>16)&0x1F] = x;
741 744
742 update_pc(tf, cause); 745 update_pc(tf, cause);
743} 746}
744 747
745void 748void
746mips_emul_lhu(uint32_t inst, struct trapframe *tf, uint32_t cause) 749mips_emul_lhu(uint32_t inst, struct trapframe *tf, uint32_t cause)
747{ 750{
748 intptr_t vaddr; 751 intptr_t vaddr;
749 int16_t offset; 752 int16_t offset;
750 uint16_t x; 753 uint16_t x;
751 754
752 offset = inst & 0xFFFF; 755 offset = inst & 0xFFFF;
753 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 756 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
754 757
755 /* segment and alignment check */ 758 /* segment and alignment check */
756 if (vaddr < 0 || (vaddr & 1)) { 759 if (vaddr < 0 || (vaddr & 1)) {
757 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 760 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
758 return; 761 return;
759 } 762 }
760 763
761 if (copyin((void *)vaddr, &x, 2) != 0) { 764 if (copyin((void *)vaddr, &x, 2) != 0) {
762 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 765 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
763 return; 766 return;
764 } 767 }
765 768
766 tf->tf_regs[(inst>>16)&0x1F] = (mips_ureg_t)x; 769 tf->tf_regs[(inst>>16)&0x1F] = (mips_ureg_t)x;
767 770
768 update_pc(tf, cause); 771 update_pc(tf, cause);
769} 772}
770 773
771void 774void
772mips_emul_lw(uint32_t inst, struct trapframe *tf, uint32_t cause) 775mips_emul_lw(uint32_t inst, struct trapframe *tf, uint32_t cause)
773{ 776{
774 intptr_t vaddr; 777 intptr_t vaddr;
775 int16_t offset; 778 int16_t offset;
776 int32_t x; 779 int32_t x;
777 780
778 offset = inst & 0xFFFF; 781 offset = inst & 0xFFFF;
779 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 782 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
780 783
781 /* segment and alignment check */ 784 /* segment and alignment check */
782 if (vaddr < 0 || (vaddr & 3)) { 785 if (vaddr < 0 || (vaddr & 3)) {
783 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 786 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
784 return; 787 return;
785 } 788 }
786 789
787 if (copyin((void *)vaddr, &x, 4) != 0) { 790 if (copyin((void *)vaddr, &x, 4) != 0) {
788 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 791 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
789 return; 792 return;
790 } 793 }
791 794
792 tf->tf_regs[(inst>>16)&0x1F] = x; 795 tf->tf_regs[(inst>>16)&0x1F] = x;
793 796
794 update_pc(tf, cause); 797 update_pc(tf, cause);
795} 798}
796 799
797void 800void
798mips_emul_lwl(uint32_t inst, struct trapframe *tf, uint32_t cause) 801mips_emul_lwl(uint32_t inst, struct trapframe *tf, uint32_t cause)
799{ 802{
800 intptr_t vaddr; 803 intptr_t vaddr;
801 uint32_t a, x, shift; 804 uint32_t a, x, shift;
802 int16_t offset; 805 int16_t offset;
803 806
804 offset = inst & 0xFFFF; 807 offset = inst & 0xFFFF;
805 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 808 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
806 809
807 /* segment check */ 810 /* segment check */
808 if (vaddr < 0) { 811 if (vaddr < 0) {
809 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 812 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
810 return; 813 return;
811 } 814 }
812 815
813 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) { 816 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
814 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 817 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
815 return; 818 return;
816 } 819 }
817 820
818 x = tf->tf_regs[(inst>>16)&0x1F]; 821 x = tf->tf_regs[(inst>>16)&0x1F];
819 822
820 shift = (3 - (vaddr & 0x00000003)) * 8; 823 shift = (3 - (vaddr & 0x00000003)) * 8;
821 a <<= shift; 824 a <<= shift;
822 x &= ~(0xFFFFFFFFUL << shift); 825 x &= ~(0xFFFFFFFFUL << shift);
823 x |= a; 826 x |= a;
824 827
825 tf->tf_regs[(inst>>16)&0x1F] = x; 828 tf->tf_regs[(inst>>16)&0x1F] = x;
826 829
827 update_pc(tf, cause); 830 update_pc(tf, cause);
828} 831}
829 832
830void 833void
831mips_emul_lwr(uint32_t inst, struct trapframe *tf, uint32_t cause) 834mips_emul_lwr(uint32_t inst, struct trapframe *tf, uint32_t cause)
832{ 835{
833 intptr_t vaddr; 836 intptr_t vaddr;
834 uint32_t a, x, shift; 837 uint32_t a, x, shift;
835 int16_t offset; 838 int16_t offset;
836 839
837 offset = inst & 0xFFFF; 840 offset = inst & 0xFFFF;
838 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 841 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
839 842
840 /* segment check */ 843 /* segment check */
841 if (vaddr & 0x80000000) { 844 if (vaddr & 0x80000000) {
842 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 845 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
843 return; 846 return;
844 } 847 }
845 848
846 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) { 849 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
847 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 850 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
848 return; 851 return;
849 } 852 }
850 853
851 x = tf->tf_regs[(inst>>16)&0x1F]; 854 x = tf->tf_regs[(inst>>16)&0x1F];
852 855
853 shift = (vaddr & 0x00000003) * 8; 856 shift = (vaddr & 0x00000003) * 8;
854 a >>= shift; 857 a >>= shift;
855 x &= ~(0xFFFFFFFFUL >> shift); 858 x &= ~(0xFFFFFFFFUL >> shift);
856 x |= a; 859 x |= a;
857 860
858 tf->tf_regs[(inst>>16)&0x1F] = x; 861 tf->tf_regs[(inst>>16)&0x1F] = x;
859 862
860 update_pc(tf, cause); 863 update_pc(tf, cause);
861} 864}
862 865
863#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) 866#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
864void 867void
865mips_emul_lwu(uint32_t inst, struct trapframe *tf, uint32_t cause) 868mips_emul_lwu(uint32_t inst, struct trapframe *tf, uint32_t cause)
866{ 869{
867 intptr_t vaddr; 870 intptr_t vaddr;
868 int16_t offset; 871 int16_t offset;
869 uint32_t x; 872 uint32_t x;
870 873
871 offset = inst & 0xFFFF; 874 offset = inst & 0xFFFF;
872 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 875 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
873 876
874 /* segment and alignment check */ 877 /* segment and alignment check */
875 if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) { 878 if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
876 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 879 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
877 return; 880 return;
878 } 881 }
879 882
880 if (copyin((void *)vaddr, &x, 4) != 0) { 883 if (copyin((void *)vaddr, &x, 4) != 0) {
881 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 884 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
882 return; 885 return;
883 } 886 }
884 887
885 tf->tf_regs[(inst>>16)&0x1F] = x; 888 tf->tf_regs[(inst>>16)&0x1F] = x;
886 889
887 update_pc(tf, cause); 890 update_pc(tf, cause);
888} 891}
889 892
890void 893void
891mips_emul_ld(uint32_t inst, struct trapframe *tf, uint32_t cause) 894mips_emul_ld(uint32_t inst, struct trapframe *tf, uint32_t cause)
892{ 895{
893 intptr_t vaddr; 896 intptr_t vaddr;
894 int16_t offset; 897 int16_t offset;
895 898
896 offset = inst & 0xFFFF; 899 offset = inst & 0xFFFF;
897 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 900 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
898 901
899 /* segment and alignment check */ 902 /* segment and alignment check */
900 if (vaddr > VM_MAX_ADDRESS || vaddr & 0x7) { 903 if (vaddr > VM_MAX_ADDRESS || vaddr & 0x7) {
901 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 904 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
902 return; 905 return;
903 } 906 }
904 907
905 if (copyin((void *)vaddr, &(tf->tf_regs[(inst>>16)&0x1F]), 8) != 0) { 908 if (copyin((void *)vaddr, &(tf->tf_regs[(inst>>16)&0x1F]), 8) != 0) {
906 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 909 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
907 return; 910 return;
908 } 911 }
909 912
910 update_pc(tf, cause); 913 update_pc(tf, cause);
911} 914}
912 915
913void 916void
914mips_emul_ldl(uint32_t inst, struct trapframe *tf, uint32_t cause) 917mips_emul_ldl(uint32_t inst, struct trapframe *tf, uint32_t cause)
915{ 918{
916 intptr_t vaddr; 919 intptr_t vaddr;
917 uint64_t a, x; 920 uint64_t a, x;
918 uint32_t shift; 921 uint32_t shift;
919 int16_t offset; 922 int16_t offset;
920 923
921 offset = inst & 0xFFFF; 924 offset = inst & 0xFFFF;
922 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 925 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
923 926
924 /* segment check */ 927 /* segment check */
925 if (vaddr & 0x80000000) { 928 if (vaddr & 0x80000000) {
926 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 929 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
927 return; 930 return;
928 } 931 }
929 932
930 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) { 933 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
931 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 934 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
932 return; 935 return;
933 } 936 }
934 937
935 x = tf->tf_regs[(inst>>16)&0x1F]; 938 x = tf->tf_regs[(inst>>16)&0x1F];
936 939
937 shift = (7 - (vaddr & 0x7)) * 8; 940 shift = (7 - (vaddr & 0x7)) * 8;
938 a <<= shift; 941 a <<= shift;
939 x &= ~(~(uint64_t)0UL << shift); 942 x &= ~(~(uint64_t)0UL << shift);
940 x |= a; 943 x |= a;
941 944
942 tf->tf_regs[(inst>>16)&0x1F] = x; 945 tf->tf_regs[(inst>>16)&0x1F] = x;
943 946
944 update_pc(tf, cause); 947 update_pc(tf, cause);
945} 948}
946 949
947void 950void
948mips_emul_ldr(uint32_t inst, struct trapframe *tf, uint32_t cause) 951mips_emul_ldr(uint32_t inst, struct trapframe *tf, uint32_t cause)
949{ 952{
950 intptr_t vaddr; 953 intptr_t vaddr;
951 uint64_t a, x; 954 uint64_t a, x;
952 uint32_t shift; 955 uint32_t shift;
953 int16_t offset; 956 int16_t offset;
954 957
955 offset = inst & 0xFFFF; 958 offset = inst & 0xFFFF;
956 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 959 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
957 960
958 /* segment check */ 961 /* segment check */
959 if (vaddr < 0) { 962 if (vaddr < 0) {
960 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause); 963 send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
961 return; 964 return;
962 } 965 }
963 966
964 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) { 967 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
965 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause); 968 send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
966 return; 969 return;
967 } 970 }
968 971
969 x = tf->tf_regs[(inst>>16)&0x1F]; 972 x = tf->tf_regs[(inst>>16)&0x1F];
970 973
971 shift = (vaddr & 0x7) * 8; 974 shift = (vaddr & 0x7) * 8;
972 a >>= shift; 975 a >>= shift;
973 x &= ~(~(uint64_t)0UL >> shift); 976 x &= ~(~(uint64_t)0UL >> shift);
974 x |= a; 977 x |= a;
975 978
976 tf->tf_regs[(inst>>16)&0x1F] = x; 979 tf->tf_regs[(inst>>16)&0x1F] = x;
977 980
978 update_pc(tf, cause); 981 update_pc(tf, cause);
979} 982}
980#endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */ 983#endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */
981 984
982void 985void
983mips_emul_sb(uint32_t inst, struct trapframe *tf, uint32_t cause) 986mips_emul_sb(uint32_t inst, struct trapframe *tf, uint32_t cause)
984{ 987{
985 intptr_t vaddr; 988 intptr_t vaddr;
986 int16_t offset; 989 int16_t offset;
987 990
988 offset = inst & 0xFFFF; 991 offset = inst & 0xFFFF;
989 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 992 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
990 993
991 /* segment check */ 994 /* segment check */
992 if (vaddr < 0) { 995 if (vaddr < 0) {
993 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 996 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
994 return; 997 return;
995 } 998 }
996 999
997 if (ustore_8((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) { 1000 if (ustore_8((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
998 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1001 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
999 return; 1002 return;
1000 } 1003 }
1001 1004
1002 update_pc(tf, cause); 1005 update_pc(tf, cause);
1003} 1006}
1004 1007
1005void 1008void
1006mips_emul_sh(uint32_t inst, struct trapframe *tf, uint32_t cause) 1009mips_emul_sh(uint32_t inst, struct trapframe *tf, uint32_t cause)
1007{ 1010{
1008 intptr_t vaddr; 1011 intptr_t vaddr;
1009 int16_t offset; 1012 int16_t offset;
1010 1013
1011 offset = inst & 0xFFFF; 1014 offset = inst & 0xFFFF;
1012 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1015 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1013 1016
1014 /* segment and alignment check */ 1017 /* segment and alignment check */
1015 if (vaddr < 0 || vaddr & 1) { 1018 if (vaddr < 0 || vaddr & 1) {
1016 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1019 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1017 return; 1020 return;
1018 } 1021 }
1019 1022
1020 if (ustore_16((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) { 1023 if (ustore_16((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
1021 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1024 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1022 return; 1025 return;
1023 } 1026 }
1024 1027
1025 update_pc(tf, cause); 1028 update_pc(tf, cause);
1026} 1029}
1027 1030
1028void 1031void
1029mips_emul_sw(uint32_t inst, struct trapframe *tf, uint32_t cause) 1032mips_emul_sw(uint32_t inst, struct trapframe *tf, uint32_t cause)
1030{ 1033{
1031 intptr_t vaddr; 1034 intptr_t vaddr;
1032 int16_t offset; 1035 int16_t offset;
1033 1036
1034 offset = inst & 0xFFFF; 1037 offset = inst & 0xFFFF;
1035 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1038 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1036 1039
1037 /* segment and alignment check */ 1040 /* segment and alignment check */
1038 if (vaddr < 0 || (vaddr & 3)) { 1041 if (vaddr < 0 || (vaddr & 3)) {
1039 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1042 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1040 return; 1043 return;
1041 } 1044 }
1042 1045
1043 if (ustore_32((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) { 1046 if (ustore_32((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
1044 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1047 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1045 return; 1048 return;
1046 } 1049 }
1047 1050
1048 update_pc(tf, cause); 1051 update_pc(tf, cause);
1049} 1052}
1050 1053
1051void 1054void
1052mips_emul_swl(uint32_t inst, struct trapframe *tf, uint32_t cause) 1055mips_emul_swl(uint32_t inst, struct trapframe *tf, uint32_t cause)
1053{ 1056{
1054 intptr_t vaddr; 1057 intptr_t vaddr;
1055 uint32_t a, x, shift; 1058 uint32_t a, x, shift;
1056 int16_t offset; 1059 int16_t offset;
1057 1060
1058 offset = inst & 0xFFFF; 1061 offset = inst & 0xFFFF;
1059 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1062 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1060 1063
1061 /* segment check */ 1064 /* segment check */
1062 if (vaddr < 0) { 1065 if (vaddr < 0) {
1063 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1066 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1064 return; 1067 return;
1065 } 1068 }
1066 1069
1067 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) { 1070 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
1068 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1071 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1069 return; 1072 return;
1070 } 1073 }
1071 1074
1072 x = tf->tf_regs[(inst>>16)&0x1F]; 1075 x = tf->tf_regs[(inst>>16)&0x1F];
1073 1076
1074 shift = (3 - (vaddr & 3)) * 8; 1077 shift = (3 - (vaddr & 3)) * 8;
1075 x >>= shift; 1078 x >>= shift;
1076 a &= ~(0xFFFFFFFFUL >> shift); 1079 a &= ~(0xFFFFFFFFUL >> shift);
1077 a |= x; 1080 a |= x;
1078 1081
1079 if (ustore_32((void *)vaddr, a) != 0) { 1082 if (ustore_32((void *)vaddr, a) != 0) {
1080 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1083 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1081 return; 1084 return;
1082 } 1085 }
1083 1086
1084 update_pc(tf, cause); 1087 update_pc(tf, cause);
1085} 1088}
1086 1089
1087void 1090void
1088mips_emul_swr(uint32_t inst, struct trapframe *tf, uint32_t cause) 1091mips_emul_swr(uint32_t inst, struct trapframe *tf, uint32_t cause)
1089{ 1092{
1090 intptr_t vaddr; 1093 intptr_t vaddr;
1091 uint32_t a, x, shift; 1094 uint32_t a, x, shift;
1092 int16_t offset; 1095 int16_t offset;
1093 1096
1094 offset = inst & 0xFFFF; 1097 offset = inst & 0xFFFF;
1095 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1098 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1096 1099
1097 /* segment check */ 1100 /* segment check */
1098 if (vaddr < 0) { 1101 if (vaddr < 0) {
1099 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1102 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1100 return; 1103 return;
1101 } 1104 }
1102 1105
1103 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) { 1106 if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
1104 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1107 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1105 return; 1108 return;
1106 } 1109 }
1107 1110
1108 x = tf->tf_regs[(inst>>16)&0x1F]; 1111 x = tf->tf_regs[(inst>>16)&0x1F];
1109 1112
1110 shift = (vaddr & 3) * 8; 1113 shift = (vaddr & 3) * 8;
1111 x <<= shift; 1114 x <<= shift;
1112 a &= ~(0xFFFFFFFFUL << shift); 1115 a &= ~(0xFFFFFFFFUL << shift);
1113 a |= x; 1116 a |= x;
1114 1117
1115 if (ustore_32((void *)vaddr, a) != 0) { 1118 if (ustore_32((void *)vaddr, a) != 0) {
1116 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1119 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1117 return; 1120 return;
1118 } 1121 }
1119 1122
1120 update_pc(tf, cause); 1123 update_pc(tf, cause);
1121} 1124}
1122 1125
1123#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) 1126#if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
1124void 1127void
1125mips_emul_sd(uint32_t inst, struct trapframe *tf, uint32_t cause) 1128mips_emul_sd(uint32_t inst, struct trapframe *tf, uint32_t cause)
1126{ 1129{
1127 intptr_t vaddr; 1130 intptr_t vaddr;
1128 int16_t offset; 1131 int16_t offset;
1129 1132
1130 offset = inst & 0xFFFF; 1133 offset = inst & 0xFFFF;
1131 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1134 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1132 1135
1133 /* segment and alignment check */ 1136 /* segment and alignment check */
1134 if (vaddr < 0 || vaddr & 0x7) { 1137 if (vaddr < 0 || vaddr & 0x7) {
1135 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1138 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1136 return; 1139 return;
1137 } 1140 }
1138 1141
1139 if (copyout((void *)vaddr, &tf->tf_regs[(inst>>16)&0x1F], 8) < 0) { 1142 if (copyout((void *)vaddr, &tf->tf_regs[(inst>>16)&0x1F], 8) < 0) {
1140 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1143 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1141 return; 1144 return;
1142 } 1145 }
1143 1146
1144 update_pc(tf, cause); 1147 update_pc(tf, cause);
1145} 1148}
1146 1149
1147void 1150void
1148mips_emul_sdl(uint32_t inst, struct trapframe *tf, uint32_t cause) 1151mips_emul_sdl(uint32_t inst, struct trapframe *tf, uint32_t cause)
1149{ 1152{
1150 intptr_t vaddr; 1153 intptr_t vaddr;
1151 uint64_t a, x; 1154 uint64_t a, x;
1152 uint32_t shift; 1155 uint32_t shift;
1153 int16_t offset; 1156 int16_t offset;
1154 1157
1155 offset = inst & 0xFFFF; 1158 offset = inst & 0xFFFF;
1156 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1159 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1157 1160
1158 /* segment check */ 1161 /* segment check */
1159 if (vaddr < 0) { 1162 if (vaddr < 0) {
1160 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1163 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1161 return; 1164 return;
1162 } 1165 }
1163 1166
1164 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) { 1167 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
1165 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1168 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1166 return; 1169 return;
1167 } 1170 }
1168 1171
1169 x = tf->tf_regs[(inst>>16)&0x1F]; 1172 x = tf->tf_regs[(inst>>16)&0x1F];
1170 1173
1171 shift = (7 - (vaddr & 7)) * 8; 1174 shift = (7 - (vaddr & 7)) * 8;
1172 x >>= shift; 1175 x >>= shift;
1173 a &= ~(~(uint64_t)0U >> shift); 1176 a &= ~(~(uint64_t)0U >> shift);
1174 a |= x; 1177 a |= x;
1175 1178
1176 if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) { 1179 if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) {
1177 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1180 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1178 return; 1181 return;
1179 } 1182 }
1180 1183
1181 update_pc(tf, cause); 1184 update_pc(tf, cause);
1182} 1185}
1183 1186
1184void 1187void
1185mips_emul_sdr(uint32_t inst, struct trapframe *tf, uint32_t cause) 1188mips_emul_sdr(uint32_t inst, struct trapframe *tf, uint32_t cause)
1186{ 1189{
1187 intptr_t vaddr; 1190 intptr_t vaddr;
1188 uint64_t a, x; 1191 uint64_t a, x;
1189 uint32_t shift; 1192 uint32_t shift;
1190 int16_t offset; 1193 int16_t offset;
1191 1194
1192 offset = inst & 0xFFFF; 1195 offset = inst & 0xFFFF;
1193 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset; 1196 vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
1194 1197
1195 /* segment check */ 1198 /* segment check */
1196 if (vaddr < 0) { 1199 if (vaddr < 0) {
1197 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause); 1200 send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
1198 return; 1201 return;
1199 } 1202 }
1200 1203
1201 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) { 1204 if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
1202 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1205 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1203 return; 1206 return;
1204 } 1207 }
1205 1208
1206 x = tf->tf_regs[(inst>>16)&0x1F]; 1209 x = tf->tf_regs[(inst>>16)&0x1F];
1207 1210
1208 shift = (vaddr & 7) * 8; 1211 shift = (vaddr & 7) * 8;
1209 x <<= shift; 1212 x <<= shift;
1210 a &= ~(~(uint64_t)0U << shift); 1213 a &= ~(~(uint64_t)0U << shift);
1211 a |= x; 1214 a |= x;
1212 1215
1213 if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) { 1216 if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) {
1214 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause); 1217 send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
1215 return; 1218 return;
1216 } 1219 }
1217 1220
1218 update_pc(tf, cause); 1221 update_pc(tf, cause);
1219} 1222}
1220#endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */ 1223#endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */
1221#endif /* defined(FPEMUL) */ 1224#endif /* defined(FPEMUL) */