From patchwork Sun Jun 11 23:58:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bo Gan X-Patchwork-Id: 1793731 X-Patchwork-Delegate: uboot@andestech.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=WmeWjxJ5; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QfWxf6vd5z20X6 for ; Mon, 12 Jun 2023 09:59:02 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9AB6E8479D; Mon, 12 Jun 2023 01:58:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WmeWjxJ5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8D76084704; Mon, 12 Jun 2023 01:58:56 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 845408479D for ; Mon, 12 Jun 2023 01:58:52 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ganboing@gmail.com Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1b3b56dcf1bso10756725ad.2 for ; Sun, 11 Jun 2023 16:58:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686527930; x=1689119930; h=message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VwLMo5/VYPMs0QgDTf2/WYlOq2lIFMVtzoyDreU/7Kc=; b=WmeWjxJ5pcvbeqo6+Sf6hv3xdh1ZbwS6AghPmuqlDu8hLcZg76Z+S09FvTQ34P84DN /TwjkjkTlCt/DYBpmJgWpIcrnz2JXKgWPwUTotUeK+LSNn1GnGB4CkRc8u15eFoajOT0 SUc7UTVurM5GTt5wcyn/cGGj2Idx2R7nF4hLGjvEWhbvbp048TQrffZzscimozbbYNoe /pHAQfPQg6hldHUe6wlnXvjeLgxGcYdwRfkBfxtZ2RfZ3VOi850P85yhGDD8nI+vLWb5 1xMd6IdA+DEclBrUqPw6G84lXJ4QAhkZk8ZYUxquDG9vDQhQ4UXeE6cXejCav927PbjW ES5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686527930; x=1689119930; h=message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VwLMo5/VYPMs0QgDTf2/WYlOq2lIFMVtzoyDreU/7Kc=; b=dCsnm/MMoNtpsoMSVrv+jdkHrfNDB3wKFYOBpWivICeoQmTZZSBDmW+rg6KUuyEdrJ R9esLzn81updWCNFurGWtX2Vh6CPfFy8umpvZq3KZwekzpigIMHBg3GDru4NjvAAnPM9 ge9LXifTs8TcPSHfU3NHe/t0WaxU2p+Gs4UvAC4hvFfookeIPBKiutmGW0JpndRjAaPf e0Xxa1cqehs+rTOcwKEkCsaXHT+aCzAtuz28sUDZsiXILBOzvNNKOmGmsDiiytmq2nQb MYx0LFI7aGuHJ+lC/lfjJI1LP30eOMMVxshzg0Z8AVb8O1fGq8FJOd4WW/CyHYL8DtVP +hiA== X-Gm-Message-State: AC+VfDyZN9BDmTVD/jFt9Q/ScLUvlC/q5LTT6CPhUiiyZFdltZfWUMMf RjE9NBhN8V2jbFels6boQSSeCGaTT7nQrA== X-Google-Smtp-Source: ACHHUZ4L6HpRAZTpKNnkoZw415C3GwMUi/BKv+BPwB6dJyVm7MbEecqAVmjgPQLLqRe/+uWQsx/Bpw== X-Received: by 2002:a17:903:41ce:b0:1a6:a405:f714 with SMTP id u14-20020a17090341ce00b001a6a405f714mr6492011ple.63.1686527930313; Sun, 11 Jun 2023 16:58:50 -0700 (PDT) Received: from riscv.airy.home ([172.92.174.136]) by smtp.gmail.com with ESMTPSA id s23-20020a170902b19700b001afd275e186sm6782662plr.286.2023.06.11.16.58.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Jun 2023 16:58:49 -0700 (PDT) From: Bo Gan To: u-boot@lists.denx.de Cc: Bo Gan , "samin . guo" , Yanhong Wang , Rick Chen , Leo , Sean Anderson , Lukasz Majewski Subject: [RESEND PATCH v1] arch: riscv: jh7110: Correctly zero L2 LIM Date: Sun, 11 Jun 2023 16:58:43 -0700 Message-Id: <1686527923-366191-1-git-send-email-ganboing@gmail.com> X-Mailer: git-send-email 2.7.4 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Background information: JH7110 SPL runs in L2 LIM (2M in size mapped at 0x8000000). It consists of 16 0x20000 sized regions, each one can be used as either L2 cache way or SRAM (not both). From top to bottom, there're ways 0-15. The way 0 is always enabled, at most 0x1e0000 can be used. In SPL, we don't enable any cache ways, thus all 15 (except way 0) ways can be used. However, due to HW requirement, we must zero the LIM before use. This is because ECC is applied to LIM, and if not cleared first, the ECC part is invalid, which can trigger ECC errors when reading/writing data. There are several issues currently. We clear L2 LIM from __bss_end to 0x81FFFFF in `harts_early_init`. This is wrong because: a. Each hart (in the middle of a function call) overwriting its own stack and other harts' stacks. (data-race and data-corruption) b. Lottery winner hart can be doing `board_init_f_init_reserve`, while other harts're in the middle of zeroing L2 LIM. (data-race) To fix this, we split the job, such that there's one and only one owner of zeroing a specific region (No data-race). A new SPL config option `SPL_ZERO_MEM_BEFORE_USE` is introduced. Allowing The zeroing to happen in the same code path. (much easier to reason about). Another option `SPL_SYS_MALLOC_CLEAR_ON_INIT` also gets introduced. It allows us to also zero late malloc (dlmalloc) area, in case it gets configured to be inside L2 LIM (via `CUSTOM_SYS_SPL_MALLOC_ADDR`) We by default enable it to be on the safe side. `CONFIG_SPL_STACK` is adjusted to reduce the waste of L2 LIM space. When setting CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x8100000 CONFIG_SYS_SPL_MALLOC_SIZE=0xe0000 A 0.875M late malloc arena is available in L2 LIM. It's sufficient for loading JH7110 FIT Image (gzip compressed OpenSBI+UBOOT+DTB). The advantage of this config is allowing OpenSBI/UBOOT to be loaded at any DDR memory address. By default the malloc arena is configured in DDR memory, so OpenSBI/UBOOT loading address must not collide with it. CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x80000000 (DDR +1GB) CONFIG_SYS_SPL_MALLOC_SIZE=0x400000 JH7110 SPL memory map (based on the following defconfig): CONFIG_NR_CPUS=8 CONFIG_STACK_SIZE_SHIFT=14 CONFIG_SPL_STACK=0x8100000 CONFIG_SPL_SYS_MALLOC_F_LEN=0x10000 CONFIG_SPL_BSS_START_ADDR=0x8040000 +----------------+ 0x81e0000 | Free | | | +----------------+ 0x8100000 | hart 0 stack | <--- cleared by each hart (start.S) +----------------+ 0x80fc000 | hart 1 stack | . +----------------+ 0x80f8000 . | ...... | . +----------------+ | hart N-1 stack| <--- cleared by each hart (start.S) +----------------+ 0x80e0000 | ...... | <--- cleared by lottery winner hart | malloc_base | board_init_f_init_reserve() +----------------+ 0x80d0000 | GD | <--- cleared by lottery winner hart +----------------+ board_init_f_init_reserve() | | | hole | | | +----------------+ | BSS | <--- cleared by lottery winner hart +----------------+ 0x8040000 spl_clear_bss (start.S) | hole | +----------------+ | Image+DTB | <--- Assuming cleared/loaded by ROM +----------------+ 0x8000000 Signed-off-by: Bo Gan Cc: samin . guo Cc: Yanhong Wang Cc: Rick Chen Cc: Leo Cc: Sean Anderson Cc: Lukasz Majewski --- v1: - patch is on top of https://patchwork.ozlabs.org/project/uboot/patch/1684650044-313122-1-git-send-email-ganboing@gmail.com/ - Tested on VisionFive 2 board (4G) --- Kconfig | 11 +++++++++++ arch/riscv/Kconfig | 7 +++++++ arch/riscv/cpu/jh7110/Kconfig | 2 ++ arch/riscv/cpu/jh7110/spl.c | 25 ------------------------- arch/riscv/cpu/start.S | 12 ++++++++++++ common/dlmalloc.c | 6 +++--- common/init/board_init.c | 3 +++ configs/starfive_visionfive2_defconfig | 3 ++- 8 files changed, 40 insertions(+), 29 deletions(-) diff --git a/Kconfig b/Kconfig index 70efb41..e5eec1b 100644 --- a/Kconfig +++ b/Kconfig @@ -372,6 +372,17 @@ if EXPERT When disabling this, please check if malloc calls, maybe should be replaced by calloc - if one expects zeroed memory. + config SPL_SYS_MALLOC_CLEAR_ON_INIT + bool "Init with zeros the memory reserved for malloc (slow) in SPL" + depends on SPL + default SYS_MALLOC_CLEAR_ON_INIT + help + Same as SYS_MALLOC_CLEAR_ON_INIT, but for SPL. It's possible to + Enable it without SYS_MALLOC_CLEAR_ON_INIT. It's useful for boards + that must have particular memory regions zero'ed before first use. + If SYS_SPL_MALLOC_START is configured to be in such region, this + option should be enabled. + config SYS_MALLOC_DEFAULT_TO_INIT bool "Default malloc to init while reserving the memory for it" help diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index f6ed059..5d942a8 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -60,6 +60,13 @@ config SPL_SYS_DCACHE_OFF help Do not enable data cache in SPL. +config SPL_ZERO_MEM_BEFORE_USE + bool "Zero memory before use" + depends on SPL + default n + help + Zero stack/GD/malloc area in SPL. + # board-specific options below source "board/AndesTech/ae350/Kconfig" source "board/emulation/qemu-riscv/Kconfig" diff --git a/arch/riscv/cpu/jh7110/Kconfig b/arch/riscv/cpu/jh7110/Kconfig index 3f14541..de1507d 100644 --- a/arch/riscv/cpu/jh7110/Kconfig +++ b/arch/riscv/cpu/jh7110/Kconfig @@ -13,6 +13,7 @@ config STARFIVE_JH7110 select SUPPORT_SPL select SPL_RAM if SPL select SPL_STARFIVE_DDR + select SPL_ZERO_MEM_BEFORE_USE select PINCTRL_STARFIVE_JH7110 imply MMC imply MMC_BROKEN_CD @@ -26,3 +27,4 @@ config STARFIVE_JH7110 imply SPL_LOAD_FIT imply SPL_OPENSBI imply SPL_SIFIVE_CLINT + imply SPL_SYS_MALLOC_CLEAR_ON_INIT diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c index 104f0fe..72c5b25 100644 --- a/arch/riscv/cpu/jh7110/spl.c +++ b/arch/riscv/cpu/jh7110/spl.c @@ -10,7 +10,6 @@ #include #define CSR_U74_FEATURE_DISABLE 0x7c1 -#define L2_LIM_MEM_END 0x81FFFFFUL int spl_soc_init(void) { @@ -29,9 +28,6 @@ int spl_soc_init(void) void harts_early_init(void) { - ulong *ptr; - u8 *tmp; - ulong len, remain; /* * Feature Disable CSR * @@ -40,25 +36,4 @@ void harts_early_init(void) */ 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/cpu/start.S b/arch/riscv/cpu/start.S index 59d58a5..1a0b01e 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -111,6 +111,18 @@ call_board_init_f: * It's essential before any function call, otherwise, we get data-race. */ + /* clear stack if necessary */ +#if CONFIG_IS_ENABLED(ZERO_MEM_BEFORE_USE) +clear_stack: + li t1, 1 + slli t1, t1, CONFIG_STACK_SIZE_SHIFT + sub t1, sp, t1 +clear_stack_loop: + SREG zero, 0(t1) /* t1 is always 16 byte aligned */ + addi t1, t1, REGBYTES + blt t1, sp, clear_stack_loop +#endif + call_board_init_f_0: /* find top of reserve space */ #if CONFIG_IS_ENABLED(SMP) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 0f9b726..dcecdb8 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -631,7 +631,7 @@ void mem_malloc_init(ulong start, ulong size) debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start, mem_malloc_end); -#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT +#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT) memset((void *)mem_malloc_start, 0x0, size); #endif malloc_bin_reloc(); @@ -2153,7 +2153,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; /* check if expand_top called, in which case don't need to clear */ -#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT +#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT) #if MORECORE_CLEARS mchunkptr oldtop = top; INTERNAL_SIZE_T oldtopsize = chunksize(top); @@ -2184,7 +2184,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; csz = chunksize(p); -#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT +#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT) #if MORECORE_CLEARS if (p == oldtop && csz > oldtopsize) { diff --git a/common/init/board_init.c b/common/init/board_init.c index 96ffb79..ab8c508 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -162,6 +162,9 @@ 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; +#if CONFIG_IS_ENABLED(ZERO_MEM_BEFORE_USE) + memset((void *)base, '\0', CONFIG_VAL(SYS_MALLOC_F_LEN)); +#endif #endif if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig index ffbc4b9..4ce0f45 100644 --- a/configs/starfive_visionfive2_defconfig +++ b/configs/starfive_visionfive2_defconfig @@ -1,6 +1,7 @@ CONFIG_RISCV=y CONFIG_SYS_MALLOC_LEN=0x800000 CONFIG_SYS_MALLOC_F_LEN=0x10000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_GPIO=y CONFIG_NR_DRAM_BANKS=1 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -13,7 +14,7 @@ CONFIG_SYS_PROMPT="StarFive #" CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_DM_RESET=y CONFIG_SPL_MMC=y -CONFIG_SPL_STACK=0x8180000 +CONFIG_SPL_STACK=0x8100000 CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y