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.palt...@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) |
-- 
2.9.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to