linux/arch/m68k/include/asm/cacheflush_mm.h
<<
>>
Prefs
   1#ifndef _M68K_CACHEFLUSH_H
   2#define _M68K_CACHEFLUSH_H
   3
   4#include <linux/mm.h>
   5
   6/* cache code */
   7#define FLUSH_I_AND_D   (0x00000808)
   8#define FLUSH_I         (0x00000008)
   9
  10/*
  11 * Cache handling functions
  12 */
  13
  14static inline void flush_icache(void)
  15{
  16        if (CPU_IS_040_OR_060)
  17                asm volatile (  "nop\n"
  18                        "       .chip   68040\n"
  19                        "       cpusha  %bc\n"
  20                        "       .chip   68k");
  21        else {
  22                unsigned long tmp;
  23                asm volatile (  "movec  %%cacr,%0\n"
  24                        "       or.w    %1,%0\n"
  25                        "       movec   %0,%%cacr"
  26                        : "=&d" (tmp)
  27                        : "id" (FLUSH_I));
  28        }
  29}
  30
  31/*
  32 * invalidate the cache for the specified memory range.
  33 * It starts at the physical address specified for
  34 * the given number of bytes.
  35 */
  36extern void cache_clear(unsigned long paddr, int len);
  37/*
  38 * push any dirty cache in the specified memory range.
  39 * It starts at the physical address specified for
  40 * the given number of bytes.
  41 */
  42extern void cache_push(unsigned long paddr, int len);
  43
  44/*
  45 * push and invalidate pages in the specified user virtual
  46 * memory range.
  47 */
  48extern void cache_push_v(unsigned long vaddr, int len);
  49
  50/* This is needed whenever the virtual mapping of the current
  51   process changes.  */
  52#define __flush_cache_all()                                     \
  53({                                                              \
  54        if (CPU_IS_040_OR_060)                                  \
  55                __asm__ __volatile__("nop\n\t"                  \
  56                                     ".chip 68040\n\t"          \
  57                                     "cpusha %dc\n\t"           \
  58                                     ".chip 68k");              \
  59        else {                                                  \
  60                unsigned long _tmp;                             \
  61                __asm__ __volatile__("movec %%cacr,%0\n\t"      \
  62                                     "orw %1,%0\n\t"            \
  63                                     "movec %0,%%cacr"          \
  64                                     : "=&d" (_tmp)             \
  65                                     : "di" (FLUSH_I_AND_D));   \
  66        }                                                       \
  67})
  68
  69#define __flush_cache_030()                                     \
  70({                                                              \
  71        if (CPU_IS_020_OR_030) {                                \
  72                unsigned long _tmp;                             \
  73                __asm__ __volatile__("movec %%cacr,%0\n\t"      \
  74                                     "orw %1,%0\n\t"            \
  75                                     "movec %0,%%cacr"          \
  76                                     : "=&d" (_tmp)             \
  77                                     : "di" (FLUSH_I_AND_D));   \
  78        }                                                       \
  79})
  80
  81#define flush_cache_all() __flush_cache_all()
  82
  83#define flush_cache_vmap(start, end)            flush_cache_all()
  84#define flush_cache_vunmap(start, end)          flush_cache_all()
  85
  86static inline void flush_cache_mm(struct mm_struct *mm)
  87{
  88        if (mm == current->mm)
  89                __flush_cache_030();
  90}
  91
  92#define flush_cache_dup_mm(mm)                  flush_cache_mm(mm)
  93
  94/* flush_cache_range/flush_cache_page must be macros to avoid
  95   a dependency on linux/mm.h, which includes this file... */
  96static inline void flush_cache_range(struct vm_area_struct *vma,
  97                                     unsigned long start,
  98                                     unsigned long end)
  99{
 100        if (vma->vm_mm == current->mm)
 101                __flush_cache_030();
 102}
 103
 104static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
 105{
 106        if (vma->vm_mm == current->mm)
 107                __flush_cache_030();
 108}
 109
 110
 111/* Push the page at kernel virtual address and clear the icache */
 112/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
 113static inline void __flush_page_to_ram(void *vaddr)
 114{
 115        if (CPU_IS_040_OR_060) {
 116                __asm__ __volatile__("nop\n\t"
 117                                     ".chip 68040\n\t"
 118                                     "cpushp %%bc,(%0)\n\t"
 119                                     ".chip 68k"
 120                                     : : "a" (__pa(vaddr)));
 121        } else {
 122                unsigned long _tmp;
 123                __asm__ __volatile__("movec %%cacr,%0\n\t"
 124                                     "orw %1,%0\n\t"
 125                                     "movec %0,%%cacr"
 126                                     : "=&d" (_tmp)
 127                                     : "di" (FLUSH_I));
 128        }
 129}
 130
 131#define flush_dcache_page(page)         __flush_page_to_ram(page_address(page))
 132#define flush_dcache_mmap_lock(mapping)         do { } while (0)
 133#define flush_dcache_mmap_unlock(mapping)       do { } while (0)
 134#define flush_icache_page(vma, page)    __flush_page_to_ram(page_address(page))
 135
 136extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
 137                                    unsigned long addr, int len);
 138extern void flush_icache_range(unsigned long address, unsigned long endaddr);
 139
 140static inline void copy_to_user_page(struct vm_area_struct *vma,
 141                                     struct page *page, unsigned long vaddr,
 142                                     void *dst, void *src, int len)
 143{
 144        flush_cache_page(vma, vaddr, page_to_pfn(page));
 145        memcpy(dst, src, len);
 146        flush_icache_user_range(vma, page, vaddr, len);
 147}
 148static inline void copy_from_user_page(struct vm_area_struct *vma,
 149                                       struct page *page, unsigned long vaddr,
 150                                       void *dst, void *src, int len)
 151{
 152        flush_cache_page(vma, vaddr, page_to_pfn(page));
 153        memcpy(dst, src, len);
 154}
 155
 156#endif /* _M68K_CACHEFLUSH_H */
 157