From patchwork Fri Nov 11 10:59:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Schieli?= X-Patchwork-Id: 693632 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3tFcPl6vxLz9t0q for ; Fri, 11 Nov 2016 21:59:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NHqCNTgA"; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7E8A1A75C3; Fri, 11 Nov 2016 11:59:46 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Do_WNeXaKKTF; Fri, 11 Nov 2016 11:59:46 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7E154A756F; Fri, 11 Nov 2016 11:59:37 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5C322A7549 for ; Fri, 11 Nov 2016 11:59:32 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ft7Srb0iA1OX for ; Fri, 11 Nov 2016 11:59:32 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by theia.denx.de (Postfix) with ESMTPS id 1AA87A7535 for ; Fri, 11 Nov 2016 11:59:29 +0100 (CET) Received: by mail-wm0-f67.google.com with SMTP id m203so6952785wma.3 for ; Fri, 11 Nov 2016 02:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eTjH+ltX7/91rMvREUaoaqmxgYM/rRsM/p8eUmYqDaY=; b=NHqCNTgAeMqXfrlPx+PMK/sQ25iapk+EI97Nr059ct7O9KdDA4zPHTkFS4h4CPZTCy pr+ZdaIYG+vj3sRPOqMi31Pvxxm8KlmhrrHSIVRb9J/GbZwvfDug6u3uvm7uinhJTYd3 pg5Mz3OqEWL4nHyqYwzmD3fIIjSTtP3qtbRIVCz6qSu+j4p2XWc+tcHyFL0q+vJEs6iB k/F/AwxixKaG1eIoWc4Wb51b/H+pl9wXN2KN++mj7RcND2uKcUWao/qm2mcDIaQ+sPjY SopywI7ZpVE2YRnLsEcYAJHL5ZpN7XUI1PXG4okRWBn52ZO1r+tW34uCZaJsbWE+8YvW 2ReA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eTjH+ltX7/91rMvREUaoaqmxgYM/rRsM/p8eUmYqDaY=; b=a9351C+YtQyc8TAG8ayuAYgFp9Kt83KdceZQOsYJhs+/Zo5YE/o8NzN5VSQsc4WpHX 87LrHGHrsEmutggG6Hn7hvx3xG+gJrwbHP0Hht3GZYWh2yrf4Q/i/8hYFL82Xsg3JRzC YmsLz80gRCthIHgk7ekKCRP6tQYbNZCNfSA3UrVOBNUc/2yCzByKtRM7ns/ol9OvlSUN s1QaV1MHUrLhN/9LB3yq5AytOHLRjJ7NK2enMSHasg3aDTQuZOxJtf4lKfJGLqsr5JpP 3mSiz/9YQYY+A+5nQghA+bUdaRp58qDSvb6U/FyfC0UdMPinoWuw7jKXfUBhfzp9ye0w h8+g== X-Gm-Message-State: ABUngve61LPgf6cXD4wgo5mMZ2CImIcORDTKGbCg1kTP0C1CDgbTlNis/Y2526cgTmSWbg== X-Received: by 10.28.4.199 with SMTP id 190mr33778746wme.11.1478861968939; Fri, 11 Nov 2016 02:59:28 -0800 (PST) Received: from grasp.at.home (sdrik.gabriello.fr. [88.169.81.69]) by smtp.gmail.com with ESMTPSA id i10sm10824149wjd.15.2016.11.11.02.59.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Nov 2016 02:59:28 -0800 (PST) Received: by grasp.at.home (Postfix, from userid 1000) id 5B5B620278; Fri, 11 Nov 2016 11:59:27 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Schieli?= To: u-boot@lists.denx.de Date: Fri, 11 Nov 2016 11:59:07 +0100 Message-Id: <1478861947-28786-3-git-send-email-cschieli@gmail.com> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1478861947-28786-1-git-send-email-cschieli@gmail.com> References: <1478861947-28786-1-git-send-email-cschieli@gmail.com> MIME-Version: 1.0 Subject: [U-Boot] [PATCH v4 2/2] rpi: passthrough of the firmware provided FDT blob X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 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" Raspberry firmware used to pass a FDT blob at a fixed address (0x100), but this is not true anymore. The address now depends on both the memory size and the blob size [1]. If one wants to passthrough this FDT blob to the kernel, the most reliable way is to save its address from the r2/x0 register in the U-Boot entry point and expose it in a environment variable for further processing. This patch just does this: - save the provided address in the global variable fw_dtb_pointer - expose it in ${fdt_addr} if it points to a a valid FDT blob There are many different ways to use it. One can, for example, use the following script which will extract from the tree the command line built by the firmware, then hand over the blob to a previously loaded kernel: fdt addr ${fdt_addr} fdt get value bootargs /chosen bootargs bootz ${kernel_addr_r} - ${fdt_addr} Alternatively, users relying on sysboot/pxe can simply omit any FDT statement in their extlinux.conf file, U-Boot will automagically pick ${fdt_addr} and pass it to the kernel. [1] https://www.raspberrypi.org/forums//viewtopic.php?f=107&t=134018 Signed-off-by: Cédric Schieli Acked-by: Stephen Warren --- Changes in v4: None Changes in v3: - revert back to assembly for save_boot_params() Changes in v2: - merge the series in a single patch - convert the save_boot_params() function to C code - add a board_get_usable_ram_top() function to protect the blob during relocation - remove the (obsolete) extern declaration from include/configs/rpi.h - rename the global variable to fw_dtb_pointer - rename the environment variable to ${fdt_addr} - fix 64-bits compatibility issues - document possible uses of ${fdt_addr} board/raspberrypi/rpi/Makefile | 1 + board/raspberrypi/rpi/lowlevel_init.S | 36 +++++++++++++++++++++++++++++++++++ board/raspberrypi/rpi/rpi.c | 29 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 board/raspberrypi/rpi/lowlevel_init.S diff --git a/board/raspberrypi/rpi/Makefile b/board/raspberrypi/rpi/Makefile index 4ce2c98..dcb25ac 100644 --- a/board/raspberrypi/rpi/Makefile +++ b/board/raspberrypi/rpi/Makefile @@ -5,3 +5,4 @@ # obj-y := rpi.o +obj-y += lowlevel_init.o diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S new file mode 100644 index 0000000..cdbd8e1 --- /dev/null +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2016 + * Cédric Schieli + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +.align 8 +.global fw_dtb_pointer +fw_dtb_pointer: +#ifdef CONFIG_ARM64 + .dword 0x0 +#else + .word 0x0 +#endif + +/* + * Routine: save_boot_params (called after reset from start.S) + * Description: save ATAG/FDT address provided by the firmware at boot time + */ + +.global save_boot_params +save_boot_params: + + /* The firmware provided ATAG/FDT address can be found in r2/x0 */ +#ifdef CONFIG_ARM64 + adr x8, fw_dtb_pointer + str x0, [x8] +#else + str r2, fw_dtb_pointer +#endif + + /* Returns */ + b save_boot_params_ret diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 6245b36..ffd6d31 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -25,6 +25,9 @@ DECLARE_GLOBAL_DATA_PTR; +/* From lowlevel_init.S */ +extern unsigned long fw_dtb_pointer; + static const struct bcm2835_gpio_platdata gpio_platdata = { .base = BCM2835_GPIO_BASE, }; @@ -285,6 +288,31 @@ static void set_fdtfile(void) setenv("fdtfile", fdtfile); } +/* + * If the firmware provided a valid FDT at boot time, let's expose it in + * ${fdt_addr} so it may be passed unmodified to the kernel. + */ +static void set_fdt_addr(void) +{ + if (getenv("fdt_addr")) + return; + + if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) + return; + + setenv_hex("fdt_addr", fw_dtb_pointer); +} + +/* + * Prevent relocation from stomping on a firmware provided FDT blob. + */ +unsigned long board_get_usable_ram_top(unsigned long total_size) +{ + if ((gd->ram_top - fw_dtb_pointer) > SZ_64M) + return gd->ram_top; + return fw_dtb_pointer & ~0xffff; +} + static void set_usbethaddr(void) { ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1); @@ -356,6 +384,7 @@ static void set_serial_number(void) int misc_init_r(void) { + set_fdt_addr(); set_fdtfile(); set_usbethaddr(); #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG