| 1 | /* |
| 2 | * HND Run Time Environment for standalone MIPS programs. |
| 3 | * |
| 4 | * Copyright 2007, Broadcom Corporation |
| 5 | * All Rights Reserved. |
| 6 | * |
| 7 | * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY |
| 8 | * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM |
| 9 | * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS |
| 10 | * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | #ifndef _MISPINC_H |
| 15 | #define _MISPINC_H |
| 16 | |
| 17 | |
| 18 | /* MIPS defines */ |
| 19 | |
| 20 | #ifdef _LANGUAGE_ASSEMBLY |
| 21 | |
| 22 | /* |
| 23 | * Symbolic register names for 32 bit ABI |
| 24 | */ |
| 25 | #define zero $0 /* wired zero */ |
| 26 | #define AT $1 /* assembler temp - uppercase because of ".set at" */ |
| 27 | #define v0 $2 /* return value */ |
| 28 | #define v1 $3 |
| 29 | #define a0 $4 /* argument registers */ |
| 30 | #define a1 $5 |
| 31 | #define a2 $6 |
| 32 | #define a3 $7 |
| 33 | #define t0 $8 /* caller saved */ |
| 34 | #define t1 $9 |
| 35 | #define t2 $10 |
| 36 | #define t3 $11 |
| 37 | #define t4 $12 |
| 38 | #define t5 $13 |
| 39 | #define t6 $14 |
| 40 | #define t7 $15 |
| 41 | #define s0 $16 /* callee saved */ |
| 42 | #define s1 $17 |
| 43 | #define s2 $18 |
| 44 | #define s3 $19 |
| 45 | #define s4 $20 |
| 46 | #define s5 $21 |
| 47 | #define s6 $22 |
| 48 | #define s7 $23 |
| 49 | #define t8 $24 /* caller saved */ |
| 50 | #define t9 $25 |
| 51 | #define jp $25 /* PIC jump register */ |
| 52 | #define k0 $26 /* kernel scratch */ |
| 53 | #define k1 $27 |
| 54 | #define gp $28 /* global pointer */ |
| 55 | #define sp $29 /* stack pointer */ |
| 56 | #define fp $30 /* frame pointer */ |
| 57 | #define s8 $30 /* same like fp! */ |
| 58 | #define ra $31 /* return address */ |
| 59 | |
| 60 | |
| 61 | /* CP0 Registers */ |
| 62 | |
| 63 | #define C0_INX $0 |
| 64 | #define C0_RAND $1 |
| 65 | #define C0_TLBLO0 $2 |
| 66 | #define C0_TLBLO C0_TLBLO0 |
| 67 | #define C0_TLBLO1 $3 |
| 68 | #define C0_CTEXT $4 |
| 69 | #define C0_PGMASK $5 |
| 70 | #define C0_WIRED $6 |
| 71 | #define C0_INFO $7 |
| 72 | #define C0_BADVADDR $8 |
| 73 | #define C0_COUNT $9 |
| 74 | #define C0_TLBHI $10 |
| 75 | #define C0_COMPARE $11 |
| 76 | #define C0_SR $12 |
| 77 | #define C0_STATUS C0_SR |
| 78 | #define C0_CAUSE $13 |
| 79 | #define C0_EPC $14 |
| 80 | #define C0_PRID $15 |
| 81 | #define C0_CONFIG $16 |
| 82 | #define C0_LLADDR $17 |
| 83 | #define C0_WATCHLO $18 |
| 84 | #define C0_WATCHHI $19 |
| 85 | #define C0_XCTEXT $20 |
| 86 | #define C0_DIAGNOSTIC $22 |
| 87 | #define C0_BROADCOM C0_DIAGNOSTIC |
| 88 | #define C0_PERFORMANCE $25 |
| 89 | #define C0_ECC $26 |
| 90 | #define C0_CACHEERR $27 |
| 91 | #define C0_TAGLO $28 |
| 92 | #define C0_TAGHI $29 |
| 93 | #define C0_ERREPC $30 |
| 94 | #define C0_DESAVE $31 |
| 95 | |
| 96 | /* |
| 97 | * LEAF - declare leaf routine |
| 98 | */ |
| 99 | #define LEAF(symbol) \ |
| 100 | .globl symbol; \ |
| 101 | .align 2; \ |
| 102 | .type symbol, @function; \ |
| 103 | .ent symbol, 0; \ |
| 104 | symbol: .frame sp, 0, ra |
| 105 | |
| 106 | /* |
| 107 | * END - mark end of function |
| 108 | */ |
| 109 | #define END(function) \ |
| 110 | .end function; \ |
| 111 | .size function, . - function |
| 112 | |
| 113 | #define _ULCAST_ |
| 114 | |
| 115 | #define MFC0_SEL(dst, src, sel) \ |
| 116 | .word\t(0x40000000 | ((dst) << 16) | ((src) << 11) | (sel)) |
| 117 | |
| 118 | |
| 119 | #define MTC0_SEL(dst, src, sel) \ |
| 120 | .word\t(0x40800000 | ((dst) << 16) | ((src) << 11) | (sel)) |
| 121 | |
| 122 | #else |
| 123 | |
| 124 | /* |
| 125 | * The following macros are especially useful for __asm__ |
| 126 | * inline assembler. |
| 127 | */ |
| 128 | #ifndef __STR |
| 129 | #define __STR(x) #x |
| 130 | #endif |
| 131 | #ifndef STR |
| 132 | #define STR(x) __STR(x) |
| 133 | #endif |
| 134 | |
| 135 | #define _ULCAST_ (unsigned long) |
| 136 | |
| 137 | |
| 138 | /* CP0 Registers */ |
| 139 | |
| 140 | #define C0_INX 0 /* CP0: TLB Index */ |
| 141 | #define C0_RAND 1 /* CP0: TLB Random */ |
| 142 | #define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ |
| 143 | #define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ |
| 144 | #define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ |
| 145 | #define C0_CTEXT 4 /* CP0: Context */ |
| 146 | #define C0_PGMASK 5 /* CP0: TLB PageMask */ |
| 147 | #define C0_WIRED 6 /* CP0: TLB Wired */ |
| 148 | #define C0_INFO 7 /* CP0: Info */ |
| 149 | #define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ |
| 150 | #define C0_COUNT 9 /* CP0: Count */ |
| 151 | #define C0_TLBHI 10 /* CP0: TLB EntryHi */ |
| 152 | #define C0_COMPARE 11 /* CP0: Compare */ |
| 153 | #define C0_SR 12 /* CP0: Processor Status */ |
| 154 | #define C0_STATUS C0_SR /* CP0: Processor Status */ |
| 155 | #define C0_CAUSE 13 /* CP0: Exception Cause */ |
| 156 | #define C0_EPC 14 /* CP0: Exception PC */ |
| 157 | #define C0_PRID 15 /* CP0: Processor Revision Indentifier */ |
| 158 | #define C0_CONFIG 16 /* CP0: Config */ |
| 159 | #define C0_LLADDR 17 /* CP0: LLAddr */ |
| 160 | #define C0_WATCHLO 18 /* CP0: WatchpointLo */ |
| 161 | #define C0_WATCHHI 19 /* CP0: WatchpointHi */ |
| 162 | #define C0_XCTEXT 20 /* CP0: XContext */ |
| 163 | #define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ |
| 164 | #define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ |
| 165 | #define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ |
| 166 | #define C0_ECC 26 /* CP0: ECC */ |
| 167 | #define C0_CACHEERR 27 /* CP0: CacheErr */ |
| 168 | #define C0_TAGLO 28 /* CP0: TagLo */ |
| 169 | #define C0_TAGHI 29 /* CP0: TagHi */ |
| 170 | #define C0_ERREPC 30 /* CP0: ErrorEPC */ |
| 171 | #define C0_DESAVE 31 /* CP0: DebugSave */ |
| 172 | |
| 173 | #endif /* _LANGUAGE_ASSEMBLY */ |
| 174 | |
| 175 | /* |
| 176 | * Memory segments (32bit kernel mode addresses) |
| 177 | */ |
| 178 | #undef KUSEG |
| 179 | #undef KSEG0 |
| 180 | #undef KSEG1 |
| 181 | #undef KSEG2 |
| 182 | #undef KSEG3 |
| 183 | #define KUSEG 0x00000000 |
| 184 | #define KSEG0 0x80000000 |
| 185 | #define KSEG1 0xa0000000 |
| 186 | #define KSEG2 0xc0000000 |
| 187 | #define KSEG3 0xe0000000 |
| 188 | #define PHYSADDR_MASK 0x1fffffff |
| 189 | |
| 190 | /* |
| 191 | * Map an address to a certain kernel segment |
| 192 | */ |
| 193 | #undef PHYSADDR |
| 194 | #undef KSEG0ADDR |
| 195 | #undef KSEG1ADDR |
| 196 | #undef KSEG2ADDR |
| 197 | #undef KSEG3ADDR |
| 198 | |
| 199 | #define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) |
| 200 | #define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) |
| 201 | #define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) |
| 202 | #define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) |
| 203 | #define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) |
| 204 | |
| 205 | |
| 206 | #ifndef Index_Invalidate_I |
| 207 | /* |
| 208 | * Cache Operations |
| 209 | */ |
| 210 | #define Index_Invalidate_I 0x00 |
| 211 | #define Index_Writeback_Inv_D 0x01 |
| 212 | #define Index_Invalidate_SI 0x02 |
| 213 | #define Index_Writeback_Inv_SD 0x03 |
| 214 | #define Index_Load_Tag_I 0x04 |
| 215 | #define Index_Load_Tag_D 0x05 |
| 216 | #define Index_Load_Tag_SI 0x06 |
| 217 | #define Index_Load_Tag_SD 0x07 |
| 218 | #define Index_Store_Tag_I 0x08 |
| 219 | #define Index_Store_Tag_D 0x09 |
| 220 | #define Index_Store_Tag_SI 0x0A |
| 221 | #define Index_Store_Tag_SD 0x0B |
| 222 | #define Create_Dirty_Excl_D 0x0d |
| 223 | #define Create_Dirty_Excl_SD 0x0f |
| 224 | #define Hit_Invalidate_I 0x10 |
| 225 | #define Hit_Invalidate_D 0x11 |
| 226 | #define Hit_Invalidate_SI 0x12 |
| 227 | #define Hit_Invalidate_SD 0x13 |
| 228 | #define Fill_I 0x14 |
| 229 | #define Hit_Writeback_Inv_D 0x15 |
| 230 | /* 0x16 is unused */ |
| 231 | #define Hit_Writeback_Inv_SD 0x17 |
| 232 | #define R5K_Page_Invalidate_S 0x17 |
| 233 | #define Hit_Writeback_I 0x18 |
| 234 | #define Hit_Writeback_D 0x19 |
| 235 | /* 0x1a is unused */ |
| 236 | #define Hit_Writeback_SD 0x1b |
| 237 | /* 0x1c is unused */ |
| 238 | /* 0x1e is unused */ |
| 239 | #define Hit_Set_Virtual_SI 0x1e |
| 240 | #define Hit_Set_Virtual_SD 0x1f |
| 241 | #endif /* !Index_Invalidate_I */ |
| 242 | |
| 243 | |
| 244 | /* |
| 245 | * R4x00 interrupt enable / cause bits |
| 246 | */ |
| 247 | #define IE_SW0 (_ULCAST_(1) << 8) |
| 248 | #define IE_SW1 (_ULCAST_(1) << 9) |
| 249 | #define IE_IRQ0 (_ULCAST_(1) << 10) |
| 250 | #define IE_IRQ1 (_ULCAST_(1) << 11) |
| 251 | #define IE_IRQ2 (_ULCAST_(1) << 12) |
| 252 | #define IE_IRQ3 (_ULCAST_(1) << 13) |
| 253 | #define IE_IRQ4 (_ULCAST_(1) << 14) |
| 254 | #define IE_IRQ5 (_ULCAST_(1) << 15) |
| 255 | |
| 256 | #ifndef ST0_UM |
| 257 | /* |
| 258 | * Bitfields in the mips32 cp0 status register |
| 259 | */ |
| 260 | #define ST0_IE 0x00000001 |
| 261 | #define ST0_EXL 0x00000002 |
| 262 | #define ST0_ERL 0x00000004 |
| 263 | #define ST0_UM 0x00000010 |
| 264 | #define ST0_SWINT0 0x00000100 |
| 265 | #define ST0_SWINT1 0x00000200 |
| 266 | #define ST0_HWINT0 0x00000400 |
| 267 | #define ST0_HWINT1 0x00000800 |
| 268 | #define ST0_HWINT2 0x00001000 |
| 269 | #define ST0_HWINT3 0x00002000 |
| 270 | #define ST0_HWINT4 0x00004000 |
| 271 | #define ST0_HWINT5 0x00008000 |
| 272 | #define ST0_IM 0x0000ff00 |
| 273 | #define ST0_NMI 0x00080000 |
| 274 | #define ST0_SR 0x00100000 |
| 275 | #define ST0_TS 0x00200000 |
| 276 | #define ST0_BEV 0x00400000 |
| 277 | #define ST0_RE 0x02000000 |
| 278 | #define ST0_RP 0x08000000 |
| 279 | #define ST0_CU 0xf0000000 |
| 280 | #define ST0_CU0 0x10000000 |
| 281 | #define ST0_CU1 0x20000000 |
| 282 | #define ST0_CU2 0x40000000 |
| 283 | #define ST0_CU3 0x80000000 |
| 284 | #endif /* !ST0_UM */ |
| 285 | |
| 286 | |
| 287 | /* |
| 288 | * Bitfields in the mips32 cp0 cause register |
| 289 | */ |
| 290 | #define C_EXC 0x0000007c |
| 291 | #define C_EXC_SHIFT 2 |
| 292 | #define C_INT 0x0000ff00 |
| 293 | #define C_INT_SHIFT 8 |
| 294 | #define C_SW0 (_ULCAST_(1) << 8) |
| 295 | #define C_SW1 (_ULCAST_(1) << 9) |
| 296 | #define C_IRQ0 (_ULCAST_(1) << 10) |
| 297 | #define C_IRQ1 (_ULCAST_(1) << 11) |
| 298 | #define C_IRQ2 (_ULCAST_(1) << 12) |
| 299 | #define C_IRQ3 (_ULCAST_(1) << 13) |
| 300 | #define C_IRQ4 (_ULCAST_(1) << 14) |
| 301 | #define C_IRQ5 (_ULCAST_(1) << 15) |
| 302 | #define C_WP 0x00400000 |
| 303 | #define C_IV 0x00800000 |
| 304 | #define C_CE 0x30000000 |
| 305 | #define C_CE_SHIFT 28 |
| 306 | #define C_BD 0x80000000 |
| 307 | |
| 308 | /* Values in C_EXC */ |
| 309 | #define EXC_INT 0 |
| 310 | #define EXC_TLBM 1 |
| 311 | #define EXC_TLBL 2 |
| 312 | #define EXC_TLBS 3 |
| 313 | #define EXC_AEL 4 |
| 314 | #define EXC_AES 5 |
| 315 | #define EXC_IBE 6 |
| 316 | #define EXC_DBE 7 |
| 317 | #define EXC_SYS 8 |
| 318 | #define EXC_BPT 9 |
| 319 | #define EXC_RI 10 |
| 320 | #define EXC_CU 11 |
| 321 | #define EXC_OV 12 |
| 322 | #define EXC_TR 13 |
| 323 | #define EXC_WATCH 23 |
| 324 | #define EXC_MCHK 24 |
| 325 | |
| 326 | |
| 327 | /* |
| 328 | * Bits in the cp0 config register. |
| 329 | */ |
| 330 | #define CONF_CM_CACHABLE_NO_WA 0 |
| 331 | #define CONF_CM_CACHABLE_WA 1 |
| 332 | #define CONF_CM_UNCACHED 2 |
| 333 | #define CONF_CM_CACHABLE_NONCOHERENT 3 |
| 334 | #define CONF_CM_CACHABLE_CE 4 |
| 335 | #define CONF_CM_CACHABLE_COW 5 |
| 336 | #define CONF_CM_CACHABLE_CUW 6 |
| 337 | #define CONF_CM_CACHABLE_ACCELERATED 7 |
| 338 | #define CONF_CM_CMASK 7 |
| 339 | #define CONF_CU (_ULCAST_(1) << 3) |
| 340 | #define CONF_DB (_ULCAST_(1) << 4) |
| 341 | #define CONF_IB (_ULCAST_(1) << 5) |
| 342 | #define CONF_SE (_ULCAST_(1) << 12) |
| 343 | #ifndef CONF_BE /* duplicate in mipsregs.h */ |
| 344 | #define CONF_BE (_ULCAST_(1) << 15) |
| 345 | #endif |
| 346 | #define CONF_SC (_ULCAST_(1) << 17) |
| 347 | #define CONF_AC (_ULCAST_(1) << 23) |
| 348 | #define CONF_HALT (_ULCAST_(1) << 25) |
| 349 | #ifndef CONF_M /* duplicate in mipsregs.h */ |
| 350 | #define CONF_M (_ULCAST_(1) << 31) |
| 351 | #endif |
| 352 | |
| 353 | |
| 354 | /* |
| 355 | * Bits in the cp0 config register select 1. |
| 356 | */ |
| 357 | #define CONF1_FP 0x00000001 /* FPU present */ |
| 358 | #define CONF1_EP 0x00000002 /* EJTAG present */ |
| 359 | #define CONF1_CA 0x00000004 /* mips16 implemented */ |
| 360 | #define CONF1_WR 0x00000008 /* Watch registers present */ |
| 361 | #define CONF1_PC 0x00000010 /* Performance counters present */ |
| 362 | #define CONF1_DA_SHIFT 7 /* D$ associativity */ |
| 363 | #define CONF1_DA_MASK 0x00000380 |
| 364 | #define CONF1_DA_BASE 1 |
| 365 | #define CONF1_DL_SHIFT 10 /* D$ line size */ |
| 366 | #define CONF1_DL_MASK 0x00001c00 |
| 367 | #define CONF1_DL_BASE 2 |
| 368 | #define CONF1_DS_SHIFT 13 /* D$ sets/way */ |
| 369 | #define CONF1_DS_MASK 0x0000e000 |
| 370 | #define CONF1_DS_BASE 64 |
| 371 | #define CONF1_IA_SHIFT 16 /* I$ associativity */ |
| 372 | #define CONF1_IA_MASK 0x00070000 |
| 373 | #define CONF1_IA_BASE 1 |
| 374 | #define CONF1_IL_SHIFT 19 /* I$ line size */ |
| 375 | #define CONF1_IL_MASK 0x00380000 |
| 376 | #define CONF1_IL_BASE 2 |
| 377 | #define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ |
| 378 | #define CONF1_IS_MASK 0x01c00000 |
| 379 | #define CONF1_IS_BASE 64 |
| 380 | #define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ |
| 381 | #define CONF1_MS_SHIFT 25 |
| 382 | |
| 383 | /* PRID register */ |
| 384 | #define PRID_COPT_MASK 0xff000000 |
| 385 | #define PRID_COMP_MASK 0x00ff0000 |
| 386 | #define PRID_IMP_MASK 0x0000ff00 |
| 387 | #define PRID_REV_MASK 0x000000ff |
| 388 | |
| 389 | #define PRID_COMP_LEGACY 0x000000 |
| 390 | #define PRID_COMP_MIPS 0x010000 |
| 391 | #define PRID_COMP_BROADCOM 0x020000 |
| 392 | #define PRID_COMP_ALCHEMY 0x030000 |
| 393 | #define PRID_COMP_SIBYTE 0x040000 |
| 394 | #define PRID_IMP_BCM4710 0x4000 |
| 395 | #define PRID_IMP_BCM3302 0x9000 |
| 396 | #define PRID_IMP_BCM3303 0x9100 |
| 397 | |
| 398 | #define PRID_IMP_UNKNOWN 0xff00 |
| 399 | |
| 400 | #define BCM330X(id) \ |
| 401 | (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \ |
| 402 | (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) || \ |
| 403 | ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \ |
| 404 | (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) |
| 405 | |
| 406 | /* Bits in C0_BROADCOM */ |
| 407 | #define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ |
| 408 | #define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ |
| 409 | #define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ |
| 410 | #define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ |
| 411 | #define BRCM_CLF_ENABLE 0x00100000 /* Enable cache line first feature */ |
| 412 | |
| 413 | /* PreFetch Cache aka Read Ahead Cache */ |
| 414 | |
| 415 | #define PFC_CR0 0xff400000 /* control reg 0 */ |
| 416 | #define PFC_CR1 0xff400004 /* control reg 1 */ |
| 417 | |
| 418 | /* PFC operations */ |
| 419 | #define PFC_I 0x00000001 /* Enable PFC use for instructions */ |
| 420 | #define PFC_D 0x00000002 /* Enable PFC use for data */ |
| 421 | #define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ |
| 422 | #define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ |
| 423 | #define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ |
| 424 | #define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ |
| 425 | #define PFC_DPF 0x00000040 /* Enable directional prefetching */ |
| 426 | #define PFC_FLUSH 0x00000100 /* Flush the PFC */ |
| 427 | #define PFC_BRR 0x40000000 /* Bus error indication */ |
| 428 | #define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ |
| 429 | |
| 430 | /* Handy defaults */ |
| 431 | #define PFC_DISABLED 0 |
| 432 | #define PFC_AUTO 0xffffffff /* auto select the default mode */ |
| 433 | #define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) |
| 434 | #define PFC_INST_NOPF (PFC_I | PFC_CINV) |
| 435 | #define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) |
| 436 | #define PFC_DATA_NOPF (PFC_D | PFC_CINV) |
| 437 | #define PFC_I_AND_D (PFC_INST | PFC_DATA) |
| 438 | #define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) |
| 439 | |
| 440 | #ifndef _LANGUAGE_ASSEMBLY |
| 441 | |
| 442 | /* |
| 443 | * Macros to access the system control coprocessor |
| 444 | */ |
| 445 | |
| 446 | #define MFC0(source, sel) \ |
| 447 | ({ \ |
| 448 | int __res; \ |
| 449 | __asm__ __volatile__(" \ |
| 450 | .set\tnoreorder; \ |
| 451 | .set\tnoat; \ |
| 452 | .word\t"STR(0x40010000 | ((source) << 11) | (sel))"; \ |
| 453 | move\t%0, $1; \ |
| 454 | .set\tat; \ |
| 455 | .set\treorder" \ |
| 456 | :"=r" (__res) \ |
| 457 | : \ |
| 458 | :"$1"); \ |
| 459 | __res; \ |
| 460 | }) |
| 461 | |
| 462 | #define MTC0(source, sel, value) \ |
| 463 | do { \ |
| 464 | __asm__ __volatile__(" \ |
| 465 | .set\tnoreorder; \ |
| 466 | .set\tnoat; \ |
| 467 | move\t$1, %z0; \ |
| 468 | .word\t"STR(0x40810000 | ((source) << 11) | (sel))"; \ |
| 469 | .set\tat; \ |
| 470 | .set\treorder" \ |
| 471 | : \ |
| 472 | :"jr" (value) \ |
| 473 | :"$1"); \ |
| 474 | } while (0) |
| 475 | |
| 476 | #define get_c0_count() \ |
| 477 | ({ \ |
| 478 | int __res; \ |
| 479 | __asm__ __volatile__(" \ |
| 480 | .set\tnoreorder; \ |
| 481 | .set\tnoat; \ |
| 482 | mfc0\t%0, $9; \ |
| 483 | .set\tat; \ |
| 484 | .set\treorder" \ |
| 485 | :"=r" (__res)); \ |
| 486 | __res; \ |
| 487 | }) |
| 488 | |
| 489 | static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) |
| 490 | { |
| 491 | uint lsz, sets, ways; |
| 492 | |
| 493 | /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ |
| 494 | if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) |
| 495 | lsz = CONF1_IL_BASE << lsz; |
| 496 | sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); |
| 497 | ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); |
| 498 | *size = lsz * sets * ways; |
| 499 | *lsize = lsz; |
| 500 | } |
| 501 | |
| 502 | static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) |
| 503 | { |
| 504 | uint lsz, sets, ways; |
| 505 | |
| 506 | /* Data Cache Size = Associativity * Line Size * Sets Per Way */ |
| 507 | if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) |
| 508 | lsz = CONF1_DL_BASE << lsz; |
| 509 | sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); |
| 510 | ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); |
| 511 | *size = lsz * sets * ways; |
| 512 | *lsize = lsz; |
| 513 | } |
| 514 | |
| 515 | #define cache_op(base, op) \ |
| 516 | __asm__ __volatile__(" \ |
| 517 | .set noreorder; \ |
| 518 | .set mips3; \ |
| 519 | cache %1, (%0); \ |
| 520 | .set mips0; \ |
| 521 | .set reorder" \ |
| 522 | : \ |
| 523 | : "r" (base), \ |
| 524 | "i" (op)); |
| 525 | |
| 526 | #define cache_unroll4(base, delta, op) \ |
| 527 | __asm__ __volatile__(" \ |
| 528 | .set noreorder; \ |
| 529 | .set mips3; \ |
| 530 | cache %1, 0(%0); \ |
| 531 | cache %1, delta(%0); \ |
| 532 | cache %1, (2 * delta)(%0); \ |
| 533 | cache %1, (3 * delta)(%0); \ |
| 534 | .set mips0; \ |
| 535 | .set reorder" \ |
| 536 | : \ |
| 537 | : "r" (base), \ |
| 538 | "i" (op)); |
| 539 | |
| 540 | #endif /* !_LANGUAGE_ASSEMBLY */ |
| 541 | |
| 542 | #endif /* _MISPINC_H */ |
| 543 | |