Path: blob/master/arch/blackfin/include/asm/cacheflush.h
15126 views
/*1* Blackfin low-level cache routines2*3* Copyright 2004-2009 Analog Devices Inc.4*5* Licensed under the GPL-2 or later.6*/78#ifndef _BLACKFIN_CACHEFLUSH_H9#define _BLACKFIN_CACHEFLUSH_H1011#include <asm/blackfin.h> /* for SSYNC() */12#include <asm/sections.h> /* for _ramend */13#ifdef CONFIG_SMP14#include <asm/smp.h>15#endif1617extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address);18extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address);19extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);20extern void blackfin_dflush_page(void *page);21extern void blackfin_invalidate_entire_dcache(void);22extern void blackfin_invalidate_entire_icache(void);2324#define flush_dcache_mmap_lock(mapping) do { } while (0)25#define flush_dcache_mmap_unlock(mapping) do { } while (0)26#define flush_cache_mm(mm) do { } while (0)27#define flush_cache_range(vma, start, end) do { } while (0)28#define flush_cache_page(vma, vmaddr) do { } while (0)29#define flush_cache_vmap(start, end) do { } while (0)30#define flush_cache_vunmap(start, end) do { } while (0)3132#ifdef CONFIG_SMP33#define flush_icache_range_others(start, end) \34smp_icache_flush_range_others((start), (end))35#else36#define flush_icache_range_others(start, end) do { } while (0)37#endif3839static inline void flush_icache_range(unsigned start, unsigned end)40{41#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK)42if (end <= physical_mem_end)43blackfin_dcache_flush_range(start, end);44#endif45#if defined(CONFIG_BFIN_L2_WRITEBACK)46if (start >= L2_START && end <= L2_START + L2_LENGTH)47blackfin_dcache_flush_range(start, end);48#endif4950/* Make sure all write buffers in the data side of the core51* are flushed before trying to invalidate the icache. This52* needs to be after the data flush and before the icache53* flush so that the SSYNC does the right thing in preventing54* the instruction prefetcher from hitting things in cached55* memory at the wrong time -- it runs much further ahead than56* the pipeline.57*/58SSYNC();59#if defined(CONFIG_BFIN_EXTMEM_ICACHEABLE)60if (end <= physical_mem_end) {61blackfin_icache_flush_range(start, end);62flush_icache_range_others(start, end);63}64#endif65#if defined(CONFIG_BFIN_L2_ICACHEABLE)66if (start >= L2_START && end <= L2_START + L2_LENGTH) {67blackfin_icache_flush_range(start, end);68flush_icache_range_others(start, end);69}70#endif71}7273#define copy_to_user_page(vma, page, vaddr, dst, src, len) \74do { memcpy(dst, src, len); \75flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \76} while (0)7778#define copy_from_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len)7980#if defined(CONFIG_BFIN_DCACHE)81# define invalidate_dcache_range(start,end) blackfin_dcache_invalidate_range((start), (end))82#else83# define invalidate_dcache_range(start,end) do { } while (0)84#endif85#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)86# define flush_dcache_range(start,end) blackfin_dcache_flush_range((start), (end))87#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 188# define flush_dcache_page(page) blackfin_dflush_page(page_address(page))89#else90# define flush_dcache_range(start,end) do { } while (0)91#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 092# define flush_dcache_page(page) do { } while (0)93#endif9495extern unsigned long reserved_mem_dcache_on;96extern unsigned long reserved_mem_icache_on;9798static inline int bfin_addr_dcacheable(unsigned long addr)99{100#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE101if (addr < (_ramend - DMA_UNCACHED_REGION))102return 1;103#endif104105if (reserved_mem_dcache_on &&106addr >= _ramend && addr < physical_mem_end)107return 1;108109#ifdef CONFIG_BFIN_L2_DCACHEABLE110if (addr >= L2_START && addr < L2_START + L2_LENGTH)111return 1;112#endif113114return 0;115}116117#endif /* _BLACKFIN_ICACHEFLUSH_H */118119120