--- zzzz-none-000/linux-2.4.17/include/asm-mips64/mipsregs.h 2001-09-09 17:43:02.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/include/asm-mips64/mipsregs.h 2004-11-24 13:21:49.000000000 +0000 @@ -3,9 +3,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1997, 1999 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. * Modified for further R[236]000 support by Paul M. Antoine, 1996. - * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ #ifndef _ASM_MIPSREGS_H #define _ASM_MIPSREGS_H @@ -30,6 +32,7 @@ #define CP0_RANDOM $1 #define CP0_ENTRYLO0 $2 #define CP0_ENTRYLO1 $3 +#define CP0_CONF $3 #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_WIRED $6 @@ -57,14 +60,103 @@ #define CP0_ERROREPC $30 /* + * R4640/R4650 cp0 register names. These registers are listed + * here only for completeness; without MMU these CPUs are not useable + * by Linux. A future ELKS port might take make Linux run on them + * though ... + */ +#define CP0_IBASE $0 +#define CP0_IBOUND $1 +#define CP0_DBASE $2 +#define CP0_DBOUND $3 +#define CP0_CALG $17 +#define CP0_IWATCH $18 +#define CP0_DWATCH $19 + +/* + * Coprocessor 0 Set 1 register names + */ +#define CP0_S1_DERRADDR0 $26 +#define CP0_S1_DERRADDR1 $27 +#define CP0_S1_INTCONTROL $20 + +/* + * TX39 Series + */ +#define CP0_TX39_CACHE $7 + +/* * Coprocessor 1 (FPU) register names */ #define CP1_REVISION $0 #define CP1_STATUS $31 /* + * FPU Status Register Values + */ +/* + * Status Register Values + */ + +#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ +#define FPU_CSR_COND 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ +#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ +#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ +#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ +#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ +#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ +#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ + +/* + * X the exception cause indicator + * E the exception enable + * S the sticky/flag bit +*/ +#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_UNI_X 0x00020000 +#define FPU_CSR_INV_X 0x00010000 +#define FPU_CSR_DIV_X 0x00008000 +#define FPU_CSR_OVF_X 0x00004000 +#define FPU_CSR_UDF_X 0x00002000 +#define FPU_CSR_INE_X 0x00001000 + +#define FPU_CSR_ALL_E 0x00000f80 +#define FPU_CSR_INV_E 0x00000800 +#define FPU_CSR_DIV_E 0x00000400 +#define FPU_CSR_OVF_E 0x00000200 +#define FPU_CSR_UDF_E 0x00000100 +#define FPU_CSR_INE_E 0x00000080 + +#define FPU_CSR_ALL_S 0x0000007c +#define FPU_CSR_INV_S 0x00000040 +#define FPU_CSR_DIV_S 0x00000020 +#define FPU_CSR_OVF_S 0x00000010 +#define FPU_CSR_UDF_S 0x00000008 +#define FPU_CSR_INE_S 0x00000004 + +/* rounding mode */ +#define FPU_CSR_RN 0x0 /* nearest */ +#define FPU_CSR_RZ 0x1 /* towards zero */ +#define FPU_CSR_RU 0x2 /* towards +Infinity */ +#define FPU_CSR_RD 0x3 /* towards -Infinity */ + + +/* * Values for PageMask register */ +#include +#ifdef CONFIG_CPU_VR41XX + +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 + +#else + #define PM_4K 0x00000000 #define PM_16K 0x00006000 #define PM_64K 0x0001e000 @@ -73,6 +165,8 @@ #define PM_4M 0x007fe000 #define PM_16M 0x01ffe000 +#endif + /* * Values used for computation of new tlb entries */ @@ -85,37 +179,6 @@ #define PL_16M 24 /* - * Macros to access the system control coprocessor - */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - "mfc0\t%0,"STR(source) \ - : "=r" (__res)); \ - __res;}) - -#define read_64bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmfc0\t%0,"STR(source)"\n\t" \ - ".set\tmips0" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register) \ - : : "r" (value)); - -#define write_64bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmtc0\t%0,"STR(register)"\n\t" \ - ".set\tmips0" \ - : : "r" (value)) - -/* * R4x00 interrupt enable / cause bits */ #define IE_SW0 (1<< 8) @@ -139,31 +202,6 @@ #define C_IRQ4 (1<<14) #define C_IRQ5 (1<<15) -#ifndef _LANGUAGE_ASSEMBLY -/* - * Manipulate the status register. - * Mostly used to access the interrupt bits. - */ -#define __BUILD_SET_CP0(name,register) \ -extern __inline__ unsigned int \ -set_cp0_##name(unsigned int change, unsigned int new) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~change; \ - res |= (new & change); \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} - -__BUILD_SET_CP0(status,CP0_STATUS) -__BUILD_SET_CP0(cause,CP0_CAUSE) -__BUILD_SET_CP0(config,CP0_CONFIG) - -#endif /* defined (_LANGUAGE_ASSEMBLY) */ - /* * Bitfields in the R4xx0 cp0 status register */ @@ -181,6 +219,60 @@ #define ST0_CE 0x00020000 /* + * Bitfields in the R[23]000 cp0 status register. + */ +#define ST0_IEC 0x00000001 +#define ST0_KUC 0x00000002 +#define ST0_IEP 0x00000004 +#define ST0_KUP 0x00000008 +#define ST0_IEO 0x00000010 +#define ST0_KUO 0x00000020 +/* bits 6 & 7 are reserved on R[23]000 */ +#define ST0_ISC 0x00010000 +#define ST0_SWC 0x00020000 +#define ST0_CM 0x00080000 + +/* + * Bits specific to the R4640/R4650 + */ +#define ST0_UM (1 << 4) +#define ST0_IL (1 << 23) +#define ST0_DL (1 << 24) + +/* + * Bitfields in the TX39 family CP0 Configuration Register 3 + */ +#define TX39_CONF_ICS_SHIFT 19 +#define TX39_CONF_ICS_MASK 0x00380000 +#define TX39_CONF_ICS_1KB 0x00000000 +#define TX39_CONF_ICS_2KB 0x00080000 +#define TX39_CONF_ICS_4KB 0x00100000 +#define TX39_CONF_ICS_8KB 0x00180000 +#define TX39_CONF_ICS_16KB 0x00200000 + +#define TX39_CONF_DCS_SHIFT 16 +#define TX39_CONF_DCS_MASK 0x00070000 +#define TX39_CONF_DCS_1KB 0x00000000 +#define TX39_CONF_DCS_2KB 0x00010000 +#define TX39_CONF_DCS_4KB 0x00020000 +#define TX39_CONF_DCS_8KB 0x00030000 +#define TX39_CONF_DCS_16KB 0x00040000 + +#define TX39_CONF_CWFON 0x00004000 +#define TX39_CONF_WBON 0x00002000 +#define TX39_CONF_RF_SHIFT 10 +#define TX39_CONF_RF_MASK 0x00000c00 +#define TX39_CONF_DOZE 0x00000200 +#define TX39_CONF_HALT 0x00000100 +#define TX39_CONF_LOCK 0x00000080 +#define TX39_CONF_ICE 0x00000020 +#define TX39_CONF_DCE 0x00000010 +#define TX39_CONF_IRSIZE_SHIFT 2 +#define TX39_CONF_IRSIZE_MASK 0x0000000c +#define TX39_CONF_DRSIZE_SHIFT 0 +#define TX39_CONF_DRSIZE_MASK 0x00000003 + +/* * Status register bits available in all MIPS CPUs. */ #define ST0_IM 0x0000ff00 @@ -200,6 +292,22 @@ #define STATUSF_IP6 (1 << 14) #define STATUSB_IP7 15 #define STATUSF_IP7 (1 << 15) +#define STATUSB_IP8 0 +#define STATUSF_IP8 (1 << 0) +#define STATUSB_IP9 1 +#define STATUSF_IP9 (1 << 1) +#define STATUSB_IP10 2 +#define STATUSF_IP10 (1 << 2) +#define STATUSB_IP11 3 +#define STATUSF_IP11 (1 << 3) +#define STATUSB_IP12 4 +#define STATUSF_IP12 (1 << 4) +#define STATUSB_IP13 5 +#define STATUSF_IP13 (1 << 5) +#define STATUSB_IP14 6 +#define STATUSF_IP14 (1 << 6) +#define STATUSB_IP15 7 +#define STATUSF_IP15 (1 << 7) #define ST0_CH 0x00040000 #define ST0_SR 0x00100000 #define ST0_TS 0x00200000 @@ -246,7 +354,7 @@ #define CAUSEF_BD (1 << 31) /* - * Bits in the coprocessor 0 config register. + * Bits in the coprozessor 0 config register. */ #define CONF_CM_CACHABLE_NO_WA 0 #define CONF_CM_CACHABLE_WA 1 @@ -260,6 +368,16 @@ #define CONF_DB (1 << 4) #define CONF_IB (1 << 5) #define CONF_SC (1 << 17) +#define CONF_AC (1 << 23) +#define CONF_HALT (1 << 25) + +/* + * Bits in the TX49 coprozessor 0 config register. + */ +#define TX49_CONF_DC (1 << 16) +#define TX49_CONF_IC (1 << 17) /* conflict with CONF_SC */ +#define TX49_CONF_HALT (1 << 18) +#define TX49_CONF_CWFON (1 << 27) /* * R10000 performance counter definitions. @@ -318,13 +436,406 @@ #define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ #ifndef _LANGUAGE_ASSEMBLY + /* - * Functions to access the performance counter and control registers + * Macros to access the system control coprocessor */ -extern asmlinkage unsigned int read_perf_cntr(unsigned int counter); -extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val); -extern asmlinkage unsigned int read_perf_cntl(unsigned int counter); -extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val); -#endif +#define read_32bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "mfc0\t%0,"STR(source) \ + : "=r" (__res)); \ + __res;}) + +#define read_64bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0,"STR(source)"\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + "mtc0\t%0,"STR(register) \ + : : "r" (value)); + +#define write_64bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%0,"STR(register)"\n\t" \ + ".set\tmips0" \ + : : "r" (value)) + +/* + * This should be changed when we get a compiler that support the MIPS32 ISA. + */ +#define read_mips32_cp0_config1() \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "#.set\tmips64\n\t" \ + "#mfc0\t$1, $16, 1\n\t" \ + "#.set\tmips0\n\t" \ + ".word\t0x40018001\n\t" \ + "move\t%0,$1\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + :"=r" (__res)); \ + __res;}) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* TLB operations. */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* Dealing with various CP0 mmu/cache related registers. */ + +/* CP0_PAGEMASK register */ +static inline unsigned long get_pagemask(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $5\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_pagemask(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "mtc0 %z0, $5\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */ +static inline unsigned long get_entrylo0(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "dmfc0 %0, $2\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_entrylo0(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "dmtc0 %z0, $2\n\t" + ".set reorder" + : : "Jr" (val)); +} + +static inline unsigned long get_entrylo1(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "dmfc0 %0, $3\n\t" + ".set reorder" : "=r" (val)); + + return val; +} + +static inline void set_entrylo1(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "dmtc0 %z0, $3\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* CP0_ENTRYHI register */ +static inline unsigned long get_entryhi(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "dmfc0 %0, $10\n\t" + ".set reorder" + : "=r" (val)); + + return val; +} + +static inline void set_entryhi(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "dmtc0 %z0, $10\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* CP0_INDEX register */ +static inline unsigned int get_index(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $0\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_index(unsigned int val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "mtc0 %z0, $0\n\t" + ".set reorder\n\t" + : : "Jr" (val)); +} + +/* CP0_WIRED register */ +static inline unsigned long get_wired(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $6\n\t" + ".set reorder\n\t" + : "=r" (val)); + return val; +} + +static inline void set_wired(unsigned long val) +{ + __asm__ __volatile__( + "\n\t.set noreorder\n\t" + "mtc0 %z0, $6\n\t" + ".set reorder" + : : "Jr" (val)); +} + +static inline unsigned long get_info(void) +{ + unsigned long val; + + __asm__(".set push\n\t" + ".set reorder\n\t" + "mfc0 %0, $7\n\t" + ".set pop" + : "=r" (val)); + return val; +} + +/* CP0_STATUS registers */ +static inline unsigned long get_status(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $12\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_status(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "mtc0 %z0, $12\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* CP0_TAGLO and CP0_TAGHI registers */ +static inline unsigned long get_taglo(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $28\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_taglo(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "mtc0 %z0, $28\n\t" + ".set reorder" + : : "Jr" (val)); +} + +static inline unsigned long get_taghi(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "mfc0 %0, $29\n\t" + ".set reorder" + : "=r" (val)); + return val; +} + +static inline void set_taghi(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "mtc0 %z0, $29\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* CP0_CONTEXT register */ +static inline unsigned long get_context(void) +{ + unsigned long val; + + __asm__ __volatile__( + ".set noreorder\n\t" + "dmfc0 %0, $4\n\t" + ".set reorder" + : "=r" (val)); + + return val; +} + +static inline void set_context(unsigned long val) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "dmtc0 %z0, $4\n\t" + ".set reorder" + : : "Jr" (val)); +} + +/* + * Manipulate the status register. + * Mostly used to access the interrupt bits. + */ +#define __BUILD_SET_CP0(name,register) \ +static inline unsigned int \ +set_cp0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + \ + res = read_32bit_cp0_register(register); \ + res |= set; \ + write_32bit_cp0_register(register, res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_cp0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + \ + res = read_32bit_cp0_register(register); \ + res &= ~clear; \ + write_32bit_cp0_register(register, res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_cp0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_32bit_cp0_register(register); \ + res &= ~change; \ + res |= (new & change); \ + if (change) \ + write_32bit_cp0_register(register, res); \ + \ + return res; \ +} + +__BUILD_SET_CP0(status,CP0_STATUS) +__BUILD_SET_CP0(cause,CP0_CAUSE) +__BUILD_SET_CP0(config,CP0_CONFIG) + +#define __enable_fpu() \ +do { \ + set_cp0_status(ST0_CU1); \ + asm("nop;nop;nop;nop"); /* max. hazard */ \ +} while (0) + +#define __disable_fpu() \ +do { \ + clear_cp0_status(ST0_CU1); \ + /* We don't care about the cp0 hazard here */ \ +} while (0) + +#define enable_fpu() \ +do { \ + if (mips_cpu.options & MIPS_CPU_FPU) \ + __enable_fpu(); \ +} while (0) + +#define disable_fpu() \ +do { \ + if (mips_cpu.options & MIPS_CPU_FPU) \ + __disable_fpu(); \ +} while (0) +#endif /* defined (_LANGUAGE_ASSEMBLY) */ #endif /* _ASM_MIPSREGS_H */