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