Skip to contentSkip to conversation

ARM: cache: Introduce weak dram_bank_setup function

RFC PATCH New R Sricharan 2 participants 4 messages Jan 8, 2013 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/2 ARM: cache: Introduce weak dram_bank_setup function

Introduce a weak version of dram_bank_setup function to allow a platform specific redefinition.

This is used in the subsequent patch to setup dram region without 'XN' attribute in order to enable the region under client permissions.

Cc Vincent Stehle <[email protected]>
Cc Tom Rini <[email protected]>
---
 arch/arm/include/asm/cache.h |    1 +
 arch/arm/lib/cache-cp15.c    |    7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)
arch/arm/include/asm/cache.h +1 -0
index eef6a5a..93811d2 100644
@@ -42,6 +42,7 @@ static inline void invalidate_l2_cache(void)
 void l2_cache_enable(void);
 void l2_cache_disable(void);
 
+void dram_bank_mmu_setup(int bank);
 /*
  * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
  * use that value for aligning DMA buffers unless the board config has specified
arch/arm/lib/cache-cp15.c +6 -1
index 6edf815..843078e 100644
@@ -23,6 +23,8 @@
 
 #include <common.h>
 #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
@@ -77,7 +79,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
 	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+void __dram_bank_mmu_setup(int bank)
 {
 	bd_t *bd = gd->bd;
 	int	i;
@@ -94,6 +96,9 @@ static inline void dram_bank_mmu_setup(int bank)
 	}
 }
 
+void dram_bank_mmu_setup(int bank)
+	__attribute__((weak, alias("__dram_bank_mmu_setup")));
+
 /* to activate the MMU we need to set up virtual memory: use 1M areas */
 static inline void mmu_setup(void)
 {
Signature · 1 line
1.7.9.5
#1 lore raw

RFC PATCH 2/2 ARM: mmu: Set domain permissions to client access

The 'XN' execute never bit is set in the pagetables. This will prevent speculative prefetches to non executable regions. But the domain permissions are set as master in the DACR register. So the pagetable attribute for 'XN' is not effective. Change the permissions to client.

This fixes lot of speculative prefetch aborts seen with CORTEX A15 otherwise.

Cc Vincent Stehle <[email protected]>
Cc Tom Rini <[email protected]>
---
 arch/arm/cpu/armv7/cache_v7.c                  |    3 ++
 arch/arm/cpu/armv7/omap-common/hwinit-common.c |   35 ++++++++++++++++++++++++
 arch/arm/include/asm/system.h                  |   14 ++++++++++
 arch/arm/lib/cache-cp15.c                      |    9 ++++++
 4 files changed, 61 insertions(+)
arch/arm/cpu/armv7/cache_v7.c +3 -0
index 5f6d039..8748c14 100644
@@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
 {
 }
 
+void arm_init_domains(void)
+{
+}
 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
 
 #ifndef CONFIG_SYS_ICACHE_OFF
arch/arm/cpu/armv7/omap-common/hwinit-common.c +35 -0
index 9ef10bd..4eaf75b 100644
@@ -32,6 +32,12 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/sizes.h>
 #include <asm/emif.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define ARMV7_DCACHE_WRITEBACK  0xe
+#define	ARMV7_DOMAIN_CLIENT	1
+#define ARMV7_DOMAIN_MASK	(0x3 << 0)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -258,4 +264,33 @@ void enable_caches(void)
 	/* Enable D-cache. I-cache is already enabled in start.S */
 	dcache_enable();
 }
+
+void dram_bank_mmu_setup(int bank)
+{
+	bd_t *bd = gd->bd;
+	int	i;
+
+	u32 start = bd->bi_dram[bank].start >> 20;
+	u32 size = bd->bi_dram[bank].size >> 20;
+	u32 end = start + size;
+
+	debug("%s: bank: %d\n", __func__, bank);
+	for (i = start; i < end; i++)
+		set_section_dcache(i, ARMV7_DCACHE_WRITEBACK);
+
+}
+
+void arm_init_domains(void)
+{
+	u32 reg;
+
+	reg = get_dacr();
+	/*
+	* Set DOMAIN to client access so that all permissions
+	* set in pagetables are validated by the mmu.
+	*/
+	reg &= ~ARMV7_DOMAIN_MASK;
+	reg |= ARMV7_DOMAIN_CLIENT;
+	set_dacr(reg);
+}
 #endif
arch/arm/include/asm/system.h +14 -0
index 78ca8e0..9cfbb17 100644
@@ -75,6 +75,20 @@ static inline void set_cr(unsigned int val)
 	isb();
 }
 
+static inline unsigned int get_dacr(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c3, c0, 0	@ get DACR" : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c3, c0, 0	@ set DACR"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
 /* options available for data cache on each page */
 enum dcache_option {
 	DCACHE_OFF = 0x12,
arch/arm/lib/cache-cp15.c +9 -0
index 843078e..2149677 100644
@@ -36,6 +36,12 @@ void __arm_init_before_mmu(void)
 void arm_init_before_mmu(void)
 	__attribute__((weak, alias("__arm_init_before_mmu")));
 
+void __arm_init_domains(void)
+{
+}
+void arm_init_domains(void)
+	__attribute__((weak, alias("__arm_init_domains")));
+
 static void cp_delay (void)
 {
 	volatile int i;
@@ -120,6 +126,9 @@ static inline void mmu_setup(void)
 	/* Set the access control to all-supervisor */
 	asm volatile("mcr p15, 0, %0, c3, c0, 0"
 		     : : "r" (~0));
+
+	arm_init_domains();
+
 	/* and enable the mmu */
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
Signature · 1 line
1.7.9.5
#2 lore raw

RFC PATCH 1/2 ARM: cache: Introduce weak dram_bank_setup function

In reply to R Sricharan
Quoted 50 lines · R Sricharan

Introduce a weak version of dram_bank_setup function to allow a platform specific redefinition.

This is used in the subsequent patch to setup dram region without 'XN' attribute in order to enable the region under client permissions.

Cc Vincent Stehle <[email protected]>
Cc Tom Rini <[email protected]>
---
 arch/arm/include/asm/cache.h |    1 +
 arch/arm/lib/cache-cp15.c    |    7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)
arch/arm/include/asm/cache.h +1 -0
index eef6a5a..93811d2 100644
@@ -42,6 +42,7 @@ static inline void invalidate_l2_cache(void)
 void l2_cache_enable(void);
 void l2_cache_disable(void);
 
+void dram_bank_mmu_setup(int bank);
 /*
  * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
  * use that value for aligning DMA buffers unless the board config has specified
arch/arm/lib/cache-cp15.c +3 -1
index 6edf815..843078e 100644
@@ -23,6 +23,8 @@
 
 #include <common.h>
 #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
@@ -77,7 +79,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
 	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+void __dram_bank_mmu_setup(int bank)
 {
 	bd_t *bd = gd->bd;
 	int	i;

arch/arm/lib/cache-cp15.c static inline void dram_bank_mmu_setup(int bank) · line 100

Quoted 5 lines
arch/arm/lib/cache-cp15.c +2 -0
@@ -94,6 +96,9 @@ static inline void dram_bank_mmu_setup(int bank)
 	}
 }
 
+void dram_bank_mmu_setup(int bank)
+	__attribute__((weak, alias("__dram_bank_mmu_setup")));

Please use this instead (you already included linux/compiler.h for this):

__weak void dram_bank_mmu_setup(int bank)
{
...

Thanks,
Stefan

#3 lore raw

RFC PATCH 1/2 ARM: cache: Introduce weak dram_bank_setup function

Hi Stefan,

Quoted 54 lines · Stefan Roese
Quoted 53 lines · R Sricharan

Introduce a weak version of dram_bank_setup function to allow a platform specific redefinition.

This is used in the subsequent patch to setup dram region without 'XN' attribute in order to enable the region under client permissions.

Cc Vincent Stehle <[email protected]>
Cc Tom Rini <[email protected]>
---
  arch/arm/include/asm/cache.h |    1 +
  arch/arm/lib/cache-cp15.c    |    7 ++++++-
  2 files changed, 7 insertions(+), 1 deletion(-)
arch/arm/include/asm/cache.h +1 -0
index eef6a5a..93811d2 100644
@@ -42,6 +42,7 @@ static inline void invalidate_l2_cache(void)
  void l2_cache_enable(void);
  void l2_cache_disable(void);
 
+void dram_bank_mmu_setup(int bank);
  /*
   * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
   * use that value for aligning DMA buffers unless the board config has specified
arch/arm/lib/cache-cp15.c +3 -1
index 6edf815..843078e 100644
@@ -23,6 +23,8 @@
 
  #include <common.h>
  #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
  #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
@@ -77,7 +79,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
  	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
  }
 
-static inline void dram_bank_mmu_setup(int bank)
+void __dram_bank_mmu_setup(int bank)
  {
  	bd_t *bd = gd->bd;
  	int	i;
@@ -94,6 +96,9 @@ static inline void dram_bank_mmu_setup(int bank)
  	}
  }
 
Quoted 8 lines

arch/arm/lib/cache-cp15.c static inline void dram_bank_mmu_setup(int bank) · line 100

Quoted 2 lines
arch/arm/lib/cache-cp15.c +2 -0
+void dram_bank_mmu_setup(int bank)
+	__attribute__((weak, alias("__dram_bank_mmu_setup")));

Please use this instead (you already included linux/compiler.h for this):

__weak void dram_bank_mmu_setup(int bank)
{
...

Ok, will correct this and repost.

Regards,
Sricharan