From patchwork Mon Jan 27 14:07:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 11352695 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C0310924 for ; Mon, 27 Jan 2020 14:07:35 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 83C662071E for ; Mon, 27 Jan 2020 14:07:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="BPll3xCo" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 83C662071E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=glider.be Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=lsypkJ5hJrLr8SZqUFect0UFWQwwf2VnFxrkdRCtQ2g=; b=BPl l3xCop5D1fedXmftKKfHuX2Y0cXnJg1lbn14hRauFacFZWe9s+lhUuAfQbuh9PR0Wxb/BPHtZ2sKA ZObP53oIHFKneiizBurD5td4jJLHJCekEDOF92aN43Z/Q2uAsmbDP3S3/x/WLjqJ88WLyE7R93A8n CtNB/2U8GsuiXpezSu1gghwKAJR8c914VMK/Lri/DS/AjpTDtiOncK5IkPnt3mscZGRHM99Lildq4 OUz2e1wuiPWeR+mZdnnDmZ6Pg3260xIC3sxOd1Vj0ukbddnPJeTYGqoAlp90CEvGyu8GLaZw/sQjP VAei+qQBKbfpCDFuCg4jGJfYtlMnlWQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iw537-0008VF-KF; Mon, 27 Jan 2020 14:07:33 +0000 Received: from andre.telenet-ops.be ([2a02:1800:120:4::f00:15]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iw534-0008UW-7F for linux-arm-kernel@lists.infradead.org; Mon, 27 Jan 2020 14:07:33 +0000 Received: from ramsan ([84.195.182.253]) by andre.telenet-ops.be with bizsmtp id vS7J210055USYZQ01S7JqT; Mon, 27 Jan 2020 15:07:18 +0100 Received: from rox.of.borg ([192.168.97.57]) by ramsan with esmtp (Exim 4.90_1) (envelope-from ) id 1iw52s-0000ua-3G; Mon, 27 Jan 2020 15:07:18 +0100 Received: from geert by rox.of.borg with local (Exim 4.90_1) (envelope-from ) id 1iw52s-00045X-0p; Mon, 27 Jan 2020 15:07:18 +0100 From: Geert Uytterhoeven To: Russell King , Nicolas Pitre , Arnd Bergmann , Eric Miao , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= Subject: [PATCH v2] ARM: boot: Obtain start of physical memory from DTB Date: Mon, 27 Jan 2020 15:07:16 +0100 Message-Id: <20200127140716.15673-1-geert+renesas@glider.be> X-Mailer: git-send-email 2.17.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200127_060730_430347_14B1C8C9 X-CRM114-Status: GOOD ( 15.61 ) X-Spam-Score: 0.3 (/) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (0.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2a02:1800:120:4:0:0:f00:15 listed in] [list.dnswl.org] 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-renesas-soc@vger.kernel.org, Chris Brandt , Geert Uytterhoeven , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Currently, the start address of physical memory is obtained by masking the program counter with a fixed mask of 0xf8000000. This mask value was chosen as a balance between the requirements of different platforms. However, this does require that the start address of physical memory is a multiple of 128 MiB, precluding booting Linux on platforms where this requirement is not fulfilled. Fix this limitation by obtaining the start address from the DTB instead, if available (either explicitly passed, or appended to the kernel). Fall back to the traditional method when needed. This allows to boot Linux on r7s9210/rza2mevb using the 64 MiB of SDRAM on the RZA2MEVB sub board, which is located at 0x0C000000 (CS3 space), i.e. not at a multiple of 128 MiB. Suggested-by: Nicolas Pitre Signed-off-by: Geert Uytterhoeven Reviewed-by: Nicolas Pitre --- Against arm/for-next. Tested with the following configurations: - zImage + DTB (r8a7791/koelsch), - uImage + DTB (r8a73a4/ape6evm, r7s72100/rskrza1, r7s9210/rza2mevb), - zImage with appended DTB (r8a7740/armadillo, sh73a0/kzm9g). v2: - Use "cmp r0, #-1", instead of "cmn r0, #1", - Add missing stack setup, - Support appended DTBs. v1: https://lore.kernel.org/linux-arm-kernel/20200121192741.20597-1-geert+renesas@glider.be/ --- arch/arm/boot/compressed/Makefile | 6 ++- arch/arm/boot/compressed/fdt_get_mem_start.c | 52 ++++++++++++++++++++ arch/arm/boot/compressed/head.S | 52 +++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 arch/arm/boot/compressed/fdt_get_mem_start.c diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index da599c3a11934332..bbfecd648a1a3b57 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -86,12 +86,15 @@ libfdt_objs := $(addsuffix .o, $(basename $(libfdt))) $(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/% $(call cmd,shipped) -$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \ +$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o fdt_get_mem_start.o): \ $(addprefix $(obj)/,$(libfdt_hdrs)) ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) OBJS += $(libfdt_objs) atags_to_fdt.o endif +ifeq ($(CONFIG_USE_OF),y) +OBJS += $(libfdt_objs) fdt_get_mem_start.o +endif targets := vmlinux vmlinux.lds piggy_data piggy.o \ lib1funcs.o ashldi3.o bswapsdi2.o \ @@ -116,6 +119,7 @@ CFLAGS_fdt.o := $(nossp-flags-y) CFLAGS_fdt_ro.o := $(nossp-flags-y) CFLAGS_fdt_rw.o := $(nossp-flags-y) CFLAGS_fdt_wip.o := $(nossp-flags-y) +CFLAGS_fdt_get_mem_start.o := $(nossp-flags-y) ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) asflags-y := -DZIMAGE diff --git a/arch/arm/boot/compressed/fdt_get_mem_start.c b/arch/arm/boot/compressed/fdt_get_mem_start.c new file mode 100644 index 0000000000000000..2c5ac47f656317ee --- /dev/null +++ b/arch/arm/boot/compressed/fdt_get_mem_start.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +static const void *getprop(const void *fdt, const char *node_path, + const char *property) +{ + int offset = fdt_path_offset(fdt, node_path); + + if (offset == -FDT_ERR_NOTFOUND) + return NULL; + + return fdt_getprop(fdt, offset, property, NULL); +} + +static uint32_t get_addr_size(const void *fdt) +{ + const __be32 *addr_len = getprop(fdt, "/", "#address-cells"); + + if (!addr_len) { + /* default */ + return 1; + } + + return fdt32_to_cpu(*addr_len); +} + +/* + * Get the start of physical memory + */ + +unsigned long fdt_get_mem_start(const void *fdt) +{ + const __be32 *memory; + uint32_t addr_size; + + if (!fdt) + return -1; + + if (*(__be32 *)fdt != cpu_to_fdt32(FDT_MAGIC)) + return -1; + + /* Find the first memory node */ + memory = getprop(fdt, "/memory", "reg"); + if (!memory) + return -1; + + /* There may be multiple cells on LPAE platforms */ + addr_size = get_addr_size(fdt); + + return fdt32_to_cpu(memory[addr_size - 1]); +} diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 927f5dc413d7dff2..aa2d7de2ddc86fa8 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -235,8 +235,56 @@ not_angel: .text #ifdef CONFIG_AUTO_ZRELADDR +#ifdef CONFIG_USE_OF /* - * Find the start of physical memory. As we are executing + * Find the start of physical memory. + * Try the DTB first, if available. + */ + adr r0, LC0 + ldr r1, [r0] @ get absolute LC0 + ldr sp, [r0, #28] @ get stack location + sub r1, r0, r1 @ compute relocation offset + add sp, sp, r1 @ apply relocation + +#ifdef CONFIG_ARM_APPENDED_DTB + /* + * Look for an appended DTB. If found, use it and + * move stack away from it. + */ + ldr r6, [r0, #12] @ get &_edata + add r6, r6, r1 @ relocate it + ldmia r6, {r0, r5} @ get DTB signature and size +#ifndef __ARMEB__ + ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian + /* convert DTB size to little endian */ + eor r2, r5, r5, ror #16 + bic r2, r2, #0x00ff0000 + mov r5, r5, ror #8 + eor r5, r5, r2, lsr #8 +#else + ldr r1, =0xd00dfeed +#endif + cmp r0, r1 @ do we have a DTB there? + bne 1f + + mov r8, r6 @ use it if so + /* preserve 64-bit alignment */ + add r5, r5, #7 + bic r5, r5, #7 + add sp, sp, r5 @ and move stack above it + +1: +#endif /* CONFIG_ARM_APPENDED_DTB */ + + mov r0, r8 + bl fdt_get_mem_start + mov r4, r0 + cmp r0, #-1 + bne 1f +#endif /* CONFIG_USE_OF */ + + /* + * Fall back to the traditional method. As we are executing * without the MMU on, we are in the physical address space. * We just need to get rid of any offset by aligning the * address. @@ -254,6 +302,8 @@ not_angel: */ mov r4, pc and r4, r4, #0xf8000000 + +1: /* Determine final kernel image address. */ add r4, r4, #TEXT_OFFSET #else