[PATCH] ARM: get rid of a few StrongARM cache-related build time constants
Nicolas Pitre
nicolas.pitre at linaro.org
Tue Jul 5 22:33:56 EDT 2011
The StrongARM based machines define a couple constants which are
obstacles to a single kernel image. Amongst them are FLUSH_BASE,
FLUSH_BASE_PHYS, FLUSH_BASE_MINICACHE and UNCACHEABLE_ADDR.
The affected code can be found in mm/mmu.c, mm/proc-sa110.S,
mm/proc-sa1100.S and cache-v4wb.S. Let's create some code to
deal with the differences at run time and initialize the proper
mappings with common virtual addresses for them instead.
This should be functionally equivalent except for the following
details:
- Mappings are created using second level PTEs instead of first
level sections. The first level page table covering those PTEs
is already there because of the fixmaps and the vector page so no
additional memory is required. There might also be more TLB usage,
however this is not something one might be concerned about when the
whole cache is being flushed, completely pushing the cost of those
TLBs below noise level.
- CACHE_DLIMIT is now the same for both SA110 and SA1100. This is
unclear if loading a variable each time v4wb_flush_user_cache_range
is called would be beneficial.
- The way UNCACHEABLE_ADDR was defined and used on RiscPC and Shark
didn't produce a real uncacheable address, probably inhibiting the
clock switching in cpu_sa110_do_idle(). As a side effect, this patch
fixes this.
Signed-off-by: Nicolas Pitre <nicolas.pitre at linaro.org>
---
Documentation/arm/memory.txt | 7 +-
arch/arm/include/asm/cacheflush.h | 10 +++
arch/arm/mach-ebsa110/core.c | 4 +
arch/arm/mach-ebsa110/include/mach/hardware.h | 5 -
arch/arm/mach-ebsa110/include/mach/memory.h | 6 --
arch/arm/mach-footbridge/common.c | 3 +
arch/arm/mach-footbridge/include/mach/hardware.h | 2 -
arch/arm/mach-footbridge/include/mach/memory.h | 7 --
arch/arm/mach-rpc/include/mach/hardware.h | 2 -
arch/arm/mach-rpc/include/mach/memory.h | 6 --
arch/arm/mach-rpc/riscpc.c | 4 +
arch/arm/mach-sa1100/generic.c | 7 ++-
arch/arm/mach-sa1100/include/mach/hardware.h | 4 -
arch/arm/mach-sa1100/include/mach/memory.h | 7 --
arch/arm/mach-shark/core.c | 2 +
arch/arm/mach-shark/include/mach/hardware.h | 2 -
arch/arm/mach-shark/include/mach/memory.h | 6 --
arch/arm/mm/Makefile | 2 +-
arch/arm/mm/cache-v4wb-init.c | 89 ++++++++++++++++++++++
arch/arm/mm/cache-v4wb.S | 31 +------
arch/arm/mm/proc-sa110.S | 5 +
arch/arm/mm/proc-sa1100.S | 5 +
22 files changed, 138 insertions(+), 78 deletions(-)
create mode 100644 arch/arm/mm/cache-v4wb-init.c
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 771d48d..b7a5ae8 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -31,9 +31,10 @@ ffff0000 ffff0fff CPU vector page.
CPU supports vector relocation (control
register V bit.)
-fffe0000 fffeffff XScale cache flush area. This is used
- in proc-xscale.S to flush the whole data
- cache. (XScale does not have TCM.)
+fffe0000 fffeffff StrongARM and XScale cache flush area.
+ This is used in cache-v4wb.S and proc-xscale.S
+ to flush the whole data cache.
+ (Neither StrongARM nor XScale have TCM.)
fffe8000 fffeffff DTCM mapping area for platforms with
DTCM mounted inside the CPU.
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index d5d8d5c..1821757 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -157,6 +157,16 @@ extern void dmac_flush_range(const void *, const void *);
#endif
+#ifdef CONFIG_CPU_CACHE_V4WB
+
+enum cache_v4wb_cputype { CACHE_CPU_SA110, CACHE_CPU_SA1100 };
+
+extern void cache_v4wb_init(unsigned long flush_phys_addr,
+ unsigned long uncached_phys_addr,
+ enum cache_v4wb_cputype cpu_type);
+
+#endif
+
/*
* Copy user data from/to a page which is mapped into a different
* processes address space. Really, we want to allow our "user
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 087bc77..f8a94d6 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -23,6 +23,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
@@ -114,9 +115,12 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
}
};
+#define SRAM_PHYS 0xdf000000
+
static void __init ebsa110_map_io(void)
{
iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
+ cache_v4wb_init(SRAM_PHYS, TRICK4_PHYS, CACHE_CPU_SA110);
}
diff --git a/arch/arm/mach-ebsa110/include/mach/hardware.h b/arch/arm/mach-ebsa110/include/mach/hardware.h
index 4b2fb77..705dc40 100644
--- a/arch/arm/mach-ebsa110/include/mach/hardware.h
+++ b/arch/arm/mach-ebsa110/include/mach/hardware.h
@@ -54,10 +54,5 @@
#define PIT_BASE 0xfc000000
#define SOFT_BASE 0xfd000000
-/*
- * RAM definitions
- */
-#define UNCACHEABLE_ADDR 0xff000000 /* IRQ_STAT */
-
#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/memory.h b/arch/arm/mach-ebsa110/include/mach/memory.h
index 8e49066..2af7ec4 100644
--- a/arch/arm/mach-ebsa110/include/mach/memory.h
+++ b/arch/arm/mach-ebsa110/include/mach/memory.h
@@ -21,10 +21,4 @@
*/
#define PLAT_PHYS_OFFSET UL(0x00000000)
-/*
- * Cache flushing area - SRAM
- */
-#define FLUSH_BASE_PHYS 0x40000000
-#define FLUSH_BASE 0xdf000000
-
#endif
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index 38a44f9..2b9d83a 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -21,6 +21,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
+#include <asm/cacheflush.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach/irq.h>
@@ -185,6 +186,8 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
void __init footbridge_map_io(void)
{
+ cache_v4wb_init(0x50000000, 0x50010000, CACHE_CPU_SA110);
+
/*
* Set up the common mapping first; we need this to
* determine whether we're in host mode or not.
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
index b6fdf23..f8b7e95 100644
--- a/arch/arm/mach-footbridge/include/mach/hardware.h
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -63,8 +63,6 @@
#define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5))
#define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6))
-#define UNCACHEABLE_ADDR (ARMCSR_BASE + 0x108)
-
/* PIC irq control */
#define PIC_LO 0x20
diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h
index 5c6df37..3e17e5c 100644
--- a/arch/arm/mach-footbridge/include/mach/memory.h
+++ b/arch/arm/mach-footbridge/include/mach/memory.h
@@ -55,15 +55,8 @@ extern unsigned long __bus_to_pfn(unsigned long);
#endif
/*
- * Cache flushing area.
- */
-#define FLUSH_BASE 0xf9000000
-
-/*
* Physical DRAM offset.
*/
#define PLAT_PHYS_OFFSET UL(0x00000000)
-#define FLUSH_BASE_PHYS 0x50000000
-
#endif
diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h
index dde6b3c..4f3b227 100644
--- a/arch/arm/mach-rpc/include/mach/hardware.h
+++ b/arch/arm/mach-rpc/include/mach/hardware.h
@@ -46,8 +46,6 @@
#define SCREEN_END 0xdfc00000
#define SCREEN_BASE 0xdf800000
-#define UNCACHEABLE_ADDR 0xdf010000
-
/*
* IO Addresses
*/
diff --git a/arch/arm/mach-rpc/include/mach/memory.h b/arch/arm/mach-rpc/include/mach/memory.h
index 18a2210..e2fcf9b 100644
--- a/arch/arm/mach-rpc/include/mach/memory.h
+++ b/arch/arm/mach-rpc/include/mach/memory.h
@@ -24,12 +24,6 @@
#define PLAT_PHYS_OFFSET UL(0x10000000)
/*
- * Cache flushing area - ROM
- */
-#define FLUSH_BASE_PHYS 0x00000000
-#define FLUSH_BASE 0xdf000000
-
-/*
* Sparsemem support. Each section is a maximum of 64MB. The sections
* are offset by 128MB and can cover 128MB, so that gives us a maximum
* of 29 physmem bits.
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index 580b3c7..fd086ff 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -27,6 +27,7 @@
#include <asm/page.h>
#include <asm/domain.h>
#include <asm/setup.h>
+#include <asm/cacheflush.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
@@ -84,6 +85,9 @@ static struct map_desc rpc_io_desc[] __initdata = {
static void __init rpc_map_io(void)
{
iotable_init(rpc_io_desc, ARRAY_SIZE(rpc_io_desc));
+#ifdef CPU_CACHE_V4WB
+ cache_v4wb_init(0, 0x10000, CACHE_CPU_SA110);
+#endif
/*
* Turn off floppy.
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index e21f347..9ddd265 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -21,6 +21,7 @@
#include <asm/div64.h>
#include <mach/hardware.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/irq.h>
@@ -403,12 +404,16 @@ static struct map_desc standard_io_desc[] __initdata = {
.pfn = __phys_to_pfn(0xb0000000),
.length = 0x00200000,
.type = MT_DEVICE
- },
+ }
};
+#define SA1100_ZERO_BANK 0xe0000000
+#define ICIP_PHYS_ADDR 0x90050000
+
void __init sa1100_map_io(void)
{
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+ cache_v4wb_init(SA1100_ZERO_BANK, ICIP_PHYS_ADDR, CACHE_CPU_SA1100);
}
/*
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index 967ae76..355f0b0 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -12,10 +12,6 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
-
-#define UNCACHEABLE_ADDR 0xfa050000
-
-
/*
* SA1100 internal I/O mappings
*
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index 12d3767..8b56fb3 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -31,11 +31,4 @@
#define MAX_PHYSMEM_BITS 32
#define SECTION_SIZE_BITS 27
-/*
- * Cache flushing area - SA1100 zero bank
- */
-#define FLUSH_BASE_PHYS 0xe0000000
-#define FLUSH_BASE 0xf5000000
-#define FLUSH_BASE_MINICACHE 0xf5100000
-
#endif
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index ac2873c..1173082 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -15,6 +15,7 @@
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/param.h>
+#include <asm/cacheflush.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,7 @@ static struct map_desc shark_io_desc[] __initdata = {
static void __init shark_map_io(void)
{
iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
+ cache_v4wb_init(0x80000000, 0x80010000, CACHE_CPU_SA110);
}
#define IRQ_TIMER 0
diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h
index 94d84b2..dab0857 100644
--- a/arch/arm/mach-shark/include/mach/hardware.h
+++ b/arch/arm/mach-shark/include/mach/hardware.h
@@ -10,8 +10,6 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
-#define UNCACHEABLE_ADDR 0xdf010000
-
#define pcibios_assign_all_busses() 1
#define PCIBIOS_MIN_IO 0x6000
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
index 1cf8d69..e19df6f 100644
--- a/arch/arm/mach-shark/include/mach/memory.h
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -17,10 +17,4 @@
*/
#define PLAT_PHYS_OFFSET UL(0x08000000)
-/*
- * Cache flushing area
- */
-#define FLUSH_BASE_PHYS 0x80000000
-#define FLUSH_BASE 0xdf000000
-
#endif
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index bca7e61..14b0af1 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -36,7 +36,7 @@ obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o
obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
-obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
+obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o cache-v4wb-init.o
obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o
obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o
diff --git a/arch/arm/mm/cache-v4wb-init.c b/arch/arm/mm/cache-v4wb-init.c
new file mode 100644
index 0000000..e86b14e
--- /dev/null
+++ b/arch/arm/mm/cache-v4wb-init.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mm/cache-v4wb-init.c
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Runtime initialization for the code in cache-v4wb.S.
+ */
+
+#include <linux/init.h>
+#include <asm/sizes.h>
+#include <asm/cacheflush.h>
+#include <asm/mach/map.h>
+
+#define FLUSH_BASE 0xfffe0000
+#define FLUSH_OFF_ALT SZ_32K
+#define FLUSH_BASE_ALT (FLUSH_BASE + FLUSH_OFF_ALT)
+#define UNCACHEABLE_ADDR 0xfffee000
+
+static struct map_desc cache_v4wb_map[] __initdata = {
+ {
+ .virtual = FLUSH_BASE,
+ .length = SZ_16K,
+ .type = MT_CACHECLEAN,
+ }, {
+ .virtual = FLUSH_BASE + SZ_16K,
+ .length = PAGE_SIZE,
+ .type = MT_MINICLEAN,
+ }, {
+ .virtual = FLUSH_BASE_ALT,
+ .length = SZ_16K,
+ .type = MT_CACHECLEAN,
+ }, {
+ .virtual = FLUSH_BASE_ALT + SZ_16K,
+ .length = PAGE_SIZE,
+ .type = MT_MINICLEAN,
+ }, {
+ .virtual = UNCACHEABLE_ADDR,
+ .length = PAGE_SIZE,
+ .type = MT_UNCACHED,
+ }
+};
+
+/* shared with cache-v4wb.S */
+struct {
+ unsigned long addr;
+ unsigned long size;
+} cache_v4wb_params;
+
+/*
+ * This sets up cache flushing areas for the SA110 and SA11x0 processors.
+ * For convenience, uncached_phys_addr is used here to create an uncacheable
+ * mapping as needed by proc-sa110.S and proc-sa1100.S.
+ */
+void __init cache_v4wb_init(unsigned long flush_phys_addr,
+ unsigned long uncached_phys_addr,
+ enum cache_v4wb_cputype cpu_type)
+{
+ cache_v4wb_map[0].pfn = __phys_to_pfn(flush_phys_addr);
+ cache_v4wb_map[1].pfn = __phys_to_pfn(flush_phys_addr + SZ_16K);
+ cache_v4wb_map[2].pfn = __phys_to_pfn(flush_phys_addr + FLUSH_OFF_ALT);
+ cache_v4wb_map[3].pfn = __phys_to_pfn(flush_phys_addr + FLUSH_OFF_ALT + SZ_16K);
+ cache_v4wb_map[4].pfn = __phys_to_pfn(uncached_phys_addr);
+
+ /*
+ * SA110 has a 16KB cache and no minicache.
+ * SA1100 has a 8KB cache and a 512-byte minicache.
+ * To make the flush code straight forward, we simply pretend
+ * that the SA1100 has a cache of 8704 bytes in size and its
+ * flush area is located at an offset of 8192 bytes into
+ * the mapped area.
+ */
+ switch (cpu_type) {
+ case CACHE_CPU_SA110:
+ cache_v4wb_params.addr = FLUSH_BASE;
+ cache_v4wb_params.size = SZ_16K;
+ break;
+ case CACHE_CPU_SA1100:
+ cache_v4wb_params.addr = FLUSH_BASE + SZ_8K;
+ cache_v4wb_params.size = SZ_8K + 512;
+ break;
+ }
+
+ iotable_init(cache_v4wb_map, ARRAY_SIZE(cache_v4wb_map));
+}
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index f40c696..bff5fec 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -19,17 +19,6 @@
#define CACHE_DLINESIZE 32
/*
- * The total size of the data cache.
- */
-#if defined(CONFIG_CPU_SA110)
-# define CACHE_DSIZE 16384
-#elif defined(CONFIG_CPU_SA1100)
-# define CACHE_DSIZE 8192
-#else
-# error Unknown cache size
-#endif
-
-/*
* This is the size at which it becomes more efficient to
* clean the whole cache, rather than using the individual
* cache line maintenance instructions.
@@ -43,11 +32,8 @@
* 131072 591 591 591 656 657 651
* Whole 132 136 132 221 217 207 <---
*/
-#define CACHE_DLIMIT (CACHE_DSIZE * 4)
+#define CACHE_DLIMIT 32768
- .data
-flush_base:
- .long FLUSH_BASE
.text
/*
@@ -78,21 +64,14 @@ ENTRY(v4wb_flush_kern_cache_all)
mov ip, #0
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
__flush_whole_cache:
- ldr r3, =flush_base
- ldr r1, [r3, #0]
- eor r1, r1, #CACHE_DSIZE
+ ldr r3, =cache_v4wb_params
+ ldmia r3, {r1, r2}
+ eor r1, r1, #32768 @ FLUSH_OFF_ALT
str r1, [r3, #0]
- add r2, r1, #CACHE_DSIZE
-1: ldr r3, [r1], #32
- cmp r1, r2
- blo 1b
-#ifdef FLUSH_BASE_MINICACHE
- add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE
- sub r1, r2, #512 @ only 512 bytes
+ add r2, r1, r2
1: ldr r3, [r1], #32
cmp r1, r2
blo 1b
-#endif
mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
mov pc, lr
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 46f09ed..e8c44a2 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -30,6 +30,11 @@
*/
#define DCACHELINESIZE 32
+/*
+ * Address used for uncached access (mapping set up in cache-v4wb-init.c)
+ */
+#define UNCACHEABLE_ADDR 0xfffee000
+
.text
/*
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 184a9c9..2d805ae 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -34,6 +34,11 @@
*/
#define DCACHELINESIZE 32
+/*
+ * Address used for uncached access (mapping set up in cache-v4wb-init.c)
+ */
+#define UNCACHEABLE_ADDR 0xfffee000
+
__INIT
/*
--
1.7.4
More information about the linux-arm-kernel
mailing list