From mboxrd@z Thu Jan 1 00:00:00 1970 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85B32C433EF for ; Sat, 23 Oct 2021 23:29:26 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F349260E9C for ; Sat, 23 Oct 2021 23:29:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F349260E9C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5413B83521; Sun, 24 Oct 2021 01:28:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="D5ckM4Za"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7A22E8353C; Sun, 24 Oct 2021 01:27:39 +0200 (CEST) Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3C5F78348B for ; Sun, 24 Oct 2021 01:27:08 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x331.google.com with SMTP id p6-20020a9d7446000000b0054e6bb223f3so9332455otk.3 for ; Sat, 23 Oct 2021 16:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=A81TZBzU6aix7z16L6Jo63KqYJFmqKXujnMgrJoV2w0=; b=D5ckM4Za2XtRut1JVuUouXBpEL3uMubpkuo7wvc4tTJCyoiYN/wJMY7Xeg8x1LA38c oqF4mbgVMZ2UZjTJfveGjSa+QI/CHVl3Hc5E8Gs1Q3c9NykdTYXoB3AtvnUMlJL7qCGF JTrTbdP5hugNmsXMc2DAD//Uhk4jsfFcFeg6o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=A81TZBzU6aix7z16L6Jo63KqYJFmqKXujnMgrJoV2w0=; b=H2yvGrpeZKQ9R9puNiWvV4inZzw+Cxv9kaaWuprdmmBngLhiyZfF10uqRN0zYDj/yv VNcIltBzGfGPkvnN685xn0VOIO4ojjOdW9rAGNsgm/EpXtOg+Df0jnGWpLxuAeRobXP8 XFo58Z1v7Yn/JxQHheZgxQG4GgSPX+xNVHpIjxQpO5rnbo+uqkLyuDeRIqy7YtB2t61+ xRrOsXJ8dVpwr7KK4RD/7EMv9fbJ4WNdEJ2CtRkDQkiJuulT+CsJFfKsNadQO2YDhBMe 26UC+C854ZAoxItIgsvpj8AJT+MYq3rR/M9Kyero4CdG7oVcQz30NAWha0CI+q/ntVKI XFDw== X-Gm-Message-State: AOAM530HRXfyL3aadnqJ9VA5/TMKbBPwxehd1Dy0ZW2aX5Jj+17YTVYB VJQ5+JFfxF9vHlDLwjpEMcHGd5UlyCQ= X-Google-Smtp-Source: ABdhPJxRuhZ+TjBT8LTFZVCqoOJdoko0vJvvLAeaTC5thW+uBDlOzprzYWsF6+9FNcBuOgfqvBg6Lw== X-Received: by 2002:a05:6830:30ba:: with SMTP id g26mr6711866ots.32.1635031626625; Sat, 23 Oct 2021 16:27:06 -0700 (PDT) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id l24sm2253885oop.4.2021.10.23.16.27.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 Oct 2021 16:27:06 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Michal Simek , Heinrich Schuchardt , Tom Rini , Ilias Apalodimas , Daniel Schwierzeck , Steffen Jaeckel , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Lukas Auer , Dennis Gilmore , Simon Glass Subject: [PATCH v2 20/41] bootstd: Add the bootstd uclass and core implementation Date: Sat, 23 Oct 2021 17:26:14 -0600 Message-Id: <20211023172618.v2.20.I3b5bc09d034cd72b2a9c604a0907c10abc05956a@changeid> X-Mailer: git-send-email 2.33.0.1079.g6e70778dc9-goog In-Reply-To: <20211023232635.9195-1-sjg@chromium.org> References: <20211023232635.9195-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean The 'bootstd' device provides the central information about U-Boot standard boot. Add a uclass for bootstd and the various helpers needed to make it work. Also add a binding file. Signed-off-by: Simon Glass --- (no changes since v1) MAINTAINERS | 2 + boot/Kconfig | 21 ++++ boot/Makefile | 3 + boot/bootstd-uclass.c | 145 +++++++++++++++++++++++++++ doc/device-tree-bindings/bootstd.txt | 28 ++++++ include/bootstd.h | 80 +++++++++++++++ include/dm/uclass-id.h | 1 + 7 files changed, 280 insertions(+) create mode 100644 boot/bootstd-uclass.c create mode 100644 doc/device-tree-bindings/bootstd.txt create mode 100644 include/bootstd.h diff --git a/MAINTAINERS b/MAINTAINERS index 8f4211baf1f..c928130f94b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -636,6 +636,8 @@ F: tools/binman/ BOOTDEVICE M: Simon Glass S: Maintained +F: boot/bootstd.c +F: include/bootstd.h F: include/bootflow.h BTRFS diff --git a/boot/Kconfig b/boot/Kconfig index 9b84a8d005f..58c495bb347 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -274,6 +274,27 @@ endif # SPL endif # FIT +config BOOTSTD + bool "Standard boot support" + default y + depends on OF_CONTROL + help + U-Boot supports a standard way of locating something to boot, + typically an Operating System such as Linux, provided by a distro such + as Arch Linux or Debian. Enable this to support iterating through + available bootdevs and using bootmeths to find bootflows suitable for + booting. + + Standard boot is not a standard way of booting, just a framework + within U-Boot for supporting all the different ways that exist. + + Terminology: + + - bootdev - a device which can hold a distro (e.g. MMC) + - bootmeth - a method to scan a bootdev to find bootflows (owned by + U-Boot) + - bootflow - a description of how to boot (owned by the distro) + config LEGACY_IMAGE_FORMAT bool "Enable support for the legacy image format" default y if !FIT_SIGNATURE diff --git a/boot/Makefile b/boot/Makefile index 2938c3f1458..48031d1c2b0 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -22,6 +22,9 @@ endif obj-y += image.o image-board.o obj-$(CONFIG_ANDROID_AB) += android_ab.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o + +obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootstd-uclass.o + obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c new file mode 100644 index 00000000000..04823e5ba03 --- /dev/null +++ b/boot/bootstd-uclass.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Uclass implemenation for standard boot + * + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int bootstd_of_to_plat(struct udevice *dev) +{ + struct bootstd_priv *priv = dev_get_priv(dev); + int ret; + + /* Don't check errors since livetree and flattree are different */ + ret = dev_read_string_list(dev, "filename-prefixes", &priv->prefixes); + dev_read_string_list(dev, "bootdev-order", &priv->bootdev_order); + + return 0; +} + +static void bootstd_clear_glob_(struct bootstd_priv *priv) +{ + while (!list_empty(&priv->glob_head)) { + struct bootflow *bflow; + + bflow = list_first_entry(&priv->glob_head, struct bootflow, + glob_node); + /* add later bootflow_remove(bflow); */ + } +} + +void bootstd_clear_glob(void) +{ + struct bootstd_priv *std; + + if (bootstd_get_priv(&std)) + return; + + bootstd_clear_glob_(std); +} + +static int bootstd_remove(struct udevice *dev) +{ + struct bootstd_priv *priv = dev_get_priv(dev); + + free(priv->prefixes); + free(priv->bootdev_order); + bootstd_clear_glob_(priv); + + return 0; +} + +const char *const *const bootstd_get_bootdev_order(struct udevice *dev) +{ + struct bootstd_priv *std = dev_get_priv(dev); + + return std->bootdev_order; +} + +const char *const *const bootstd_get_prefixes(struct udevice *dev) +{ + struct bootstd_priv *std = dev_get_priv(dev); + + return std->prefixes; +} + +int bootstd_get_priv(struct bootstd_priv **stdp) +{ + struct udevice *dev; + int ret; + + ret = uclass_first_device_err(UCLASS_BOOTSTD, &dev); + if (ret) + return ret; + *stdp = dev_get_priv(dev); + + return 0; +} + +static int bootstd_probe(struct udevice *dev) +{ + struct bootstd_priv *std = dev_get_priv(dev); + + INIT_LIST_HEAD(&std->glob_head); + + return 0; +} + +/* For now, bind the boormethod device if none are found in the devicetree */ +int dm_scan_other(bool pre_reloc_only) +{ + struct udevice *bootstd; + int ret; + + /* These are not needed before relocation */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + + /* Create a bootstd device if needed */ + uclass_find_first_device(UCLASS_BOOTSTD, &bootstd); + if (!bootstd) { + ret = device_bind_driver(gd->dm_root, "bootstd_drv", "bootstd", + &bootstd); + if (ret) + return log_msg_ret("bootstd", ret); + } + + return 0; +} + +static const struct udevice_id bootstd_ids[] = { + { .compatible = "u-boot,boot-std" }, + { } +}; + +U_BOOT_DRIVER(bootstd_drv) = { + .id = UCLASS_BOOTSTD, + .name = "bootstd_drv", + .of_to_plat = bootstd_of_to_plat, + .probe = bootstd_probe, + .remove = bootstd_remove, + .of_match = bootstd_ids, + .priv_auto = sizeof(struct bootstd_priv), +}; + +UCLASS_DRIVER(bootstd) = { + .id = UCLASS_BOOTSTD, + .name = "bootstd", +#if CONFIG_IS_ENABLED(OF_REAL) + .post_bind = dm_scan_fdt_dev, +#endif +}; diff --git a/doc/device-tree-bindings/bootstd.txt b/doc/device-tree-bindings/bootstd.txt new file mode 100644 index 00000000000..f048b9dd327 --- /dev/null +++ b/doc/device-tree-bindings/bootstd.txt @@ -0,0 +1,28 @@ +U-Boot standard boot device (bootstd) +===================================== + +This is the controlling device for U-Boot standard boot, providing a way to +boot operating systems in a way that can be controlled by distros. + +Required properties: + +compatible: "u-boot,boot-std" + +Optional properties: + +filename-prefixes: + List of strings, each a directory to search for bootflow files + +bootdev-order: + List of bootdevs to check for bootflows, each a bootdev label (the media + uclass followed by the numeric sequence number of the media device) + + +Example: + + bootstd { + compatible = "u-boot,boot-std"; + + filename-prefixes = "/", "/boot/"; + bootdev-order = "mmc2", "mmc1"; + }; diff --git a/include/bootstd.h b/include/bootstd.h new file mode 100644 index 00000000000..95b6e5e1a3c --- /dev/null +++ b/include/bootstd.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Standard U-Boot boot framework + * + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#ifndef __bootstd_h +#define __bootstd_h + +struct udevice; + +/** + * struct bootstd_priv - priv data for the bootstd driver + * + * This is attached to the (only) bootstd device, so there is only one instance + * of this struct. It provides overall information about bootdevs and bootflows. + * + * @prefixes: NULL-terminated list of prefixes to use for bootflow filenames, + * e.g. "/", "/boot/"; NULL if none + * @bootdev_order: Order to use for bootdevs (or NULL if none), with each item + * being a bootdev label, e.g. "mmc2", "mmc1"; + * @cur_bootdev: Currently selected bootdev (for commands) + * @cur_bootflow: Currently selected bootflow (for commands) + * @glob_head: Head for the global list of all bootflows across all bootdevs + * @bootmeth_count: Number of bootmeth devices in @bootmeth_order + * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated + */ +struct bootstd_priv { + const char **prefixes; + const char **bootdev_order; + struct udevice *cur_bootdev; + struct bootflow *cur_bootflow; + struct list_head glob_head; + int bootmeth_count; + struct udevice **bootmeth_order; +}; + +/** + * bootstd_get_bootdev_order() - Get the boot-order list + * + * This reads the boot order, e.g. {"mmc0", "mmc2", NULL} + * + * The list is alloced by the bootstd driver so should not be freed. That is the + * reason for all the const stuff in the function signature + * + * @return list of string points, terminated by NULL; or NULL if no boot order + */ +const char *const *const bootstd_get_bootdev_order(struct udevice *dev); + +/** + * bootstd_get_prefixes() - Get the filename-prefixes list + * + * This reads the prefixes, e.g. {"/", "/bpot", NULL} + * + * The list is alloced by the bootstd driver so should not be freed. That is the + * reason for all the const stuff in the function signature + * + * @return list of string points, terminated by NULL; or NULL if no boot order + */ +const char *const *const bootstd_get_prefixes(struct udevice *dev); + +/** + * bootstd_get_priv() - Get the (single) state for the bootstd system + * + * The state holds a global list of all bootflows that have been found. + * + * @return 0 if OK, -ve if the uclass does not exist + */ +int bootstd_get_priv(struct bootstd_priv **stdp); + +/** + * bootstd_clear_glob() - Clear the global list of bootflows + * + * This removes all bootflows globally and across all bootdevs. + */ +void bootstd_clear_glob(void); + +#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 3768432b680..17383fc38c1 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -38,6 +38,7 @@ enum uclass_id { UCLASS_AXI, /* AXI bus */ UCLASS_BLK, /* Block device */ UCLASS_BOOTCOUNT, /* Bootcount backing store */ + UCLASS_BOOTSTD, /* Standard boot driver */ UCLASS_BUTTON, /* Button */ UCLASS_CACHE, /* Cache controller */ UCLASS_CLK, /* Clock source, e.g. used by peripherals */ -- 2.33.0.1079.g6e70778dc9-goog