]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
arc: check caches existence before use
authorIgor Guryanov <guryanov@synopsys.com>
Wed, 24 Dec 2014 13:07:07 +0000 (16:07 +0300)
committerAlexey Brodkin <abrodkin@synopsys.com>
Thu, 15 Jan 2015 19:38:42 +0000 (22:38 +0300)
Some cache operations ({i|d}cache_{enable|disable|status} or
flush_dcache_all) are built and used even if CONFIG_SYS_{I|D}CACHE_OFF
is set.

This is required for force disable of caches on early boot.
What if something was executed before U-boot and enabled caches
(low-level bootloaders, previously run kernel etc.)?

But if CPU doesn't really have caches any attempt to access
cache-related AUX registers triggers instruction error exception.

So for convenience we'll try to avoid exceptions by checking if CPU
actually has caches (we check separately data and instruction cache
existence) at all.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Signed-off-by: Igor Guryanov <guryanov@synopsys.com>
arch/arc/cpu/arc700/cache.c
arch/arc/include/asm/arcregs.h

index 39d522d22f24dfbf2d418b0e150a923cb014a12c..fa19a13b7e698f49384683423b157a55557ffb17 100644 (file)
 #define DC_CTRL_CACHE_DISABLE  (1 << 0)
 #define DC_CTRL_INV_MODE_FLUSH (1 << 6)
 #define DC_CTRL_FLUSH_STATUS   (1 << 8)
+#define CACHE_VER_NUM_MASK     0xF
 
 int icache_status(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
+               return 0;
+
        return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) !=
               IC_CTRL_CACHE_DISABLE;
 }
 
 void icache_enable(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
+               return;
+
        write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
                      ~IC_CTRL_CACHE_DISABLE);
 }
 
 void icache_disable(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
+               return;
+
        write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
                      IC_CTRL_CACHE_DISABLE);
 }
@@ -43,24 +56,40 @@ void invalidate_icache_all(void)
 
 int dcache_status(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+               return 0;
+
        return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) !=
                DC_CTRL_CACHE_DISABLE;
 }
 
 void dcache_enable(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+               return;
+
        write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
                      ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE));
 }
 
 void dcache_disable(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+               return;
+
        write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
                      DC_CTRL_CACHE_DISABLE);
 }
 
 void flush_dcache_all(void)
 {
+       /* If no cache in CPU exit immediately */
+       if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
+               return;
+
        /* Do flush of entire cache */
        write_aux_reg(ARC_AUX_DC_FLSH, 1);
 
index 5d48d11bab6b76e2878b69e2ecb7742dd90beca2..8ace87fa0f25953a910161c8c9eaf4e845822b9f 100644 (file)
@@ -24,6 +24,7 @@
 #if (CONFIG_ARC_MMU_VER > 2)
 #define ARC_AUX_IC_PTAG                0x1E
 #endif
+#define ARC_BCR_IC_BUILD       0x77
 
 /* Timer related auxiliary registers */
 #define ARC_AUX_TIMER0_CNT     0x21    /* Timer 0 count */
@@ -42,6 +43,7 @@
 #if (CONFIG_ARC_MMU_VER > 2)
 #define ARC_AUX_DC_PTAG                0x5C
 #endif
+#define ARC_BCR_DC_BUILD       0x72
 
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */