Home | History | Annotate | Line # | Download | only in include
locore.h revision 1.78.36.1.2.24
      1 /* $NetBSD: locore.h,v 1.78.36.1.2.24 2010/05/11 22:08:02 matt 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  * archtecture (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 #ifndef _LKM
     32 #include "opt_cputype.h"
     33 #endif
     34 
     35 #include <mips/cpuregs.h>
     36 #include <mips/reg.h>
     37 
     38 struct tlbmask;
     39 
     40 uint32_t mips_cp0_cause_read(void);
     41 void	mips_cp0_cause_write(uint32_t);
     42 uint32_t mips_cp0_status_read(void);
     43 void	mips_cp0_status_write(uint32_t);
     44 
     45 void	softint_process(uint32_t);
     46 void	softint_fast_dispatch(struct lwp *, int);
     47 
     48 /*
     49  * Convert an address to an offset used in a MIPS jump instruction.  The offset
     50  * contains the low 28 bits (allowing a jump to anywhere within the same 256MB
     51  * segment of address space) of the address but since mips instructions are
     52  * always on a 4 byte boundary the low 2 bits are always zero so the 28 bits
     53  * get shifted right by 2 bits leaving us with a 26 bit result.  To make the
     54  * offset, we shift left to clear the upper four bits and then right by 6.
     55  */
     56 #define	fixup_addr2offset(x)	((((uint32_t)(uintptr_t)(x)) << 4) >> 6)
     57 typedef bool (*mips_fixup_callback_t)(int32_t, uint32_t [2]);
     58 struct mips_jump_fixup_info {
     59 	uint32_t jfi_stub;
     60 	uint32_t jfi_real;
     61 };
     62 
     63 void	fixup_splcalls(void);				/* splstubs.c */
     64 bool	mips_fixup_exceptions(mips_fixup_callback_t);
     65 bool	mips_fixup_zero_relative(int32_t, uint32_t [2]);
     66 void	mips_fixup_stubs(uint32_t *, uint32_t *,
     67 	    const struct mips_jump_fixup_info *, size_t);
     68 void	fixup_mips_cpu_switch_resume(void);
     69 
     70 void	mips_cpu_switch_resume(struct lwp *);
     71 
     72 #ifdef MIPS1
     73 void	mips1_tlb_set_asid(uint32_t);
     74 void	mips1_tlb_invalidate_all(void);
     75 void	mips1_tlb_invalidate_globals(void);
     76 void	mips1_tlb_invalidate_asids(uint32_t, uint32_t);
     77 void	mips1_tlb_invalidate_addr(vaddr_t);
     78 u_int	mips1_tlb_record_asids(u_long *, uint32_t);
     79 int	mips1_tlb_update(vaddr_t, uint32_t);
     80 void	mips1_tlb_enter(size_t, vaddr_t, uint32_t);
     81 void	mips1_tlb_read_indexed(size_t, struct tlbmask *);
     82 void	mips1_wbflush(void);
     83 void	mips1_lwp_trampoline(void);
     84 void	mips1_setfunc_trampoline(void);
     85 void	mips1_cpu_switch_resume(struct lwp *);
     86 
     87 uint32_t tx3900_cp0_config_read(void);
     88 #endif
     89 
     90 #if defined(MIPS3) || defined(MIPS4)
     91 void	mips3_tlb_set_asid(uint32_t);
     92 void	mips3_tlb_invalidate_all(void);
     93 void	mips3_tlb_invalidate_globals(void);
     94 void	mips3_tlb_invalidate_asids(uint32_t, uint32_t);
     95 void	mips3_tlb_invalidate_addr(vaddr_t);
     96 u_int	mips3_tlb_record_asids(u_long *, uint32_t);
     97 int	mips3_tlb_update(vaddr_t, uint32_t);
     98 void	mips3_tlb_enter(size_t, vaddr_t, uint32_t);
     99 void	mips3_tlb_read_indexed(size_t, struct tlbmask *);
    100 void	mips3_tlb_write_indexed_VPS(size_t, struct tlbmask *);
    101 void	mips3_wbflush(void);
    102 void	mips3_lwp_trampoline(void);
    103 void	mips3_setfunc_trampoline(void);
    104 void	mips3_cpu_switch_resume(struct lwp *);
    105 void	mips3_pagezero(void *dst);
    106 
    107 #ifdef MIPS3_5900
    108 void	mips5900_tlb_set_asid(uint32_t);
    109 void	mips5900_tlb_invalidate_all(void);
    110 void	mips5900_tlb_invalidate_globals(void);
    111 void	mips5900_tlb_invalidate_asids(uint32_t, uint32_t);
    112 void	mips5900_tlb_invalidate_addr(vaddr_t);
    113 u_int	mips5900_tlb_record_asids(u_long *, uint32_t);
    114 int	mips5900_tlb_update(vaddr_t, uint32_t);
    115 void	mips5900_tlb_enter(size_t, vaddr_t, uint32_t);
    116 void	mips5900_tlb_read_indexed(size_t, struct tlbmask *);
    117 void	mips5900_tlb_write_indexed_VPS(size_t, struct tlbmask *);
    118 void	mips5900_wbflush(void);
    119 void	mips5900_lwp_trampoline(void);
    120 void	mips5900_setfunc_trampoline(void);
    121 void	mips5900_cpu_switch_resume(struct lwp *);
    122 void	mips5900_pagezero(void *dst);
    123 #endif
    124 #endif
    125 
    126 #ifdef MIPS32
    127 void	mips32_tlb_set_asid(uint32_t);
    128 void	mips32_tlb_invalidate_all(void);
    129 void	mips32_tlb_invalidate_globals(void);
    130 void	mips32_tlb_invalidate_asids(uint32_t, uint32_t);
    131 void	mips32_tlb_invalidate_addr(vaddr_t);
    132 u_int	mips32_tlb_record_asids(u_long *, uint32_t);
    133 int	mips32_tlb_update(vaddr_t, uint32_t);
    134 void	mips32_tlb_enter(size_t, vaddr_t, uint32_t);
    135 void	mips32_tlb_read_indexed(size_t, struct tlbmask *);
    136 void	mips32_tlb_write_indexed_VPS(size_t, struct tlbmask *);
    137 void	mips32_wbflush(void);
    138 void	mips32_lwp_trampoline(void);
    139 void	mips32_setfunc_trampoline(void);
    140 void	mips32_cpu_switch_resume(struct lwp *);
    141 #endif
    142 
    143 #ifdef MIPS64
    144 void	mips64_tlb_set_asid(uint32_t);
    145 void	mips64_tlb_invalidate_all(void);
    146 void	mips64_tlb_invalidate_globals(void);
    147 void	mips64_tlb_invalidate_asids(uint32_t, uint32_t);
    148 void	mips64_tlb_invalidate_addr(vaddr_t);
    149 u_int	mips64_tlb_record_asids(u_long *, uint32_t);
    150 int	mips64_tlb_update(vaddr_t, uint32_t);
    151 void	mips64_tlb_enter(size_t, vaddr_t, uint32_t);
    152 void	mips64_tlb_read_indexed(size_t, struct tlbmask *);
    153 void	mips64_tlb_write_indexed_VPS(size_t, struct tlbmask *);
    154 void	mips64_wbflush(void);
    155 void	mips64_lwp_trampoline(void);
    156 void	mips64_setfunc_trampoline(void);
    157 void	mips64_cpu_switch_resume(struct lwp *);
    158 void	mips64_pagezero(void *dst);
    159 #endif
    160 
    161 #if defined(MIPS3) || defined(MIPS4) || defined(MIPS32) || defined(MIPS64)
    162 uint32_t mips3_cp0_compare_read(void);
    163 void	mips3_cp0_compare_write(uint32_t);
    164 
    165 uint32_t mips3_cp0_config_read(void);
    166 void	mips3_cp0_config_write(uint32_t);
    167 #if defined(MIPS32) || defined(MIPS64)
    168 uint32_t mipsNN_cp0_config1_read(void);
    169 void	mipsNN_cp0_config1_write(uint32_t);
    170 uint32_t mipsNN_cp0_config2_read(void);
    171 uint32_t mipsNN_cp0_config3_read(void);
    172 #endif
    173 
    174 uint32_t mips3_cp0_count_read(void);
    175 void	mips3_cp0_count_write(uint32_t);
    176 
    177 uint32_t mips3_cp0_wired_read(void);
    178 void	mips3_cp0_wired_write(uint32_t);
    179 void	mips3_cp0_pg_mask_write(uint32_t);
    180 
    181 #if defined(__GNUC__) && !defined(__mips_o32)
    182 static inline uint64_t
    183 mips3_ld(const volatile uint64_t *va)
    184 {
    185 	uint64_t rv;
    186 #if defined(__mips_o32)
    187 	uint32_t sr;
    188 
    189 	sr = mips_cp0_status_read();
    190 	mips_cp0_status_write(sr & ~MIPS_SR_INT_IE);
    191 
    192 	__asm volatile(
    193 		".set push		\n\t"
    194 		".set mips3		\n\t"
    195 		".set noreorder		\n\t"
    196 		".set noat		\n\t"
    197 		"ld	%M0,0(%1)	\n\t"
    198 		"dsll32	%L0,%M0,0	\n\t"
    199 		"dsra32	%M0,%M0,0	\n\t"		/* high word */
    200 		"dsra32	%L0,%L0,0	\n\t"		/* low word */
    201 		"ld	%0,0(%1)	\n\t"
    202 		".set pop"
    203 	    : "=d"(rv)
    204 	    : "r"(va));
    205 
    206 	mips_cp0_status_write(sr);
    207 #elif defined(_LP64)
    208 	rv = *va;
    209 #else
    210 	__asm volatile("ld	%0,0(%1)" : "=d"(rv) : "r"(va));
    211 #endif
    212 
    213 	return rv;
    214 }
    215 static inline void
    216 mips3_sd(volatile uint64_t *va, uint64_t v)
    217 {
    218 #if defined(__mips_o32)
    219 	uint32_t sr;
    220 
    221 	sr = mips_cp0_status_read();
    222 	mips_cp0_status_write(sr & ~MIPS_SR_INT_IE);
    223 
    224 	__asm volatile(
    225 		".set push		\n\t"
    226 		".set mips3		\n\t"
    227 		".set noreorder		\n\t"
    228 		".set noat		\n\t"
    229 		"dsll32	%M0,%M0,0	\n\t"
    230 		"dsll32	%L0,%L0,0	\n\t"
    231 		"dsrl32	%L0,%L0,0	\n\t"
    232 		"or	%0,%L0,%M0	\n\t"
    233 		"sd	%0,0(%1)	\n\t"
    234 		".set pop"
    235 	    : "=d"(v) : "0"(v), "r"(va));
    236 
    237 	mips_cp0_status_write(sr);
    238 #elif defined(_LP64)
    239 	*va = v;
    240 #else
    241 	__asm volatile("sd	%0,0(%1)" :: "r"(v), "r"(va));
    242 #endif
    243 }
    244 #else
    245 uint64_t mips3_ld(volatile uint64_t *va);
    246 void	mips3_sd(volatile uint64_t *, uint64_t);
    247 #endif	/* __GNUC__ */
    248 #endif	/* MIPS3 || MIPS4 || MIPS32 || MIPS64 */
    249 
    250 #if defined(MIPS3) || defined(MIPS4) || defined(MIPS64)
    251 static __inline uint32_t	mips3_lw_a64(uint64_t addr)
    252 		    __attribute__((__unused__));
    253 static __inline void	mips3_sw_a64(uint64_t addr, uint32_t val)
    254 		    __attribute__ ((__unused__));
    255 
    256 static __inline uint32_t
    257 mips3_lw_a64(uint64_t addr)
    258 {
    259 	uint32_t rv;
    260 #if defined(__mips_o32)
    261 	uint32_t sr;
    262 
    263 	sr = mips_cp0_status_read();
    264 	mips_cp0_status_write((sr & ~MIPS_SR_INT_IE) | MIPS3_SR_KX);
    265 
    266 	__asm volatile (
    267 		".set push		\n\t"
    268 		".set mips3		\n\t"
    269 		".set noreorder		\n\t"
    270 		".set noat		\n\t"
    271 		"dsll32	%M1,%M1,0	\n\t"
    272 		"dsll32	%L1,%L1,0	\n\t"
    273 		"dsrl32	%L1,%L1,0	\n\t"
    274 		"or	%1,%M1,%L1	\n\t"
    275 		"lw	%0, 0(%1)	\n\t"
    276 		".set pop"
    277 	    : "=r"(rv), "=d"(addr)
    278 	    : "1"(addr)
    279 	    );
    280 
    281 	mips_cp0_status_write(sr);
    282 #elif defined(__mips_n32)
    283 	uint32_t sr = mips_cp0_status_read();
    284 	mips_cp0_status_write((sr & ~MIPS_SR_INT_IE) | MIPS3_SR_KX);
    285 	__asm volatile("lw	%0, 0(%1)" : "=r"(rv) : "d"(addr));
    286 	mips_cp0_status_write(sr);
    287 #elif defined(_LP64)
    288 	rv = *(const uint32_t *)addr;
    289 #else
    290 #error unknown ABI
    291 #endif
    292 	return (rv);
    293 }
    294 
    295 static __inline void
    296 mips3_sw_a64(uint64_t addr, uint32_t val)
    297 {
    298 #if defined(__mips_o32)
    299 	uint32_t sr;
    300 
    301 	sr = mips_cp0_status_read();
    302 	mips_cp0_status_write((sr & ~MIPS_SR_INT_IE) | MIPS3_SR_KX);
    303 
    304 	__asm volatile (
    305 		".set push		\n\t"
    306 		".set mips3		\n\t"
    307 		".set noreorder		\n\t"
    308 		".set noat		\n\t"
    309 		"dsll32	%M0,%M0,0	\n\t"
    310 		"dsll32	%L0,%L0,0	\n\t"
    311 		"dsrl32	%L0,%L0,0	\n\t"
    312 		"or	%0,%M0,%L0	\n\t"
    313 		"sw	%1, 0(%0)	\n\t"
    314 		".set pop"
    315 	    : "=d"(addr): "r"(val), "0"(addr)
    316 	    );
    317 
    318 	mips_cp0_status_write(sr);
    319 #elif defined(__mips_n32)
    320 	uint32_t sr = mips_cp0_status_read();
    321 	mips_cp0_status_write((sr & ~MIPS_SR_INT_IE) | MIPS3_SR_KX);
    322 	__asm volatile("sw	%1, 0(%0)" :: "d"(addr), "r"(val));
    323 	mips_cp0_status_write(sr);
    324 #elif defined(_LP64)
    325 	*(uint32_t *)addr = val;
    326 #else
    327 #error unknown ABI
    328 #endif
    329 }
    330 #endif	/* MIPS3 || MIPS4 || MIPS64 */
    331 
    332 /*
    333  * A vector with an entry for each mips-ISA-level dependent
    334  * locore function, and macros which jump through it.
    335  */
    336 typedef struct  {
    337 	void	(*ljv_tlb_set_asid)(uint32_t pid);
    338 	void	(*ljv_tlb_invalidate_asids)(uint32_t, uint32_t);
    339 	void	(*ljv_tlb_invalidate_addr)(vaddr_t);
    340 	void	(*ljv_tlb_invalidate_globals)(void);
    341 	void	(*ljv_tlb_invalidate_all)(void);
    342 	u_int	(*ljv_tlb_record_asids)(u_long *, uint32_t);
    343 	int	(*ljv_tlb_update)(vaddr_t, uint32_t);
    344 	void	(*ljv_tlb_enter)(size_t, vaddr_t, uint32_t);
    345 	void	(*ljv_tlb_read_indexed)(size_t, struct tlbmask *);
    346 	void	(*ljv_wbflush)(void);
    347 } mips_locore_jumpvec_t;
    348 
    349 void	mips_set_wbflush(void (*)(void));
    350 void	mips_wait_idle(void);
    351 
    352 void	stacktrace(void);
    353 void	logstacktrace(void);
    354 
    355 struct locoresw {
    356 	void		(*lsw_cpu_switch_resume)(struct lwp *);
    357 	uintptr_t	lsw_lwp_trampoline;
    358 	void		(*lsw_cpu_idle)(void);
    359 	uintptr_t	lsw_setfunc_trampoline;
    360 	int		(*lsw_send_ipi)(struct cpu_info *, int);
    361 	void		(*lsw_cpu_offline_md)(void);
    362 	void		(*lsw_cpu_init)(struct cpu_info *);
    363 };
    364 
    365 struct mips_vmfreelist {
    366 	paddr_t fl_start;
    367 	paddr_t fl_end;
    368 	int fl_freelist;
    369 };
    370 
    371 /*
    372  * The "active" locore-fuction vector, and
    373  */
    374 extern mips_locore_jumpvec_t mips_locore_jumpvec;
    375 extern struct locoresw mips_locoresw;
    376 extern void mips_vector_init(const struct splsw *);
    377 
    378 #if    defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64)
    379 #define tlb_set_asid		mips1_tlb_set_asid
    380 #define tlb_invalidate_asids	mips1_tlb_invalidate_asids
    381 #define tlb_invalidate_addr	mips1_tlb_invalidate_addr
    382 #define tlb_invalidate_globals	mips1_tlb_invalidate_globals
    383 #define tlb_invalidate_all	mips1_tlb_invalidate_all
    384 #define tlb_record_asids	mips1_tlb_record_asids
    385 #define tlb_update		mips1_tlb_update
    386 #define tlb_enter		mips1_tlb_enter
    387 #define tlb_read_indexed	mips1_tlb_read_indexed
    388 #define wbflush			mips1_wbflush
    389 #define lwp_trampoline		mips1_lwp_trampoline
    390 #define setfunc_trampoline	mips1_setfunc_trampoline
    391 #elif !defined(MIPS1) &&  defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && !defined(MIPS3_5900)
    392 #define tlb_set_asid		mips3_tlb_set_asid
    393 #define tlb_invalidate_asids	mips3_tlb_invalidate_asids
    394 #define tlb_invalidate_addr	mips3_tlb_invalidate_addr
    395 #define tlb_invalidate_globals	mips3_tlb_invalidate_globals
    396 #define tlb_invalidate_all	mips3_tlb_invalidate_all
    397 #define tlb_record_asids	mips3_tlb_record_asids
    398 #define tlb_update		mips3_tlb_update
    399 #define tlb_enter		mips3_tlb_enter
    400 #define tlb_read_indexed	mips3_tlb_read_indexed
    401 #define tlb_write_indexed_VPS	mips3_tlb_write_indexed_VPS
    402 #define lwp_trampoline		mips3_lwp_trampoline
    403 #define setfunc_trampoline	mips3_setfunc_trampoline
    404 #define wbflush			mips3_wbflush
    405 #elif !defined(MIPS1) && !defined(MIPS3) &&  defined(MIPS32) && !defined(MIPS64)
    406 #define tlb_set_asid		mips32_tlb_set_asid
    407 #define tlb_invalidate_asids	mips32_tlb_invalidate_asids
    408 #define tlb_invalidate_addr	mips32_tlb_invalidate_addr
    409 #define tlb_invalidate_globals	mips32_tlb_invalidate_globals
    410 #define tlb_invalidate_all	mips32_tlb_invalidate_all
    411 #define tlb_record_asids	mips32_tlb_record_asids
    412 #define tlb_update		mips32_tlb_update
    413 #define tlb_enter		mips32_tlb_enter
    414 #define tlb_read_indexed	mips32_tlb_read_indexed
    415 #define tlb_write_indexed_VPS	mips32_tlb_write_indexed_VPS
    416 #define lwp_trampoline		mips32_lwp_trampoline
    417 #define setfunc_trampoline	mips32_setfunc_trampoline
    418 #define wbflush			mips32_wbflush
    419 #elif !defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) &&  defined(MIPS64)
    420  /* all common with mips3 */
    421 #define tlb_set_asid		mips64_tlb_set_asid
    422 #define tlb_invalidate_asids	mips64_tlb_invalidate_asids
    423 #define tlb_invalidate_addr	mips64_tlb_invalidate_addr
    424 #define tlb_invalidate_globals	mips64_tlb_invalidate_globals
    425 #define tlb_invalidate_all	mips64_tlb_invalidate_all
    426 #define tlb_record_asids	mips64_tlb_record_asids
    427 #define tlb_update		mips64_tlb_update
    428 #define tlb_enter		mips64_tlb_enter
    429 #define tlb_read_indexed	mips64_tlb_read_indexed
    430 #define tlb_write_indexed_VPS	mips64_tlb_write_indexed_VPS
    431 #define lwp_trampoline		mips64_lwp_trampoline
    432 #define setfunc_trampoline	mips64_setfunc_trampoline
    433 #define wbflush			mips64_wbflush
    434 #elif !defined(MIPS1) &&  defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && defined(MIPS3_5900)
    435 #define tlb_set_asid		mips5900_tlb_set_asid
    436 #define tlb_invalidate_asids	mips5900_tlb_invalidate_asids
    437 #define tlb_invalidate_addr	mips5900_tlb_invalidate_addr
    438 #define tlb_invalidate_globals	mips5900_tlb_invalidate_globals
    439 #define tlb_invalidate_all	mips5900_tlb_invalidate_all
    440 #define tlb_record_asids	mips5900_tlb_record_asids
    441 #define tlb_update		mips5900_tlb_update
    442 #define tlb_enter		mips5900_tlb_enter
    443 #define tlb_read_indexed	mips5900_tlb_read_indexed
    444 #define tlb_write_indexed_VPS	mips5900_tlb_write_indexed_VPS
    445 #define lwp_trampoline		mips5900_lwp_trampoline
    446 #define setfunc_trampoline	mips5900_setfunc_trampoline
    447 #define wbflush			mips5900_wbflush
    448 #else
    449 #define tlb_set_asid		(*mips_locore_jumpvec.ljv_tlb_set_asid)
    450 #define tlb_invalidate_asids	(*mips_locore_jumpvec.ljv_tlb_invalidate_asids)
    451 #define tlb_invalidate_addr	(*mips_locore_jumpvec.ljv_tlb_invalidate_addr)
    452 #define tlb_invalidate_globals	(*mips_locore_jumpvec.ljv_tlb_invalidate_globals)
    453 #define tlb_invalidate_all	(*mips_locore_jumpvec.ljv_tlb_invalidate_all)
    454 #define tlb_record_asids	(*mips_locore_jumpvec.ljv_tlb_record_asids)
    455 #define tlb_update		(*mips_locore_jumpvec.ljv_tlb_update)
    456 #define tlb_enter		(*mips_locore_jumpvec.ljv_tlb_enter)
    457 #define tlb_read_indexed	(*mips_locore_jumpvec.ljv_tlb_read_indexed)
    458 #define wbflush			(*mips_locore_jumpvec.ljv_wbflush)
    459 #define lwp_trampoline		mips_locoresw.lsw_lwp_trampoline
    460 #define setfunc_trampoline	mips_locoresw.lsw_setfunc_trampoline
    461 #endif
    462 
    463 #define CPU_IDLE		mips_locoresw.lsw_cpu_idle
    464 
    465 /* cpu_switch_resume is called inside locore.S */
    466 
    467 /*
    468  * CPU identification, from PRID register.
    469  */
    470 #define MIPS_PRID_REV(x)	(((x) >>  0) & 0x00ff)
    471 #define MIPS_PRID_IMPL(x)	(((x) >>  8) & 0x00ff)
    472 
    473 /* pre-MIPS32/64 */
    474 #define MIPS_PRID_RSVD(x)	(((x) >> 16) & 0xffff)
    475 #define MIPS_PRID_REV_MIN(x)	((MIPS_PRID_REV(x) >> 0) & 0x0f)
    476 #define MIPS_PRID_REV_MAJ(x)	((MIPS_PRID_REV(x) >> 4) & 0x0f)
    477 
    478 /* MIPS32/64 */
    479 #define MIPS_PRID_CID(x)	(((x) >> 16) & 0x00ff)	/* Company ID */
    480 #define     MIPS_PRID_CID_PREHISTORIC	0x00	/* Not MIPS32/64 */
    481 #define     MIPS_PRID_CID_MTI		0x01	/* MIPS Technologies, Inc. */
    482 #define     MIPS_PRID_CID_BROADCOM	0x02	/* Broadcom */
    483 #define     MIPS_PRID_CID_ALCHEMY	0x03	/* Alchemy Semiconductor */
    484 #define     MIPS_PRID_CID_SIBYTE	0x04	/* SiByte */
    485 #define     MIPS_PRID_CID_SANDCRAFT	0x05	/* SandCraft */
    486 #define     MIPS_PRID_CID_PHILIPS	0x06	/* Philips */
    487 #define     MIPS_PRID_CID_TOSHIBA	0x07	/* Toshiba */
    488 #define     MIPS_PRID_CID_LSI		0x08	/* LSI */
    489 				/*	0x09	unannounced */
    490 				/*	0x0a	unannounced */
    491 #define     MIPS_PRID_CID_LEXRA		0x0b	/* Lexra */
    492 #define     MIPS_PRID_CID_RMI		0x0c	/* RMI / NetLogic */
    493 #define MIPS_PRID_COPTS(x)	(((x) >> 24) & 0x00ff)	/* Company Options */
    494 
    495 #ifdef _KERNEL
    496 /*
    497  * Global variables used to communicate CPU type, and parameters
    498  * such as cache size, from locore to higher-level code (e.g., pmap).
    499  */
    500 void mips_pagecopy(void *dst, void *src);
    501 void mips_pagezero(void *dst);
    502 
    503 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
    504 void mips_machdep_cache_config(void);
    505 #endif
    506 
    507 /*
    508  * trapframe argument passed to trap()
    509  */
    510 
    511 #if 0
    512 #define TF_AST		0		/* really zero */
    513 #define TF_V0		_R_V0
    514 #define TF_V1		_R_V1
    515 #define TF_A0		_R_A0
    516 #define TF_A1		_R_A1
    517 #define TF_A2		_R_A2
    518 #define TF_A3		_R_A3
    519 #define TF_T0		_R_T0
    520 #define TF_T1		_R_T1
    521 #define TF_T2		_R_T2
    522 #define TF_T3		_R_T3
    523 
    524 #if defined(__mips_n32) || defined(__mips_n64)
    525 #define TF_A4		_R_A4
    526 #define TF_A5		_R_A5
    527 #define TF_A6		_R_A6
    528 #define TF_A7		_R_A7
    529 #else
    530 #define TF_T4		_R_T4
    531 #define TF_T5		_R_T5
    532 #define TF_T6		_R_T6
    533 #define TF_T7		_R_T7
    534 #endif /* __mips_n32 || __mips_n64 */
    535 
    536 #define TF_TA0		_R_TA0
    537 #define TF_TA1		_R_TA1
    538 #define TF_TA2		_R_TA2
    539 #define TF_TA3		_R_TA3
    540 
    541 #define TF_T8		_R_T8
    542 #define TF_T9		_R_T9
    543 
    544 #define TF_RA		_R_RA
    545 #define TF_SR		_R_SR
    546 #define TF_MULLO	_R_MULLO
    547 #define TF_MULHI	_R_MULLO
    548 #define TF_EPC		_R_PC		/* may be changed by trap() call */
    549 
    550 #define	TF_NREGS	(sizeof(struct reg) / sizeof(mips_reg_t))
    551 #endif
    552 
    553 struct trapframe {
    554 	struct reg tf_registers;
    555 #define	tf_regs	tf_registers.r_regs
    556 	uint32_t   tf_ppl;		/* previous priority level */
    557 	mips_reg_t tf_pad;		/* for 8 byte aligned */
    558 };
    559 
    560 CTASSERT(sizeof(struct trapframe) % (4*sizeof(mips_reg_t)) == 0);
    561 
    562 /*
    563  * Stack frame for kernel traps. four args passed in registers.
    564  * A trapframe is pointed to by the 5th arg, and a dummy sixth argument
    565  * is used to avoid alignment problems
    566  */
    567 
    568 struct kernframe {
    569 #if defined(__mips_o32) || defined(__mips_o64)
    570 	register_t cf_args[4 + 1];
    571 #if defined(__mips_o32)
    572 	register_t cf_pad;		/* (for 8 byte alignment) */
    573 #endif
    574 #endif
    575 #if defined(__mips_n32) || defined(__mips_n64)
    576 	register_t cf_pad[2];		/* for 16 byte alignment */
    577 #endif
    578 	register_t cf_sp;
    579 	register_t cf_ra;
    580 	struct trapframe cf_frame;
    581 };
    582 
    583 CTASSERT(sizeof(struct kernframe) % (2*sizeof(mips_reg_t)) == 0);
    584 
    585 /*
    586  * PRocessor IDentity TABle
    587  */
    588 
    589 struct pridtab {
    590 	int	cpu_cid;
    591 	int	cpu_pid;
    592 	int	cpu_rev;	/* -1 == wildcard */
    593 	int	cpu_copts;	/* -1 == wildcard */
    594 	int	cpu_isa;	/* -1 == probed (mips32/mips64) */
    595 	int	cpu_ntlb;	/* -1 == unknown, 0 == probed */
    596 	int	cpu_flags;
    597 	u_int	cpu_cp0flags;	/* presence of some cp0 regs */
    598 	u_int	cpu_cidflags;	/* company-specific flags */
    599 	const char	*cpu_name;
    600 };
    601 
    602 /*
    603  * bitfield defines for cpu_cp0flags
    604  */
    605 #define  MIPS_CP0FL_USE		__BIT(0)	/* use these flags */
    606 #define  MIPS_CP0FL_ECC		__BIT(1)
    607 #define  MIPS_CP0FL_CACHE_ERR	__BIT(2)
    608 #define  MIPS_CP0FL_EIRR	__BIT(3)
    609 #define  MIPS_CP0FL_EIMR	__BIT(4)
    610 #define  MIPS_CP0FL_EBASE	__BIT(5)
    611 #define  MIPS_CP0FL_CONFIG	__BIT(6)
    612 #define  MIPS_CP0FL_CONFIGn(n)	(__BIT(7) << ((n) & 7))
    613 
    614 /*
    615  * cpu_cidflags defines, by company
    616  */
    617 /*
    618  * RMI company-specific cpu_cidflags
    619  */
    620 #define MIPS_CIDFL_RMI_TYPE     	__BITS(2,0)
    621 # define  CIDFL_RMI_TYPE_XLR     	0
    622 # define  CIDFL_RMI_TYPE_XLS     	1
    623 # define  CIDFL_RMI_TYPE_XLP     	2
    624 #define MIPS_CIDFL_RMI_THREADS_MASK	__BITS(6,3)
    625 # define MIPS_CIDFL_RMI_THREADS_SHIFT	3
    626 #define MIPS_CIDFL_RMI_CORES_MASK	__BITS(10,7)
    627 # define MIPS_CIDFL_RMI_CORES_SHIFT	7
    628 # define LOG2_1	0
    629 # define LOG2_2	1
    630 # define LOG2_4	2
    631 # define LOG2_8	3
    632 # define MIPS_CIDFL_RMI_CPUS(ncores, nthreads)				\
    633 		((LOG2_ ## ncores << MIPS_CIDFL_RMI_CORES_SHIFT)	\
    634 		|(LOG2_ ## nthreads << MIPS_CIDFL_RMI_THREADS_SHIFT))
    635 # define MIPS_CIDFL_RMI_NTHREADS(cidfl)					\
    636 		(1 << (((cidfl) & MIPS_CIDFL_RMI_THREADS_MASK)		\
    637 			>> MIPS_CIDFL_RMI_THREADS_SHIFT))
    638 # define MIPS_CIDFL_RMI_NCORES(cidfl)					\
    639 		(1 << (((cidfl) & MIPS_CIDFL_RMI_CORES_MASK)		\
    640 			>> MIPS_CIDFL_RMI_CORES_SHIFT))
    641 #define MIPS_CIDFL_RMI_L2SZ_MASK	__BITS(14,11)
    642 # define MIPS_CIDFL_RMI_L2SZ_SHIFT	11
    643 # define RMI_L2SZ_256KB	 0
    644 # define RMI_L2SZ_512KB  1
    645 # define RMI_L2SZ_1MB    2
    646 # define RMI_L2SZ_2MB    3
    647 # define RMI_L2SZ_4MB    4
    648 # define MIPS_CIDFL_RMI_L2(l2sz)					\
    649 		(RMI_L2SZ_ ## l2sz << MIPS_CIDFL_RMI_L2SZ_SHIFT)
    650 # define MIPS_CIDFL_RMI_L2SZ(cidfl)					\
    651 		((256*1024) << (((cidfl) & MIPS_CIDFL_RMI_L2SZ_MASK)	\
    652 			>> MIPS_CIDFL_RMI_L2SZ_SHIFT))
    653 
    654 #endif	/* _KERNEL */
    655 #endif	/* _MIPS_LOCORE_H */
    656