summaryrefslogtreecommitdiff
path: root/arch/m68k/include/asm/cacheflush_mm.h
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2009-01-16 21:58:10 +1000
committerGreg Ungerer <gerg@uclinux.org>2009-01-16 21:58:10 +1000
commit49148020bcb6910ce71417bd990a5ce7017f9bd3 (patch)
treee410cc433a69075a0254ee4000cb10d71df3a641 /arch/m68k/include/asm/cacheflush_mm.h
parentae04d1401577bb63151480a053057de58b8e10bb (diff)
m68k,m68knommu: merge header files
Merge header files for m68k and m68knommu to the single location: arch/m68k/include/asm The majority of this patch was the result of the script that is included in the changelog below. The script was originally written by Arnd Bergman and exten by me to cover a few more files. When the header files differed the script uses the following: The original m68k file is named <file>_mm.h [mm for memory manager] The m68knommu file is named <file>_no.h [no for no memory manager] The files uses the following include guard: This include gaurd works as the m68knommu toolchain set the __uClinux__ symbol - so this should work in userspace too. Merging the header files for m68k and m68knommu exposes the (unexpected?) ABI differences thus it is easier to actually identify these and thus to fix them. The commit has been build tested with both a m68k and a m68knommu toolchain - with success. The commit has also been tested with "make headers_check" and this patch fixes make headers_check for m68knommu. The script used: TARGET=arch/m68k/include/asm SOURCE=arch/m68knommu/include/asm INCLUDE="cachectl.h errno.h fcntl.h hwtest.h ioctls.h ipcbuf.h \ linkage.h math-emu.h md.h mman.h movs.h msgbuf.h openprom.h \ oplib.h poll.h posix_types.h resource.h rtc.h sembuf.h shmbuf.h \ shm.h shmparam.h socket.h sockios.h spinlock.h statfs.h stat.h \ termbits.h termios.h tlb.h types.h user.h" EQUAL="auxvec.h cputime.h device.h emergency-restart.h futex.h \ ioctl.h irq_regs.h kdebug.h local.h mutex.h percpu.h \ sections.h topology.h" NOMUUFILES="anchor.h bootstd.h coldfire.h commproc.h dbg.h \ elia.h flat.h m5206sim.h m520xsim.h m523xsim.h m5249sim.h \ m5272sim.h m527xsim.h m528xsim.h m5307sim.h m532xsim.h \ m5407sim.h m68360_enet.h m68360.h m68360_pram.h m68360_quicc.h \ m68360_regs.h MC68328.h MC68332.h MC68EZ328.h MC68VZ328.h \ mcfcache.h mcfdma.h mcfmbus.h mcfne.h mcfpci.h mcfpit.h \ mcfsim.h mcfsmc.h mcftimer.h mcfuart.h mcfwdebug.h \ nettel.h quicc_simple.h smp.h" FILES="atomic.h bitops.h bootinfo.h bug.h bugs.h byteorder.h cache.h \ cacheflush.h checksum.h current.h delay.h div64.h \ dma-mapping.h dma.h elf.h entry.h fb.h fpu.h hardirq.h hw_irq.h io.h \ irq.h kmap_types.h machdep.h mc146818rtc.h mmu.h mmu_context.h \ module.h page.h page_offset.h param.h pci.h pgalloc.h \ pgtable.h processor.h ptrace.h scatterlist.h segment.h \ setup.h sigcontext.h siginfo.h signal.h string.h system.h swab.h \ thread_info.h timex.h tlbflush.h traps.h uaccess.h ucontext.h \ unaligned.h unistd.h" mergefile() { BASE=${1%.h} git mv ${SOURCE}/$1 ${TARGET}/${BASE}_no.h git mv ${TARGET}/$1 ${TARGET}/${BASE}_mm.h cat << EOF > ${TARGET}/$1 EOF git add ${TARGET}/$1 } set -e mkdir -p ${TARGET} git mv include/asm-m68k/* ${TARGET} rmdir include/asm-m68k git rm ${SOURCE}/Kbuild for F in $INCLUDE $EQUAL; do git rm ${SOURCE}/$F done for F in $NOMUUFILES; do git mv ${SOURCE}/$F ${TARGET}/$F done for F in $FILES ; do mergefile $F done rmdir arch/m68knommu/include/asm rmdir arch/m68knommu/include Cc: Arnd Bergmann <arnd@arndb.de> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68k/include/asm/cacheflush_mm.h')
-rw-r--r--arch/m68k/include/asm/cacheflush_mm.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h
new file mode 100644
index 000000000000..16bf375fdbe1
--- /dev/null
+++ b/arch/m68k/include/asm/cacheflush_mm.h
@@ -0,0 +1,156 @@
+#ifndef _M68K_CACHEFLUSH_H
+#define _M68K_CACHEFLUSH_H
+
+#include <linux/mm.h>
+
+/* cache code */
+#define FLUSH_I_AND_D (0x00000808)
+#define FLUSH_I (0x00000008)
+
+/*
+ * Cache handling functions
+ */
+
+static inline void flush_icache(void)
+{
+ if (CPU_IS_040_OR_060)
+ asm volatile ( "nop\n"
+ " .chip 68040\n"
+ " cpusha %bc\n"
+ " .chip 68k");
+ else {
+ unsigned long tmp;
+ asm volatile ( "movec %%cacr,%0\n"
+ " or.w %1,%0\n"
+ " movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "id" (FLUSH_I));
+ }
+}
+
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* This is needed whenever the virtual mapping of the current
+ process changes. */
+#define __flush_cache_all() \
+({ \
+ if (CPU_IS_040_OR_060) \
+ __asm__ __volatile__("nop\n\t" \
+ ".chip 68040\n\t" \
+ "cpusha %dc\n\t" \
+ ".chip 68k"); \
+ else { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define __flush_cache_030() \
+({ \
+ if (CPU_IS_020_OR_030) { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define flush_cache_all() __flush_cache_all()
+
+#define flush_cache_vmap(start, end) flush_cache_all()
+#define flush_cache_vunmap(start, end) flush_cache_all()
+
+static inline void flush_cache_mm(struct mm_struct *mm)
+{
+ if (mm == current->mm)
+ __flush_cache_030();
+}
+
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
+/* flush_cache_range/flush_cache_page must be macros to avoid
+ a dependency on linux/mm.h, which includes this file... */
+static inline void flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start,
+ unsigned long end)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_cache_030();
+}
+
+static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_cache_030();
+}
+
+
+/* Push the page at kernel virtual address and clear the icache */
+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
+static inline void __flush_page_to_ram(void *vaddr)
+{
+ if (CPU_IS_040_OR_060) {
+ __asm__ __volatile__("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (__pa(vaddr)));
+ } else {
+ unsigned long _tmp;
+ __asm__ __volatile__("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (_tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+#define flush_dcache_page(page) __flush_page_to_ram(page_address(page))
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+#define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page))
+
+extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len);
+extern void flush_icache_range(unsigned long address, unsigned long endaddr);
+
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr,
+ void *dst, void *src, int len)
+{
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+ flush_icache_user_range(vma, page, vaddr, len);
+}
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr,
+ void *dst, void *src, int len)
+{
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+}
+
+#endif /* _M68K_CACHEFLUSH_H */