summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/Makefile11
-rw-r--r--arch/sparc/mm/srmmu.c100
-rw-r--r--arch/sparc/mm/turbosparc.S46
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