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