From patchwork Tue May 7 12:50:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 1096329 X-Patchwork-Delegate: joe.hershberger@gmail.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=baylibre.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="e6Jp6XZ/"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44yzwn3w20z9sB8 for ; Tue, 7 May 2019 22:50:33 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id C19CAC21E52; Tue, 7 May 2019 12:50:29 +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=RCVD_IN_MSPIKE_H2, T_DKIM_INVALID 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 CCC4FC21C8B; Tue, 7 May 2019 12:50:26 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 793DBC21C8B; Tue, 7 May 2019 12:50:25 +0000 (UTC) Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by lists.denx.de (Postfix) with ESMTPS id 1F4C1C21C4A for ; Tue, 7 May 2019 12:50:25 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id f2so15002955wmj.3 for ; Tue, 07 May 2019 05:50:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=7keLcHngwlpfJgl20iequHSAVE6leLJclL196NS6ges=; b=e6Jp6XZ/2rrRC4bxD0c11INg5oZD0TWvGmEuiqeS/bZrAD4DdW1HzE1/QJ3qnXBO3O 97b6ATgk14HggWZkevdr1x9FfUHxQgiaEENdJAgUCGIM0MM3xp1HvWenvPCa6uH8Uhpz MoFzwIHKzz9xc3zMjm7bymyP7JpI+efgQvHhwasSOswWU1HysvGT3nvBWTmj/hrKSrRV OlXZgZsY4VaJpZtYHb8N5+x0X5DO52zWblGG+6X+MrxT5HnnOT8ZMKW/rwUpjho4U7o3 fwWEiMYp0slaj9M6hRcZLDfDooggEWouF0OeyrNTFrfzUMmPdwx4rUenOxzuxJnxfrvu Q9Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=7keLcHngwlpfJgl20iequHSAVE6leLJclL196NS6ges=; b=M4fnRxatw1SKc0vC+2qCOH8gXrT8MEIInTHjA7lJGjjE04ns+dQzuyWJAKVLJOMGr0 Jbyw38xG7Beak4URlyC/yRXZyvgNyWdroQVQ4+RrC1aAWefeA8sKhY6XZRPQPwEvIFeU ITnzW494zVKldxcgG3/OmTdg7EEpPRuO+BHV75TDEx7g+/bOJgI7Bh09l+4iO47HFG7+ tyLAyl6INgD4QLwvVifyeWLdyire8jCmWJvzuS+9zjAfAqGNZxnMKRWRoSJoHZvvtA8X VMi8Zv7ZTHcY9Fb+H6uet/ODLsyXqn0ez5qi4o4Kw0MmnZsYm0RlbslL85pJYMoEfTL8 nY9g== X-Gm-Message-State: APjAAAUk0FbnE/u1Mumetdtp4xX/6lsuS4NdYxAVr7aJ6jKD9emJGWTe iz1hFosST2kLnHZyDFV2L0mGejG8BHRqaQ== X-Google-Smtp-Source: APXvYqxWzR8biTI1meAJ/VyItRI41Gs0r6aFAnlSOALFmfbMPp8SmgbRYgWBfVNQx/7mb9toVgYLwA== X-Received: by 2002:a1c:cc10:: with SMTP id h16mr21624162wmb.39.1557233424287; Tue, 07 May 2019 05:50:24 -0700 (PDT) Received: from bender.baylibre.local (lmontsouris-657-1-212-31.w90-63.abo.wanadoo.fr. [90.63.244.31]) by smtp.gmail.com with ESMTPSA id n17sm10759792wrw.77.2019.05.07.05.50.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 May 2019 05:50:23 -0700 (PDT) From: Neil Armstrong To: u-boot@lists.denx.de Date: Tue, 7 May 2019 14:50:21 +0200 Message-Id: <20190507125021.8184-1-narmstrong@baylibre.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Cc: =?utf-8?q?Jernej_=C5=A0krabec?= , Jonas Karlman Subject: [U-Boot] [RFC PATCH] pxe: add support for FDT overlays 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" This adds support for specicyinf FDT overlays in an extlinux/pxelinux configuration file. Without this, there is no simple way to apply overlays when the kernel and ftd is loaded by the pxe command. This change adds the 'fdtoverlays' keyword for a label, supporting multiple overlay files to be applied on top of the fdt specific in the 'fdt' or 'devicetree' keyword. Cc: Jernej Škrabec Cc: Jonas Karlman Signed-off-by: Neil Armstrong --- cmd/pxe.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/cmd/pxe.c b/cmd/pxe.c index 1dd0a74ea3..8d19e6f99f 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -481,6 +483,7 @@ struct pxe_label { char *initrd; char *fdt; char *fdtdir; + char *fdtoverlays; int ipappend; int attempted; int localboot; @@ -561,6 +564,9 @@ static void label_destroy(struct pxe_label *label) if (label->fdtdir) free(label->fdtdir); + if (label->fdtoverlays) + free(label->fdtoverlays); + free(label); } @@ -608,6 +614,92 @@ static int label_localboot(struct pxe_label *label) return run_command_list(localcmd, strlen(localcmd), 0); } +/* + * Loads fdt overlays specified in 'fdtoverlays'. + */ +#ifdef CONFIG_OF_LIBFDT_OVERLAY +static void label_boot_fdtoverlay(cmd_tbl_t *cmdtp, struct pxe_label *label) +{ + char *fdtoverlay = label->fdtoverlays; + struct fdt_header *working_fdt; + char *fdtoverlay_addr_env; + ulong fdtoverlay_addr; + ulong fdt_addr; + int err; + + /* Get the main fdt and map it */ + fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16); + working_fdt = map_sysmem(fdt_addr, 0); + err = fdt_check_header(working_fdt); + if (err) + return; + + /* Get the specific overlay loading address */ + fdtoverlay_addr_env = env_get("fdtoverlay_addr_r"); + if (!fdtoverlay_addr_env) { + printf("Invalid fdtoverlay_addr_r for loading overlays\n"); + return; + } + + fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16); + + /* Cycle over the overlay files and apply them in order */ + do { + struct fdt_header *blob; + char *overlayfile; + char *end; + int len; + + /* Drop leading spaces */ + while (*fdtoverlay == ' ') + ++fdtoverlay; + + /* Copy a single filename if multiple provided */ + end = strstr(fdtoverlay, " "); + if (end) { + len = (int)(end - fdtoverlay); + overlayfile = malloc(len + 1); + strncpy(overlayfile, fdtoverlay, len); + overlayfile[len] = '\0'; + } else + overlayfile = fdtoverlay; + + if (!strlen(overlayfile)) + goto skip_overlay; + + /* Load overlay file */ + err = get_relfile_envaddr(cmdtp, overlayfile, + "fdtoverlay_addr_r"); + if (err < 0) { + printf("Failed loading overlay %s\n", overlayfile); + goto skip_overlay; + } + + /* Resize main fdt */ + fdt_shrink_to_minimum(working_fdt, 8192); + + blob = map_sysmem(fdtoverlay_addr, 0); + err = fdt_check_header(blob); + if (err) { + printf("Invalid overlay %s, skipping\n", + overlayfile); + goto skip_overlay; + } + + err = fdt_overlay_apply_verbose(working_fdt, blob); + if (err) { + printf("Failed to apply overlay %s, skipping\n", + overlayfile); + goto skip_overlay; + } + +skip_overlay: + if (end) + free(overlayfile); + } while ((fdtoverlay = strstr(fdtoverlay, " "))); +} +#endif + /* * Boot according to the contents of a pxe_label. * @@ -798,6 +890,11 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) label->name); goto cleanup; } + +#ifdef CONFIG_OF_LIBFDT_OVERLAY + if (label->fdtoverlays) + label_boot_fdtoverlay(cmdtp, label); +#endif } else { bootm_argv[3] = NULL; } @@ -855,6 +952,7 @@ enum token_type { T_INCLUDE, T_FDT, T_FDTDIR, + T_FDTOVERLAYS, T_ONTIMEOUT, T_IPAPPEND, T_BACKGROUND, @@ -889,6 +987,7 @@ static const struct token keywords[] = { {"fdt", T_FDT}, {"devicetreedir", T_FDTDIR}, {"fdtdir", T_FDTDIR}, + {"fdtoverlays", T_FDTOVERLAYS}, {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, {"background", T_BACKGROUND,}, @@ -1322,6 +1421,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_sliteral(c, &label->fdtdir); break; + case T_FDTOVERLAYS: + if (!label->fdtoverlays) + err = parse_sliteral(c, &label->fdtoverlays); + break; + case T_LOCALBOOT: label->localboot = 1; err = parse_integer(c, &label->localboot_val);