From patchwork Mon Aug 12 10:15:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 13760400 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8BAFDC3DA7F for ; Mon, 12 Aug 2024 10:23:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=wI5JdQbYgMgKvLkTYaygW8PZ/FnbIMWpkJqhpJjQoak=; b=YhNcHr6+/8UwM6KTPBvYHizUxX 8GwSHQkyHc2NIN3i8OlFEsoLBN71/fFCmnhmK2tn+pRakjX2t6Kym7ZnyGqGvRrueWVB/T85uzuan dtdNTymLAr2nOeqg5Ubpx92bMANzhCIgfw81BgwUaMru3kQBpRrzvcaUMhNFsATxi8ljRLydZfhiF 4mjSo70o3LZlQwpdEhEYwJpsmBy4Dij9HNRkl2Nh9oG7mKHtmacUT24ZK9frWDjGvpANX8BPZhUX6 quVmhW6asyKlFZbD4/Mr9k24Ea8ycgNJE8PvrqoE4a+XXZmatCCVdy3VLjX0qyAG2WXC/YH76XMf8 JnvH6lVQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdSCX-0000000Hb1T-3cOQ; Mon, 12 Aug 2024 10:22:57 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdS63-0000000HZl8-39wF for linux-arm-kernel@lists.infradead.org; Mon, 12 Aug 2024 10:16:17 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 490F8106F; Mon, 12 Aug 2024 03:16:41 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8D1A63F6A8; Mon, 12 Aug 2024 03:16:14 -0700 (PDT) From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Cc: akos.denke@arm.com, andre.przywara@arm.com, luca.fancellu@arm.com, mark.rutland@arm.com, maz@kernel.org Subject: [BOOT-WRAPPER v2 10/10] Boot CPUs sequentially Date: Mon, 12 Aug 2024 11:15:55 +0100 Message-Id: <20240812101555.3558589-11-mark.rutland@arm.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240812101555.3558589-1-mark.rutland@arm.com> References: <20240812101555.3558589-1-mark.rutland@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240812_031615_914486_BB5BB438 X-CRM114-Status: GOOD ( 16.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Currently the boot-wrapper initializes all CPUs in parallel. This means that we cannot log errors as they happen, as this would mean multiple CPUs concurrently writing to the UART, producing garbled output. To produce meaningful output we have to special-case errors on the boot CPU and hope CPUs have been configured consistently. To make it easier to handle errors, boot CPUs sequentially so that errors can be logged as they happen. With this change it's pretty clear that the cpu_init_bootmethod() abstraction isn't helpful, and so this is removed with cpu_init_arch() directly initializing PSCI where necessary. When things go well this looks like: | Boot-wrapper v0.2 | Entered at EL3 | Memory layout: | [0000000080000000..0000000080001f90] => boot-wrapper | [000000008000fff8..0000000080010000] => mbox | [0000000080200000..0000000082cbaa00] => kernel | [0000000088000000..0000000088002df1] => dtb | CPU0: (MPIDR 0000000000000000) initializing... | CPU0: Done | CPU1: (MPIDR 0000000000000100) initializing... | CPU1: Done | CPU2: (MPIDR 0000000000000200) initializing... | CPU2: Done | CPU3: (MPIDR 0000000000000300) initializing... | CPU3: Done | CPU4: (MPIDR 0000000000010000) initializing... | CPU4: Done | CPU5: (MPIDR 0000000000010100) initializing... | CPU5: Done | CPU6: (MPIDR 0000000000010200) initializing... | CPU6: Done | CPU7: (MPIDR 0000000000010300) initializing... | CPU7: Done | All CPUs initialized. Entering kernel... | | [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd0f0] Signed-off-by: Mark Rutland Acked-by: Marc Zyngier Cc: Akos Denke Cc: Andre Przywara Cc: Luca Fancellu --- arch/aarch32/boot.S | 2 -- arch/aarch32/init.c | 17 +++++++++------ arch/aarch64/boot.S | 2 -- arch/aarch64/init.c | 17 +++++++++------ arch/aarch64/spin.S | 3 --- common/init.c | 50 +++++++++++++++++++++++++++++++++++++-------- common/psci.c | 14 ------------- include/boot.h | 6 +----- 8 files changed, 64 insertions(+), 47 deletions(-) diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S index 8b6ffac..08029ff 100644 --- a/arch/aarch32/boot.S +++ b/arch/aarch32/boot.S @@ -70,8 +70,6 @@ reset_common: bl cpu_init_bootwrapper - bl cpu_init_arch - b start_bootmethod err_invalid_id: diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c index cb67bf6..d08ac83 100644 --- a/arch/aarch32/init.c +++ b/arch/aarch32/init.c @@ -6,6 +6,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE.txt file. */ +#include #include #include #include @@ -43,24 +44,28 @@ static void cpu_init_monitor(void) #ifdef PSCI extern char psci_vectors[]; -bool cpu_init_psci_arch(void) +static void cpu_init_psci_arch(unsigned int cpu) { - if (read_cpsr_mode() != PSR_MON) - return false; + if (read_cpsr_mode() != PSR_MON) { + print_cpu_warn(cpu, "PSCI could not be initialized (not booted at PL1).\r\n"); + return; + } mcr(MVBAR, (unsigned long)psci_vectors); isb(); - - return true; } +#else +static static void cpu_init_psci_arch(unsigned int cpu) { } #endif -void cpu_init_arch(void) +void cpu_init_arch(unsigned int cpu) { if (read_cpsr_mode() == PSR_MON) { cpu_init_monitor(); gic_secure_init(); } + cpu_init_psci_arch(cpu); + mcr(CNTFRQ, COUNTER_FREQ); } diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S index 98ae77d..6bec836 100644 --- a/arch/aarch64/boot.S +++ b/arch/aarch64/boot.S @@ -69,8 +69,6 @@ reset_common: bl cpu_init_bootwrapper - bl cpu_init_arch - b start_bootmethod err_invalid_id: diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c index 68c220b..63fa949 100644 --- a/arch/aarch64/init.c +++ b/arch/aarch64/init.c @@ -6,6 +6,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE.txt file. */ +#include #include #include #include @@ -159,24 +160,28 @@ static void cpu_init_el3(void) #ifdef PSCI extern char psci_vectors[]; -bool cpu_init_psci_arch(void) +static void cpu_init_psci_arch(unsigned int cpu) { - if (mrs(CurrentEL) != CURRENTEL_EL3) - return false; + if (mrs(CurrentEL) != CURRENTEL_EL3) { + print_cpu_warn(cpu, "PSCI could not be initialized (not booted at EL3).\r\n"); + return; + } msr(VBAR_EL3, (unsigned long)psci_vectors); isb(); - - return true; } +#else +static void cpu_init_psci_arch(unsigned int cpu) { } #endif -void cpu_init_arch(void) +void cpu_init_arch(unsigned int cpu) { if (mrs(CurrentEL) == CURRENTEL_EL3) { cpu_init_el3(); gic_secure_init(); } + cpu_init_psci_arch(cpu); + msr(CNTFRQ_EL0, COUNTER_FREQ); } diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S index a7879d4..81d7ee4 100644 --- a/arch/aarch64/spin.S +++ b/arch/aarch64/spin.S @@ -12,9 +12,6 @@ .text -ASM_FUNC(cpu_init_bootmethod) - ret - ASM_FUNC(start_bootmethod) cpuid x0, x1 bl find_logical_id diff --git a/common/init.c b/common/init.c index 3c05ac3..6197ead 100644 --- a/common/init.c +++ b/common/init.c @@ -43,18 +43,50 @@ static void announce_objects(void) void announce_arch(void); +static void init_bootwrapper(void) +{ + init_uart(); + announce_bootwrapper(); + announce_arch(); + announce_objects(); + init_platform(); +} + +static void cpu_init_self(unsigned int cpu) +{ + print_string("CPU"); + print_uint_dec(cpu); + print_string(": (MPIDR "); + print_ulong_hex(read_mpidr()); + print_string(") initializing...\r\n"); + + cpu_init_arch(cpu); + + print_cpu_msg(cpu, "Done\r\n"); +} + void cpu_init_bootwrapper(void) { + static volatile unsigned int cpu_next = 0; unsigned int cpu = this_cpu_logical_id(); - if (cpu == 0) { - init_uart(); - announce_bootwrapper(); - announce_arch(); - announce_objects(); - print_string("\r\n"); - init_platform(); - } + if (cpu == 0) + init_bootwrapper(); + + while (cpu_next != cpu) + wfe(); + + cpu_init_self(cpu); + + cpu_next = cpu + 1; + dsb(sy); + sev(); + + if (cpu != 0) + return; + + while (cpu_next != NR_CPUS) + wfe(); - cpu_init_bootmethod(cpu); + print_string("All CPUs initialized. Entering kernel...\r\n\r\n"); } diff --git a/common/psci.c b/common/psci.c index 19cc315..5fe8999 100644 --- a/common/psci.c +++ b/common/psci.c @@ -87,17 +87,3 @@ void __noreturn psci_first_spin(void) unreachable(); } - -void cpu_init_bootmethod(unsigned int cpu) -{ - if (cpu_init_psci_arch()) - return; - - if (cpu == 0) { - print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n"); - return; - } - - while (1) - wfe(); -} diff --git a/include/boot.h b/include/boot.h index 18b805d..12c9c5c 100644 --- a/include/boot.h +++ b/include/boot.h @@ -17,10 +17,6 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid); void __noreturn first_spin(unsigned int cpu, unsigned long *mbox, unsigned long invalid_addr); -void cpu_init_bootmethod(unsigned int cpu); - -#ifdef PSCI -bool cpu_init_psci_arch(void); -#endif +void cpu_init_arch(unsigned int cpu); #endif