diff options
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r-- | arch/sparc/mm/Makefile | 11 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 100 | ||||
-rw-r--r-- | arch/sparc/mm/turbosparc.S | 46 |
3 files changed, 154 insertions, 3 deletions
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index f7b9b367c..84cd1d2e2 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.25 1997/05/03 05:09:11 davem Exp $ +# $Id: Makefile,v 1.26 1997/06/24 15:48:06 jj Exp $ # Makefile for the linux Sparc-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also @@ -9,7 +9,8 @@ O_TARGET := mm.o O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o viking.o \ - tsunami.o loadmmu.o generic.o asyncd.o extable.o + tsunami.o loadmmu.o generic.o asyncd.o extable.o \ + turbosparc.o include $(TOPDIR)/Rules.make @@ -18,6 +19,9 @@ ifdef SMP hypersparc.o: hypersparc.S $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o hypersparc.o hypersparc.S +turbosparc.o: turbosparc.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o turbosparc.o turbosparc.S + viking.o: viking.S $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o viking.o viking.S @@ -29,6 +33,9 @@ else hypersparc.o: hypersparc.S $(CC) -D__ASSEMBLY__ -ansi -c -o hypersparc.o hypersparc.S +turbosparc.o: turbosparc.S + $(CC) -D__ASSEMBLY__ -ansi -c -o turbosparc.o turbosparc.S + viking.o: viking.S $(CC) -D__ASSEMBLY__ -ansi -c -o viking.o viking.S diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 7420b98cb..3b9970551 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,9 +1,10 @@ -/* $Id: srmmu.c,v 1.147 1997/05/20 07:58:42 jj Exp $ +/* $Id: srmmu.c,v 1.148 1997/06/24 15:48:02 jj Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 Peter A. Zaitcev (zaitcev@ithil.mcst.ru) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ #include <linux/config.h> @@ -36,6 +37,7 @@ #include <asm/ross.h> #include <asm/tsunami.h> #include <asm/swift.h> +#include <asm/turbosparc.h> enum mbus_module srmmu_modtype; unsigned int hwbug_bitmask; @@ -2595,6 +2597,78 @@ __initfunc(static void init_swift(void)) poke_srmmu = poke_swift; } +/* turbosparc.S */ +extern void turbosparc_flush_cache_all(); +extern void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr); + +static void poke_turbosparc(void) +{ + unsigned long mreg = srmmu_get_mmureg(); + unsigned long ccreg; + + /* Clear any crap from the cache or else... */ + turbosparc_flush_cache_all(); + mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* Temporarily disable I & D caches */ + mreg &= ~(TURBOSPARC_PCENABLE); /* Don't check parity */ + srmmu_set_mmureg(mreg); + + ccreg = turbosparc_get_ccreg(); + +#ifdef TURBOSPARC_WRITEBACK + ccreg |= (TURBOSPARC_SNENABLE); /* Do DVMA snooping in Dcache */ + ccreg &= ~(TURBOSPARC_uS2 | TURBOSPARC_WTENABLE); + /* Write-back D-cache, emulate VLSI + * abortion number three, not number one */ +#else + /* For now let's play safe, optimize later */ + ccreg |= (TURBOSPARC_SNENABLE | TURBOSPARC_WTENABLE); + /* Do DVMA snooping in Dcache, Write-thru D-cache */ + ccreg &= ~(TURBOSPARC_uS2); + /* Emulate VLSI abortion number three, not number one */ +#endif + switch (ccreg & 7) { + case 0: /* No SE cache */ + case 7: /* Test mode */ + break; + default: + ccreg |= (TURBOSPARC_SCENABLE); + } + turbosparc_set_ccreg (ccreg); + + mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */ + mreg |= (TURBOSPARC_ICSNOOP); /* Icache snooping on */ + srmmu_set_mmureg(mreg); +} + +__initfunc(static void init_turbosparc(void)) +{ + srmmu_name = "Fujitsu TurboSparc"; + srmmu_modtype = TurboSparc; + + flush_cache_all = turbosparc_flush_cache_all; + flush_cache_mm = hypersparc_flush_cache_mm; + flush_cache_page = hypersparc_flush_cache_page; + flush_cache_range = hypersparc_flush_cache_range; + + flush_tlb_all = hypersparc_flush_tlb_all; + flush_tlb_mm = hypersparc_flush_tlb_mm; + flush_tlb_page = hypersparc_flush_tlb_page; + flush_tlb_range = hypersparc_flush_tlb_range; + +#ifdef TURBOSPARC_WRITEBACK + flush_page_to_ram = hypersparc_flush_page_to_ram; + flush_chunk = hypersparc_flush_chunk; +#else + flush_page_to_ram = swift_flush_page_to_ram; + flush_chunk = swift_flush_chunk; +#endif + + flush_sig_insns = turbosparc_flush_sig_insns; + flush_page_for_dma = hypersparc_flush_page_for_dma; + + poke_srmmu = poke_turbosparc; +} + static void poke_tsunami(void) { unsigned long mreg = srmmu_get_mmureg(); @@ -2785,9 +2859,33 @@ __initfunc(static void get_srmmu_type(void)) }; return; } + + /* Now Fujitsu TurboSparc. It might happen that it is + in Swift emulation mode, so we will check later... */ + if (psr_typ == 0 && psr_vers == 5) { + init_turbosparc(); + return; + } /* Next check for Fujitsu Swift. */ if(psr_typ == 0 && psr_vers == 4) { + int cpunode; + char node_str[128]; + + /* Look if it is not a TurboSparc emulating Swift... */ + cpunode = prom_getchild(prom_root_node); + while((cpunode = prom_getsibling(cpunode)) != 0) { + prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); + if(!strcmp(node_str, "cpu")) { + if (!prom_getintdefault(cpunode, "psr-implementation", 1) && + prom_getintdefault(cpunode, "psr-version", 1) == 5) { + init_turbosparc(); + return; + } + break; + } + } + init_swift(); return; } diff --git a/arch/sparc/mm/turbosparc.S b/arch/sparc/mm/turbosparc.S new file mode 100644 index 000000000..5660d4f84 --- /dev/null +++ b/arch/sparc/mm/turbosparc.S @@ -0,0 +1,46 @@ +/* $Id: turbosparc.S,v 1.1 1997/07/18 06:26:22 ralf Exp $ + * turbosparc.S: High speed Hypersparc mmu/cache operations. + * + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include <asm/ptrace.h> +#include <asm/psr.h> +#include <asm/asi.h> +#include <asm/page.h> +#include <asm/pgtsrmmu.h> + +#define WINDOW_FLUSH(tmp1, tmp2) \ + mov 0, tmp1; \ +98: ld [%g6 + AOFF_task_tss + AOFF_thread_uwinmask], tmp2; \ + orcc %g0, tmp2, %g0; \ + add tmp1, 1, tmp1; \ + bne 98b; \ + save %sp, -64, %sp; \ +99: subcc tmp1, 1, tmp1; \ + bne 99b; \ + restore %g0, %g0, %g0; + + .text + .align 4 + + .globl turbosparc_flush_cache_all + .globl turbosparc_flush_sig_insns + +turbosparc_flush_cache_all: + WINDOW_FLUSH(%g4, %g5) + sethi %hi(vac_cache_size), %g4 + ld [%g4 + %lo(vac_cache_size)], %g5 + sethi %hi(vac_line_size), %g1 + ld [%g1 + %lo(vac_line_size)], %g2 +1: + subcc %g5, %g2, %g5 + bne 1b + sta %g0, [%g5] ASI_M_DATAC_TAG + retl + sta %g0, [%g0] ASI_M_IC_FLCLEAR + +turbosparc_flush_sig_insns: + retl + nop |