1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle 7 * Copyright (C) 2000 Silicon Graphics, Inc. 8 * Modified for further R[236]000 support by Paul M. Antoine, 1996. 9 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 10 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 11 * Copyright (C) 2003 Maciej W. Rozycki 12 */ 13#ifndef _ASM_MIPSREGS_H 14#define _ASM_MIPSREGS_H 15 16#include <linux/config.h> 17#include <linux/linkage.h> 18 19/* 20 * The following macros are especially useful for __asm__ 21 * inline assembler. 22 */ 23#ifndef __STR 24#define __STR(x) #x 25#endif 26#ifndef STR 27#define STR(x) __STR(x) 28#endif 29 30/* 31 * Configure language 32 */ 33#ifdef __ASSEMBLY__ 34#define _ULCAST_ 35#else 36#define _ULCAST_ (unsigned long) 37#endif 38 39/* 40 * Coprocessor 0 register names 41 */ 42#define CP0_INDEX $0 43#define CP0_RANDOM $1 44#define CP0_ENTRYLO0 $2 45#define CP0_ENTRYLO1 $3 46#define CP0_CONF $3 47#define CP0_CONTEXT $4 48#define CP0_PAGEMASK $5 49#define CP0_WIRED $6 50#define CP0_INFO $7 51#define CP0_BADVADDR $8 52#define CP0_COUNT $9 53#define CP0_ENTRYHI $10 54#define CP0_COMPARE $11 55#define CP0_STATUS $12 56#define CP0_CAUSE $13 57#define CP0_EPC $14 58#define CP0_PRID $15 59#define CP0_CONFIG $16 60#define CP0_LLADDR $17 61#define CP0_WATCHLO $18 62#define CP0_WATCHHI $19 63#define CP0_XCONTEXT $20 64#define CP0_FRAMEMASK $21 65#define CP0_DIAGNOSTIC $22 66#define CP0_DEBUG $23 67#define CP0_DEPC $24 68#define CP0_PERFORMANCE $25 69#define CP0_ECC $26 70#define CP0_CACHEERR $27 71#define CP0_TAGLO $28 72#define CP0_TAGHI $29 73#define CP0_ERROREPC $30 74#define CP0_DESAVE $31 75 76/* 77 * R4640/R4650 cp0 register names. These registers are listed 78 * here only for completeness; without MMU these CPUs are not useable 79 * by Linux. A future ELKS port might take make Linux run on them 80 * though ... 81 */ 82#define CP0_IBASE $0 83#define CP0_IBOUND $1 84#define CP0_DBASE $2 85#define CP0_DBOUND $3 86#define CP0_CALG $17 87#define CP0_IWATCH $18 88#define CP0_DWATCH $19 89 90/* 91 * Coprocessor 0 Set 1 register names 92 */ 93#define CP0_S1_DERRADDR0 $26 94#define CP0_S1_DERRADDR1 $27 95#define CP0_S1_INTCONTROL $20 96 97/* 98 * TX39 Series 99 */ 100#define CP0_TX39_CACHE $7 101 102/* 103 * Coprocessor 1 (FPU) register names 104 */ 105#define CP1_REVISION $0 106#define CP1_STATUS $31 107 108/* 109 * FPU Status Register Values 110 */ 111/* 112 * Status Register Values 113 */ 114 115#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ 116#define FPU_CSR_COND 0x00800000 /* $fcc0 */ 117#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ 118#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ 119#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ 120#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ 121#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ 122#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ 123#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ 124#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ 125 126/* 127 * X the exception cause indicator 128 * E the exception enable 129 * S the sticky/flag bit 130*/ 131#define FPU_CSR_ALL_X 0x0003f000 132#define FPU_CSR_UNI_X 0x00020000 133#define FPU_CSR_INV_X 0x00010000 134#define FPU_CSR_DIV_X 0x00008000 135#define FPU_CSR_OVF_X 0x00004000 136#define FPU_CSR_UDF_X 0x00002000 137#define FPU_CSR_INE_X 0x00001000 138 139#define FPU_CSR_ALL_E 0x00000f80 140#define FPU_CSR_INV_E 0x00000800 141#define FPU_CSR_DIV_E 0x00000400 142#define FPU_CSR_OVF_E 0x00000200 143#define FPU_CSR_UDF_E 0x00000100 144#define FPU_CSR_INE_E 0x00000080 145 146#define FPU_CSR_ALL_S 0x0000007c 147#define FPU_CSR_INV_S 0x00000040 148#define FPU_CSR_DIV_S 0x00000020 149#define FPU_CSR_OVF_S 0x00000010 150#define FPU_CSR_UDF_S 0x00000008 151#define FPU_CSR_INE_S 0x00000004 152 153/* rounding mode */ 154#define FPU_CSR_RN 0x0 /* nearest */ 155#define FPU_CSR_RZ 0x1 /* towards zero */ 156#define FPU_CSR_RU 0x2 /* towards +Infinity */ 157#define FPU_CSR_RD 0x3 /* towards -Infinity */ 158 159 160/* 161 * Values for PageMask register 162 */ 163#ifdef CONFIG_CPU_VR41XX 164 165/* Why doesn't stupidity hurt ... */ 166 167#define PM_1K 0x00000000 168#define PM_4K 0x00001800 169#define PM_16K 0x00007800 170#define PM_64K 0x0001f800 171#define PM_256K 0x0007f800 172 173#else 174 175#define PM_4K 0x00000000 176#define PM_16K 0x00006000 177#define PM_64K 0x0001e000 178#define PM_256K 0x0007e000 179#define PM_1M 0x001fe000 180#define PM_4M 0x007fe000 181#define PM_16M 0x01ffe000 182#define PM_64M 0x07ffe000 183#define PM_256M 0x1fffe000 184 185#endif 186 187/* 188 * Values used for computation of new tlb entries 189 */ 190#define PL_4K 12 191#define PL_16K 14 192#define PL_64K 16 193#define PL_256K 18 194#define PL_1M 20 195#define PL_4M 22 196#define PL_16M 24 197#define PL_64M 26 198#define PL_256M 28 199 200/* 201 * R4x00 interrupt enable / cause bits 202 */ 203#define IE_SW0 (_ULCAST_(1) << 8) 204#define IE_SW1 (_ULCAST_(1) << 9) 205#define IE_IRQ0 (_ULCAST_(1) << 10) 206#define IE_IRQ1 (_ULCAST_(1) << 11) 207#define IE_IRQ2 (_ULCAST_(1) << 12) 208#define IE_IRQ3 (_ULCAST_(1) << 13) 209#define IE_IRQ4 (_ULCAST_(1) << 14) 210#define IE_IRQ5 (_ULCAST_(1) << 15) 211 212/* 213 * R4x00 interrupt cause bits 214 */ 215#define C_SW0 (_ULCAST_(1) << 8) 216#define C_SW1 (_ULCAST_(1) << 9) 217#define C_IRQ0 (_ULCAST_(1) << 10) 218#define C_IRQ1 (_ULCAST_(1) << 11) 219#define C_IRQ2 (_ULCAST_(1) << 12) 220#define C_IRQ3 (_ULCAST_(1) << 13) 221#define C_IRQ4 (_ULCAST_(1) << 14) 222#define C_IRQ5 (_ULCAST_(1) << 15) 223 224/* 225 * Bitfields in the R4xx0 cp0 status register 226 */ 227#define ST0_IE 0x00000001 228#define ST0_EXL 0x00000002 229#define ST0_ERL 0x00000004 230#define ST0_KSU 0x00000018 231# define KSU_USER 0x00000010 232# define KSU_SUPERVISOR 0x00000008 233# define KSU_KERNEL 0x00000000 234#define ST0_UX 0x00000020 235#define ST0_SX 0x00000040 236#define ST0_KX 0x00000080 237#define ST0_DE 0x00010000 238#define ST0_CE 0x00020000 239 240/* 241 * Bitfields in the R[23]000 cp0 status register. 242 */ 243#define ST0_IEC 0x00000001 244#define ST0_KUC 0x00000002 245#define ST0_IEP 0x00000004 246#define ST0_KUP 0x00000008 247#define ST0_IEO 0x00000010 248#define ST0_KUO 0x00000020 249/* bits 6 & 7 are reserved on R[23]000 */ 250#define ST0_ISC 0x00010000 251#define ST0_SWC 0x00020000 252#define ST0_CM 0x00080000 253 254/* 255 * Bits specific to the R4640/R4650 256 */ 257#define ST0_UM (_ULCAST_(1) << 4) 258#define ST0_IL (_ULCAST_(1) << 23) 259#define ST0_DL (_ULCAST_(1) << 24) 260 261/* 262 * Bitfields in the TX39 family CP0 Configuration Register 3 263 */ 264#define TX39_CONF_ICS_SHIFT 19 265#define TX39_CONF_ICS_MASK 0x00380000 266#define TX39_CONF_ICS_1KB 0x00000000 267#define TX39_CONF_ICS_2KB 0x00080000 268#define TX39_CONF_ICS_4KB 0x00100000 269#define TX39_CONF_ICS_8KB 0x00180000 270#define TX39_CONF_ICS_16KB 0x00200000 271 272#define TX39_CONF_DCS_SHIFT 16 273#define TX39_CONF_DCS_MASK 0x00070000 274#define TX39_CONF_DCS_1KB 0x00000000 275#define TX39_CONF_DCS_2KB 0x00010000 276#define TX39_CONF_DCS_4KB 0x00020000 277#define TX39_CONF_DCS_8KB 0x00030000 278#define TX39_CONF_DCS_16KB 0x00040000 279 280#define TX39_CONF_CWFON 0x00004000 281#define TX39_CONF_WBON 0x00002000 282#define TX39_CONF_RF_SHIFT 10 283#define TX39_CONF_RF_MASK 0x00000c00 284#define TX39_CONF_DOZE 0x00000200 285#define TX39_CONF_HALT 0x00000100 286#define TX39_CONF_LOCK 0x00000080 287#define TX39_CONF_ICE 0x00000020 288#define TX39_CONF_DCE 0x00000010 289#define TX39_CONF_IRSIZE_SHIFT 2 290#define TX39_CONF_IRSIZE_MASK 0x0000000c 291#define TX39_CONF_DRSIZE_SHIFT 0 292#define TX39_CONF_DRSIZE_MASK 0x00000003 293 294/* 295 * Status register bits available in all MIPS CPUs. 296 */ 297#define ST0_IM 0x0000ff00 298#define STATUSB_IP0 8 299#define STATUSF_IP0 (_ULCAST_(1) << 8) 300#define STATUSB_IP1 9 301#define STATUSF_IP1 (_ULCAST_(1) << 9) 302#define STATUSB_IP2 10 303#define STATUSF_IP2 (_ULCAST_(1) << 10) 304#define STATUSB_IP3 11 305#define STATUSF_IP3 (_ULCAST_(1) << 11) 306#define STATUSB_IP4 12 307#define STATUSF_IP4 (_ULCAST_(1) << 12) 308#define STATUSB_IP5 13 309#define STATUSF_IP5 (_ULCAST_(1) << 13) 310#define STATUSB_IP6 14 311#define STATUSF_IP6 (_ULCAST_(1) << 14) 312#define STATUSB_IP7 15 313#define STATUSF_IP7 (_ULCAST_(1) << 15) 314#define STATUSB_IP8 0 315#define STATUSF_IP8 (_ULCAST_(1) << 0) 316#define STATUSB_IP9 1 317#define STATUSF_IP9 (_ULCAST_(1) << 1) 318#define STATUSB_IP10 2 319#define STATUSF_IP10 (_ULCAST_(1) << 2) 320#define STATUSB_IP11 3 321#define STATUSF_IP11 (_ULCAST_(1) << 3) 322#define STATUSB_IP12 4 323#define STATUSF_IP12 (_ULCAST_(1) << 4) 324#define STATUSB_IP13 5 325#define STATUSF_IP13 (_ULCAST_(1) << 5) 326#define STATUSB_IP14 6 327#define STATUSF_IP14 (_ULCAST_(1) << 6) 328#define STATUSB_IP15 7 329#define STATUSF_IP15 (_ULCAST_(1) << 7) 330#define ST0_CH 0x00040000 331#define ST0_SR 0x00100000 332#define ST0_TS 0x00200000 333#define ST0_BEV 0x00400000 334#define ST0_RE 0x02000000 335#define ST0_FR 0x04000000 336#define ST0_CU 0xf0000000 337#define ST0_CU0 0x10000000 338#define ST0_CU1 0x20000000 339#define ST0_CU2 0x40000000 340#define ST0_CU3 0x80000000 341#define ST0_XX 0x80000000 /* MIPS IV naming */ 342 343/* 344 * Bitfields and bit numbers in the coprocessor 0 cause register. 345 * 346 * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. 347 */ 348#define CAUSEB_EXCCODE 2 349#define CAUSEF_EXCCODE (_ULCAST_(31) << 2) 350#define CAUSEB_IP 8 351#define CAUSEF_IP (_ULCAST_(255) << 8) 352#define CAUSEB_IP0 8 353#define CAUSEF_IP0 (_ULCAST_(1) << 8) 354#define CAUSEB_IP1 9 355#define CAUSEF_IP1 (_ULCAST_(1) << 9) 356#define CAUSEB_IP2 10 357#define CAUSEF_IP2 (_ULCAST_(1) << 10) 358#define CAUSEB_IP3 11 359#define CAUSEF_IP3 (_ULCAST_(1) << 11) 360#define CAUSEB_IP4 12 361#define CAUSEF_IP4 (_ULCAST_(1) << 12) 362#define CAUSEB_IP5 13 363#define CAUSEF_IP5 (_ULCAST_(1) << 13) 364#define CAUSEB_IP6 14 365#define CAUSEF_IP6 (_ULCAST_(1) << 14) 366#define CAUSEB_IP7 15 367#define CAUSEF_IP7 (_ULCAST_(1) << 15) 368#define CAUSEB_IV 23 369#define CAUSEF_IV (_ULCAST_(1) << 23) 370#define CAUSEB_CE 28 371#define CAUSEF_CE (_ULCAST_(3) << 28) 372#define CAUSEB_BD 31 373#define CAUSEF_BD (_ULCAST_(1) << 31) 374 375/* 376 * Bits in the coprozessor 0 config register. 377 */ 378#define CONF_CM_CACHABLE_NO_WA 0 379#define CONF_CM_CACHABLE_WA 1 380#define CONF_CM_UNCACHED 2 381#define CONF_CM_CACHABLE_NONCOHERENT 3 382#define CONF_CM_CACHABLE_CE 4 383#define CONF_CM_CACHABLE_COW 5 384#define CONF_CM_CACHABLE_CUW 6 385#define CONF_CM_CACHABLE_ACCELERATED 7 386#define CONF_CM_CMASK 7 387#define CONF_CU (_ULCAST_(1) << 3) 388#define CONF_DB (_ULCAST_(1) << 4) 389#define CONF_IB (_ULCAST_(1) << 5) 390#define CONF_SE (_ULCAST_(1) << 12) 391#define CONF_SC (_ULCAST_(1) << 17) 392#define CONF_AC (_ULCAST_(1) << 23) 393#define CONF_HALT (_ULCAST_(1) << 25) 394 395/* 396 * Bits in the TX49 coprozessor 0 config register. 397 */ 398#define TX49_CONF_DC (_ULCAST_(1) << 16) 399#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */ 400#define TX49_CONF_HALT (_ULCAST_(1) << 18) 401#define TX49_CONF_CWFON (_ULCAST_(1) << 27) 402 403/* mips32/64 definitions for CP0 config register */ 404#define CONF_MT_MASK 0x00000380 /* MMU Type */ 405#define CONF_MT_NONE 0x00000000 /* No mmu */ 406#define CONF_MT_TLB 0x00000080 /* TLB present */ 407#define CONF_MT_BAT 0x00000100 /* Block address translation */ 408#define CONF_MT_FM 0x00000180 /* Fixed map (Like 4Kp/4Km) */ 409#define CONF_AR_MASK 0x00001c00 /* Architecture revision */ 410#define CONF_AT_MASK 0x00006000 /* Architecture type */ 411#define CONF_AT_M32 0x00000000 /* mips32 */ 412#define CONF_AT_M6432 0x00002000 /* mips64/mips32?? */ 413#define CONF_AT_M64 0x00004000 /* mips64 */ 414#define CONF_BE 0x00008000 /* BigEndian */ 415#define CONF_BM 0x00010000 /* Burst Mode */ 416#define CONF_BM_SEQ 0x00000000 /* Sequential */ 417#define CONF_BM_SB 0x00010000 /* SubBlock */ 418#define CONF_MM_MASK 0x00060000 /* Merge Mode */ 419#define CONF_MM_NONE 0x00000000 /* No merging */ 420#define CONF_MM_SYSAD 0x00020000 /* SysAD merging */ 421#define CONF_MM_FULL 0x00040000 /* Full merging */ 422#define CONF_MDU 0x00100000 /* Slow MDU */ 423#define CONF_KU_MASK 0x0e000000 /* Kuseg and useg cacheability (for MT=FM) */ 424#define CONF_K23_MASK 0x70000000 /* Kseg2 and Kseg3 cacheability (for MT=FM) */ 425#define CONF_M 0x80000000 /* config1 register present */ 426 427/* mips32/64 definitions for CP0 config1 register */ 428#define CONF1_FP 0x00000001 /* FPU present */ 429#define CONF1_EP 0x00000002 /* EJTAG present */ 430#define CONF1_CA 0x00000004 /* Code compression (mips16) implemented */ 431#define CONF1_WR 0x00000008 /* Watch registers present */ 432#define CONF1_PC 0x00000010 /* Performance counters present */ 433#define CONF1_DA_SHIFT 7 /* Data cache associativity */ 434#define CONF1_DA_MASK 0x00000380 435#define CONF1_DA_BASE 1 436#define CONF1_DA_DM 0x00000000 /* Direct mapped */ 437#define CONF1_DA_2W 0x00000080 /* 2-way */ 438#define CONF1_DA_3W 0x00000100 /* 3-way */ 439#define CONF1_DA_4W 0x00000180 /* 4-way */ 440#define CONF1_DL_SHIFT 10 /* Data cache line size */ 441#define CONF1_DL_MASK 0x00001c00 442#define CONF1_DL_BASE 2 443#define CONF1_DL_NONE 0x00000000 /* No data cache present */ 444#define CONF1_DL_16 0x00000c00 /* 16 bytes */ 445#define CONF1_DS_SHIFT 13 /* Data cache sets/way */ 446#define CONF1_DS_MASK 0x0000e000 447#define CONF1_DS_BASE 64 448#define CONF1_DS_64 0x00000000 /* 64 sets */ 449#define CONF1_DS_128 0x00002000 /* 128 sets */ 450#define CONF1_DS_256 0x00004000 /* 256 sets */ 451#define CONF1_IA_SHIFT 16 /* Instruction cache associativity */ 452#define CONF1_IA_MASK 0x00070000 453#define CONF1_IA_BASE 1 454#define CONF1_IA_DM 0x00000000 /* Direct mapped */ 455#define CONF1_IA_2W 0x00010000 /* 2-way */ 456#define CONF1_IA_3W 0x00020000 /* 3-way */ 457#define CONF1_IA_4W 0x00030000 /* 4-way */ 458#define CONF1_IL_SHIFT 19 /* Instruction cache line size */ 459#define CONF1_IL_MASK 0x00380000 460#define CONF1_IL_BASE 2 461#define CONF1_IL_NONE 0x00000000 /* No data cache present */ 462#define CONF1_IL_16 0x00180000 /* 16 bytes */ 463#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ 464#define CONF1_IS_MASK 0x01c00000 465#define CONF1_IS_BASE 64 466#define CONF1_IS_64 0x00000000 /* 64 sets */ 467#define CONF1_IS_128 0x00400000 /* 128 sets */ 468#define CONF1_IS_256 0x00800000 /* 256 sets */ 469#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ 470#define CONF1_MS_SHIFT 25 471 472 473/* 474 * Events counted by counter #0 475 */ 476#define CE0_CYCLES 0 477#define CE0_INSN_ISSUED 1 478#define CE0_LPSC_ISSUED 2 479#define CE0_S_ISSUED 3 480#define CE0_SC_ISSUED 4 481#define CE0_SC_FAILED 5 482#define CE0_BRANCH_DECODED 6 483#define CE0_QW_WB_SECONDARY 7 484#define CE0_CORRECTED_ECC_ERRORS 8 485#define CE0_ICACHE_MISSES 9 486#define CE0_SCACHE_I_MISSES 10 487#define CE0_SCACHE_I_WAY_MISSPREDICTED 11 488#define CE0_EXT_INTERVENTIONS_REQ 12 489#define CE0_EXT_INVALIDATE_REQ 13 490#define CE0_VIRTUAL_COHERENCY_COND 14 491#define CE0_INSN_GRADUATED 15 492 493/* 494 * Events counted by counter #1 495 */ 496#define CE1_CYCLES 0 497#define CE1_INSN_GRADUATED 1 498#define CE1_LPSC_GRADUATED 2 499#define CE1_S_GRADUATED 3 500#define CE1_SC_GRADUATED 4 501#define CE1_FP_INSN_GRADUATED 5 502#define CE1_QW_WB_PRIMARY 6 503#define CE1_TLB_REFILL 7 504#define CE1_BRANCH_MISSPREDICTED 8 505#define CE1_DCACHE_MISS 9 506#define CE1_SCACHE_D_MISSES 10 507#define CE1_SCACHE_D_WAY_MISSPREDICTED 11 508#define CE1_EXT_INTERVENTION_HITS 12 509#define CE1_EXT_INVALIDATE_REQ 13 510#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS 14 511#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS 15 512 513/* 514 * These flags define in which priviledge mode the counters count events 515 */ 516#define CEB_USER 8 /* Count events in user mode, EXL = ERL = 0 */ 517#define CEB_SUPERVISOR 4 /* Count events in supvervisor mode EXL = ERL = 0 */ 518#define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ 519#define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ 520 521#ifndef __ASSEMBLY__ 522 523/* 524 * Functions to access the r10k performance counter and control registers 525 */ 526#define read_r10k_perf_cntr(counter) \ 527({ unsigned int __res; \ 528 __asm__ __volatile__( \ 529 "mfpc\t%0, "STR(counter) \ 530 : "=r" (__res)); \ 531 __res;}) 532 533#define write_r10k_perf_cntr(counter,val) \ 534 __asm__ __volatile__( \ 535 "mtpc\t%0, "STR(counter) \ 536 : : "r" (val)); 537 538#define read_r10k_perf_cntl(counter) \ 539({ unsigned int __res; \ 540 __asm__ __volatile__( \ 541 "mfps\t%0, "STR(counter) \ 542 : "=r" (__res)); \ 543 __res;}) 544 545#define write_r10k_perf_cntl(counter,val) \ 546 __asm__ __volatile__( \ 547 "mtps\t%0, "STR(counter) \ 548 : : "r" (val)); 549 550/* 551 * Macros to access the system control coprocessor 552 */ 553 554#define __read_32bit_c0_register(source, sel) \ 555({ int __res; \ 556 if (sel == 0) \ 557 __asm__ __volatile__( \ 558 "mfc0\t%0, " #source "\n\t" \ 559 : "=r" (__res)); \ 560 else \ 561 __asm__ __volatile__( \ 562 ".set\tmips32\n\t" \ 563 "mfc0\t%0, " #source ", " #sel "\n\t" \ 564 ".set\tmips0\n\t" \ 565 : "=r" (__res)); \ 566 __res; \ 567}) 568 569#define __read_64bit_c0_register(source, sel) \ 570({ unsigned long __res; \ 571 if (sel == 0) \ 572 __asm__ __volatile__( \ 573 ".set\tmips3\n\t" \ 574 "dmfc0\t%0, " #source "\n\t" \ 575 ".set\tmips0" \ 576 : "=r" (__res)); \ 577 else \ 578 __asm__ __volatile__( \ 579 ".set\tmips64\n\t" \ 580 "dmfc0\t%0, " #source ", " #sel "\n\t" \ 581 ".set\tmips0" \ 582 : "=r" (__res)); \ 583 __res; \ 584}) 585 586#define __write_32bit_c0_register(register, sel, value) \ 587do { \ 588 if (sel == 0) \ 589 __asm__ __volatile__( \ 590 "mtc0\t%z0, " #register "\n\t" \ 591 : : "Jr" (value)); \ 592 else \ 593 __asm__ __volatile__( \ 594 ".set\tmips32\n\t" \ 595 "mtc0\t%z0, " #register ", " #sel "\n\t" \ 596 ".set\tmips0" \ 597 : : "Jr" (value)); \ 598} while (0) 599 600#define __write_64bit_c0_register(register, sel, value) \ 601do { \ 602 if (sel == 0) \ 603 __asm__ __volatile__( \ 604 ".set\tmips3\n\t" \ 605 "dmtc0\t%z0, " #register "\n\t" \ 606 ".set\tmips0" \ 607 : : "Jr" (value)); \ 608 else \ 609 __asm__ __volatile__( \ 610 ".set\tmips64\n\t" \ 611 "dmtc0\t%z0, " #register ", " #sel "\n\t" \ 612 ".set\tmips0" \ 613 : : "Jr" (value)); \ 614} while (0) 615 616#define __read_ulong_c0_register(reg, sel) \ 617 ((sizeof(unsigned long) == 4) ? \ 618 __read_32bit_c0_register(reg, sel) : \ 619 __read_64bit_c0_register(reg, sel)) 620 621#define __write_ulong_c0_register(reg, sel, val) \ 622do { \ 623 if (sizeof(unsigned long) == 4) \ 624 __write_32bit_c0_register(reg, sel, val); \ 625 else \ 626 __write_64bit_c0_register(reg, sel, val); \ 627} while (0) 628 629/* 630 * These versions are only needed for systems with more than 38 bits of 631 * physical address space running the 32-bit kernel. That's none atm :-) 632 */ 633#define __read_64bit_c0_split(source, sel) \ 634({ \ 635 unsigned long long val; \ 636 unsigned long flags; \ 637 \ 638 local_irq_save(flags); \ 639 if (sel == 0) \ 640 __asm__ __volatile__( \ 641 ".set\tmips64\n\t" \ 642 "dmfc0\t%M0, " #source "\n\t" \ 643 "dsll\t%L0, %M0, 32\n\t" \ 644 "dsrl\t%M0, %M0, 32\n\t" \ 645 "dsrl\t%L0, %L0, 32\n\t" \ 646 ".set\tmips0" \ 647 : "=r" (val)); \ 648 else \ 649 __asm__ __volatile__( \ 650 ".set\tmips64\n\t" \ 651 "dmfc0\t%M0, " #source ", " #sel "\n\t" \ 652 "dsll\t%L0, %M0, 32\n\t" \ 653 "dsrl\t%M0, %M0, 32\n\t" \ 654 "dsrl\t%L0, %L0, 32\n\t" \ 655 ".set\tmips0" \ 656 : "=r" (val)); \ 657 local_irq_restore(flags); \ 658 \ 659 val; \ 660}) 661 662#define __write_64bit_c0_split(source, sel, val) \ 663do { \ 664 unsigned long flags; \ 665 \ 666 local_irq_save(flags); \ 667 if (sel == 0) \ 668 __asm__ __volatile__( \ 669 ".set\tmips64\n\t" \ 670 "dsll\t%L0, %L0, 32\n\t" \ 671 "dsrl\t%L0, %L0, 32\n\t" \ 672 "dsll\t%M0, %M0, 32\n\t" \ 673 "or\t%L0, %L0, %M0\n\t" \ 674 "dmtc0\t%L0, " #source "\n\t" \ 675 ".set\tmips0" \ 676 : : "r" (val)); \ 677 else \ 678 __asm__ __volatile__( \ 679 ".set\tmips64\n\t" \ 680 "dsll\t%L0, %L0, 32\n\t" \ 681 "dsrl\t%L0, %L0, 32\n\t" \ 682 "dsll\t%M0, %M0, 32\n\t" \ 683 "or\t%L0, %L0, %M0\n\t" \ 684 "dmtc0\t%L0, " #source ", " #sel "\n\t" \ 685 ".set\tmips0" \ 686 : : "r" (val)); \ 687 local_irq_restore(flags); \ 688} while (0) 689 690#define read_c0_index() __read_32bit_c0_register($0, 0) 691#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) 692 693#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) 694#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) 695 696#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) 697#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) 698 699#define read_c0_conf() __read_32bit_c0_register($3, 0) 700#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) 701 702#define read_c0_context() __read_ulong_c0_register($4, 0) 703#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) 704 705#define read_c0_pagemask() __read_32bit_c0_register($5, 0) 706#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) 707 708#define read_c0_wired() __read_32bit_c0_register($6, 0) 709#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) 710 711#define read_c0_info() __read_32bit_c0_register($7, 0) 712 713#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ 714#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) 715 716#define read_c0_count() __read_32bit_c0_register($9, 0) 717#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) 718 719#define read_c0_entryhi() __read_ulong_c0_register($10, 0) 720#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) 721 722#define read_c0_compare() __read_32bit_c0_register($11, 0) 723#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) 724 725#define read_c0_status() __read_32bit_c0_register($12, 0) 726#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) 727 728#define read_c0_cause() __read_32bit_c0_register($13, 0) 729#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) 730 731#define read_c0_prid() __read_32bit_c0_register($15, 0) 732 733#define read_c0_config() __read_32bit_c0_register($16, 0) 734#define read_c0_config1() __read_32bit_c0_register($16, 1) 735#define read_c0_config2() __read_32bit_c0_register($16, 2) 736#define read_c0_config3() __read_32bit_c0_register($16, 3) 737#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) 738#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) 739#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) 740#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) 741 742/* 743 * The WatchLo register. There may be upto 8 of them. 744 */ 745#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) 746#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) 747#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) 748#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) 749#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) 750#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) 751#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) 752#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) 753#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) 754#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) 755#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) 756#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) 757#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) 758#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) 759#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) 760#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) 761 762/* 763 * The WatchHi register. There may be upto 8 of them. 764 */ 765#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) 766#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) 767#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) 768#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) 769#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) 770#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) 771#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) 772#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) 773 774#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) 775#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) 776#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) 777#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) 778#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) 779#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) 780#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) 781#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) 782 783#define read_c0_xcontext() __read_ulong_c0_register($20, 0) 784#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) 785 786#define read_c0_intcontrol() __read_32bit_c0_register($20, 1) 787#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val) 788 789#define read_c0_framemask() __read_32bit_c0_register($21, 0) 790#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) 791 792#define read_c0_diag() __read_32bit_c0_register($22, 0) 793#define read_c0_diag1() __read_32bit_c0_register($22, 1) 794#define read_c0_diag2() __read_32bit_c0_register($22, 2) 795#define read_c0_diag3() __read_32bit_c0_register($22, 3) 796#define read_c0_diag4() __read_32bit_c0_register($22, 4) 797#define read_c0_diag5() __read_32bit_c0_register($22, 5) 798 799#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) 800#define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val) 801#define write_c0_diag2(val) __write_32bit_c0_register($22, 2, val) 802#define write_c0_diag3(val) __write_32bit_c0_register($22, 3, val) 803#define write_c0_diag4(val) __write_32bit_c0_register($22, 4, val) 804#define write_c0_diag5(val) __write_32bit_c0_register($22, 5, val) 805 806#define read_c0_debug() __read_32bit_c0_register($23, 0) 807#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) 808 809#define read_c0_depc() __read_ulong_c0_register($24, 0) 810#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) 811 812#define read_c0_ecc() __read_32bit_c0_register($26, 0) 813#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) 814 815#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) 816#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) 817 818#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) 819 820#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) 821#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) 822 823#define read_c0_taglo() __read_32bit_c0_register($28, 0) 824#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) 825 826#define read_c0_taghi() __read_32bit_c0_register($29, 0) 827#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) 828 829#define read_c0_errorepc() __read_ulong_c0_register($30, 0) 830#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) 831 832/* 833 * Macros to access the floating point coprocessor control registers 834 */ 835#define read_32bit_cp1_register(source) \ 836({ int __res; \ 837 __asm__ __volatile__( \ 838 ".set\tpush\n\t" \ 839 ".set\treorder\n\t" \ 840 "cfc1\t%0,"STR(source)"\n\t" \ 841 ".set\tpop" \ 842 : "=r" (__res)); \ 843 __res;}) 844 845/* TLB operations. */ 846static inline void tlb_probe(void) 847{ 848 __asm__ __volatile__( 849 ".set noreorder\n\t" 850 "tlbp\n\t" 851 ".set reorder"); 852} 853 854static inline void tlb_read(void) 855{ 856 __asm__ __volatile__( 857 ".set noreorder\n\t" 858 "tlbr\n\t" 859 ".set reorder"); 860} 861 862static inline void tlb_write_indexed(void) 863{ 864 __asm__ __volatile__( 865 ".set noreorder\n\t" 866 "tlbwi\n\t" 867 ".set reorder"); 868} 869 870static inline void tlb_write_random(void) 871{ 872 __asm__ __volatile__( 873 ".set noreorder\n\t" 874 "tlbwr\n\t" 875 ".set reorder"); 876} 877 878/* 879 * Manipulate bits in a c0 register. 880 */ 881#define __BUILD_SET_C0(name,register) \ 882static inline unsigned int \ 883set_c0_##name(unsigned int set) \ 884{ \ 885 unsigned int res; \ 886 \ 887 res = read_c0_##name(); \ 888 res |= set; \ 889 write_c0_##name(res); \ 890 \ 891 return res; \ 892} \ 893 \ 894static inline unsigned int \ 895clear_c0_##name(unsigned int clear) \ 896{ \ 897 unsigned int res; \ 898 \ 899 res = read_c0_##name(); \ 900 res &= ~clear; \ 901 write_c0_##name(res); \ 902 \ 903 return res; \ 904} \ 905 \ 906static inline unsigned int \ 907change_c0_##name(unsigned int change, unsigned int new) \ 908{ \ 909 unsigned int res; \ 910 \ 911 res = read_c0_##name(); \ 912 res &= ~change; \ 913 res |= (new & change); \ 914 write_c0_##name(res); \ 915 \ 916 return res; \ 917} 918 919__BUILD_SET_C0(status,CP0_STATUS) 920__BUILD_SET_C0(cause,CP0_CAUSE) 921__BUILD_SET_C0(config,CP0_CONFIG) 922 923/* 924 * Functions to access the performance counter and control registers 925 */ 926extern asmlinkage unsigned int read_perf_cntr(unsigned int counter); 927extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val); 928extern asmlinkage unsigned int read_perf_cntl(unsigned int counter); 929extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val); 930 931#endif /* !__ASSEMBLY__ */ 932 933#endif /* _ASM_MIPSREGS_H */ 934