Commit 95d6976d authored by Vineet Gupta's avatar Vineet Gupta

ARC: Cache Flush Management

* ARC700 has VIPT L1 Caches
* Caches don't snoop and are not coherent
* Given the PAGE_SIZE and Cache associativity, we don't support aliasing
  D$ configurations (yet), but do allow aliasing I$ configs
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 55bb9480
......@@ -58,6 +58,33 @@
#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
/*
* Floating Pt Registers
* Status regs are read-only (build-time) so need not be saved/restored
......@@ -132,6 +159,31 @@
#endif
#define READ_BCR(reg, into) \
{ \
unsigned int tmp; \
tmp = read_aux_reg(reg); \
if (sizeof(tmp) == sizeof(into)) { \
into = *((typeof(into) *)&tmp); \
} else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
} \
}
#define WRITE_BCR(reg, into) \
{ \
unsigned int tmp; \
if (sizeof(tmp) == sizeof(into)) { \
tmp = (*(unsigned int *)(into)); \
write_aux_reg(reg, tmp); \
} else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
} \
}
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
/* These DPFP regs need to be saved/restored across ctx-sw */
struct arc_fpu {
......@@ -141,6 +193,34 @@ struct arc_fpu {
};
#endif
/*
***************************************************************
* Build Configuration Registers, with encoded hardware config
*/
struct bcr_cache {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
#else
unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
#endif
};
/*
*******************************************************************
* Generic structures to hold build configuration used at runtime
*/
struct cpuinfo_arc_cache {
unsigned int has_aliasing, sz, line_len, assoc, ver;
};
struct cpuinfo_arc {
struct cpuinfo_arc_cache icache, dcache;
};
extern struct cpuinfo_arc cpuinfo_arc700[];
#endif /* __ASEMBLY__ */
#endif /* __KERNEL__ */
......
......@@ -18,4 +18,58 @@
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#define ARC_ICACHE_WAYS 2
#define ARC_DCACHE_WAYS 4
/* Helpers */
#define ARC_ICACHE_LINE_LEN L1_CACHE_BYTES
#define ARC_DCACHE_LINE_LEN L1_CACHE_BYTES
#define ICACHE_LINE_MASK (~(ARC_ICACHE_LINE_LEN - 1))
#define DCACHE_LINE_MASK (~(ARC_DCACHE_LINE_LEN - 1))
#if ARC_ICACHE_LINE_LEN != ARC_DCACHE_LINE_LEN
#error "Need to fix some code as I/D cache lines not same"
#else
#define is_not_cache_aligned(p) ((unsigned long)p & (~DCACHE_LINE_MASK))
#endif
#ifndef __ASSEMBLY__
/* Uncached access macros */
#define arc_read_uncached_32(ptr) \
({ \
unsigned int __ret; \
__asm__ __volatile__( \
" ld.di %0, [%1] \n" \
: "=r"(__ret) \
: "r"(ptr)); \
__ret; \
})
#define arc_write_uncached_32(ptr, data)\
({ \
__asm__ __volatile__( \
" st.di %0, [%1] \n" \
: \
: "r"(data), "r"(ptr)); \
})
/* used to give SHMLBA a value to avoid Cache Aliasing */
extern unsigned int ARC_shmlba;
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
/*
* ARC700 doesn't cache any access in top 256M.
* Ideal for wiring memory mapped peripherals as we don't need to do
* explicit uncached accesses (LD.di/ST.di) hence more portable drivers
*/
#define ARC_UNCACHED_ADDR_SPACE 0xc0000000
extern void arc_cache_init(void);
extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
extern void __init read_decode_cache_bcr(void);
#endif
#endif /* _ASM_CACHE_H */
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ARC_ASM_CACHECTL_H
#define __ARC_ASM_CACHECTL_H
/*
* ARC ABI flags defined for Android's finegrained cacheflush requirements
*/
#define CF_I_INV 0x0002
#define CF_D_FLUSH 0x0010
#define CF_D_FLUSH_INV 0x0020
#define CF_DEFAULT (CF_I_INV | CF_D_FLUSH)
/*
* Standard flags expected by cacheflush system call users
*/
#define ICACHE CF_I_INV
#define DCACHE CF_D_FLUSH
#define BCACHE (CF_I_INV | CF_D_FLUSH)
#endif
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* vineetg: May 2011: for Non-aliasing VIPT D-cache following can be NOPs
* -flush_cache_dup_mm (fork)
* -likewise for flush_cache_mm (exit/execve)
* -likewise for flush_cache_{range,page} (munmap, exit, COW-break)
*
* vineetg: April 2008
* -Added a critical CacheLine flush to copy_to_user_page( ) which
* was causing gdbserver to not setup breakpoints consistently
*/
#ifndef _ASM_CACHEFLUSH_H
#define _ASM_CACHEFLUSH_H
#include <linux/mm.h>
void flush_cache_all(void);
void flush_icache_range(unsigned long start, unsigned long end);
void flush_icache_page(struct vm_area_struct *vma, struct page *page);
void flush_icache_range_vaddr(unsigned long paddr, unsigned long u_vaddr,
int len);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
void flush_dcache_page(struct page *page);
void dma_cache_wback_inv(unsigned long start, unsigned long sz);
void dma_cache_inv(unsigned long start, unsigned long sz);
void dma_cache_wback(unsigned long start, unsigned long sz);
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
/* TBD: optimize this */
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
/*
* VM callbacks when entire/range of user-space V-P mappings are
* torn-down/get-invalidated
*
* Currently we don't support D$ aliasing configs for our VIPT caches
* NOPS for VIPT Cache with non-aliasing D$ configurations only
*/
#define flush_cache_dup_mm(mm) /* called on fork */
#define flush_cache_mm(mm) /* called on munmap/exit */
#define flush_cache_range(mm, u_vstart, u_vend)
#define flush_cache_page(vma, u_vaddr, pfn) /* PF handling/COW-break */
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy(dst, src, len); \
if (vma->vm_flags & VM_EXEC) \
flush_icache_range_vaddr((unsigned long)(dst), vaddr, len);\
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len); \
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment