summaryrefslogtreecommitdiff
path: root/arch/arc/cpu/arc700/cache.c
diff options
context:
space:
mode:
authorIgor Guryanov <guryanov@synopsys.com>2014-12-24 16:07:07 +0300
committerAlexey Brodkin <abrodkin@synopsys.com>2015-01-15 22:38:42 +0300
commitf8cf3d1ebdf7622f65c4eeba9eae1ed04982de12 (patch)
tree0c6ef6836bf450895c669e52a7c9b9b2042dca62 /arch/arc/cpu/arc700/cache.c
parent28c4dae114c9b94b2a1111d81d4da716e9fc2cba (diff)
downloadu-boot-imx-f8cf3d1ebdf7622f65c4eeba9eae1ed04982de12.zip
u-boot-imx-f8cf3d1ebdf7622f65c4eeba9eae1ed04982de12.tar.gz
u-boot-imx-f8cf3d1ebdf7622f65c4eeba9eae1ed04982de12.tar.bz2
arc: check caches existence before use
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>
Diffstat (limited to 'arch/arc/cpu/arc700/cache.c')
-rw-r--r--arch/arc/cpu/arc700/cache.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/arc/cpu/arc700/cache.c b/arch/arc/cpu/arc700/cache.c
index 39d522d..fa19a13 100644
--- a/arch/arc/cpu/arc700/cache.c
+++ b/arch/arc/cpu/arc700/cache.c
@@ -14,21 +14,34 @@
#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);