From 9332bf5462630e1f20ba65152ed64231bcc52e9c Mon Sep 17 00:00:00 2001 From: "Gleb O. Raiko" Date: Mon, 13 Mar 2000 10:33:02 +0000 Subject: Add R3081 support --- arch/mips/kernel/setup.c | 48 ++++++++++++++++++++++++++++++++++++++------ arch/mips/kernel/traps.c | 8 ++++---- arch/mips/mm/loadmmu.c | 3 ++- arch/mips/mm/r2300.c | 8 ++++---- include/asm-mips/bugs.h | 9 +++++++-- include/asm-mips/mipsregs.h | 5 ++++- include/asm-mips/processor.h | 6 ++++-- 7 files changed, 67 insertions(+), 20 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]); diff --git a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c index cb5e1e66d..01fadac31 100644 --- a/arch/mips/mm/loadmmu.c +++ b/arch/mips/mm/loadmmu.c @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: loadmmu.c,v 1.15 2000/02/24 00:12:40 ralf Exp $ + * $Id: loadmmu.c,v 1.16 2000/03/07 15:45:28 ralf Exp $ */ #include #include @@ -59,6 +59,7 @@ void __init loadmmu(void) case CPU_R2000: case CPU_R3000: case CPU_R3000A: + case CPU_R3081E: printk("Loading R[23]00 MMU routines.\n"); ld_mmu_r2300(); break; diff --git a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c index 63d9b1f7b..cf871fb63 100644 --- a/arch/mips/mm/r2300.c +++ b/arch/mips/mm/r2300.c @@ -7,7 +7,7 @@ * Copyright (C) 1998, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov * - * $Id: r2300.c,v 1.14 2000/02/13 20:52:05 harald Exp $ + * $Id: r2300.c,v 1.15 2000/02/24 00:12:40 ralf Exp $ */ #include #include @@ -116,7 +116,7 @@ static void r3k_copy_page(void * to, void * from) "I" (PAGE_SIZE)); } -static unsigned long __init size_cache(unsigned long ca_flags) +unsigned long __init r3k_cache_size(unsigned long ca_flags) { unsigned long flags, status, dummy, size; volatile unsigned long *p; @@ -152,14 +152,14 @@ static unsigned long __init size_cache(unsigned long ca_flags) static void __init probe_dcache(void) { - dcache_size = size_cache(ST0_DE); + dcache_size = r3k_cache_size(ST0_DE); printk("Primary data cache %dkb, linesize 4 bytes\n", dcache_size >> 10); } static void __init probe_icache(void) { - icache_size = size_cache(ST0_DE|ST0_CE); + icache_size = r3k_cache_size(ST0_DE|ST0_CE); printk("Primary instruction cache %dkb, linesize 8 bytes\n", icache_size >> 10); } diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index 9195f9fd3..7a7871dd3 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h @@ -1,4 +1,4 @@ -/* $Id: bugs.h,v 1.3 1997/12/01 18:00:36 ralf Exp $ +/* $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 @@ -17,6 +17,11 @@ static inline void check_wait(void) { printk("Checking for 'wait' instruction... "); switch(mips_cputype) { + case CPU_R3081: + case CPU_R3081E: + cpu_wait = r3081_wait; + printk(" available.\n"); + break; case CPU_R4200: case CPU_R4300: case CPU_R4600: @@ -25,7 +30,7 @@ static inline void check_wait(void) case CPU_R4700: case CPU_R5000: case CPU_NEVADA: - wait_available = 1; + cpu_wait = r4k_wait; printk(" available.\n"); break; default: diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 72a657573..23ed82cfd 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -1,4 +1,4 @@ -/* $Id: mipsregs.h,v 1.5 1999/04/11 17:13:57 harald Exp $ +/* $Id: mipsregs.h,v 1.6 1999/07/26 19:42:43 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 @@ -30,6 +30,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 @@ -333,6 +334,8 @@ __BUILD_SET_CP0(config,CP0_CONFIG) #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) /* * R10000 performance counter definitions. diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 6c9334269..fc4dff224 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.24 2000/01/29 01:42:28 ralf Exp $ +/* $Id: processor.h,v 1.25 2000/02/05 06:47:37 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 @@ -37,7 +37,9 @@ struct mips_cpuinfo { * System setup and hardware flags.. * XXX: Should go into mips_cpuinfo. */ -extern char wait_available; /* only available on R4[26]00 */ +extern void (*cpu_wait)(void); /* only available on R4[26]00 and R3081 */ +extern void r3081_wait(void); +extern void r4k_wait(void); extern char cyclecounter_available; /* only available from R4000 upwards. */ extern char dedicated_iv_available; /* some embedded MIPS like Nevada */ extern char vce_available; /* Supports VCED / VCEI exceptions */ -- cgit v1.2.3