summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /arch/sparc/mm
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/Makefile7
-rw-r--r--arch/sparc/mm/asyncd.c2
-rw-r--r--arch/sparc/mm/fault.c39
-rw-r--r--arch/sparc/mm/generic.c11
-rw-r--r--arch/sparc/mm/init.c2
-rw-r--r--arch/sparc/mm/io-unit.c50
-rw-r--r--arch/sparc/mm/srmmu.c125
-rw-r--r--arch/sparc/mm/sun4c.c23
-rw-r--r--arch/sparc/mm/turbosparc.S48
9 files changed, 203 insertions, 104 deletions
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 929b2a6f0..a9e51c67f 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.31 1998/07/26 03:02:45 davem Exp $
+# $Id: Makefile,v 1.32 1998/08/16 16:02:25 ecd Exp $
# Makefile for the linux Sparc-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
@@ -12,7 +12,7 @@ O_OBJS := fault.o init.o loadmmu.o generic.o asyncd.o extable.o btfixup.o
ifeq ($(CONFIG_SUN4),y)
O_OBJS += nosrmmu.o
else
-O_OBJS += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o turbosparc.o
+O_OBJS += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o
endif
ifdef SMP
O_OBJS += nosun4c.o
@@ -25,9 +25,6 @@ include $(TOPDIR)/Rules.make
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
diff --git a/arch/sparc/mm/asyncd.c b/arch/sparc/mm/asyncd.c
index 908501dc9..666bf8429 100644
--- a/arch/sparc/mm/asyncd.c
+++ b/arch/sparc/mm/asyncd.c
@@ -1,4 +1,4 @@
-/* $Id: asyncd.c,v 1.11 1997/12/14 23:24:34 ecd Exp $
+/* $Id: asyncd.c,v 1.12 1998/09/13 04:30:30 davem Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 88d85004c..3c8ffbfae 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.94 1998/05/01 16:00:27 jj Exp $
+/* $Id: fault.c,v 1.96 1998/11/08 11:13:56 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -149,7 +149,9 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
(unsigned long) tsk->mm->context);
printk(KERN_ALERT "tsk->mm->pgd = %08lx\n",
(unsigned long) tsk->mm->pgd);
+ lock_kernel();
die_if_kernel("Oops", regs);
+ unlock_kernel();
}
asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
@@ -196,11 +198,11 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
unsigned int fixup;
unsigned long g2;
int from_user = !(regs->psr & PSR_PS);
- lock_kernel();
- down(&mm->mmap_sem);
+
if(text_fault)
address = regs->pc;
+ down(&mm->mmap_sem);
/* The kernel referencing a bad kernel pointer can lock up
* a sun4c machine completely, so we must attempt recovery.
*/
@@ -229,9 +231,10 @@ good_area:
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- handle_mm_fault(current, vma, address, write);
+ if (!handle_mm_fault(current, vma, address, write))
+ goto do_sigbus;
up(&mm->mmap_sem);
- goto out;
+ return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
@@ -239,7 +242,7 @@ good_area:
bad_area:
up(&mm->mmap_sem);
/* Is this in ex_table? */
-
+do_kernel_fault:
g2 = regs->u_regs[UREG_G2];
if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) {
if (fixup > 10) { /* Values below are reserved for other things */
@@ -263,7 +266,7 @@ bad_area:
regs->u_regs[UREG_G2] = g2;
regs->pc = fixup;
regs->npc = regs->pc + 4;
- goto out;
+ return;
}
}
if(from_user) {
@@ -274,11 +277,18 @@ bad_area:
tsk->tss.sig_address = address;
tsk->tss.sig_desc = SUBSIG_NOMAPPING;
force_sig(SIGSEGV, tsk);
- goto out;
+ return;
}
unhandled_fault (address, tsk, regs);
-out:
- unlock_kernel();
+ return;
+
+do_sigbus:
+ up(&mm->mmap_sem);
+ tsk->tss.sig_address = address;
+ tsk->tss.sig_desc = SUBSIG_MISCERROR;
+ force_sig(SIGBUS, tsk);
+ if (! from_user)
+ goto do_kernel_fault;
}
asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
@@ -372,7 +382,8 @@ good_area:
else
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
- handle_mm_fault(current, vma, address, write);
+ if (!handle_mm_fault(current, vma, address, write))
+ goto do_sigbus;
up(&mm->mmap_sem);
return;
bad_area:
@@ -385,6 +396,12 @@ bad_area:
tsk->tss.sig_desc = SUBSIG_NOMAPPING;
send_sig(SIGSEGV, tsk, 1);
return;
+
+do_sigbus:
+ up(&mm->mmap_sem);
+ tsk->tss.sig_address = address;
+ tsk->tss.sig_desc = SUBSIG_MISCERROR;
+ force_sig(SIGBUS, tsk);
}
void window_overflow_fault(void)
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index 4ad1810e3..ea94a8f60 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -1,4 +1,4 @@
-/* $Id: generic.c,v 1.5 1996/12/18 06:43:23 tridge Exp $
+/* $Id: generic.c,v 1.6 1998/10/27 23:28:00 davem Exp $
* generic.c: Generic Sparc mm routines that are not dependent upon
* MMU type but are Sparc specific.
*
@@ -41,10 +41,11 @@ static inline void forget_pte(pte_t page)
unsigned long addr = pte_page(page);
if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
return;
- free_page(addr);
- if (current->mm->rss <= 0)
- return;
- current->mm->rss--;
+ /*
+ * free_page() used to be able to clear swap cache
+ * entries. We may now have to do it manually.
+ */
+ free_page_and_swap_cache(addr);
return;
}
swap_free(pte_val(page));
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index eef01666d..391a4dedb 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.59 1998/03/27 06:59:57 davem Exp $
+/* $Id: init.c,v 1.60 1998/09/13 04:30:31 davem Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 41bd72671..6cd8c9b7c 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -1,4 +1,4 @@
-/* $Id: io-unit.c,v 1.11 1998/04/13 07:26:37 davem Exp $
+/* $Id: io-unit.c,v 1.13 1998/11/08 11:13:57 davem Exp $
* io-unit.c: IO-UNIT specific routines for memory management.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -231,3 +231,51 @@ __initfunc(void ld_mmu_iounit(void))
BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);
#endif
}
+
+__u32 iounit_map_dma_init(struct linux_sbus *sbus, int size)
+{
+ int i, j, k, npages;
+ unsigned long rotor, scan, limit;
+ unsigned long flags;
+ __u32 ret;
+ struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+
+ npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+ i = 0x0213;
+ spin_lock_irqsave(&iounit->lock, flags);
+next: j = (i & 15);
+ rotor = iounit->rotor[j - 1];
+ limit = iounit->limit[j];
+ scan = rotor;
+nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan);
+ if (scan + npages > limit) {
+ if (limit != rotor) {
+ limit = rotor;
+ scan = iounit->limit[j - 1];
+ goto nexti;
+ }
+ i >>= 4;
+ if (!(i & 15))
+ panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size);
+ goto next;
+ }
+ for (k = 1, scan++; k < npages; k++)
+ if (test_bit(scan++, iounit->bmap))
+ goto nexti;
+ iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
+ scan -= npages;
+ ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT);
+ for (k = 0; k < npages; k++, scan++)
+ set_bit(scan, iounit->bmap);
+ spin_unlock_irqrestore(&iounit->lock, flags);
+ return ret;
+}
+
+__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct linux_sbus *sbus)
+{
+ int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
+ struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+
+ iounit->page_table[scan] = MKIOPTE(mmu_v2p(((unsigned long)addr) & PAGE_MASK));
+ return vaddr + (((unsigned long)addr) & ~PAGE_MASK);
+}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 97bd5be37..69d40fa09 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.173 1998/08/04 20:48:57 davem Exp $
+/* $Id: srmmu.c,v 1.175 1998/08/28 18:57:31 zaitcev Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1997,7 +1997,7 @@ static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long ad
static void srmmu_destroy_context(struct mm_struct *mm)
{
- if(mm->context != NO_CONTEXT && mm->count == 1) {
+ if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
flush_cache_mm(mm);
ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
flush_tlb_mm(mm);
@@ -2071,7 +2071,7 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
static void hypersparc_destroy_context(struct mm_struct *mm)
{
- if(mm->context != NO_CONTEXT && mm->count == 1) {
+ if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
ctxd_t *ctxp;
/* HyperSparc is copy-back, any data for this
@@ -2399,10 +2399,93 @@ __initfunc(static void init_swift(void))
poke_srmmu = poke_swift;
}
-/* turbosparc.S */
-extern void turbosparc_flush_cache_all(void);
-extern void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void turbosparc_flush_page_for_dma(unsigned long page);
+static void turbosparc_flush_cache_all(void)
+{
+ flush_user_windows();
+ turbosparc_idflash_clear();
+}
+
+static void turbosparc_flush_cache_mm(struct mm_struct *mm)
+{
+ FLUSH_BEGIN(mm)
+ flush_user_windows();
+ turbosparc_idflash_clear();
+ FLUSH_END
+}
+
+static void turbosparc_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+ FLUSH_BEGIN(mm)
+ flush_user_windows();
+ turbosparc_idflash_clear();
+ FLUSH_END
+}
+
+static void turbosparc_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
+{
+ FLUSH_BEGIN(vma->vm_mm)
+ flush_user_windows();
+ if (vma->vm_flags & VM_EXEC)
+ turbosparc_flush_icache();
+ turbosparc_flush_dcache();
+ FLUSH_END
+}
+
+/* TurboSparc is copy-back, if we turn it on, but this does not work. */
+static void turbosparc_flush_page_to_ram(unsigned long page)
+{
+#ifdef TURBOSPARC_WRITEBACK
+ volatile unsigned long clear;
+
+ if (srmmu_hwprobe(page))
+ turbosparc_flush_page_cache(page);
+ clear = srmmu_get_fstatus();
+#endif
+}
+
+static void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
+{
+}
+
+static void turbosparc_flush_page_for_dma(unsigned long page)
+{
+ turbosparc_flush_dcache();
+}
+
+static void turbosparc_flush_chunk(unsigned long chunk)
+{
+}
+
+static void turbosparc_flush_tlb_all(void)
+{
+ srmmu_flush_whole_tlb();
+ module_stats.invall++;
+}
+
+static void turbosparc_flush_tlb_mm(struct mm_struct *mm)
+{
+ FLUSH_BEGIN(mm)
+ srmmu_flush_whole_tlb();
+ module_stats.invmm++;
+ FLUSH_END
+}
+
+static void turbosparc_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
+{
+ FLUSH_BEGIN(mm)
+ srmmu_flush_whole_tlb();
+ module_stats.invrnge++;
+ FLUSH_END
+}
+
+static void turbosparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ FLUSH_BEGIN(vma->vm_mm)
+ srmmu_flush_whole_tlb();
+ module_stats.invpg++;
+ FLUSH_END
+}
+
__initfunc(static void poke_turbosparc(void))
{
@@ -2420,7 +2503,7 @@ __initfunc(static void poke_turbosparc(void))
#ifdef TURBOSPARC_WRITEBACK
ccreg |= (TURBOSPARC_SNENABLE); /* Do DVMA snooping in Dcache */
ccreg &= ~(TURBOSPARC_uS2 | TURBOSPARC_WTENABLE);
- /* Write-back D-cache, emulate VLSI
+ /* Write-back D-cache, emulate VLSI
* abortion number three, not number one */
#else
/* For now let's play safe, optimize later */
@@ -2428,7 +2511,8 @@ __initfunc(static void poke_turbosparc(void))
/* Do DVMA snooping in Dcache, Write-thru D-cache */
ccreg &= ~(TURBOSPARC_uS2);
/* Emulate VLSI abortion number three, not number one */
-#endif
+#endif
+
switch (ccreg & 7) {
case 0: /* No SE cache */
case 7: /* Test mode */
@@ -2449,22 +2533,17 @@ __initfunc(static void init_turbosparc(void))
srmmu_modtype = TurboSparc;
BTFIXUPSET_CALL(flush_cache_all, turbosparc_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, hypersparc_flush_cache_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_cache_mm, turbosparc_flush_cache_mm, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_cache_page, turbosparc_flush_cache_page, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_cache_range, turbosparc_flush_cache_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_all, hypersparc_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, hypersparc_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_tlb_all, turbosparc_flush_tlb_all, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_tlb_mm, turbosparc_flush_tlb_mm, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM);
-#ifdef TURBOSPARC_WRITEBACK
- BTFIXUPSET_CALL(flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_chunk, hypersparc_flush_chunk, BTFIXUPCALL_NORM);
-#else
- BTFIXUPSET_CALL(flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(flush_chunk, swift_flush_chunk, BTFIXUPCALL_NOP);
-#endif
+ BTFIXUPSET_CALL(flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM);
+ BTFIXUPSET_CALL(flush_chunk, turbosparc_flush_chunk, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP);
BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NOP);
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 448881608..fa8105d57 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.166 1998/08/04 20:49:05 davem Exp $
+/* $Id: sun4c.c,v 1.171 1998/09/21 05:05:41 jj Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -400,7 +400,9 @@ void sun4c_complete_all_stores(void)
_unused = sun4c_get_context();
sun4c_set_context(_unused);
+#ifdef CONFIG_SUN_AUXIO
_unused = *AUXREG;
+#endif
}
/* Bootup utility functions. */
@@ -622,9 +624,8 @@ __initfunc(static void sun4c_probe_mmu(void))
break;
case (SM_SUN4|SM_4_470):
- prom_printf("No support for 4400 yet\n");
- prom_halt();
- num_segmaps = 1024;
+ /* should be 1024 segmaps. when it get fixed */
+ num_segmaps = 256;
num_contexts = 64;
break;
default:
@@ -755,13 +756,15 @@ static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on,
~bits_off);
}
-/* the 4/260 dies real hard on the prom_putsegment line.
- not sure why, but it seems to work without it cgd */
static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
{
unsigned long vaddr;
unsigned char pseg, ctx;
-#ifndef CONFIG_SUN4
+#ifdef CONFIG_SUN4
+ /* sun4/110 and 260 have no kadb. */
+ if((idprom->id_machtype != (SM_SUN4 | SM_4_260)) &&
+ (idprom->id_machtype != (SM_SUN4 | SM_4_110))) {
+#endif
for(vaddr = KADB_DEBUGGER_BEGVM;
vaddr < LINUX_OPPROM_ENDVM;
vaddr += SUN4C_REAL_PGDIR_SIZE) {
@@ -773,6 +776,8 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);
}
}
+#ifdef CONFIG_SUN4
+ }
#endif
for(vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {
pseg = sun4c_get_segmap(vaddr);
@@ -2142,7 +2147,7 @@ static void sun4c_destroy_context_hw(struct mm_struct *mm)
{
struct ctx_list *ctx_old;
- if(mm->context != NO_CONTEXT && mm->count == 1) {
+ if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
sun4c_demap_context_hw(&sun4c_context_ring[mm->context], mm->context);
ctx_old = ctx_list_pool + mm->context;
remove_from_ctx_list(ctx_old);
@@ -2205,7 +2210,7 @@ static void sun4c_destroy_context_sw(struct mm_struct *mm)
{
struct ctx_list *ctx_old;
- if(mm->context != NO_CONTEXT && mm->count == 1) {
+ if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
sun4c_demap_context_sw(&sun4c_context_ring[mm->context], mm->context);
ctx_old = ctx_list_pool + mm->context;
remove_from_ctx_list(ctx_old);
diff --git a/arch/sparc/mm/turbosparc.S b/arch/sparc/mm/turbosparc.S
deleted file mode 100644
index df580a85c..000000000
--- a/arch/sparc/mm/turbosparc.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: turbosparc.S,v 1.3 1998/05/04 12:41:29 ralf Exp $
- * turbosparc.S: High speed TurboSparc 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
- .globl turbosparc_flush_page_for_dma
-
-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:
-turbosparc_flush_page_for_dma:
- retl
- nop