[U-Boot] [PATCH v2] riscv: cache: Implement i/dcache [status, enable, disable]

Andes uboot at andestech.com
Thu Nov 1 04:08:08 UTC 2018


From: Rick Chen <rick at andestech.com>

AndeStar RISC-V(V5) provide mcache_ctl register which
can configure I/D cache as enabled or disabled.

This CSR will be encapsulated by CONFIG_RISCV_NDS.
If you want to configure cache on AndeStar V5
AE350 platform. YOu can enable [*] AndeStar V5 ISA support
by make menuconfig.

This approach also provide the expansion when the
vender specific features are going to join in.

Signed-off-by: Rick Chen <rick at andestech.com>
Cc: Greentime Hu <greentime at andestech.com>
---
 arch/riscv/Kconfig             |  8 ++++
 arch/riscv/cpu/ax25/Makefile   |  1 +
 arch/riscv/cpu/ax25/cache.c    | 89 ++++++++++++++++++++++++++++++++++++++++++
 arch/riscv/cpu/ax25/cpu.c      |  4 ++
 arch/riscv/cpu/qemu/cpu.c      |  2 +-
 arch/riscv/cpu/start.S         |  6 +++
 arch/riscv/include/asm/cache.h |  9 +++++
 arch/riscv/lib/cache.c         | 30 +++++++++-----
 8 files changed, 138 insertions(+), 11 deletions(-)
 create mode 100644 arch/riscv/cpu/ax25/cache.c

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 371921b..a356729 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -74,4 +74,12 @@ config 32BIT
 config 64BIT
 	bool
 
+config RISCV_NDS
+	bool "AndeStar V5 ISA support"
+	default n
+	help
+		Say Y here if you plan to run U-Boot on AndeStar v5
+		platforms and use some specific features which are
+		provided by Andes Technology AndeStar V5 Families.
+
 endmenu
diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile
index 2ab0342..318bacc 100644
--- a/arch/riscv/cpu/ax25/Makefile
+++ b/arch/riscv/cpu/ax25/Makefile
@@ -4,3 +4,4 @@
 # Rick Chen, Andes Technology Corporation <rick at andestech.com>
 
 obj-y	:= cpu.o
+obj-y	+= cache.o
diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c
new file mode 100644
index 0000000..e0bcaa2
--- /dev/null
+++ b/arch/riscv/cpu/ax25/cache.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick at andestech.com>
+ */
+
+#include <common.h>
+
+void icache_enable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void icache_disable(void)
+{
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x1\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+}
+
+void dcache_enable(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"ori t0, t1, 0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+#endif
+}
+
+void dcache_disable(void)
+{
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi t0, t1, ~0x2\n\t"
+		"csrw mcache_ctl, t0\n\t"
+	);
+#endif
+}
+
+int icache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x01\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}
+
+int dcache_status(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RISCV_NDS
+	asm volatile (
+		"csrr t1, mcache_ctl\n\t"
+		"andi	%0, t1, 0x02\n\t"
+		: "=r" (ret)
+		:
+		: "memory"
+	);
+#endif
+
+	return ret;
+}
diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
index fddcc15..76689b2 100644
--- a/arch/riscv/cpu/ax25/cpu.c
+++ b/arch/riscv/cpu/ax25/cpu.c
@@ -6,6 +6,7 @@
 
 /* CPU specific code */
 #include <common.h>
+#include <asm/cache.h>
 
 /*
  * cleanup_before_linux() is called just before we call linux
@@ -18,6 +19,9 @@ int cleanup_before_linux(void)
 	disable_interrupts();
 
 	/* turn off I/D-cache */
+	cache_flush();
+	icache_disable();
+	dcache_disable();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c
index 6c7a327..25d97d0 100644
--- a/arch/riscv/cpu/qemu/cpu.c
+++ b/arch/riscv/cpu/qemu/cpu.c
@@ -15,7 +15,7 @@ int cleanup_before_linux(void)
 {
 	disable_interrupts();
 
-	/* turn off I/D-cache */
+	cache_flush();
 
 	return 0;
 }
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 331a534..0e21679 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -46,6 +46,10 @@ _start:
 	/* mask all interrupts */
 	csrw	mie, zero
 
+/* Enable cache */
+jal	icache_enable
+jal	dcache_enable
+
 /*
  * Set stackpointer in internal/ex RAM to call board_init_f
  */
@@ -181,6 +185,8 @@ clbss_l:
  * initialization, now running from RAM.
  */
 call_board_init_r:
+	jal	invalidate_icache_all
+	jal	flush_dcache_all
 	la	t0, board_init_r
 	mv	t4, t0			/* offset of board_init_r() */
 	add	t4, t4, t6		/* real address of board_init_r() */
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
index ca83dd6..e76ca13 100644
--- a/arch/riscv/include/asm/cache.h
+++ b/arch/riscv/include/asm/cache.h
@@ -7,6 +7,15 @@
 #ifndef _ASM_RISCV_CACHE_H
 #define _ASM_RISCV_CACHE_H
 
+/* cache */
+int	icache_status(void);
+void	icache_enable(void);
+void	icache_disable(void);
+int	dcache_status(void);
+void	dcache_enable(void);
+void	dcache_disable(void);
+void	cache_flush(void);
+
 /*
  * The current upper bound for RISCV L1 data cache line sizes is 32 bytes.
  * We use that value for aligning DMA buffers unless the board config has
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c
index d642a38..121db09 100644
--- a/arch/riscv/lib/cache.c
+++ b/arch/riscv/lib/cache.c
@@ -6,6 +6,15 @@
 
 #include <common.h>
 
+void invalidate_icache_all(void)
+{
+	asm volatile ("fence.i" ::: "memory");
+}
+
+void flush_dcache_all(void)
+{
+	asm volatile("fence" :::"memory");
+}
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
 }
@@ -19,41 +28,42 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
 	invalidate_icache_all();
 }
 
-void invalidate_icache_all(void)
+void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
-	asm volatile ("fence.i" ::: "memory");
 }
 
-void invalidate_dcache_range(unsigned long start, unsigned long end)
+void cache_flush(void)
 {
+	invalidate_icache_all();
+	flush_dcache_all();
 }
 
-void flush_cache(unsigned long addr, unsigned long size)
+__weak void flush_cache(unsigned long addr, unsigned long size)
 {
 }
 
-void icache_enable(void)
+__weak void icache_enable(void)
 {
 }
 
-void icache_disable(void)
+__weak void icache_disable(void)
 {
 }
 
-int icache_status(void)
+__weak int icache_status(void)
 {
 	return 0;
 }
 
-void dcache_enable(void)
+__weak void dcache_enable(void)
 {
 }
 
-void dcache_disable(void)
+__weak void dcache_disable(void)
 {
 }
 
-int dcache_status(void)
+__weak int dcache_status(void)
 {
 	return 0;
 }
-- 
2.7.4



More information about the U-Boot mailing list