summaryrefslogtreecommitdiff
path: root/arch/riscv/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/cpu')
-rw-r--r--arch/riscv/cpu/cpu.c60
-rw-r--r--arch/riscv/cpu/cv1800b/Kconfig12
-rw-r--r--arch/riscv/cpu/cv1800b/Makefile7
-rw-r--r--arch/riscv/cpu/cv1800b/cache.c45
-rw-r--r--arch/riscv/cpu/cv1800b/cpu.c9
-rw-r--r--arch/riscv/cpu/cv1800b/dram.c21
-rw-r--r--arch/riscv/cpu/start.S1
7 files changed, 133 insertions, 22 deletions
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index ecfefa1a025..affe70081b5 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -38,35 +38,51 @@ static inline bool supports_extension(char ext)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
return csr_read(CSR_MISA) & (1 << (ext - 'a'));
#elif CONFIG_CPU
+ char sext[2] = {ext};
struct udevice *dev;
- char desc[32];
- int i;
+ const char *isa;
+ int ret, i;
uclass_find_first_device(UCLASS_CPU, &dev);
if (!dev) {
debug("unable to find the RISC-V cpu device\n");
return false;
}
- if (!cpu_get_desc(dev, desc, sizeof(desc))) {
- /*
- * skip the first 4 characters (rv32|rv64)
- */
- for (i = 4; i < sizeof(desc); i++) {
- switch (desc[i]) {
- case 's':
- case 'x':
- case 'z':
- case '_':
- case '\0':
- /*
- * Any of these characters mean the single
- * letter extensions have all been consumed.
- */
- return false;
- default:
- if (desc[i] == ext)
- return true;
- }
+
+ ret = dev_read_stringlist_search(dev, "riscv,isa-extensions", sext);
+ if (ret >= 0)
+ return true;
+
+ /*
+ * Only if the property is not found (ENODATA) is the fallback to
+ * riscv,isa used, otherwise the extension is not present in this
+ * CPU.
+ */
+ if (ret != -ENODATA)
+ return false;
+
+ isa = dev_read_string(dev, "riscv,isa");
+ if (!isa)
+ return false;
+
+ /*
+ * Skip the first 4 characters (rv32|rv64).
+ */
+ for (i = 4; i < sizeof(isa); i++) {
+ switch (isa[i]) {
+ case 's':
+ case 'x':
+ case 'z':
+ case '_':
+ case '\0':
+ /*
+ * Any of these characters mean the single
+ * letter extensions have all been consumed.
+ */
+ return false;
+ default:
+ if (isa[i] == ext)
+ return true;
}
}
diff --git a/arch/riscv/cpu/cv1800b/Kconfig b/arch/riscv/cpu/cv1800b/Kconfig
new file mode 100644
index 00000000000..7225b1210c5
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+config SOPHGO_CV1800B
+ bool
+ select ARCH_EARLY_INIT_R
+ select SYS_CACHE_SHIFT_6
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_TIMER
+ imply CMD_CPU
diff --git a/arch/riscv/cpu/cv1800b/Makefile b/arch/riscv/cpu/cv1800b/Makefile
new file mode 100644
index 00000000000..95beb34b51a
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+obj-y += dram.o
+obj-y += cpu.o
+obj-y += cache.o
diff --git a/arch/riscv/cpu/cv1800b/cache.c b/arch/riscv/cpu/cv1800b/cache.c
new file mode 100644
index 00000000000..b8051e29e02
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cache.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+#include <cpu_func.h>
+
+/*
+ * dcache.ipa rs1 (invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01010 rs1 000 00000 0001011
+ *
+ * dcache.cpa rs1 (clean)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01001 rs1 000 00000 0001011
+ *
+ * dcache.cipa rs1 (clean then invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01011 rs1 000 00000 0001011
+ *
+ * sync.s
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000000 11001 00000 000 00000 0001011
+ */
+#define DCACHE_IPA_A0 ".long 0x02a5000b"
+#define DCACHE_CPA_A0 ".long 0x0295000b"
+#define DCACHE_CIPA_A0 ".long 0x02b5000b"
+
+#define SYNC_S ".long 0x0190000b"
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_IPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_CPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
diff --git a/arch/riscv/cpu/cv1800b/cpu.c b/arch/riscv/cpu/cv1800b/cpu.c
new file mode 100644
index 00000000000..233a6a3d64e
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cpu.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+int cleanup_before_linux(void)
+{
+ return 0;
+}
diff --git a/arch/riscv/cpu/cv1800b/dram.c b/arch/riscv/cpu/cv1800b/dram.c
new file mode 100644
index 00000000000..91007c0a3d3
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/dram.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6cecadfac56..a9e19356928 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -418,6 +418,7 @@ call_board_init_r:
*/
mv a0, s3 /* gd_t */
mv a1, s4 /* dest_addr */
+ mv s0, zero /* fp == NULL */
/*
* jump to it ...