[xtensa-cvscommit] linux/arch/xtensa/mm cache.c,NONE,1.1 Makefile,1.1.1.1,1.2
Brought to you by:
zankel
|
From: <joe...@us...> - 2003-01-17 00:31:33
|
Update of /cvsroot/xtensa/linux/arch/xtensa/mm
In directory sc8-pr-cvs1:/tmp/cvs-serv4681/arch/xtensa/mm
Modified Files:
Makefile
Added Files:
cache.c
Log Message:
Add support for writeback caches. Affects only linux_test config.
--- NEW FILE: cache.c ---
/*
* arch/xtensa/mm/cache.c
*
* Documentation/cachetlb.txt implementation. Derived from many archs.
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of
* this archive for more details.
*
* Copyright (C) 2003 Tensilica Inc. (by Joe Taylor, jo...@te...)
*/
/* Some points to remember:
- Instruction and data caches are separate and independent.
- Icaches are never writeback.
- If dcaches are not writeback, dhwbi equals dhi, etc.
- When flushing a range in the icache, we have to first writeback
the dcache for the same range, so new ifetches will see any
data that was dirty in the dcache.
*/
/* XTFIXME: Compare against arch/mips/mm/r4xx0.c, which has extensive
tests before deciding to flush anything. Possible optimization
opportunities. */
/* XTFIXME: I don't know why the *cache_region_* functions don't do
the job in flush_cache_range, but the system hangs. Wiping it all
out works, though probably less efficiently than desired. */
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <xtensa/hal.h>
#if XCHAL_DCACHE_IS_WRITEBACK
void flush_cache_all(void)
{
unsigned long flags;
save_and_cli(flags);
xthal_dcache_all_writeback_inv();
xthal_icache_all_invalidate();
restore_flags(flags);
}
void flush_cache_mm(struct mm_struct *mm)
{
if (mm && mm->context != 0) {
#ifdef DEBUG_CACHE
printk("cmm[%d]", (int)mm->context);
#endif
/* Too compute intensive, so just wipe it all out. */
flush_cache_all();
}
}
void flush_cache_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
flush_cache_all();
#if 0 /* this is broken for some reason.. */
struct vm_area_struct *vma;
if (!mm || mm->context == 0)
return;
start &= PAGE_MASK;
#ifdef DEBUG_CACHE
printk("crange[%d,%08lx,%08lx]", (long)mm->context, start, end);
#endif
vma = find_vma(mm, start);
if (!vma)
return;
if (mm->context != current->active_mm->context) {
flush_cache_all();
} else {
unsigned long flags;
save_and_cli(flags);
xthal_dcache_region_writeback_inv((void *)start, end - start);
xthal_icache_region_invalidate((void *)start, end - start);
restore_flags(flags);
}
#endif
}
void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long flags;
if (!mm || mm->context == 0)
return;
addr &= PAGE_MASK;
#ifdef DEBUG_CACHE
printk("cpage[%d,%08lx]", (long)mm->context, addr);
#endif
save_and_cli(flags);
xthal_dcache_region_writeback_inv((void *)addr, PAGE_SIZE);
xthal_icache_region_invalidate((void *)addr, PAGE_SIZE);
restore_flags(flags);
}
void flush_icache_range(unsigned long start, unsigned long end)
{
unsigned long flags;
save_and_cli(flags);
xthal_dcache_region_writeback_inv((void *)start, end - start);
xthal_icache_region_invalidate((void *)start, end - start);
restore_flags(flags);
}
void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long start;
if (!mm || mm->context == 0)
return;
if ( ! (vma->vm_flags & VM_EXEC) )
return;
start = (unsigned long) page_address(page);
#ifdef DEBUG_CACHE
printk("icpage[%d,%08lx]", (long)mm->context, start);
#endif
flush_icache_range(start, start + PAGE_SIZE);
}
void flush_page_to_ram (struct page *page)
{
unsigned long addr = (unsigned long) page_address(page);
unsigned long flags;
save_and_cli(flags);
xthal_dcache_region_writeback_inv((void *)addr, PAGE_SIZE);
restore_flags(flags);
}
/* Define only if dcache aliasing is a problem. It currently is not. */
#if 0
void flush_dcache_page (struct page *page)
{
unsigned long addr = (unsigned long) page_address(page);
unsigned long flags;
save_and_cli(flags);
xthal_dcache_region_writeback_inv((void *)addr, PAGE_SIZE);
restore_flags(flags);
}
#endif
#endif /* #if XCHAL_DCACHE_IS_WRITEBACK */
Index: Makefile
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/mm/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** Makefile 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- Makefile 17 Jan 2003 00:31:30 -0000 1.2
***************
*** 9,13 ****
O_TARGET := mm.o
! obj-y := extable.o init.o fault.o loadmmu.o mmu.o
include $(TOPDIR)/Rules.make
--- 9,13 ----
O_TARGET := mm.o
! obj-y := extable.o init.o fault.o loadmmu.o mmu.o cache.o
include $(TOPDIR)/Rules.make
|