
There is the problem with current implementation if we start u-boot from ROM, as we use cache global variables before ther initialization, so these variables are overwritten when we copy .data section from ROM.
So use icache_exists(), dcache_exists(), slc_exists(), pae_exists() functions which check BCRs every time instead of corresponding global variables.
Signed-off-by: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com --- arch/arc/lib/cache.c | 65 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 23 deletions(-)
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 8633ba5..cb90c60 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -20,7 +20,6 @@ #define DC_CTRL_CACHE_DISABLE BIT(0) #define DC_CTRL_INV_MODE_FLUSH BIT(6) #define DC_CTRL_FLUSH_STATUS BIT(8) -#define CACHE_VER_NUM_MASK 0xF
#define OP_INV BIT(0) #define OP_FLUSH BIT(1) @@ -38,20 +37,16 @@ * relocation but will be used after being zeroed. */ int l1_line_sz __section(".data"); -bool dcache_exists __section(".data") = false; -bool icache_exists __section(".data") = false;
#define CACHE_LINE_MASK (~(l1_line_sz - 1))
int slc_line_sz __section(".data"); -bool slc_exists __section(".data") = false; bool ioc_exists __section(".data") = false; -bool pae_exists __section(".data") = false;
/* To force enable IOC set ioc_enable to 'true' */ bool ioc_enable __section(".data") = false;
-void read_decode_mmu_bcr(void) +static inline bool pae_exists(void) { /* TODO: should we compare mmu version from BCR and from CONFIG? */ #if (CONFIG_ARC_MMU_VER >= 4) @@ -59,14 +54,45 @@ void read_decode_mmu_bcr(void)
mmu4.word = read_aux_reg(ARC_AUX_MMU_BCR);
- pae_exists = !!mmu4.fields.pae; + if (mmu4.fields.pae) + return true; #endif /* (CONFIG_ARC_MMU_VER >= 4) */ + + return false; +} + +static inline bool icache_exists(void) +{ + union bcr_di_cache ibcr; + + ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD); + return !!ibcr.fields.ver; +} + +static inline bool dcache_exists(void) +{ + union bcr_di_cache dbcr; + + dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD); + return !!dbcr.fields.ver; +} + +static inline bool slc_exists(void) +{ + if (is_isa_arcv2()) { + union bcr_generic sbcr; + + sbcr.word = read_aux_reg(ARC_BCR_SLC); + return !!sbcr.fields.ver; + } + + return false; }
static inline bool slc_status(void) { /* TODO: HS 3.0 supports SLC disable so we need to check it here */ - return slc_exists; + return slc_exists(); }
static void __slc_entire_op(const int op) @@ -189,12 +215,9 @@ static void read_decode_cache_bcr_arcv2(void) { union bcr_slc_cfg slc_cfg; union bcr_clust_cfg cbcr; - union bcr_generic sbcr;
- sbcr.word = read_aux_reg(ARC_BCR_SLC); - if (sbcr.fields.ver) { + if (slc_exists()) { slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG); - slc_exists = true; slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64; }
@@ -210,7 +233,6 @@ void read_decode_cache_bcr(void)
ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD); if (ibcr.fields.ver) { - icache_exists = true; l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len; if (!ic_line_sz) panic("Instruction exists but line length is 0\n"); @@ -218,7 +240,6 @@ void read_decode_cache_bcr(void)
dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD); if (dbcr.fields.ver) { - dcache_exists = true; l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len; if (!dc_line_sz) panic("Data cache exists but line length is 0\n"); @@ -238,20 +259,18 @@ void cache_init(void) if (is_isa_arcv2() && ioc_exists) arc_ioc_setup();
- read_decode_mmu_bcr(); - /* * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist * only if PAE exists in current HW. So we had to check pae_exist * before using them. */ - if (is_isa_arcv2() && slc_exists && pae_exists) + if (is_isa_arcv2() && slc_exists() && pae_exists()) slc_upper_region_init(); }
int icache_status(void) { - if (!icache_exists) + if (!icache_exists()) return 0;
if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) @@ -262,14 +281,14 @@ int icache_status(void)
void icache_enable(void) { - if (icache_exists) + if (icache_exists()) write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & ~IC_CTRL_CACHE_DISABLE); }
void icache_disable(void) { - if (icache_exists) + if (icache_exists()) write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | IC_CTRL_CACHE_DISABLE); } @@ -302,7 +321,7 @@ void invalidate_icache_all(void)
int dcache_status(void) { - if (!dcache_exists) + if (!dcache_exists()) return 0;
if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) @@ -313,7 +332,7 @@ int dcache_status(void)
void dcache_enable(void) { - if (!dcache_exists) + if (!dcache_exists()) return;
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & @@ -322,7 +341,7 @@ void dcache_enable(void)
void dcache_disable(void) { - if (!dcache_exists) + if (!dcache_exists()) return;
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |