diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/jazz/hw-access.c | 4 | ||||
-rw-r--r-- | arch/mips/jazz/reset.c | 2 | ||||
-rw-r--r-- | arch/mips/jazz/setup.c | 8 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_sc.c | 248 |
5 files changed, 259 insertions, 9 deletions
diff --git a/arch/mips/jazz/hw-access.c b/arch/mips/jazz/hw-access.c index 73122bcc7..8765be1a7 100644 --- a/arch/mips/jazz/hw-access.c +++ b/arch/mips/jazz/hw-access.c @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: hw-access.c,v 1.4 1997/12/01 17:57:23 ralf Exp $ + * $Id: hw-access.c,v 1.5 1997/12/29 00:06:49 tsbogend Exp $ */ #include <linux/delay.h> #include <linux/linkage.h> @@ -180,5 +180,5 @@ void jazz_keyboard_setup(void) kbd_write_command = jazz_write_command; kbd_read_status = jazz_read_status; request_region(0x60, 16, "keyboard"); - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_KEYBOARD); + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_KEYBOARD); } diff --git a/arch/mips/jazz/reset.c b/arch/mips/jazz/reset.c index d26e44034..f1aac5388 100644 --- a/arch/mips/jazz/reset.c +++ b/arch/mips/jazz/reset.c @@ -2,6 +2,8 @@ * linux/arch/mips/jazz/process.c * * Reset a Jazz machine. + * + * $Id:$ */ #include <linux/sched.h> diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index d6ca9c516..d088a302c 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -7,7 +7,7 @@ * * Copyright (C) 1996, 1997 by Ralf Baechle * - * $Id: setup.c,v 1.6 1997/12/02 03:43:43 ralf Exp $ + * $Id: setup.c,v 1.7 1997/12/29 00:06:49 tsbogend Exp $ */ #include <linux/init.h> #include <linux/ioport.h> @@ -100,9 +100,9 @@ __initfunc(void jazz_setup(void)) } } - add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K); - add_wired_entry (0x02400017, 0x02440017, 0xe2000000, PM_16M); - add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M); + add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K); + add_wired_entry (0x02400017, 0x02440017, 0xe2000000, PM_16M); + add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M); irq_setup = jazz_irq_setup; fd_cacheflush = jazz_fd_cacheflush; diff --git a/arch/mips/sgi/kernel/Makefile b/arch/mips/sgi/kernel/Makefile index c79023b23..43758c5f7 100644 --- a/arch/mips/sgi/kernel/Makefile +++ b/arch/mips/sgi/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 1996/06/08 12:08:38 dm Exp $ +# $Id: Makefile,v 1.1.1.1 1997/06/01 03:16:40 ralf Exp $ # Makefile for the SGI specific kernel interface routines # under Linux. # @@ -13,8 +13,8 @@ .S.o: $(CC) $(CFLAGS) -c $< -o $*.o -OBJS = indy_mc.o indy_hpc.o indy_int.o system.o indy_timer.o indyIRQ.o \ - reset.o setup.o time.o +OBJS = indy_mc.o indy_sc.o indy_hpc.o indy_int.o system.o indy_timer.o \ + indyIRQ.o reset.o setup.o time.o all: sgikern.a diff --git a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c new file mode 100644 index 000000000..462723a7e --- /dev/null +++ b/arch/mips/sgi/kernel/indy_sc.c @@ -0,0 +1,248 @@ +/* + * indy_sc.c: Indy cache managment functions. + * + * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + * + * $Id: indy_sc.c,v 1.4 1998/01/13 04:39:38 ralf Exp $ + */ +#include <linux/config.h> + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/autoconf.h> + +#include <asm/bcache.h> +#include <asm/sgi.h> +#include <asm/sgimc.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/sgialib.h> +#include <asm/mmu_context.h> + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +/* Primary cache parameters. */ +static int icache_size, dcache_size; /* Size in bytes */ +static int ic_lsize, dc_lsize; /* LineSize in bytes */ + +/* Secondary cache (if present) parameters. */ +static scache_size, sc_lsize; /* Again, in bytes */ + +#include <asm/cacheops.h> +#include <asm/r4kcache.h> + +#undef DEBUG_CACHE + + +static void indy_sc_wback_invalidate(unsigned long page, unsigned long size) +{ + unsigned long tmp1, tmp2, flags; + + page &= PAGE_MASK; + +#ifdef DEBUG_CACHE + printk("indy_sc_flush_page_to_ram[%08lx]", page); +#endif + if (size == 0) + return; + + save_and_cli(flags); + + __asm__ __volatile__(" + .set noreorder + .set mips3 + li %0, 0x1 + dsll %0, 31 + or %0, %0, %2 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %0, %1 + daddu %1, %0, %4 + li %2, 0x80 + mtc0 %2, $12 + nop; nop; nop; nop; +1: sw $0, 0(%0) + bltu %0, %1, 1b + daddu %0, 32 + mtc0 $0, $12 + nop; nop; nop; nop; + .set mips0 + .set reorder" + : "=&r" (tmp1), "=&r" (tmp2), + "=&r" (page) + : "2" (page & 0x0007f000), + "r" (size - 32)); + restore_flags(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ + printk("Enabling R4600 SCACHE\n"); + __asm__ __volatile__(" + .set noreorder + .set mips3 + mfc0 %2, $12 + nop; nop; nop; nop; + li %1, 0x80 + mtc0 %1, $12 + nop; nop; nop; nop; + li %0, 0x1 + dsll %0, 31 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %1, %0 + sb $0, 0(%0) + mtc0 $0, $12 + nop; nop; nop; nop; + mtc0 %2, $12 + nop; nop; nop; nop; + .set mips0 + .set reorder" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + + if(mips_cputype != CPU_R4600 && + mips_cputype != CPU_R4640 && + mips_cputype != CPU_R4700) + return; + printk("Disabling R4600 SCACHE\n"); + __asm__ __volatile__(" + .set noreorder + .set mips3 + li %0, 0x1 + dsll %0, 31 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %1, %0 + mfc0 %2, $12 + nop; nop; nop; nop; + li %1, 0x80 + mtc0 %1, $12 + nop; nop; nop; nop; + sh $0, 0(%0) + mtc0 $0, $12 + nop; nop; nop; nop; + mtc0 %2, $12 + nop; nop; nop; nop; + .set mips2 + .set reorder + " : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int indy_sc_probe(void) +{ + volatile unsigned int *cpu_control; + unsigned short cmd = 0xc220; + unsigned long data = 0; + unsigned long addr; + int i, n; + +#ifdef __MIPSEB__ + cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034); +#else + cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030); +#endif +#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) +#define ASSERT(bit) (*(cpu_control) |= (bit)) +#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") + DEASSERT(SGIMC_EEPROM_PRE); + DEASSERT(SGIMC_EEPROM_SDATAO); + DEASSERT(SGIMC_EEPROM_SECLOCK); + DEASSERT(SGIMC_EEPROM_PRE); + DELAY; + ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); + for(i = 0; i < 11; i++) { + if(cmd & (1<<15)) + ASSERT(SGIMC_EEPROM_SDATAO); + else + DEASSERT(SGIMC_EEPROM_SDATAO); + DEASSERT(SGIMC_EEPROM_SECLOCK); + ASSERT(SGIMC_EEPROM_SECLOCK); + cmd <<= 1; + } + DEASSERT(SGIMC_EEPROM_SDATAO); + for(i = 0; i < (sizeof(unsigned short) * 8); i++) { + unsigned int tmp; + + DEASSERT(SGIMC_EEPROM_SECLOCK); + DELAY; + ASSERT(SGIMC_EEPROM_SECLOCK); + DELAY; + data <<= 1; + tmp = *cpu_control; + if(tmp & SGIMC_EEPROM_SDATAI) + data |= 1; + } + DEASSERT(SGIMC_EEPROM_SECLOCK); + DEASSERT(SGIMC_EEPROM_CSEL); + ASSERT(SGIMC_EEPROM_PRE); + ASSERT(SGIMC_EEPROM_SECLOCK); + data <<= PAGE_SHIFT; + printk("R4600/R5000 SCACHE size %dK ", (int) (data >> 10)); + switch(mips_cputype) { + case CPU_R4600: + case CPU_R4640: + sc_lsize = 32; + break; + + default: + sc_lsize = 128; + break; + } + printk("linesize %d bytes\n", sc_lsize); + scache_size = data; + if (data == 0) { + if (mips_cputype == CPU_R5000) + return -1; + else + return 0; + } + + /* Enable r4600/r5000 cache. But flush it first. */ + for(addr = KSEG0; addr < (KSEG0 + dcache_size); + addr += dc_lsize) + flush_dcache_line_indexed(addr); + for(addr = KSEG0; addr < (KSEG0 + icache_size); + addr += ic_lsize) + flush_icache_line_indexed(addr); + for(addr = KSEG0; addr < (KSEG0 + scache_size); + addr += sc_lsize) + flush_scache_line_indexed(addr); + + if (mips_cputype == CPU_R4600 || + mips_cputype == CPU_R5000) + return 1; + + return 0; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + indy_sc_enable, + indy_sc_disable, + indy_sc_wback_invalidate, + indy_sc_wback_invalidate +}; + +void indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} |