1 /* $NetBSD: locore.h,v 1.78 2007/10/17 19:55:36 garbled Exp $ */ 2 3 /* 4 * Copyright 1996 The Board of Trustees of The Leland Stanford 5 * Junior University. All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and distribute this 8 * software and its documentation for any purpose and without 9 * fee is hereby granted, provided that the above copyright 10 * notice appear in all copies. Stanford University 11 * makes no representations about the suitability of this 12 * software for any purpose. It is provided "as is" without 13 * express or implied warranty. 14 */ 15 16 /* 17 * Jump table for MIPS CPU locore functions that are implemented 18 * differently on different generations, or instruction-level 19 * archtecture (ISA) level, the Mips family. 20 * 21 * We currently provide support for MIPS I and MIPS III. 22 */ 23 24 #ifndef _MIPS_LOCORE_H 25 #define _MIPS_LOCORE_H 26 27 #ifndef _LKM 28 #include "opt_cputype.h" 29 #endif 30 31 #include <mips/cpuregs.h> 32 33 struct tlb; 34 35 uint32_t mips_cp0_cause_read(void); 36 void mips_cp0_cause_write(uint32_t); 37 uint32_t mips_cp0_status_read(void); 38 void mips_cp0_status_write(uint32_t); 39 40 int _splraise(int); 41 int _spllower(int); 42 int _splset(int); 43 int _splget(void); 44 void _splnone(void); 45 void _setsoftintr(int); 46 void _clrsoftintr(int); 47 48 #ifdef MIPS1 49 void mips1_SetPID(int); 50 void mips1_TBIA(int); 51 void mips1_TBIAP(int); 52 void mips1_TBIS(vaddr_t); 53 int mips1_TLBUpdate(u_int, u_int); 54 void mips1_wbflush(void); 55 void mips1_lwp_trampoline(void); 56 void mips1_cpu_switch_resume(void); 57 58 uint32_t tx3900_cp0_config_read(void); 59 #endif 60 61 #if defined(MIPS3) || defined(MIPS4) 62 void mips3_SetPID(int); 63 void mips3_TBIA(int); 64 void mips3_TBIAP(int); 65 void mips3_TBIS(vaddr_t); 66 int mips3_TLBUpdate(u_int, u_int); 67 void mips3_TLBRead(int, struct tlb *); 68 void mips3_TLBWriteIndexedVPS(int, struct tlb *); 69 void mips3_wbflush(void); 70 void mips3_lwp_trampoline(void); 71 void mips3_cpu_switch_resume(void); 72 void mips3_pagezero(void *dst); 73 74 #ifdef MIPS3_5900 75 void mips5900_SetPID(int); 76 void mips5900_TBIA(int); 77 void mips5900_TBIAP(int); 78 void mips5900_TBIS(vaddr_t); 79 int mips5900_TLBUpdate(u_int, u_int); 80 void mips5900_TLBRead(int, struct tlb *); 81 void mips5900_TLBWriteIndexedVPS(int, struct tlb *); 82 void mips5900_wbflush(void); 83 void mips5900_lwp_trampoline(void); 84 void mips5900_cpu_switch_resume(void); 85 void mips5900_pagezero(void *dst); 86 #endif 87 #endif 88 89 #ifdef MIPS32 90 void mips32_SetPID(int); 91 void mips32_TBIA(int); 92 void mips32_TBIAP(int); 93 void mips32_TBIS(vaddr_t); 94 int mips32_TLBUpdate(u_int, u_int); 95 void mips32_TLBRead(int, struct tlb *); 96 void mips32_TLBWriteIndexedVPS(int, struct tlb *); 97 void mips32_wbflush(void); 98 void mips32_lwp_trampoline(void); 99 void mips32_cpu_switch_resume(void); 100 #endif 101 102 #ifdef MIPS64 103 void mips64_SetPID(int); 104 void mips64_TBIA(int); 105 void mips64_TBIAP(int); 106 void mips64_TBIS(vaddr_t); 107 int mips64_TLBUpdate(u_int, u_int); 108 void mips64_TLBRead(int, struct tlb *); 109 void mips64_TLBWriteIndexedVPS(int, struct tlb *); 110 void mips64_wbflush(void); 111 void mips64_lwp_trampoline(void); 112 void mips64_cpu_switch_resume(void); 113 void mips64_pagezero(void *dst); 114 #endif 115 116 #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64) 117 uint32_t mips3_cp0_compare_read(void); 118 void mips3_cp0_compare_write(uint32_t); 119 120 uint32_t mips3_cp0_config_read(void); 121 void mips3_cp0_config_write(uint32_t); 122 #if defined(MIPS32) || defined(MIPS64) 123 uint32_t mipsNN_cp0_config1_read(void); 124 void mipsNN_cp0_config1_write(uint32_t); 125 uint32_t mipsNN_cp0_config2_read(void); 126 uint32_t mipsNN_cp0_config3_read(void); 127 #endif 128 129 uint32_t mips3_cp0_count_read(void); 130 void mips3_cp0_count_write(uint32_t); 131 132 uint32_t mips3_cp0_wired_read(void); 133 void mips3_cp0_wired_write(uint32_t); 134 void mips3_cp0_pg_mask_write(uint32_t); 135 136 uint64_t mips3_ld(uint64_t *); 137 void mips3_sd(uint64_t *, uint64_t); 138 #endif /* MIPS3 || MIPS4 || MIPS32 || MIPS64 */ 139 140 #if defined(MIPS3) || defined(MIPS4) || defined(MIPS64) 141 static __inline uint32_t mips3_lw_a64(uint64_t addr) 142 __attribute__((__unused__)); 143 static __inline void mips3_sw_a64(uint64_t addr, uint32_t val) 144 __attribute__ ((__unused__)); 145 146 static __inline uint32_t 147 mips3_lw_a64(uint64_t addr) 148 { 149 uint32_t addrlo, addrhi; 150 uint32_t rv; 151 uint32_t sr; 152 153 sr = mips_cp0_status_read(); 154 mips_cp0_status_write(sr | MIPS3_SR_KX); 155 156 addrlo = addr & 0xffffffff; 157 addrhi = addr >> 32; 158 __asm volatile (" \n\ 159 .set push \n\ 160 .set mips3 \n\ 161 .set noreorder \n\ 162 .set noat \n\ 163 dsll32 $3, %1, 0 \n\ 164 dsll32 $1, %2, 0 \n\ 165 dsrl32 $3, $3, 0 \n\ 166 or $1, $1, $3 \n\ 167 lw %0, 0($1) \n\ 168 .set pop \n\ 169 " : "=r"(rv) : "r"(addrlo), "r"(addrhi) : "$1", "$3" ); 170 171 mips_cp0_status_write(sr); 172 173 return (rv); 174 } 175 176 static __inline void 177 mips3_sw_a64(uint64_t addr, uint32_t val) 178 { 179 uint32_t addrlo, addrhi; 180 uint32_t sr; 181 182 sr = mips_cp0_status_read(); 183 mips_cp0_status_write(sr | MIPS3_SR_KX); 184 185 addrlo = addr & 0xffffffff; 186 addrhi = addr >> 32; 187 __asm volatile (" \n\ 188 .set push \n\ 189 .set mips3 \n\ 190 .set noreorder \n\ 191 .set noat \n\ 192 dsll32 $3, %1, 0 \n\ 193 dsll32 $1, %2, 0 \n\ 194 dsrl32 $3, $3, 0 \n\ 195 or $1, $1, $3 \n\ 196 sw %0, 0($1) \n\ 197 .set pop \n\ 198 " : : "r"(val), "r"(addrlo), "r"(addrhi) : "$1", "$3" ); 199 200 mips_cp0_status_write(sr); 201 } 202 #endif /* MIPS3 || MIPS4 || MIPS64 */ 203 204 /* 205 * A vector with an entry for each mips-ISA-level dependent 206 * locore function, and macros which jump through it. 207 * 208 * XXX the macro names are chosen to be compatible with the old 209 * XXX Sprite coding-convention names used in 4.4bsd/pmax. 210 */ 211 typedef struct { 212 void (*setTLBpid)(int pid); 213 void (*TBIAP)(int); 214 void (*TBIS)(vaddr_t); 215 int (*tlbUpdate)(u_int highreg, u_int lowreg); 216 void (*wbflush)(void); 217 } mips_locore_jumpvec_t; 218 219 void mips_set_wbflush(void (*)(void)); 220 void mips_wait_idle(void); 221 222 void stacktrace(void); 223 void logstacktrace(void); 224 225 /* 226 * The "active" locore-fuction vector, and 227 */ 228 extern mips_locore_jumpvec_t mips_locore_jumpvec; 229 extern long *mips_locoresw[]; 230 231 #if defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) 232 #define MachSetPID mips1_SetPID 233 #define MIPS_TBIAP() mips1_TBIAP(mips_num_tlb_entries) 234 #define MIPS_TBIS mips1_TBIS 235 #define MachTLBUpdate mips1_TLBUpdate 236 #define wbflush() mips1_wbflush() 237 #define lwp_trampoline mips1_lwp_trampoline 238 #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && !defined(MIPS3_5900) 239 #define MachSetPID mips3_SetPID 240 #define MIPS_TBIAP() mips3_TBIAP(mips_num_tlb_entries) 241 #define MIPS_TBIS mips3_TBIS 242 #define MachTLBUpdate mips3_TLBUpdate 243 #define MachTLBWriteIndexedVPS mips3_TLBWriteIndexedVPS 244 #define lwp_trampoline mips3_lwp_trampoline 245 #define wbflush() mips3_wbflush() 246 #elif !defined(MIPS1) && !defined(MIPS3) && defined(MIPS32) && !defined(MIPS64) 247 #define MachSetPID mips32_SetPID 248 #define MIPS_TBIAP() mips32_TBIAP(mips_num_tlb_entries) 249 #define MIPS_TBIS mips32_TBIS 250 #define MachTLBUpdate mips32_TLBUpdate 251 #define MachTLBWriteIndexedVPS mips32_TLBWriteIndexedVPS 252 #define lwp_trampoline mips32_lwp_trampoline 253 #define wbflush() mips32_wbflush() 254 #elif !defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && defined(MIPS64) 255 /* all common with mips3 */ 256 #define MachSetPID mips64_SetPID 257 #define MIPS_TBIAP() mips64_TBIAP(mips_num_tlb_entries) 258 #define MIPS_TBIS mips64_TBIS 259 #define MachTLBUpdate mips64_TLBUpdate 260 #define MachTLBWriteIndexedVPS mips64_TLBWriteIndexedVPS 261 #define lwp_trampoline mips64_lwp_trampoline 262 #define wbflush() mips64_wbflush() 263 #elif !defined(MIPS1) && defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && defined(MIPS3_5900) 264 #define MachSetPID mips5900_SetPID 265 #define MIPS_TBIAP() mips5900_TBIAP(mips_num_tlb_entries) 266 #define MIPS_TBIS mips5900_TBIS 267 #define MachTLBUpdate mips5900_TLBUpdate 268 #define MachTLBWriteIndexedVPS mips5900_TLBWriteIndexedVPS 269 #define lwp_trampoline mips5900_lwp_trampoline 270 #define wbflush() mips5900_wbflush() 271 #else 272 #define MachSetPID (*(mips_locore_jumpvec.setTLBpid)) 273 #define MIPS_TBIAP() (*(mips_locore_jumpvec.TBIAP))(mips_num_tlb_entries) 274 #define MIPS_TBIS (*(mips_locore_jumpvec.TBIS)) 275 #define MachTLBUpdate (*(mips_locore_jumpvec.tlbUpdate)) 276 #define wbflush() (*(mips_locore_jumpvec.wbflush))() 277 #define lwp_trampoline (mips_locoresw[1]) 278 #endif 279 280 #define CPU_IDLE (mips_locoresw[2]) 281 282 /* cpu_switch_resume is called inside locore.S */ 283 284 /* 285 * CPU identification, from PRID register. 286 */ 287 typedef int mips_prid_t; 288 289 #define MIPS_PRID_REV(x) (((x) >> 0) & 0x00ff) 290 #define MIPS_PRID_IMPL(x) (((x) >> 8) & 0x00ff) 291 292 /* pre-MIPS32/64 */ 293 #define MIPS_PRID_RSVD(x) (((x) >> 16) & 0xffff) 294 #define MIPS_PRID_REV_MIN(x) ((MIPS_PRID_REV(x) >> 0) & 0x0f) 295 #define MIPS_PRID_REV_MAJ(x) ((MIPS_PRID_REV(x) >> 4) & 0x0f) 296 297 /* MIPS32/64 */ 298 #define MIPS_PRID_CID(x) (((x) >> 16) & 0x00ff) /* Company ID */ 299 #define MIPS_PRID_CID_PREHISTORIC 0x00 /* Not MIPS32/64 */ 300 #define MIPS_PRID_CID_MTI 0x01 /* MIPS Technologies, Inc. */ 301 #define MIPS_PRID_CID_BROADCOM 0x02 /* Broadcom */ 302 #define MIPS_PRID_CID_ALCHEMY 0x03 /* Alchemy Semiconductor */ 303 #define MIPS_PRID_CID_SIBYTE 0x04 /* SiByte */ 304 #define MIPS_PRID_CID_SANDCRAFT 0x05 /* SandCraft */ 305 #define MIPS_PRID_CID_PHILIPS 0x06 /* Philips */ 306 #define MIPS_PRID_CID_TOSHIBA 0x07 /* Toshiba */ 307 #define MIPS_PRID_CID_LSI 0x08 /* LSI */ 308 /* 0x09 unannounced */ 309 /* 0x0a unannounced */ 310 #define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */ 311 #define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */ 312 313 #ifdef _KERNEL 314 /* 315 * Global variables used to communicate CPU type, and parameters 316 * such as cache size, from locore to higher-level code (e.g., pmap). 317 */ 318 319 extern mips_prid_t cpu_id; 320 extern mips_prid_t fpu_id; 321 extern int mips_num_tlb_entries; 322 323 void mips_pagecopy(void *dst, void *src); 324 void mips_pagezero(void *dst); 325 326 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG 327 void mips_machdep_cache_config(void); 328 #endif 329 330 /* 331 * trapframe argument passed to trap() 332 */ 333 334 #define TF_AST 0 335 #define TF_V0 1 336 #define TF_V1 2 337 #define TF_A0 3 338 #define TF_A1 4 339 #define TF_A2 5 340 #define TF_A3 6 341 #define TF_T0 7 342 #define TF_T1 8 343 #define TF_T2 9 344 #define TF_T3 10 345 346 #if defined(__mips_n32) || defined(__mips_n64) 347 #define TF_A4 11 348 #define TF_A5 12 349 #define TF_A6 13 350 #define TF_A7 14 351 #else 352 #define TF_T4 11 353 #define TF_T5 12 354 #define TF_T6 13 355 #define TF_T7 14 356 #endif /* __mips_n32 || __mips_n64 */ 357 358 #define TF_TA0 11 359 #define TF_TA1 12 360 #define TF_TA2 13 361 #define TF_TA3 14 362 363 #define TF_T8 15 364 #define TF_T9 16 365 366 #define TF_RA 17 367 #define TF_SR 18 368 #define TF_MULLO 19 369 #define TF_MULHI 20 370 #define TF_EPC 21 /* may be changed by trap() call */ 371 372 #define TF_NREGS 22 373 374 struct trapframe { 375 mips_reg_t tf_regs[TF_NREGS]; 376 u_int32_t tf_ppl; /* previous priority level */ 377 int32_t tf_pad; /* for 8 byte aligned */ 378 }; 379 380 /* 381 * Stack frame for kernel traps. four args passed in registers. 382 * A trapframe is pointed to by the 5th arg, and a dummy sixth argument 383 * is used to avoid alignment problems 384 */ 385 386 struct kernframe { 387 register_t cf_args[4 + 1]; 388 register_t cf_pad; /* (for 8 word alignment) */ 389 register_t cf_sp; 390 register_t cf_ra; 391 struct trapframe cf_frame; 392 }; 393 #endif /* _KERNEL */ 394 #endif /* _MIPS_LOCORE_H */ 395