Skip to content
Snippets Groups Projects
Commit 75790873 authored by Eugeniy Paltsev's avatar Eugeniy Paltsev Committed by Alexey Brodkin
Browse files

ARC: Cache: Get rid of [slc,pae,icache,dcache]_exists global variables


There is a problem with current implementation if we start U-Boot
from ROM, as we use global variables before ther initialization,
so these variables get overwritten when we copy .data section
from ROM.

Instead we'll use icache_exists(), dcache_exists(), slc_exists(), pae_exists()
functions which directly check BCRs every time.

In U-Boot case ops are used only during self-relocation and DMA
so we shouldn't be hit by noticeable performance degradation.

Signed-off-by: default avatarEugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: default avatarAlexey Brodkin <abrodkin@synopsys.com>
parent ea9f6f1e
No related branches found
No related tags found
No related merge requests found
...@@ -94,7 +94,6 @@ ...@@ -94,7 +94,6 @@
#define DC_CTRL_CACHE_DISABLE BIT(0) #define DC_CTRL_CACHE_DISABLE BIT(0)
#define DC_CTRL_INV_MODE_FLUSH BIT(6) #define DC_CTRL_INV_MODE_FLUSH BIT(6)
#define DC_CTRL_FLUSH_STATUS BIT(8) #define DC_CTRL_FLUSH_STATUS BIT(8)
#define CACHE_VER_NUM_MASK 0xF
#define OP_INV BIT(0) #define OP_INV BIT(0)
#define OP_FLUSH BIT(1) #define OP_FLUSH BIT(1)
...@@ -112,20 +111,16 @@ ...@@ -112,20 +111,16 @@
* relocation but will be used after being zeroed. * relocation but will be used after being zeroed.
*/ */
int l1_line_sz __section(".data"); 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)) #define CACHE_LINE_MASK (~(l1_line_sz - 1))
int slc_line_sz __section(".data"); int slc_line_sz __section(".data");
bool slc_exists __section(".data") = false;
bool ioc_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' */ /* To force enable IOC set ioc_enable to 'true' */
bool ioc_enable __section(".data") = false; 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? */ /* TODO: should we compare mmu version from BCR and from CONFIG? */
#if (CONFIG_ARC_MMU_VER >= 4) #if (CONFIG_ARC_MMU_VER >= 4)
...@@ -133,15 +128,46 @@ void read_decode_mmu_bcr(void) ...@@ -133,15 +128,46 @@ void read_decode_mmu_bcr(void)
mmu4.word = read_aux_reg(ARC_AUX_MMU_BCR); 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) */ #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 void __slc_entire_op(const int op) static void __slc_entire_op(const int op)
{ {
unsigned int ctrl; unsigned int ctrl;
if (!slc_exists) if (!slc_exists())
return; return;
ctrl = read_aux_reg(ARC_AUX_SLC_CTRL); ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
...@@ -182,7 +208,7 @@ static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op) ...@@ -182,7 +208,7 @@ static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
unsigned int ctrl; unsigned int ctrl;
unsigned long end; unsigned long end;
if (!slc_exists) if (!slc_exists())
return; return;
/* /*
...@@ -263,12 +289,9 @@ static void read_decode_cache_bcr_arcv2(void) ...@@ -263,12 +289,9 @@ static void read_decode_cache_bcr_arcv2(void)
union bcr_slc_cfg slc_cfg; union bcr_slc_cfg slc_cfg;
union bcr_clust_cfg cbcr; union bcr_clust_cfg cbcr;
union bcr_generic sbcr;
sbcr.word = read_aux_reg(ARC_BCR_SLC); if (slc_exists()) {
if (sbcr.fields.ver) {
slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG); slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG);
slc_exists = true;
slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64; slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
} }
...@@ -286,7 +309,6 @@ void read_decode_cache_bcr(void) ...@@ -286,7 +309,6 @@ void read_decode_cache_bcr(void)
ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD); ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
if (ibcr.fields.ver) { if (ibcr.fields.ver) {
icache_exists = true;
l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len; l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len;
if (!ic_line_sz) if (!ic_line_sz)
panic("Instruction exists but line length is 0\n"); panic("Instruction exists but line length is 0\n");
...@@ -294,7 +316,6 @@ void read_decode_cache_bcr(void) ...@@ -294,7 +316,6 @@ void read_decode_cache_bcr(void)
dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD); dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
if (dbcr.fields.ver) { if (dbcr.fields.ver) {
dcache_exists = true;
l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len; l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
if (!dc_line_sz) if (!dc_line_sz)
panic("Data cache exists but line length is 0\n"); panic("Data cache exists but line length is 0\n");
...@@ -314,20 +335,18 @@ void cache_init(void) ...@@ -314,20 +335,18 @@ void cache_init(void)
if (is_isa_arcv2() && ioc_exists) if (is_isa_arcv2() && ioc_exists)
arc_ioc_setup(); arc_ioc_setup();
read_decode_mmu_bcr();
/* /*
* ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist * 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 * only if PAE exists in current HW. So we had to check pae_exist
* before using them. * before using them.
*/ */
if (is_isa_arcv2() && slc_exists && pae_exists) if (is_isa_arcv2() && slc_exists() && pae_exists())
slc_upper_region_init(); slc_upper_region_init();
} }
int icache_status(void) int icache_status(void)
{ {
if (!icache_exists) if (!icache_exists())
return 0; return 0;
if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE)
...@@ -338,14 +357,14 @@ int icache_status(void) ...@@ -338,14 +357,14 @@ int icache_status(void)
void icache_enable(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) & write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
~IC_CTRL_CACHE_DISABLE); ~IC_CTRL_CACHE_DISABLE);
} }
void icache_disable(void) void icache_disable(void)
{ {
if (icache_exists) if (icache_exists())
write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
IC_CTRL_CACHE_DISABLE); IC_CTRL_CACHE_DISABLE);
} }
...@@ -378,7 +397,7 @@ void invalidate_icache_all(void) ...@@ -378,7 +397,7 @@ void invalidate_icache_all(void)
int dcache_status(void) int dcache_status(void)
{ {
if (!dcache_exists) if (!dcache_exists())
return 0; return 0;
if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE)
...@@ -389,7 +408,7 @@ int dcache_status(void) ...@@ -389,7 +408,7 @@ int dcache_status(void)
void dcache_enable(void) void dcache_enable(void)
{ {
if (!dcache_exists) if (!dcache_exists())
return; return;
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
...@@ -398,7 +417,7 @@ void dcache_enable(void) ...@@ -398,7 +417,7 @@ void dcache_enable(void)
void dcache_disable(void) void dcache_disable(void)
{ {
if (!dcache_exists) if (!dcache_exists())
return; return;
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) | write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment