diff mbox series

[v5,01/17] riscv: cpu: jh7110: Add support for jh7110 SoC

Message ID 20230329034224.26545-2-yanhong.wang@starfivetech.com
State Accepted
Commit 218534153ec8932a873dcca48a1a2b4aba0e32b5
Delegated to: Andes
Headers show
Series Basic StarFive JH7110 RISC-V SoC support | expand

Commit Message

Yanhong Wang March 29, 2023, 3:42 a.m. UTC
Add StarFive JH7110 SoC to support RISC-V arch.

Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Tested-by: Conor Dooley <conor.dooley@microchip.com>
---
 arch/riscv/cpu/jh7110/Makefile            | 10 ++++
 arch/riscv/cpu/jh7110/cpu.c               | 23 ++++++++
 arch/riscv/cpu/jh7110/dram.c              | 38 ++++++++++++++
 arch/riscv/cpu/jh7110/spl.c               | 64 +++++++++++++++++++++++
 arch/riscv/include/asm/arch-jh7110/regs.h | 19 +++++++
 arch/riscv/include/asm/arch-jh7110/spl.h  | 12 +++++
 6 files changed, 166 insertions(+)
 create mode 100644 arch/riscv/cpu/jh7110/Makefile
 create mode 100644 arch/riscv/cpu/jh7110/cpu.c
 create mode 100644 arch/riscv/cpu/jh7110/dram.c
 create mode 100644 arch/riscv/cpu/jh7110/spl.c
 create mode 100644 arch/riscv/include/asm/arch-jh7110/regs.h
 create mode 100644 arch/riscv/include/asm/arch-jh7110/spl.h

Comments

Bo Gan May 12, 2023, 5:50 a.m. UTC | #1
On 3/28/23 8:42 PM, Yanhong Wang wrote:
> +void harts_early_init(void)
> +{
> +	ulong *ptr;
> +	u8 *tmp;
> +	ulong len, remain;
> +	/*
> +	 * Feature Disable CSR
> +	 *
> +	 * Clear feature disable CSR to '0' to turn on all features for
> +	 * each core. This operation must be in M-mode.
> +	 */
> +	if (CONFIG_IS_ENABLED(RISCV_MMODE))
> +		csr_write(CSR_U74_FEATURE_DISABLE, 0);
> +
> +	/* clear L2 LIM  memory
> +	 * set __bss_end to 0x81FFFFF region to zero
> +	 * The L2 Cache Controller supports ECC. ECC is applied to SRAM.
> +	 * If it is not cleared, the ECC part is invalid, and an ECC error
> +	 * will be reported when reading data.
> +	 */
> +	ptr = (ulong *)&__bss_end;
> +	len = L2_LIM_MEM_END - (ulong)&__bss_end;
> +	remain = len % sizeof(ulong);
> +	len /= sizeof(ulong);
> +
> +	while (len--)
> +		*ptr++ = 0;
> +
> +	/* clear the remain bytes */
> +	if (remain) {
> +		tmp = (u8 *)ptr;
> +		while (remain--)
> +			*tmp++ = 0;
> +	}
> +}
Hi Yanhong, I know this is already merged, but it looks wrong to me.`harts_early_init`
will be called by all harts in SPL. The per-hart stack sits between __bss_end and L2_LIM_MEM_END.
Zeroing this region could overwrite the hart's stack, and other harts' stacks. The current
implementation works likely because harts_early_init doesn't use any stack space, but it's up to
the compiler and we can't guarantee that. If it were to save and restore `ra` register, then we
would crash in function epilogue. Also, we are having data-races here, because harts are writing
over each other's stack.

My advice is that we should split the zeroing of L2 LIM into different places just before the
region is to be used. For stacks, we can let each hart clearing its own stack, and for the malloc
space, we can do so during malloc initialization. Doing so also gives us the benefit of catching
the read of uninitialized data. In this approach, the L2_LIM_MEM_END macro is not needed anymore.
Yanhong Wang May 16, 2023, 6:49 a.m. UTC | #2
On 2023/5/12 13:50, Bo Gan wrote:
> On 3/28/23 8:42 PM, Yanhong Wang wrote:
>> +void harts_early_init(void)
>> +{
>> +    ulong *ptr;
>> +    u8 *tmp;
>> +    ulong len, remain;
>> +    /*
>> +     * Feature Disable CSR
>> +     *
>> +     * Clear feature disable CSR to '0' to turn on all features for
>> +     * each core. This operation must be in M-mode.
>> +     */
>> +    if (CONFIG_IS_ENABLED(RISCV_MMODE))
>> +        csr_write(CSR_U74_FEATURE_DISABLE, 0);
>> +
>> +    /* clear L2 LIM  memory
>> +     * set __bss_end to 0x81FFFFF region to zero
>> +     * The L2 Cache Controller supports ECC. ECC is applied to SRAM.
>> +     * If it is not cleared, the ECC part is invalid, and an ECC error
>> +     * will be reported when reading data.
>> +     */
>> +    ptr = (ulong *)&__bss_end;
>> +    len = L2_LIM_MEM_END - (ulong)&__bss_end;
>> +    remain = len % sizeof(ulong);
>> +    len /= sizeof(ulong);
>> +
>> +    while (len--)
>> +        *ptr++ = 0;
>> +
>> +    /* clear the remain bytes */
>> +    if (remain) {
>> +        tmp = (u8 *)ptr;
>> +        while (remain--)
>> +            *tmp++ = 0;
>> +    }
>> +}
> Hi Yanhong, I know this is already merged, but it looks wrong to me.`harts_early_init`
> will be called by all harts in SPL. The per-hart stack sits between __bss_end and L2_LIM_MEM_END.
> Zeroing this region could overwrite the hart's stack, and other harts' stacks. The current
> implementation works likely because harts_early_init doesn't use any stack space, but it's up to
> the compiler and we can't guarantee that. If it were to save and restore `ra` register, then we
> would crash in function epilogue. Also, we are having data-races here, because harts are writing
> over each other's stack.
> 
> My advice is that we should split the zeroing of L2 LIM into different places just before the
> region is to be used. For stacks, we can let each hart clearing its own stack, and for the malloc
> space, we can do so during malloc initialization. Doing so also gives us the benefit of catching
> the read of uninitialized data. In this approach, the L2_LIM_MEM_END macro is not needed anymore.

Hi,Bo Gan, I agree with you, there is some problem with the initialization of the L2 LIM, 
so, as you suggested, we should split the zeroing of L2 LIM into different places.
Something like:

diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
index 72adcefa0e..574ffc3d33 100644
--- a/arch/riscv/cpu/jh7110/spl.c
+++ b/arch/riscv/cpu/jh7110/spl.c
@@ -13,7 +13,6 @@
 #include <init.h>
 
 #define CSR_U74_FEATURE_DISABLE	0x7c1
-#define L2_LIM_MEM_END	0x81FFFFFUL
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -61,7 +60,7 @@ void harts_early_init(void)
 {
 	ulong *ptr;
 	u8 *tmp;
-	ulong len, remain;
+	ulong len, remain, init_end;
 	/*
 	 * Feature Disable CSR
 	 *
@@ -77,8 +76,10 @@ void harts_early_init(void)
 	 * If it is not cleared, the ECC part is invalid, and an ECC error
 	 * will be reported when reading data.
 	 */
+	init_end = CONFIG_SPL_STACK -CONFIG_VAL(SYS_MALLOC_F_LEN) - sizeof(*gd)
+			- CONFIG_NR_CPUS * BIT(CONFIG_STACK_SIZE_SHIFT);
 	ptr = (ulong *)&__bss_end;
-	len = L2_LIM_MEM_END - (ulong)&__bss_end;
+	len = init_end - (ulong)&__bss_end;
 	remain = len % sizeof(ulong);
 	len /= sizeof(ulong);
 
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index dad22bfea8..46da9ec503 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -118,6 +118,20 @@ call_board_init_f_0:
 	mv	sp, a0
 #endif
 
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) && \
+		defined(CONFIG_STARFIVE_JH7110)
+
+	/* Set the stack region to zero */
+	li t0, 1
+	slli t1, t0, CONFIG_STACK_SIZE_SHIFT
+	mv t0, sp
+	sub t1, t0, t1
+clear_stack:
+	SREG	zero, 0(t1)
+	addi	t1, t1, REGBYTES
+	blt t1, t0, clear_stack
+#endif
+
 	/* Configure proprietary settings and customized CSRs of harts */
 call_harts_early_init:
 	jal	harts_early_init
diff --git a/common/init/board_init.c b/common/init/board_init.c
index 96ffb79a98..46e4e4abc7 100644
--- a/common/init/board_init.c
+++ b/common/init/board_init.c
@@ -162,6 +162,7 @@ void board_init_f_init_reserve(ulong base)
 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
 	/* go down one 'early malloc arena' */
 	gd->malloc_base = base;
+	memset((void *)base, 0, CONFIG_VAL(SYS_MALLOC_F_LEN));
 #endif
 
 	if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
diff mbox series

Patch

diff --git a/arch/riscv/cpu/jh7110/Makefile b/arch/riscv/cpu/jh7110/Makefile
new file mode 100644
index 0000000000..951c95631e
--- /dev/null
+++ b/arch/riscv/cpu/jh7110/Makefile
@@ -0,0 +1,10 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2022 StarFive Technology Co., Ltd.
+
+ifeq ($(CONFIG_SPL_BUILD),y)
+obj-y += spl.o
+else
+obj-y += cpu.o
+obj-y += dram.o
+endif
diff --git a/arch/riscv/cpu/jh7110/cpu.c b/arch/riscv/cpu/jh7110/cpu.c
new file mode 100644
index 0000000000..1d7c026584
--- /dev/null
+++ b/arch/riscv/cpu/jh7110/cpu.c
@@ -0,0 +1,23 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
+ */
+
+#include <asm/cache.h>
+#include <irq_func.h>
+
+/*
+ * cleanup_before_linux() is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we disable interrupt and caches.
+ */
+int cleanup_before_linux(void)
+{
+	disable_interrupts();
+
+	cache_flush();
+
+	return 0;
+}
diff --git a/arch/riscv/cpu/jh7110/dram.c b/arch/riscv/cpu/jh7110/dram.c
new file mode 100644
index 0000000000..2ad3f2044a
--- /dev/null
+++ b/arch/riscv/cpu/jh7110/dram.c
@@ -0,0 +1,38 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <init.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();
+}
+
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
+{
+	/*
+	 * Ensure that we run from first 4GB so that all
+	 * addresses used by U-Boot are 32bit addresses.
+	 *
+	 * This in-turn ensures that 32bit DMA capable
+	 * devices work fine because DMA mapping APIs will
+	 * provide 32bit DMA addresses only.
+	 */
+	if (IS_ENABLED(CONFIG_64BIT) && gd->ram_top > SZ_4G)
+		return SZ_4G;
+
+	return gd->ram_top;
+}
diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
new file mode 100644
index 0000000000..104f0fe949
--- /dev/null
+++ b/arch/riscv/cpu/jh7110/spl.c
@@ -0,0 +1,64 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
+ */
+
+#include <asm/csr.h>
+#include <asm/sections.h>
+#include <dm.h>
+#include <log.h>
+
+#define CSR_U74_FEATURE_DISABLE	0x7c1
+#define L2_LIM_MEM_END	0x81FFFFFUL
+
+int spl_soc_init(void)
+{
+	int ret;
+	struct udevice *dev;
+
+	/* DDR init */
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void harts_early_init(void)
+{
+	ulong *ptr;
+	u8 *tmp;
+	ulong len, remain;
+	/*
+	 * Feature Disable CSR
+	 *
+	 * Clear feature disable CSR to '0' to turn on all features for
+	 * each core. This operation must be in M-mode.
+	 */
+	if (CONFIG_IS_ENABLED(RISCV_MMODE))
+		csr_write(CSR_U74_FEATURE_DISABLE, 0);
+
+	/* clear L2 LIM  memory
+	 * set __bss_end to 0x81FFFFF region to zero
+	 * The L2 Cache Controller supports ECC. ECC is applied to SRAM.
+	 * If it is not cleared, the ECC part is invalid, and an ECC error
+	 * will be reported when reading data.
+	 */
+	ptr = (ulong *)&__bss_end;
+	len = L2_LIM_MEM_END - (ulong)&__bss_end;
+	remain = len % sizeof(ulong);
+	len /= sizeof(ulong);
+
+	while (len--)
+		*ptr++ = 0;
+
+	/* clear the remain bytes */
+	if (remain) {
+		tmp = (u8 *)ptr;
+		while (remain--)
+			*tmp++ = 0;
+	}
+}
diff --git a/arch/riscv/include/asm/arch-jh7110/regs.h b/arch/riscv/include/asm/arch-jh7110/regs.h
new file mode 100644
index 0000000000..05026870a0
--- /dev/null
+++ b/arch/riscv/include/asm/arch-jh7110/regs.h
@@ -0,0 +1,19 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
+ */
+
+#ifndef __STARFIVE_JH7110_REGS_H
+#define __STARFIVE_JH7110_REGS_H
+
+#define JH7110_SYS_CRG			0x13020000
+#define JH7110_SYS_SYSCON		0x13030000
+#define JH7110_SYS_IOMUX		0x13040000
+#define JH7110_AON_CRG			0x17000000
+#define JH7110_AON_SYSCON		0x17010000
+
+#define JH7110_BOOT_MODE_SELECT_REG	0x1702002c
+#define JH7110_BOOT_MODE_SELECT_MASK	GENMASK(1, 0)
+
+#endif /* __STARFIVE_JH7110_REGS_H */
diff --git a/arch/riscv/include/asm/arch-jh7110/spl.h b/arch/riscv/include/asm/arch-jh7110/spl.h
new file mode 100644
index 0000000000..23ce8871b3
--- /dev/null
+++ b/arch/riscv/include/asm/arch-jh7110/spl.h
@@ -0,0 +1,12 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
+ */
+
+#ifndef _SPL_STARFIVE_H
+#define _SPL_STARFIVE_H
+
+int spl_soc_init(void);
+
+#endif /* _SPL_STARFIVE_H */