From patchwork Mon Feb 11 22:13:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Auer X-Patchwork-Id: 1040177 X-Patchwork-Delegate: uboot@andestech.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=aisec.fraunhofer.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43z0Wh575Bz9sLw for ; Tue, 12 Feb 2019 09:17:04 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 5B9DAC2207F; Mon, 11 Feb 2019 22:15:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 10B17C22093; Mon, 11 Feb 2019 22:14:44 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 5F430C22083; Mon, 11 Feb 2019 22:14:37 +0000 (UTC) Received: from mail-edgeS23.fraunhofer.de (mail-edges23.fraunhofer.de [153.97.7.23]) by lists.denx.de (Postfix) with ESMTPS id BEEECC22087 for ; Mon, 11 Feb 2019 22:14:33 +0000 (UTC) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2FbAAAO4PJb/xmnZsBiGgEBAQEBAgEBAQEHAgEBAQGBZYIEgVY5jG+LHZs9DYF3gnUCg24iOBIBAwEBAgEBAgICaSiFPgYyAUYQUT0aBg4FgyGCAqh8ihwJAYdQhCuBVz+BEAGHWYYSAosIlGcHAoERgQkEjn4LGIFYiACHJYlkjjKBXSKBVTMaJIM7kFs+ATIBjA6CTQEB X-IPAS-Result: A2FbAAAO4PJb/xmnZsBiGgEBAQEBAgEBAQEHAgEBAQGBZYIEgVY5jG+LHZs9DYF3gnUCg24iOBIBAwEBAgEBAgICaSiFPgYyAUYQUT0aBg4FgyGCAqh8ihwJAYdQhCuBVz+BEAGHWYYSAosIlGcHAoERgQkEjn4LGIFYiACHJYlkjjKBXSKBVTMaJIM7kFs+ATIBjA6CTQEB X-IronPort-AV: E=Sophos;i="5.56,253,1539640800"; d="scan'208";a="9182862" Received: from mail-mtadd25.fraunhofer.de ([192.102.167.25]) by mail-edgeS23.fraunhofer.de with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Feb 2019 23:14:33 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DkAAAq4PJb/xBhWMBiGwEBAQEDAQEBBwMBAQGBZYM5ITmMb6ZaDYF3gnUChA84EgEDAQECAQECbSiFPQYyAUYQUT0aBg4FgyGCAqh8ih0JAYdQhgI/gRABh1mGEgKLCJRnBwKBEYEJBI5+CxiBWIgAhyWJZI4ygV0hgVUzGiSDO5BbPgMwAYwOgk0BAQ X-IronPort-AV: E=Sophos;i="5.56,253,1539640800"; d="scan'208";a="31721294" Received: from fgdemucivp01ltm.xch.fraunhofer.de (HELO FGDEMUCIMP11EXC.ads.fraunhofer.de) ([192.88.97.16]) by mail-mtaDD25.fraunhofer.de with ESMTP/TLS/AES256-SHA; 11 Feb 2019 23:14:32 +0100 Received: from localhost.de (10.80.233.50) by FGDEMUCIMP11EXC.ads.fraunhofer.de (10.80.232.42) with Microsoft SMTP Server (TLS) id 14.3.435.0; Mon, 11 Feb 2019 23:16:22 +0100 From: Lukas Auer To: Date: Mon, 11 Feb 2019 23:13:42 +0100 Message-ID: <20190211221345.31980-6-lukas.auer@aisec.fraunhofer.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190211221345.31980-1-lukas.auer@aisec.fraunhofer.de> References: <20190211221345.31980-1-lukas.auer@aisec.fraunhofer.de> MIME-Version: 1.0 X-TM-AS-Product-Ver: SMEX-11.0.0.4179-8.200.1013-24422.005 X-TM-AS-Result: No--12.590400-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No Cc: Baruch Siach , Palmer Dabbelt , Andreas Schwab , Alexander Graf , Stefan Roese Subject: [U-Boot] [PATCH 5/7] riscv: add support for multi-hart systems X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" On RISC-V, all harts boot independently. To be able to run on a multi-hart system, U-Boot must be extended with the functionality to manage all harts in the system. A new config option, CONFIG_MAIN_HART, is used to select the hart U-Boot runs on. All other harts are halted. U-Boot can delegate functions to them using smp_call_function(). Every hart has a valid pointer to the global data structure and a 8KiB stack by default. The stack size is set with CONFIG_STACK_SIZE_SHIFT. Signed-off-by: Lukas Auer --- arch/riscv/Kconfig | 12 +++++ arch/riscv/cpu/start.S | 102 ++++++++++++++++++++++++++++++++++- arch/riscv/include/asm/csr.h | 1 + 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 3a51339c4d..af8d0f8d67 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -140,4 +140,16 @@ config SBI_IPI default y if RISCV_SMODE depends on SMP +config MAIN_HART + int "Main hart in system" + default 0 + help + Some SoCs include harts of various sizes, some of which might not + be suitable for running U-Boot. CONFIG_MAIN_HART is used to select + the hart U-Boot runs on. + +config STACK_SIZE_SHIFT + int + default 13 + endmenu diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index a30f6f7194..ce7230df37 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,23 @@ _start: /* mask all interrupts */ csrw MODE_PREFIX(ie), zero +#ifdef CONFIG_SMP + /* check if hart is within range */ + /* s0: hart id */ + li t0, CONFIG_NR_CPUS + bge s0, t0, hart_out_of_bounds_loop +#endif + +#ifdef CONFIG_SMP + /* set xSIE bit to receive IPIs */ +#ifdef CONFIG_RISCV_MMODE + li t0, MIE_MSIE +#else + li t0, SIE_SSIE +#endif + csrs MODE_PREFIX(ie), t0 +#endif + /* * Set stackpointer in internal/ex RAM to call board_init_f */ @@ -56,7 +74,25 @@ call_board_init_f: call_board_init_f_0: mv a0, sp jal board_init_f_alloc_reserve + + /* + * Set global data pointer here for all harts, uninitialized at this + * point. + */ + mv gp, a0 + + /* setup stack */ +#ifdef CONFIG_SMP + /* s0: hart id */ + slli t0, s0, CONFIG_STACK_SIZE_SHIFT + sub sp, a0, t0 +#else mv sp, a0 +#endif + + /* Continue on main hart, others branch to secondary_hart_loop */ + li t0, CONFIG_MAIN_HART + bne s0, t0, secondary_hart_loop la t0, prior_stage_fdt_address SREG s1, 0(t0) @@ -95,7 +131,14 @@ relocate_code: *Set up the stack */ stack_setup: +#ifdef CONFIG_SMP + /* s0: hart id */ + slli t0, s0, CONFIG_STACK_SIZE_SHIFT + sub sp, s2, t0 +#else mv sp, s2 +#endif + la t0, _start sub t6, s4, t0 /* t6 <- relocation offset */ beq t0, s4, clear_bss /* skip relocation */ @@ -175,13 +218,30 @@ clear_bss: add t0, t0, t6 /* t0 <- rel __bss_start in RAM */ la t1, __bss_end /* t1 <- rel __bss_end in FLASH */ add t1, t1, t6 /* t1 <- rel __bss_end in RAM */ - beq t0, t1, call_board_init_r + beq t0, t1, relocate_secondary_harts clbss_l: SREG zero, 0(t0) /* clear loop... */ addi t0, t0, REGBYTES bne t0, t1, clbss_l +relocate_secondary_harts: +#ifdef CONFIG_SMP + /* send relocation IPI */ + la t0, secondary_hart_relocate + add a0, t0, t6 + + /* store relocation offset */ + mv s5, t6 + + mv a1, s2 + mv a2, s3 + jal smp_call_function + + /* restore relocation offset */ + mv t6, s5 +#endif + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -202,3 +262,43 @@ call_board_init_r: * jump to it ... */ jr t4 /* jump to board_init_r() */ + +#ifdef CONFIG_SMP +hart_out_of_bounds_loop: + /* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */ + wfi + j hart_out_of_bounds_loop +#endif + +#ifdef CONFIG_SMP +/* SMP relocation entry */ +secondary_hart_relocate: + /* a1: new sp */ + /* a2: new gd */ + /* s0: hart id */ + + /* setup stack */ + slli t0, s0, CONFIG_STACK_SIZE_SHIFT + sub sp, a1, t0 + + /* update global data pointer */ + mv gp, a2 +#endif + +secondary_hart_loop: + wfi + +#ifdef CONFIG_SMP + csrr t0, MODE_PREFIX(ip) +#ifdef CONFIG_RISCV_MMODE + andi t0, t0, MIE_MSIE +#else + andi t0, t0, SIE_SSIE +#endif + beqz t0, secondary_hart_loop + + mv a0, s0 + jal handle_ipi +#endif + + j secondary_hart_loop diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 86136f542c..644e6baa15 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -46,6 +46,7 @@ #endif /* Interrupt Enable and Interrupt Pending flags */ +#define MIE_MSIE _AC(0x00000008, UL) /* Software Interrupt Enable */ #define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ #define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */