diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/setup.c | 48 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 8 |
2 files changed, 46 insertions, 10 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 18cab56c3..24837a49a 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.25 2000/03/06 14:39:33 raiko Exp $ +/* $Id: setup.c,v 1.26 2000/03/08 21:00:55 harald 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 @@ -47,11 +47,13 @@ struct mips_cpuinfo boot_cpu_data = { NULL, NULL, 0 }; /* - * Not all of the MIPS CPUs have the "wait" instruction available. This - * is set to true if it is available. The wait instruction stops the - * pipeline and reduces the power consumption of the CPU very much. + * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, + * the implementation of the "wait" feature differs between CPU families. This + * points to the function that implements CPU specific wait. + * The wait instruction stops the pipeline and reduces the power consumption of + * the CPU very much. */ -char wait_available; +void (*cpu_wait)(void) = NULL; /* * Do we have a cyclecounter available? @@ -125,6 +127,24 @@ extern void SetUpBootInfo(void); extern void loadmmu(void); extern asmlinkage void start_kernel(void); +/* + * Probe whether cpu has config register by trying to play with + * alternate cache bit and see whether it matters. + * It's used by cpu_probe to distinguish between R3000A and R3081. + */ +static inline int cpu_has_confreg(void) +{ + extern unsigned long r3k_cache_size(unsigned long); + unsigned long size1, size2; + unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + + size1 = r3k_cache_size(ST0_DE); + write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); + size2 = r3k_cache_size(ST0_DE); + write_32bit_cp0_register(CP0_CONF, cfg); + return size1 != size2; +} + static inline void cpu_probe(void) { unsigned int prid = read_32bit_cp0_register(CP0_PRID); @@ -134,7 +154,10 @@ static inline void cpu_probe(void) break; case PRID_IMP_R3000: if((prid & 0xff) == PRID_REV_R3000A) - mips_cputype = CPU_R3000A; + if(cpu_has_confreg()) + mips_cputype = CPU_R3081E; + else + mips_cputype = CPU_R3000A; else mips_cputype = CPU_R3000; break; @@ -331,3 +354,16 @@ void __init setup_arch(char **cmdline_p) paging_init(); } + +void r3081_wait(void) +{ + unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); +} + +void r4k_wait(void) +{ + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 14ea93094..d0d72c0c0 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.26 1999/12/04 03:59:00 ralf Exp $ +/* $Id: traps.c,v 1.27 2000/01/16 01:29:05 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 @@ -718,14 +718,14 @@ void __init trap_init(void) case CPU_R2000: case CPU_R3000: case CPU_R3000A: - memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); - memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); - break; case CPU_R3041: case CPU_R3051: case CPU_R3052: case CPU_R3081: case CPU_R3081E: + memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); + memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); + break; case CPU_R8000: printk("Detected unsupported CPU type %s.\n", cpu_names[mips_cputype]); |