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 /arch/mips/kernel/setup.c | |
parent | 4c86076eb07eb647b1080355e18dc9d4c49bf7e1 (diff) |
Kernel FPU emulator, chain saw edition.
Diffstat (limited to 'arch/mips/kernel/setup.c')
-rw-r--r-- | arch/mips/kernel/setup.c | 146 |
1 files changed, 118 insertions, 28 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index db1838916..58d834a43 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -36,6 +36,7 @@ #include <asm/asm.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/cpu.h> #include <asm/io.h> #include <asm/stackframe.h> #include <asm/system.h> @@ -95,7 +96,6 @@ struct kbd_ops *kbd_ops; * These are initialized so they are in the .data section */ unsigned long mips_memory_upper = KSEG0; /* this is set by kernel_entry() */ -unsigned long mips_cputype = CPU_UNKNOWN; unsigned long mips_machtype = MACH_UNKNOWN; unsigned long mips_machgroup = MACH_GROUP_UNKNOWN; @@ -152,63 +152,153 @@ static inline int cpu_has_confreg(void) #endif } +/* declaration of the global struct */ +struct mips_cpu mips_cpu = {PRID_IMP_UNKNOWN, CPU_UNKNOWN, 0, 0, 0, + {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; + +/* Shortcut for assembler access to mips_cpu.options */ +int *cpuoptions = &mips_cpu.options; + +#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ + | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) + static inline void cpu_probe(void) { - unsigned int prid = read_32bit_cp0_register(CP0_PRID); - switch(prid & 0xff00) { + unsigned long config1; + + mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); + switch (mips_cpu.processor_id & 0xff00) { case PRID_IMP_R2000: - mips_cputype = CPU_R2000; + mips_cpu.cputype = CPU_R2000; + mips_cpu.isa_level = MIPS_CPU_ISA_I; + mips_cpu.options = MIPS_CPU_TLB; + mips_cpu.tlbsize = 32; break; case PRID_IMP_R3000: - if((prid & 0xff) == PRID_REV_R3000A) - if(cpu_has_confreg()) - mips_cputype = CPU_R3081E; + if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + mips_cpu.cputype = CPU_R3081E; else - mips_cputype = CPU_R3000A; + mips_cpu.cputype = CPU_R3000A; else - mips_cputype = CPU_R3000; + mips_cpu.cputype = CPU_R3000; + mips_cpu.isa_level = MIPS_CPU_ISA_I; + mips_cpu.options = MIPS_CPU_TLB; + mips_cpu.tlbsize = 32; break; case PRID_IMP_R4000: - if((prid & 0xff) == PRID_REV_R4400) - mips_cputype = CPU_R4400SC; + if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) + mips_cpu.cputype = CPU_R4400SC; else - mips_cputype = CPU_R4000SC; + mips_cpu.cputype = CPU_R4000SC; + mips_cpu.isa_level = MIPS_CPU_ISA_III; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE; + mips_cpu.tlbsize = 48; break; case PRID_IMP_R4600: - mips_cputype = CPU_R4600; + mips_cpu.cputype = CPU_R4600; + mips_cpu.isa_level = MIPS_CPU_ISA_III; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; + mips_cpu.tlbsize = 48; break; case PRID_IMP_R4650: - mips_cputype = CPU_R4650; + mips_cpu.cputype = CPU_R4650; + mips_cpu.isa_level = MIPS_CPU_ISA_III; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; + mips_cpu.tlbsize = 48; break; case PRID_IMP_R4700: - mips_cputype = CPU_R4700; + mips_cpu.cputype = CPU_R4700; + mips_cpu.isa_level = MIPS_CPU_ISA_III; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; + mips_cpu.tlbsize = 48; break; case PRID_IMP_R5000: - mips_cputype = CPU_R5000; + mips_cpu.cputype = CPU_R5000; + mips_cpu.isa_level = MIPS_CPU_ISA_IV; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; + mips_cpu.tlbsize = 48; + break; + case PRID_IMP_R5432: + mips_cpu.cputype = CPU_R5432; + mips_cpu.isa_level = MIPS_CPU_ISA_IV; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; + mips_cpu.tlbsize = 48; break; - case PRID_IMP_R5432: - mips_cputype = CPU_R5432; - break; case PRID_IMP_NEVADA: - mips_cputype = CPU_NEVADA; + mips_cpu.cputype = CPU_NEVADA; + mips_cpu.isa_level = MIPS_CPU_ISA_IV; + mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC; + mips_cpu.tlbsize = 48; break; case PRID_IMP_R6000: - mips_cputype = CPU_R6000; + mips_cpu.cputype = CPU_R6000; + mips_cpu.isa_level = MIPS_CPU_ISA_II; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; + mips_cpu.tlbsize = 32; break; case PRID_IMP_R6000A: - mips_cputype = CPU_R6000A; + mips_cpu.cputype = CPU_R6000A; + mips_cpu.isa_level = MIPS_CPU_ISA_II; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; + mips_cpu.tlbsize = 32; break; case PRID_IMP_RM7000: - mips_cputype = CPU_RM7000; + mips_cpu.cputype = CPU_RM7000; + mips_cpu.isa_level = MIPS_CPU_ISA_IV; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER; break; case PRID_IMP_R8000: - mips_cputype = CPU_R8000; + mips_cpu.cputype = CPU_R8000; + mips_cpu.isa_level = MIPS_CPU_ISA_IV; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR; + mips_cpu.tlbsize = 384; /* has wierd TLB: 3-way x 128 */ break; case PRID_IMP_R10000: - mips_cputype = CPU_R10000; + mips_cpu.cputype = CPU_R10000; + mips_cpu.cputype = MIPS_CPU_ISA_IV; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH; + mips_cpu.tlbsize = 64; + break; +#ifdef CONFIG_CPU_MIPS32 + case PRID_IMP_4KC: + mips_cpu.cputype = CPU_4KC; + mips_cpu.cputype = MIPS_CPU_ISA_M32; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | + MIPS_CPU_DIVEC | MIPS_CPU_WATCH; + config1 = read_mips32_cp0_config1(); + if (config1 & (1 << 3)) + mips_cpu.options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + mips_cpu.options |= MIPS_CPU_MIPS16; + if (config1 & 1) + mips_cpu.options |= MIPS_CPU_FPU; break; + case PRID_IMP_5KC: + mips_cpu.cputype = CPU_5KC; + mips_cpu.cputype = MIPS_CPU_ISA_M64; + mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | + MIPS_CPU_DIVEC | MIPS_CPU_WATCH; + config1 = read_mips32_cp0_config1(); + if (config1 & (1 << 3)) + mips_cpu.options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + mips_cpu.options |= MIPS_CPU_MIPS16; + if (config1 & 1) + mips_cpu.options |= MIPS_CPU_FPU; + break; +#endif default: - mips_cputype = CPU_UNKNOWN; + mips_cpu.cputype = CPU_UNKNOWN; } } @@ -232,9 +322,9 @@ asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_v */ loadmmu(); - /* Disable coprocessors */ + /* Disable coprocessors and set FPU for 16 FPRs */ s = read_32bit_cp0_register(CP0_STATUS); - s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX); + s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); s |= ST0_CU0; write_32bit_cp0_register(CP0_STATUS, s); |