diff options
Diffstat (limited to 'arch/riscv/cpu')
-rw-r--r-- | arch/riscv/cpu/cpu.c | 60 | ||||
-rw-r--r-- | arch/riscv/cpu/cv1800b/Kconfig | 12 | ||||
-rw-r--r-- | arch/riscv/cpu/cv1800b/Makefile | 7 | ||||
-rw-r--r-- | arch/riscv/cpu/cv1800b/cache.c | 45 | ||||
-rw-r--r-- | arch/riscv/cpu/cv1800b/cpu.c | 9 | ||||
-rw-r--r-- | arch/riscv/cpu/cv1800b/dram.c | 21 | ||||
-rw-r--r-- | arch/riscv/cpu/start.S | 1 |
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 ... |