ARC: Disable caches in early boot if so configured

Requested-by: Noam Camus <noamc@ezchip.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
Vineet Gupta 2014-03-07 18:08:11 +05:30
parent e87a850b9c
commit ef680cdc24
3 changed files with 87 additions and 84 deletions

View File

@ -55,4 +55,31 @@ extern void read_decode_cache_bcr(void);
#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 */

View File

@ -12,10 +12,42 @@
* to skip certain things during boot on simulator
*/
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/entry.h>
#include <linux/linkage.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
@ -27,7 +59,7 @@ stext:
; 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
; Ensure Boot (Master) proceeds. Others wait in platform dependent way
@ -90,7 +122,7 @@ stext:
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
ld r0, [@secondary_idle_tsk]

View File

@ -73,33 +73,6 @@
#include <asm/cachectl.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)
{
int n = 0;
@ -168,72 +141,43 @@ void read_decode_cache_bcr(void)
*/
void arc_cache_init(void)
{
unsigned int cpu = smp_processor_id();
struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
unsigned int dcache_does_alias, temp;
unsigned int __maybe_unused cpu = smp_processor_id();
struct cpuinfo_arc_cache __maybe_unused *ic, __maybe_unused *dc;
char str[256];
printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
if (!ic->ver)
goto chk_dc;
#ifdef CONFIG_ARC_HAS_ICACHE
/* 1. Confirm some of I-cache params which Linux assumes */
if (ic->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config");
ic = &cpuinfo_arc700[cpu].icache;
if (ic->ver) {
if (ic->line_len != L1_CACHE_BYTES)
panic("ICache line [%d] != kernel Config [%d]",
ic->line_len, L1_CACHE_BYTES);
if (ic->ver != CONFIG_ARC_MMU_VER)
panic("Cache ver doesn't match MMU ver\n");
if (ic->ver != CONFIG_ARC_MMU_VER)
panic("Cache ver [%d] doesn't match MMU ver [%d]\n",
ic->ver, CONFIG_ARC_MMU_VER);
}
#endif
/* 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
write_aux_reg(ARC_REG_IC_CTRL, temp);
chk_dc:
if (!dc->ver)
return;
#ifdef CONFIG_ARC_HAS_DCACHE
if (dc->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config");
dc = &cpuinfo_arc700[cpu].dcache;
if (dc->ver) {
unsigned int dcache_does_alias;
/* check for D-Cache aliasing */
dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
if (dc->line_len != L1_CACHE_BYTES)
panic("DCache line [%d] != kernel Config [%d]",
dc->line_len, L1_CACHE_BYTES);
if (dcache_does_alias && !cache_is_vipt_aliasing())
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
else if (!dcache_does_alias && cache_is_vipt_aliasing())
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
/* check for D-Cache aliasing */
dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
if (dcache_does_alias && !cache_is_vipt_aliasing())
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
else if (!dcache_does_alias && cache_is_vipt_aliasing())
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
}
#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