aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/mm/c-r3k.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-29 14:06:55 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-29 14:06:55 -0700
commit82798a17ad40df827d465329a20ace80497f9b32 (patch)
tree449ba69dc5a5e19a56b2a9d12d218f9486e5316d /arch/mips/mm/c-r3k.c
parentdb8185360d91c01f6e482db5ee402c0ad90dec52 (diff)
parent1a3b7920fe55247d39c3e1ac1e9b8aca607d0188 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (34 commits) [MIPS] tb0219: Update copyright message. [MIPS] MT: Fix bug in multithreaded kernels. [MIPS] Alchemy: Remove CONFIG_TS_AU1X00_ADS7846 from defconfigs. Author: Ralf Baechle <ralf@linux-mips.org> [MIPS] sb1250: Enable GenBus IDE in defconfig. [MIPS] vmlinux.ld.S: correctly indent .data section [MIPS] c-r3k: Implement flush_cache_range() [MIPS] Store sign-extend register values for PTRACE_GETREGS [MIPS] Alchemy: Register platform devices [MIPS] Add len and addr validation for MAP_FIXED mappings. [MIPS] IRIX: Fix off-by-one error in signal compat code. [MIPS] time: Replace plat_timer_setup with modern APIs. [MIPS] time: Fix cut'n'paste bug in Sibyte clockevent driver. [MIPS] time: Make c0_compare_int_usable faster [MIPS] time: Fix cevt-r4k.c for 64-bit kernel [MIPS] Sibyte: Delete {sb1250,bcm1480}_steal_irq(). [MIPS] txx9tmr clockevent/clocksource driver [MIPS] Add mips_hpt_frequency check to mips_clockevent_init(). [MIPS] IP32: Fixes after interrupt renumbering. [MIPS] IP27: Fix slice logic to work for arbitrary number of slices. ...
Diffstat (limited to 'arch/mips/mm/c-r3k.c')
-rw-r--r--arch/mips/mm/c-r3k.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index c55312f6fd3..562abb77d1d 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -7,7 +7,7 @@
* Tx39XX R4k style caches added. HK
* Copyright (C) 1998, 1999, 2000 Harald Koerfgen
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- * Copyright (C) 2001, 2004 Maciej W. Rozycki
+ * Copyright (C) 2001, 2004, 2007 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -26,8 +26,6 @@
static unsigned long icache_size, dcache_size; /* Size in bytes */
static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */
-#undef DEBUG_CACHE
-
unsigned long __init r3k_cache_size(unsigned long ca_flags)
{
unsigned long flags, status, dummy, size;
@@ -217,26 +215,6 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
write_c0_status(flags);
}
-static inline unsigned long get_phys_page(unsigned long addr,
- struct mm_struct *mm)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long physpage;
-
- pgd = pgd_offset(mm, addr);
- pud = pud_offset(pgd, addr);
- pmd = pmd_offset(pud, addr);
- pte = pte_offset(pmd, addr);
-
- if ((physpage = pte_val(*pte)) & _PAGE_VALID)
- return KSEG0ADDR(physpage & PAGE_MASK);
-
- return 0;
-}
-
static inline void r3k_flush_cache_all(void)
{
}
@@ -252,12 +230,40 @@ static void r3k_flush_cache_mm(struct mm_struct *mm)
}
static void r3k_flush_cache_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
+ unsigned long start, unsigned long end)
{
}
-static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+static void r3k_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
{
+ unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
+ int exec = vma->vm_flags & VM_EXEC;
+ struct mm_struct *mm = vma->vm_mm;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ pr_debug("cpage[%08lx,%08lx]\n",
+ cpu_context(smp_processor_id(), mm), addr);
+
+ /* No ASID => no such page in the cache. */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
+
+ /* Invalid => no such page in the cache. */
+ if (!(pte_val(*ptep) & _PAGE_PRESENT))
+ return;
+
+ r3k_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+ if (exec)
+ r3k_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
}
static void local_r3k_flush_data_cache_page(void *addr)
@@ -272,9 +278,7 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
{
unsigned long flags;
-#ifdef DEBUG_CACHE
- printk("csigtramp[%08lx]", addr);
-#endif
+ pr_debug("csigtramp[%08lx]\n", addr);
flags = read_c0_status();