diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-25 04:49:46 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-25 04:49:46 +0000 |
commit | 4c55adaa6d06e5533aebaceea7640ecf10952231 (patch) | |
tree | 0f2e4190d1e9db004e50c7f33a1fe46337fd1885 /include | |
parent | 4c86076eb07eb647b1080355e18dc9d4c49bf7e1 (diff) |
Kernel FPU emulator, chain saw edition.
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-mips/bootinfo.h | 2 | ||||
-rw-r--r-- | include/asm-mips/bugs.h | 6 | ||||
-rw-r--r-- | include/asm-mips/cache.h | 17 | ||||
-rw-r--r-- | include/asm-mips/cpu.h | 110 | ||||
-rw-r--r-- | include/asm-mips/inst.h | 77 | ||||
-rw-r--r-- | include/asm-mips/mipsregs.h | 52 | ||||
-rw-r--r-- | include/asm-mips/processor.h | 35 |
7 files changed, 252 insertions, 47 deletions
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 51ad431ba..8b290f916 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -196,7 +196,7 @@ typedef struct mips_arc_DisplayInfo { /* video adapter information */ * .data section */ extern unsigned long mips_memory_upper; -extern unsigned long mips_cputype; +extern struct mips_cpu mips_cpu; extern unsigned long mips_machtype; extern unsigned long mips_machgroup; extern unsigned long mips_tlb_entries; diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index ebcfe4928..17b94e269 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h @@ -1,9 +1,9 @@ -/* $Id: bugs.h,v 1.4 1999/08/18 23:37:49 ralf Exp $ - * +/* * Copyright (C) 1995 Waldorf Electronics * Copyright (C) 1997, 1999 Ralf Baechle */ #include <asm/bootinfo.h> +#include <asm/cpu.h> /* * This is included by init/main.c to check for architecture-dependent bugs. @@ -16,7 +16,7 @@ static inline void check_wait(void) { printk("Checking for 'wait' instruction... "); - switch(mips_cputype) { + switch(mips_cpu.cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h index a6c80d31e..2eb57fc4c 100644 --- a/include/asm-mips/cache.h +++ b/include/asm-mips/cache.h @@ -1,10 +1,9 @@ -/* $Id: cache.h,v 1.4 2000/02/04 07:40:53 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle + * Copyright (C) 1997, 98, 99, 2000 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CACHE_H @@ -12,6 +11,18 @@ #include <linux/config.h> +#ifndef _LANGUAGE_ASSEMBLY +/* + * Descriptor for a cache + */ +struct cache_desc { + int linesz; + int sets; + int ways; + int flags; /* Details like write thru/back, coherent, etc. */ +}; +#endif + #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) #define L1_CACHE_BYTES 16 #else diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index cc5653447..dfbf913a6 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -1,41 +1,91 @@ -/* $Id: cpu.h,v 1.1 1996/06/23 09:38:33 dm Exp $ +/* * cpu.h: Values of the PRId register used to match up * various MIPS cpu types. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ -#ifndef _MIPS_CPU_H -#define _MIPS_CPU_H +#ifndef _ASM_CPU_H +#define _ASM_CPU_H + +#include <asm/cache.h> /* * Assigned values for the product ID register. In order to detect a * certain CPU type exactly eventually additional registers may need to * be examined. */ -#define PRID_IMP_R2000 0x0100 -#define PRID_IMP_R3000 0x0200 -#define PRID_IMP_R6000 0x0300 -#define PRID_IMP_R4000 0x0400 -#define PRID_IMP_R6000A 0x0600 -#define PRID_IMP_R10000 0x0900 -#define PRID_IMP_R4300 0x0b00 -#define PRID_IMP_R8000 0x1000 -#define PRID_IMP_R4600 0x2000 -#define PRID_IMP_R4700 0x2100 -#define PRID_IMP_R4640 0x2200 -#define PRID_IMP_R4650 0x2200 /* Same as R4640 */ -#define PRID_IMP_R5000 0x2300 -#define PRID_IMP_R5432 0x5400 -#define PRID_IMP_SONIC 0x2400 -#define PRID_IMP_MAGIC 0x2500 -#define PRID_IMP_RM7000 0x2700 -#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ - -#define PRID_IMP_UNKNOWN 0xff00 - -#define PRID_REV_R4400 0x0040 -#define PRID_REV_R3000A 0x0030 -#define PRID_REV_R3000 0x0020 -#define PRID_REV_R2000A 0x0010 - -#endif /* !(_MIPS_CPU_H) */ +#define PRID_IMP_R2000 0x0100 +#define PRID_IMP_R3000 0x0200 +#define PRID_IMP_R6000 0x0300 +#define PRID_IMP_R4000 0x0400 +#define PRID_IMP_R6000A 0x0600 +#define PRID_IMP_R10000 0x0900 +#define PRID_IMP_R4300 0x0b00 +#define PRID_IMP_R8000 0x1000 +#define PRID_IMP_R4600 0x2000 +#define PRID_IMP_R4700 0x2100 +#define PRID_IMP_R4640 0x2200 +#define PRID_IMP_R4650 0x2200 /* Same as R4640 */ +#define PRID_IMP_R5000 0x2300 +#define PRID_IMP_R5432 0x5400 +#define PRID_IMP_SONIC 0x2400 +#define PRID_IMP_MAGIC 0x2500 +#define PRID_IMP_RM7000 0x2700 +#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ +#define PRID_IMP_4KC 0x8000 +#define PRID_IMP_5KC 0x8100 + + +#define PRID_IMP_UNKNOWN 0xff00 + +#define PRID_REV_R4400 0x0040 +#define PRID_REV_R3000A 0x0030 +#define PRID_REV_R3000 0x0020 +#define PRID_REV_R2000A 0x0010 + +#ifndef _LANGUAGE_ASSEMBLY +/* + * Capability and feature descriptor structure for MIPS CPU + */ +struct mips_cpu { + unsigned int processor_id; + unsigned int cputype; /* Old "mips_cputype" code */ + int isa_level; + int options; + int tlbsize; + struct cache_desc icache; /* Primary I-cache */ + struct cache_desc dcache; /* Primary D or combined I/D cache */ + struct cache_desc scache; /* Secondary cache */ + struct cache_desc tcache; /* Tertiary/split secondary cache */ +}; + +#endif + +/* + * ISA Level encodings + */ +#define MIPS_CPU_ISA_I 0x00000001 +#define MIPS_CPU_ISA_II 0x00000002 +#define MIPS_CPU_ISA_III 0x00000003 +#define MIPS_CPU_ISA_IV 0x00000004 +#define MIPS_CPU_ISA_V 0x00000005 +#define MIPS_CPU_ISA_M32 0x00000020 +#define MIPS_CPU_ISA_M64 0x00000040 + +/* + * CPU Option encodings + */ +#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ +/* Leave a spare bit for variant MMU types... */ +#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ +#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ +#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ +#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ +#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ +#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ +#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ +#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ +#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ +#define MIPS_CPU_CACHE_CDEX 0x00000800 /* Create_Dirty_Exclusive CACHE op */ + +#endif /* _ASM_CPU_H */ diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h index 8d7328f6d..6ad517241 100644 --- a/include/asm-mips/inst.h +++ b/include/asm-mips/inst.h @@ -5,10 +5,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 2000 by Ralf Baechle */ -#ifndef __ASM_MIPS_INST_H -#define __ASM_MIPS_INST_H +#ifndef _ASM_INST_H +#define _ASM_INST_H /* * Major opcodes; before MIPS IV cop1x was called cop3. @@ -21,7 +21,7 @@ enum major_op { cop0_op, cop1_op, cop2_op, cop1x_op, beql_op, bnel_op, blezl_op, bgtzl_op, daddi_op, daddiu_op, ldl_op, ldr_op, - major_1c_op, major_1d_op, major_1e_op, major_1f_op, + major_1c_op, jalx_op, major_1e_op, major_1f_op, lb_op, lh_op, lwl_op, lw_op, lbu_op, lhu_op, lwr_op, lwu_op, sb_op, sh_op, swl_op, sw_op, @@ -80,6 +80,13 @@ enum cop_op { }; /* + * rt field of cop.bc_op opcodes + */ +enum bcop_op { + bcf_op, bct_op, bcfl_op, bctl_op +}; + +/* * func field of cop0 coi opcodes. */ enum cop0_coi_func { @@ -301,4 +308,64 @@ union mips_instruction { struct ma_format ma_format; }; -#endif /* __ASM_MIPS_INST_H */ +/* HACHACHAHCAHC ... */ + +/* In case some other massaging is needed, keep MIPSInst as wrapper */ + +#define MIPSInst(x) x + +#define I_OPCODE_SFT 26 +#define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT) + +#define I_JTARGET_SFT 0 +#define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff) + +#define I_RS_SFT 21 +#define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT) + +#define I_RT_SFT 16 +#define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT) + +#define I_IMM_SFT 0 +#define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff))) +#define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff) + +#define I_CACHEOP_SFT 18 +#define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT) + +#define I_CACHESEL_SFT 16 +#define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT) + +#define I_RD_SFT 11 +#define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT) + +#define I_RE_SFT 6 +#define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT) + +#define I_FUNC_SFT 0 +#define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f) + +#define I_FFMT_SFT 21 +#define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT) + +#define I_FT_SFT 16 +#define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT) + +#define I_FS_SFT 11 +#define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT) + +#define I_FD_SFT 6 +#define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT) + +#define I_FR_SFT 21 +#define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT) + +#define I_FMA_FUNC_SFT 2 +#define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT) + +#define I_FMA_FFMT_SFT 0 +#define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003) + +typedef unsigned int mips_instruction; + +#endif /* _ASM_INST_H */ diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 11f8e68d5..a3c3f64ba 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -77,6 +77,58 @@ #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 */ #define PM_4K 0x00000000 diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 7e160259c..decd449f3 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -98,15 +98,20 @@ extern struct task_struct *last_task_used_math; #define NUM_FPU_REGS 32 struct mips_fpu_hard_struct { - unsigned int fp_regs[NUM_FPU_REGS]; + double fp_regs[NUM_FPU_REGS]; unsigned int control; -} __attribute__((aligned(8))); +}; /* - * FIXME: no fpu emulator yet (but who cares anyway?) + * It would be nice to add some more fields for emulator statistics, but there + * are a number of fixed offsets in offset.h and elsewhere that would have to + * be recalculated by hand. So the additional information will be private to + * the FPU emulator for now. See asm-mips/fpu_emulator.h. */ +typedef u64 fpureg_t; struct mips_fpu_soft_struct { - long dummy; + fpureg_t regs[NUM_FPU_REGS]; + unsigned int sr; }; union mips_fpu_union { @@ -148,6 +153,21 @@ struct thread_struct { mm_segment_t current_ds; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; + + /* + * These are really only needed if the full FPU emulator is configured. + * Would be made conditional on MIPS_FPU_EMULATOR if it weren't for the + * fact that having offset.h rebuilt differently for different config + * options would be asking for trouble. + * + * Saved EPC during delay-slot emulation (see math-emu/cp1emu.c) + */ + unsigned long dsemul_epc; + + /* + * Pointer to instruction used to induce address error + */ + unsigned long dsemul_aerpc; }; #endif /* !defined (_LANGUAGE_ASSEMBLY) */ @@ -176,7 +196,12 @@ struct thread_struct { /* \ * For now the default is to fix address errors \ */ \ - MF_FIXADE, { 0 }, 0, 0 \ + MF_FIXADE, { 0 }, 0, 0, \ + /* \ + * dsemul_epc and dsemul_aerpc should never be used uninitialized, \ + * but... \ + */ \ + 0 ,0 \ } #ifdef __KERNEL__ |