Commit ef680cdc authored by Vineet Gupta's avatar Vineet Gupta

ARC: Disable caches in early boot if so configured

Requested-by: default avatarNoam Camus <noamc@ezchip.com>
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent e87a850b
...@@ -55,4 +55,31 @@ extern void read_decode_cache_bcr(void); ...@@ -55,4 +55,31 @@ extern void read_decode_cache_bcr(void);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72 /* Build Config reg */
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
#endif /* _ASM_CACHE_H */ #endif /* _ASM_CACHE_H */
...@@ -12,10 +12,42 @@ ...@@ -12,10 +12,42 @@
* to skip certain things during boot on simulator * to skip certain things during boot on simulator
*/ */
#include <linux/linkage.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/entry.h> #include <asm/entry.h>
#include <linux/linkage.h>
#include <asm/arcregs.h> #include <asm/arcregs.h>
#include <asm/cache.h>
.macro CPU_EARLY_SETUP
; Setting up Vectror Table (in case exception happens in early boot
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
; Disable I-cache/D-cache if kernel so configured
lr r5, [ARC_REG_IC_BCR]
breq r5, 0, 1f ; I$ doesn't exist
lr r5, [ARC_REG_IC_CTRL]
#ifdef CONFIG_ARC_HAS_ICACHE
bclr r5, r5, 0 ; 0 - Enable, 1 is Disable
#else
bset r5, r5, 0 ; I$ exists, but is not used
#endif
sr r5, [ARC_REG_IC_CTRL]
1:
lr r5, [ARC_REG_DC_BCR]
breq r5, 0, 1f ; D$ doesn't exist
lr r5, [ARC_REG_DC_CTRL]
bclr r5, r5, 6 ; Invalidate (discard w/o wback)
#ifdef CONFIG_ARC_HAS_DCACHE
bclr r5, r5, 0 ; Enable (+Inv)
#else
bset r5, r5, 0 ; Disable (+Inv)
#endif
sr r5, [ARC_REG_DC_CTRL]
1:
.endm
.cpu A7 .cpu A7
...@@ -27,7 +59,7 @@ stext: ...@@ -27,7 +59,7 @@ stext:
; Don't clobber r0-r2 yet. It might have bootloader provided info ; Don't clobber r0-r2 yet. It might have bootloader provided info
;------------------------------------------------------------------- ;-------------------------------------------------------------------
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] CPU_EARLY_SETUP
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
; Ensure Boot (Master) proceeds. Others wait in platform dependent way ; Ensure Boot (Master) proceeds. Others wait in platform dependent way
...@@ -90,7 +122,7 @@ stext: ...@@ -90,7 +122,7 @@ stext:
first_lines_of_secondary: first_lines_of_secondary:
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] CPU_EARLY_SETUP
; setup per-cpu idle task as "current" on this CPU ; setup per-cpu idle task as "current" on this CPU
ld r0, [@secondary_idle_tsk] ld r0, [@secondary_idle_tsk]
......
...@@ -73,33 +73,6 @@ ...@@ -73,33 +73,6 @@
#include <asm/cachectl.h> #include <asm/cachectl.h>
#include <asm/setup.h> #include <asm/setup.h>
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72 /* Build Config reg */
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
char *arc_cache_mumbojumbo(int c, char *buf, int len) char *arc_cache_mumbojumbo(int c, char *buf, int len)
{ {
int n = 0; int n = 0;
...@@ -168,44 +141,33 @@ void read_decode_cache_bcr(void) ...@@ -168,44 +141,33 @@ void read_decode_cache_bcr(void)
*/ */
void arc_cache_init(void) void arc_cache_init(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int __maybe_unused cpu = smp_processor_id();
struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; struct cpuinfo_arc_cache __maybe_unused *ic, __maybe_unused *dc;
struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
unsigned int dcache_does_alias, temp;
char str[256]; char str[256];
printk(arc_cache_mumbojumbo(0, str, sizeof(str))); printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
if (!ic->ver)
goto chk_dc;
#ifdef CONFIG_ARC_HAS_ICACHE #ifdef CONFIG_ARC_HAS_ICACHE
/* 1. Confirm some of I-cache params which Linux assumes */ ic = &cpuinfo_arc700[cpu].icache;
if (ic->ver) {
if (ic->line_len != L1_CACHE_BYTES) if (ic->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config"); panic("ICache line [%d] != kernel Config [%d]",
ic->line_len, L1_CACHE_BYTES);
if (ic->ver != CONFIG_ARC_MMU_VER) if (ic->ver != CONFIG_ARC_MMU_VER)
panic("Cache ver doesn't match MMU ver\n"); panic("Cache ver [%d] doesn't match MMU ver [%d]\n",
#endif ic->ver, CONFIG_ARC_MMU_VER);
}
/* Enable/disable I-Cache */
temp = read_aux_reg(ARC_REG_IC_CTRL);
#ifdef CONFIG_ARC_HAS_ICACHE
temp &= ~IC_CTRL_CACHE_DISABLE;
#else
temp |= IC_CTRL_CACHE_DISABLE;
#endif #endif
write_aux_reg(ARC_REG_IC_CTRL, temp);
chk_dc:
if (!dc->ver)
return;
#ifdef CONFIG_ARC_HAS_DCACHE #ifdef CONFIG_ARC_HAS_DCACHE
dc = &cpuinfo_arc700[cpu].dcache;
if (dc->ver) {
unsigned int dcache_does_alias;
if (dc->line_len != L1_CACHE_BYTES) if (dc->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config"); panic("DCache line [%d] != kernel Config [%d]",
dc->line_len, L1_CACHE_BYTES);
/* check for D-Cache aliasing */ /* check for D-Cache aliasing */
dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE; dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
...@@ -214,26 +176,8 @@ void arc_cache_init(void) ...@@ -214,26 +176,8 @@ void arc_cache_init(void)
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
else if (!dcache_does_alias && cache_is_vipt_aliasing()) else if (!dcache_does_alias && cache_is_vipt_aliasing())
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n"); panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
}
#endif #endif
/* Set the default Invalidate Mode to "simpy discard dirty lines"
* as this is more frequent then flush before invalidate
* Ofcourse we toggle this default behviour when desired
*/
temp = read_aux_reg(ARC_REG_DC_CTRL);
temp &= ~DC_CTRL_INV_MODE_FLUSH;
#ifdef CONFIG_ARC_HAS_DCACHE
/* Enable D-Cache: Clear Bit 0 */
write_aux_reg(ARC_REG_DC_CTRL, temp & ~IC_CTRL_CACHE_DISABLE);
#else
/* Flush D cache */
write_aux_reg(ARC_REG_DC_FLSH, 0x1);
/* Disable D cache */
write_aux_reg(ARC_REG_DC_CTRL, temp | IC_CTRL_CACHE_DISABLE);
#endif
return;
} }
#define OP_INV 0x1 #define OP_INV 0x1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment