]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
riscv: cache: Implement i/dcache [status, enable, disable]
authorRick Chen <rick@andestech.com>
Wed, 7 Nov 2018 01:34:06 +0000 (09:34 +0800)
committerAndes <uboot@andestech.com>
Mon, 26 Nov 2018 05:58:01 +0000 (13:58 +0800)
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@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
arch/riscv/Kconfig
arch/riscv/cpu/ax25/Kconfig [new file with mode: 0644]
arch/riscv/cpu/ax25/Makefile
arch/riscv/cpu/ax25/cache.c [new file with mode: 0644]
arch/riscv/cpu/ax25/cpu.c
arch/riscv/cpu/qemu/cpu.c
arch/riscv/cpu/start.S
arch/riscv/include/asm/cache.h
arch/riscv/lib/cache.c

index 0de77a75d7b8f4ee222baf3b9c752d573d08ac49..3e0af55e7152c7b334a7b045ff7a8bffb4e39d52 100644 (file)
@@ -16,9 +16,15 @@ config TARGET_QEMU_VIRT
 
 endchoice
 
+# board-specific options below
 source "board/AndesTech/ax25-ae350/Kconfig"
 source "board/emulation/qemu-riscv/Kconfig"
 
+# platform-specific options below
+source "arch/riscv/cpu/ax25/Kconfig"
+
+# architecture-specific options below
+
 choice
        prompt "Base ISA"
        default ARCH_RV32I
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
new file mode 100644 (file)
index 0000000..6c7022f
--- /dev/null
@@ -0,0 +1,7 @@
+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.
index 2ab0342fe85105eef35320edb6a71cc7c6872f56..318baccb09c6d8612b103db65779e515e071a72d 100644 (file)
@@ -4,3 +4,4 @@
 # Rick Chen, Andes Technology Corporation <rick@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 (file)
index 0000000..6600ac2
--- /dev/null
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@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)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+       asm volatile (
+               "fence.i\n\t"
+               "csrr t1, mcache_ctl\n\t"
+               "andi t0, t1, ~0x1\n\t"
+               "csrw mcache_ctl, t0\n\t"
+       );
+#endif
+#endif
+}
+
+void dcache_enable(void)
+{
+#ifndef CONFIG_SYS_DCACHE_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)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_RISCV_NDS
+       asm volatile (
+               "fence\n\t"
+               "csrr t1, mcache_ctl\n\t"
+               "andi t0, t1, ~0x2\n\t"
+               "csrw mcache_ctl, t0\n\t"
+       );
+#endif
+#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;
+}
index fddcc156c3dce4f75ec154307ea4ce352710161c..76689b21d3d94c10350dc287361fd5b6fd5e7419 100644 (file)
@@ -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;
 }
index 6c7a32755a698b29a3adb7e4f3151137f23a1928..25d97d0b416d90f4ee63423a0f3115d6b9c4d85c 100644 (file)
@@ -15,7 +15,7 @@ int cleanup_before_linux(void)
 {
        disable_interrupts();
 
-       /* turn off I/D-cache */
+       cache_flush();
 
        return 0;
 }
index 331a5345e3a9624483af0a45d10bdf1164344497..15e1b8199a3bfef01f0cdab7058ac101e2ec9d61 100644 (file)
@@ -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() */
index ca83dd67c2f24268e3d3f8755eea68f8c2a5bd69..ec8fe201d3c9ccd4b8421386db616410fdd66eb4 100644 (file)
@@ -7,6 +7,9 @@
 #ifndef _ASM_RISCV_CACHE_H
 #define _ASM_RISCV_CACHE_H
 
+/* cache */
+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
index d642a38a0716bcfbab5b4260ca852d1fb0722ef6..ae5c60716ffdd82742dc783095eebd54a0dde7eb 100644 (file)
@@ -6,8 +6,18 @@
 
 #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)
 {
+       flush_dcache_all();
 }
 
 void invalidate_icache_range(unsigned long start, unsigned long end)
@@ -19,41 +29,45 @@ 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");
+       flush_dcache_all();
 }
 
-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)
 {
+       invalidate_icache_all();
+       flush_dcache_all();
 }
 
-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;
 }