ARC: [mm] remove the pessimistic all-alias-invalidate icache helpers
No users of this code anymore - so RIP ! Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
94bad1afee
commit
7f250a0fa1
1 changed files with 17 additions and 184 deletions
|
@ -72,16 +72,6 @@
|
||||||
#include <asm/cachectl.h>
|
#include <asm/cachectl.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_HAS_ICACHE
|
|
||||||
static void __ic_line_inv_no_alias(unsigned long, int);
|
|
||||||
static void __ic_line_inv_2_alias(unsigned long, int);
|
|
||||||
static void __ic_line_inv_4_alias(unsigned long, int);
|
|
||||||
|
|
||||||
/* Holds the ptr to flush routine, dependign on size due to aliasing issues */
|
|
||||||
static void (*___flush_icache_rtn) (unsigned long, int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
|
char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -171,30 +161,6 @@ void __cpuinit arc_cache_init(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* if Cache way size is <= page size then no aliasing exhibited
|
|
||||||
* otherwise ratio determines num of aliases.
|
|
||||||
* e.g. 32K I$, 2 way set assoc, 8k pg size
|
|
||||||
* way-sz = 32k/2 = 16k
|
|
||||||
* way-pg-ratio = 16k/8k = 2, so 2 aliases possible
|
|
||||||
* (meaning 1 line could be in 2 possible locations).
|
|
||||||
*/
|
|
||||||
way_pg_ratio = ic->sz / ARC_ICACHE_WAYS / PAGE_SIZE;
|
|
||||||
switch (way_pg_ratio) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
___flush_icache_rtn = __ic_line_inv_no_alias;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
___flush_icache_rtn = __ic_line_inv_2_alias;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
___flush_icache_rtn = __ic_line_inv_4_alias;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panic("Unsupported I-Cache Sz\n");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enable/disable I-Cache */
|
/* Enable/disable I-Cache */
|
||||||
|
@ -391,75 +357,38 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz,
|
||||||
/*
|
/*
|
||||||
* I-Cache Aliasing in ARC700 VIPT caches
|
* I-Cache Aliasing in ARC700 VIPT caches
|
||||||
*
|
*
|
||||||
* For fetching code from I$, ARC700 uses vaddr (embedded in program code)
|
* ARC VIPT I-cache uses vaddr to index into cache and paddr to match the tag.
|
||||||
* to "index" into SET of cache-line and paddr from MMU to match the TAG
|
* The orig Cache Management Module "CDU" only required paddr to invalidate a
|
||||||
* in the WAYS of SET.
|
* certain line since it sufficed as index in Non-Aliasing VIPT cache-geometry.
|
||||||
|
* Infact for distinct V1,V2,P: all of {V1-P},{V2-P},{P-P} would end up fetching
|
||||||
|
* the exact same line.
|
||||||
*
|
*
|
||||||
* However the CDU iterface (to flush/inv) lines from software, only takes
|
* However for larger Caches (way-size > page-size) - i.e. in Aliasing config,
|
||||||
* paddr (to have simpler hardware interface). For simpler cases, using paddr
|
* paddr alone could not be used to correctly index the cache.
|
||||||
* alone suffices.
|
|
||||||
* e.g. 2-way-set-assoc, 16K I$ (8k MMU pg sz, 32b cache line size):
|
|
||||||
* way_sz = cache_sz / num_ways = 16k/2 = 8k
|
|
||||||
* num_sets = way_sz / line_sz = 8k/32 = 256 => 8 bits
|
|
||||||
* Ignoring the bottom 5 bits corresp to the off within a 32b cacheline,
|
|
||||||
* bits req for calc set-index = bits 12:5 (0 based). Since this range fits
|
|
||||||
* inside the bottom 13 bits of paddr, which are same for vaddr and paddr
|
|
||||||
* (with 8k pg sz), paddr alone can be safely used by CDU to unambigously
|
|
||||||
* locate a cache-line.
|
|
||||||
*
|
|
||||||
* However for a difft sized cache, say 32k I$, above math yields need
|
|
||||||
* for 14 bits of vaddr to locate a cache line, which can't be provided by
|
|
||||||
* paddr, since the bit 13 (0 based) might differ between the two.
|
|
||||||
*
|
|
||||||
* This lack of extra bits needed for correct line addressing, defines the
|
|
||||||
* classical problem of Cache aliasing with VIPT architectures
|
|
||||||
* num_aliases = 1 << extra_bits
|
|
||||||
* e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz => 2 aliases
|
|
||||||
* 2-way-set-assoc, 64K I$ with 8k MMU pg sz => 4 aliases
|
|
||||||
* 2-way-set-assoc, 16K I$ with 8k MMU pg sz => NO aliases
|
|
||||||
*
|
*
|
||||||
* ------------------
|
* ------------------
|
||||||
* MMU v1/v2 (Fixed Page Size 8k)
|
* MMU v1/v2 (Fixed Page Size 8k)
|
||||||
* ------------------
|
* ------------------
|
||||||
* The solution was to provide CDU with these additonal vaddr bits. These
|
* The solution was to provide CDU with these additonal vaddr bits. These
|
||||||
* would be bits [x:13], x would depend on cache-geom.
|
* would be bits [x:13], x would depend on cache-geometry, 13 comes from
|
||||||
|
* standard page size of 8k.
|
||||||
* H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits
|
* H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits
|
||||||
* of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the
|
* of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the
|
||||||
* orig 5 bits of paddr were anyways ignored by CDU line ops, as they
|
* orig 5 bits of paddr were anyways ignored by CDU line ops, as they
|
||||||
* represent the offset within cache-line. The adv of using this "clumsy"
|
* represent the offset within cache-line. The adv of using this "clumsy"
|
||||||
* interface for additional info was no new reg was needed in CDU.
|
* interface for additional info was no new reg was needed in CDU programming
|
||||||
|
* model.
|
||||||
*
|
*
|
||||||
* 17:13 represented the max num of bits passable, actual bits needed were
|
* 17:13 represented the max num of bits passable, actual bits needed were
|
||||||
* fewer, based on the num-of-aliases possible.
|
* fewer, based on the num-of-aliases possible.
|
||||||
* -for 2 alias possibility, only bit 13 needed (32K cache)
|
* -for 2 alias possibility, only bit 13 needed (32K cache)
|
||||||
* -for 4 alias possibility, bits 14:13 needed (64K cache)
|
* -for 4 alias possibility, bits 14:13 needed (64K cache)
|
||||||
*
|
*
|
||||||
* Since vaddr was not available for all instances of I$ flush req by core
|
|
||||||
* kernel, the only safe way (non-optimal though) was to kill all possible
|
|
||||||
* lines which could represent an alias (even if they didnt represent one
|
|
||||||
* in execution).
|
|
||||||
* e.g. for 64K I$, 4 aliases possible, so we did
|
|
||||||
* flush start
|
|
||||||
* flush start | 0x01
|
|
||||||
* flush start | 0x2
|
|
||||||
* flush start | 0x3
|
|
||||||
*
|
|
||||||
* The penalty was invoking the operation itself, since tag match is anyways
|
|
||||||
* paddr based, a line which didn't represent an alias would not match the
|
|
||||||
* paddr, hence wont be killed
|
|
||||||
*
|
|
||||||
* Note that aliasing concerns are independent of line-sz for a given cache
|
|
||||||
* geometry (size + set_assoc) because the extra bits required by line-sz are
|
|
||||||
* reduced from the set calc.
|
|
||||||
* e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz and using math above
|
|
||||||
* 32b line-sz: 9 bits set-index-calc, 5 bits offset-in-line => 1 extra bit
|
|
||||||
* 64b line-sz: 8 bits set-index-calc, 6 bits offset-in-line => 1 extra bit
|
|
||||||
*
|
|
||||||
* ------------------
|
* ------------------
|
||||||
* MMU v3
|
* MMU v3
|
||||||
* ------------------
|
* ------------------
|
||||||
* This ver of MMU supports var page sizes (1k-16k) - Linux will support
|
* This ver of MMU supports variable page sizes (1k-16k): although Linux will
|
||||||
* 8k (default), 16k and 4k.
|
* only support 8k (default), 16k and 4k.
|
||||||
* However from hardware perspective, smaller page sizes aggrevate aliasing
|
* However from hardware perspective, smaller page sizes aggrevate aliasing
|
||||||
* meaning more vaddr bits needed to disambiguate the cache-line-op ;
|
* meaning more vaddr bits needed to disambiguate the cache-line-op ;
|
||||||
* the existing scheme of piggybacking won't work for certain configurations.
|
* the existing scheme of piggybacking won't work for certain configurations.
|
||||||
|
@ -468,105 +397,10 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
* Machine specific helpers for per line I-Cache invalidate.
|
* Machine specific helper for per line I-Cache invalidate.
|
||||||
* 3 routines to accpunt for 1, 2, 4 aliases possible
|
|
||||||
*/
|
*/
|
||||||
|
static void __ic_line_inv_vaddr(unsigned long phy_start, unsigned long vaddr,
|
||||||
static void __ic_line_inv_no_alias(unsigned long start, int num_lines)
|
unsigned long sz)
|
||||||
{
|
|
||||||
while (num_lines-- > 0) {
|
|
||||||
#if (CONFIG_ARC_MMU_VER > 2)
|
|
||||||
write_aux_reg(ARC_REG_IC_PTAG, start);
|
|
||||||
#endif
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start);
|
|
||||||
start += ARC_ICACHE_LINE_LEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __ic_line_inv_2_alias(unsigned long start, int num_lines)
|
|
||||||
{
|
|
||||||
while (num_lines-- > 0) {
|
|
||||||
|
|
||||||
#if (CONFIG_ARC_MMU_VER > 2)
|
|
||||||
/*
|
|
||||||
* MMU v3, CDU prog model (for line ops) now uses a new IC_PTAG
|
|
||||||
* reg to pass the "tag" bits and existing IVIL reg only looks
|
|
||||||
* at bits relevant for "index" (details above)
|
|
||||||
* Programming Notes:
|
|
||||||
* -when writing tag to PTAG reg, bit chopping can be avoided,
|
|
||||||
* CDU ignores non-tag bits.
|
|
||||||
* -Ideally "index" must be computed from vaddr, but it is not
|
|
||||||
* avail in these rtns. So to be safe, we kill the lines in all
|
|
||||||
* possible indexes corresp to num of aliases possible for
|
|
||||||
* given cache config.
|
|
||||||
*/
|
|
||||||
write_aux_reg(ARC_REG_IC_PTAG, start);
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL,
|
|
||||||
start & ~(0x1 << PAGE_SHIFT));
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | (0x1 << PAGE_SHIFT));
|
|
||||||
#else
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start);
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | 0x01);
|
|
||||||
#endif
|
|
||||||
start += ARC_ICACHE_LINE_LEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __ic_line_inv_4_alias(unsigned long start, int num_lines)
|
|
||||||
{
|
|
||||||
while (num_lines-- > 0) {
|
|
||||||
|
|
||||||
#if (CONFIG_ARC_MMU_VER > 2)
|
|
||||||
write_aux_reg(ARC_REG_IC_PTAG, start);
|
|
||||||
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL,
|
|
||||||
start & ~(0x3 << PAGE_SHIFT));
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL,
|
|
||||||
start & ~(0x2 << PAGE_SHIFT));
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL,
|
|
||||||
start & ~(0x1 << PAGE_SHIFT));
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | (0x3 << PAGE_SHIFT));
|
|
||||||
#else
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start);
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | 0x01);
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | 0x02);
|
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, start | 0x03);
|
|
||||||
#endif
|
|
||||||
start += ARC_ICACHE_LINE_LEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __ic_line_inv(unsigned long start, unsigned long sz)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
int num_lines, slack;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ensure we properly floor/ceil the non-line aligned/sized requests
|
|
||||||
* and have @start - aligned to cache line, and integral @num_lines
|
|
||||||
* However page sized flushes can be compile time optimised.
|
|
||||||
* -@start will be cache-line aligned already (being page aligned)
|
|
||||||
* -@sz will be integral multiple of line size (being page sized).
|
|
||||||
*/
|
|
||||||
if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) {
|
|
||||||
slack = start & ~ICACHE_LINE_MASK;
|
|
||||||
sz += slack;
|
|
||||||
start -= slack;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN);
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
(*___flush_icache_rtn) (start, num_lines);
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlike routines above, having vaddr for flush op (along with paddr),
|
|
||||||
* prevents the need to speculatively kill the lines in multiple sets
|
|
||||||
* based on ratio of way_sz : pg_sz
|
|
||||||
*/
|
|
||||||
static void __ic_line_inv_vaddr(unsigned long phy_start,
|
|
||||||
unsigned long vaddr, unsigned long sz)
|
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int num_lines, slack;
|
int num_lines, slack;
|
||||||
|
@ -595,7 +429,7 @@ static void __ic_line_inv_vaddr(unsigned long phy_start,
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, vaddr);
|
write_aux_reg(ARC_REG_IC_IVIL, vaddr);
|
||||||
vaddr += ARC_ICACHE_LINE_LEN;
|
vaddr += ARC_ICACHE_LINE_LEN;
|
||||||
#else
|
#else
|
||||||
/* this paddr contains vaddrs bits as needed */
|
/* paddr contains stuffed vaddrs bits */
|
||||||
write_aux_reg(ARC_REG_IC_IVIL, addr);
|
write_aux_reg(ARC_REG_IC_IVIL, addr);
|
||||||
#endif
|
#endif
|
||||||
addr += ARC_ICACHE_LINE_LEN;
|
addr += ARC_ICACHE_LINE_LEN;
|
||||||
|
@ -605,7 +439,6 @@ static void __ic_line_inv_vaddr(unsigned long phy_start,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define __ic_line_inv(start, sz)
|
|
||||||
#define __ic_line_inv_vaddr(pstart, vstart, sz)
|
#define __ic_line_inv_vaddr(pstart, vstart, sz)
|
||||||
|
|
||||||
#endif /* CONFIG_ARC_HAS_ICACHE */
|
#endif /* CONFIG_ARC_HAS_ICACHE */
|
||||||
|
|
Loading…
Add table
Reference in a new issue