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