[U-Boot] [PATCH 2/6] SH2A cache support.
Yoshinori Sato
ysato at users.sourceforge.jp
Tue Feb 11 13:24:42 CET 2014
Signed-off-by: Yoshinori Sato <ysato at users.sourceforge.jp>
---
arch/sh/cpu/sh2/Makefile | 6 ++
arch/sh/cpu/sh2/cache-sh2a.c | 143 ++++++++++++++++++++++++++++++++++++++++++
arch/sh/cpu/sh2/cpu.c | 31 ---------
arch/sh/cpu/sh2/nocache.c | 37 +++++++++++
arch/sh/include/asm/cpu_sh2.h | 9 ---
5 files changed, 186 insertions(+), 40 deletions(-)
create mode 100644 arch/sh/cpu/sh2/cache-sh2a.c
create mode 100644 arch/sh/cpu/sh2/nocache.c
diff --git a/arch/sh/cpu/sh2/Makefile b/arch/sh/cpu/sh2/Makefile
index a19ed5e..6a11448 100644
--- a/arch/sh/cpu/sh2/Makefile
+++ b/arch/sh/cpu/sh2/Makefile
@@ -4,9 +4,15 @@
#
# Copyright (C) 2007,2008 Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
# Copyright (C) 2008 Renesas Solutions Corp.
+# Copyright (C) 2013 Yoshinori Sato <ysato at users.sourceforge.jp>
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y = start.o
obj-y = cpu.o interrupts.o watchdog.o
+ifdef CONFIG_SH2A
+obj-y += cache-sh2a.o
+else
+obj-y += nocache.o
+endif
diff --git a/arch/sh/cpu/sh2/cache-sh2a.c b/arch/sh/cpu/sh2/cache-sh2a.c
new file mode 100644
index 0000000..a7bf5bc
--- /dev/null
+++ b/arch/sh/cpu/sh2/cache-sh2a.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Yoshinori Sato <ysato at users.sourceforge.jp>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+
+/*
+ * Jump to cache disabled area
+ * When handling caches, we need to do it from non-cache area.
+ */
+#define jump_to_uncacheable() \
+do { \
+ unsigned long __dummy; \
+ __asm__ __volatile__( \
+ "mov.l 1f, %0\n\t" \
+ "or %1, %0\n\t" \
+ "jmp @%0\n\t" \
+ " nop\n\t" \
+ ".balign 4\n" \
+ "1: .long 2f\n" \
+ "2:" \
+ : "=&r" (__dummy) \
+ : "r" (0x20000000)); \
+} while (0)
+
+/*
+ * Back to cache area.
+ */
+#define back_to_cacheable() \
+do { \
+ unsigned long __dummy; \
+ __asm__ __volatile__( \
+ "nop;nop;nop;nop;nop;nop;nop\n\t" \
+ "mov.l 1f, %0\n\t" \
+ "jmp @%0\n\t" \
+ " nop\n\t" \
+ ".balign 4\n" \
+ "1: .long 2f\n" \
+ "2:" \
+ : "=&r" (__dummy)); \
+} while (0)
+
+#define CACHE_OC_NUM_ENTRIES 128
+#define CACHE_OC_NUM_WAYS 4
+#define CACHE_OC_ADDRESS_ARRAY 0xf0800000
+#define CACHE_OC_WAY_SHIFT 11
+#define CACHE_OC_ENTRY_SHIFT 2
+#define CACHE_UPDATED 0x02
+
+static inline void cache_wback_all(void)
+{
+ unsigned long addr, data, i, j;
+
+ for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){
+ for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
+ addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT)
+ | (i << CACHE_OC_ENTRY_SHIFT);
+ data = inl(addr);
+ if (data & CACHE_UPDATED) {
+ data &= ~CACHE_UPDATED;
+ outl(data, addr);
+ }
+ }
+ }
+}
+void flush_cache(unsigned long addr, unsigned long size)
+{
+ unsigned long entry;
+ unsigned long tag;
+ size = (size + 3) & ~3;
+ jump_to_uncacheable();
+ while(size > 0) {
+ entry = addr & 0x000003ff0;
+ tag = addr & 0x1ffff0000;
+ /* I-Cache flush */
+ outl(tag, 0xf0000008 | entry);
+ /* D-Cache flush with wb */
+ outl(tag, 0xf0800008 | entry);
+ addr += 4;
+ size -= 4;
+ }
+ back_to_cacheable();
+}
+
+void icache_enable(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ ccr |= 0x00000900;
+ jump_to_uncacheable();
+ writel(ccr, CCR1);
+ back_to_cacheable();
+}
+
+void icache_disable(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ ccr &= ~0x00000100;
+ jump_to_uncacheable();
+ writel(ccr, CCR1);
+ back_to_cacheable();
+}
+
+int icache_status(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ return ((ccr & 0x00000100) != 0);
+}
+
+void dcache_enable(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ ccr |= 0x00000009;
+ jump_to_uncacheable();
+ writel(ccr, CCR1);
+ back_to_cacheable();
+}
+
+void dcache_disable(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ ccr &= ~0x00000001;
+ jump_to_uncacheable();
+ cache_wback_all();
+ writel(ccr, CCR1);
+ back_to_cacheable();
+}
+
+int dcache_status(void)
+{
+ unsigned long ccr;
+ ccr = readl(CCR1);
+ return ((ccr & 0x00000001) != 0);
+}
diff --git a/arch/sh/cpu/sh2/cpu.c b/arch/sh/cpu/sh2/cpu.c
index a2f856f..b401d08 100644
--- a/arch/sh/cpu/sh2/cpu.c
+++ b/arch/sh/cpu/sh2/cpu.c
@@ -52,34 +52,3 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
reset_cpu(0);
return 0;
}
-
-void flush_cache(unsigned long addr, unsigned long size)
-{
-
-}
-
-void icache_enable(void)
-{
-}
-
-void icache_disable(void)
-{
-}
-
-int icache_status(void)
-{
- return 0;
-}
-
-void dcache_enable(void)
-{
-}
-
-void dcache_disable(void)
-{
-}
-
-int dcache_status(void)
-{
- return 0;
-}
diff --git a/arch/sh/cpu/sh2/nocache.c b/arch/sh/cpu/sh2/nocache.c
new file mode 100644
index 0000000..06b7f4c
--- /dev/null
+++ b/arch/sh/cpu/sh2/nocache.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Yoshinori Sato <ysato at users.sourceforge.jp>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* dummy cache control functions */
+void flush_cache(unsigned long addr, unsigned long size)
+{
+
+}
+
+void icache_enable(void)
+{
+}
+
+void icache_disable(void)
+{
+}
+
+int icache_status(void)
+{
+ return 0;
+}
+
+void dcache_enable(void)
+{
+}
+
+void dcache_disable(void)
+{
+}
+
+int dcache_status(void)
+{
+ return 0;
+}
diff --git a/arch/sh/include/asm/cpu_sh2.h b/arch/sh/include/asm/cpu_sh2.h
index 18a0f0b..b67c093 100644
--- a/arch/sh/include/asm/cpu_sh2.h
+++ b/arch/sh/include/asm/cpu_sh2.h
@@ -8,15 +8,6 @@
#ifndef _ASM_CPU_SH2_H_
#define _ASM_CPU_SH2_H_
-/* cache control */
-#define CCR_CACHE_STOP 0x00000008
-#define CCR_CACHE_ENABLE 0x00000005
-#define CCR_CACHE_ICI 0x00000008
-
-#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_OC_WAY_SHIFT 13
-#define CACHE_OC_NUM_ENTRIES 256
-#define CACHE_OC_ENTRY_SHIFT 4
#if defined(CONFIG_CPU_SH7203)
# include <asm/cpu_sh7203.h>
--
1.8.5.3
More information about the U-Boot
mailing list