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 4F83AC433EF for ; Sat, 23 Oct 2021 23:29:57 +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 CC64360E9C for ; Sat, 23 Oct 2021 23:29:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CC64360E9C 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 18F9E8355F; Sun, 24 Oct 2021 01:29:34 +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="ZFooPXUr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 36506833D8; Sun, 24 Oct 2021 01:27:43 +0200 (CEST) Received: from mail-ot1-x32c.google.com (mail-ot1-x32c.google.com [IPv6:2607:f8b0:4864:20::32c]) (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 99898834E0 for ; Sun, 24 Oct 2021 01:27:10 +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-x32c.google.com with SMTP id y15-20020a9d460f000000b0055337e17a55so9283216ote.10 for ; Sat, 23 Oct 2021 16:27:10 -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=KJwhzo2SEfhpUgSIq3rEUjdLhlyVe82NqYLvScMJFYw=; b=ZFooPXUrLggpf7WTBqVY0OveqC/mnE9qy0A0/CJ8AtxjHYqqdS8/7DNL0Xk/8NqtFo d9K9XzC7umaXpIpkY4Br3bEQLmsUAc/d2j8GPLMYknz3oZi0VYrhC37bc3qsfgMXpHnG TO7islQHgHPJaGPV0yS1MACuvBp19wlkCjh6A= 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=KJwhzo2SEfhpUgSIq3rEUjdLhlyVe82NqYLvScMJFYw=; b=KbJlcv3Mr6ybZR9YrYS4XIwxRadkqvK8XbS6WzMpT6hCoK9cnqaVCEmPKJmdhAt3Kw eFuxu1F8OH7zzbK9uBLNCQGvY5F4P0FRoTk1mmQnpz87KZIDuecsRus2QjFNb7vAaq0k HJc8nWZbXZM8ha7OEKFl5rb6GWhLoZl3voOnwKJ3uRZdXY7TEMG7OflJpc4ObgcMveFa O4W2ZFskUo4w00bsh7z78LR205AA0KZ8nSNkU6sC+O6CiWrx+kGHYObtqXiWsnHBVsb5 MIyw4CNLBJ4G9c07K4yf41CUEFD3y1hoZjiyWCfXD1xovAJvz+/ANqGAkMgDMoEul/I1 Du5w== X-Gm-Message-State: AOAM5305UjkTRFGB5w6aIUD9ReH64yI5gDXWCtz8PHev7E99eS2zjFEi 0E4BZlXeJMdvvHQktrtw1D3569P436gU9g== X-Google-Smtp-Source: ABdhPJzkP7CriHfX0oChVWTGMD8j4SQ3h+iK9qdiMdq+GJP3yCRthCSv7H7swmpzYqQWlDmTx9STpg== X-Received: by 2002:a05:6830:2a14:: with SMTP id y20mr6692561otu.224.1635031628973; Sat, 23 Oct 2021 16:27:08 -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.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 Oct 2021 16:27:08 -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 22/41] bootstd: Add the bootmeth uclass and helpers Date: Sat, 23 Oct 2021 17:26:16 -0600 Message-Id: <20211023232635.9195-19-sjg@chromium.org> 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 A bootmeth is a method of locating an operating system. For now, just add the uclass itself. Drivers for particular bootmeths are added later. If no bootmeths devices are included in the devicetree, create them automatically. This avoids the need for boilerplate in the devicetree files. Signed-off-by: Simon Glass --- (no changes since v1) MAINTAINERS | 2 + boot/Makefile | 1 + boot/bootmeth-uclass.c | 59 ++++++++++++++++ boot/bootstd-uclass.c | 29 +++++++- include/bootmeth.h | 156 +++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 6 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 boot/bootmeth-uclass.c create mode 100644 include/bootmeth.h diff --git a/MAINTAINERS b/MAINTAINERS index d800a3b7acb..be11e3c2f2a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -636,10 +636,12 @@ F: tools/binman/ BOOTDEVICE M: Simon Glass S: Maintained +F: boot/bootmeth*.c F: boot/bootdev*.c F: boot/bootstd.c F: include/bootdev*.h F: include/bootflow.h +F: include/bootmeth.h F: include/bootstd.h BTRFS diff --git a/boot/Makefile b/boot/Makefile index 35abfd37654..54ded9541e0 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_ANDROID_AB) += android_ab.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootdev-uclass.o +obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootmeth-uclass.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootstd-uclass.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c new file mode 100644 index 00000000000..5df5fb55c31 --- /dev/null +++ b/boot/bootmeth-uclass.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter) +{ + const struct bootmeth_ops *ops = bootmeth_get_ops(dev); + + if (!ops->check) + return 0; + + return ops->check(dev, iter); +} + +int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow) +{ + const struct bootmeth_ops *ops = bootmeth_get_ops(dev); + + if (!ops->read_bootflow) + return -ENOSYS; + + return ops->read_bootflow(dev, bflow); +} + +int bootmeth_boot(struct udevice *dev, struct bootflow *bflow) +{ + const struct bootmeth_ops *ops = bootmeth_get_ops(dev); + + if (!ops->boot) + return -ENOSYS; + + return ops->boot(dev, bflow); +} + +int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow, + const char *file_path, ulong addr, ulong *sizep) +{ + const struct bootmeth_ops *ops = bootmeth_get_ops(dev); + + if (!ops->read_file) + return -ENOSYS; + + return ops->read_file(dev, bflow, file_path, addr, sizep); +} + +UCLASS_DRIVER(bootmeth) = { + .id = UCLASS_BOOTMETH, + .name = "bootmeth", + .flags = DM_UC_FLAG_SEQ_ALIAS, + .per_device_plat_auto = sizeof(struct bootmeth_uc_plat), +}; diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index 04823e5ba03..f812fbd0ae8 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -102,8 +102,10 @@ static int bootstd_probe(struct udevice *dev) /* 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; + struct driver *drv = ll_entry_start(struct driver, driver); + const int n_ents = ll_entry_count(struct driver, driver); + struct udevice *dev, *bootstd; + int i, ret; /* These are not needed before relocation */ if (!(gd->flags & GD_FLG_RELOC)) @@ -118,6 +120,29 @@ int dm_scan_other(bool pre_reloc_only) return log_msg_ret("bootstd", ret); } + /* If there are no bootmeth devices, create them */ + uclass_find_first_device(UCLASS_BOOTMETH, &dev); + if (dev) + return 0; + + for (i = 0; i < n_ents; i++, drv++) { + /* + * Disable EFI Manager for now as no one uses it so it is + * confusing + */ + if (drv->id == UCLASS_BOOTMETH && + strcmp("efi_mgr_bootmeth", drv->name)) { + const char *name = drv->name; + + if (!strncmp("bootmeth_", name, 9)) + name += 9; + ret = device_bind(bootstd, drv, name, 0, ofnode_null(), + &dev); if (ret) + + return log_msg_ret("meth", ret); + } + } + return 0; } diff --git a/include/bootmeth.h b/include/bootmeth.h new file mode 100644 index 00000000000..645fdc93add --- /dev/null +++ b/include/bootmeth.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 Google LLC + * Written by Simon Glass + */ + +#ifndef __bootmeth_h +#define __bootmeth_h + +struct bootflow; +struct bootflow_iter; +struct udevice; + +/** + * struct bootmeth_uc_plat - information the uclass keeps about each bootmeth + * + * @desc: A long description of the bootmeth + */ +struct bootmeth_uc_plat { + const char *desc; +}; + +/** struct bootmeth_ops - Operations for boot methods */ +struct bootmeth_ops { + /** + * check_supported() - check if a bootmeth supports this bootflow + * + * This is optional. If not provided, the bootdev is assumed to be + * supported + * + * The bootmeth can check the bootdev (e.g. to make sure it is a + * network device) or the partition information. The following fields + * in @iter are available: + * + * name, dev, state, part + * max_part may be set if part != 0 (i.e. there is a valid partition + * table). Otherwise max_part is 0 + * method is available but is the same as @dev + * the partition has not yet been read, nor has the filesystem been + * checked + * + * It may update only the flags in @iter + * + * @dev: Bootmethod device to check against + * @iter: On entry, provides bootdev, hwpart, part + * @return 0 if OK, -ENOTSUPP if this bootdev is not supported + */ + int (*check)(struct udevice *dev, struct bootflow_iter *iter); + + /** + * read_bootflow() - read a bootflow for a device + * + * @dev: Bootmethod device to use + * @bflow: On entry, provides dev, hwpart, part and method. + * Returns updated bootflow if found + * @return 0 if OK, -ve on error + */ + int (*read_bootflow)(struct udevice *dev, struct bootflow *bflow); + + /** + * read_file() - read a file needed for a bootflow + * + * Read a file from the same place as the bootflow came from + * + * @dev: Bootmethod device to use + * @bflow: Bootflow providing info on where to read from + * @file_path: Path to file (may be absolute or relative) + * @addr: Address to load file + * @sizep: On entry provides the maximum permitted size; on exit + * returns the size of the file + * @return 0 if OK, -ENOSPC if the file is too large for @sizep, other + * -ve value if something else goes wrong + */ + int (*read_file)(struct udevice *dev, struct bootflow *bflow, + const char *file_path, ulong addr, ulong *sizep); + + /** + * boot() - boot a bootflow + * + * @dev: Bootmethod device to boot + * @bflow: Bootflow to boot + * @return does not return on success, since it should boot the + * Operating Systemn. Returns -EFAULT if that fails, -ENOTSUPP if + * trying method resulted in finding out that is not actually + * supported for this boot and should not be tried again unless + * something changes, other -ve on other error + */ + int (*boot)(struct udevice *dev, struct bootflow *bflow); +}; + +#define bootmeth_get_ops(dev) ((struct bootmeth_ops *)(dev)->driver->ops) + +/** + * bootmeth_check() - check if a bootmeth supports this bootflow + * + * This is optional. If not provided, the bootdev is assumed to be + * supported + * + * The bootmeth can check the bootdev (e.g. to make sure it is a + * network device) or the partition information. The following fields + * in @iter are available: + * + * name, dev, state, part + * max_part may be set if part != 0 (i.e. there is a valid partition + * table). Otherwise max_part is 0 + * method is available but is the same as @dev + * the partition has not yet been read, nor has the filesystem been + * checked + * + * It may update only the flags in @iter + * + * @dev: Bootmethod device to check against + * @iter: On entry, provides bootdev, hwpart, part + * @return 0 if OK, -ENOTSUPP if this bootdev is not supported + */ +int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter); + +/** + * bootmeth_read_bootflow() - set up a bootflow for a device + * + * @dev: Bootmethod device to check + * @bflow: On entry, provides dev, hwpart, part and method. + * Returns updated bootflow if found + * @return 0 if OK, -ve on error + */ +int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow); + +/** + * bootmeth_read_file() - read a file needed for a bootflow + * + * Read a file from the same place as the bootflow came from + * + * @dev: Bootmethod device to use + * @bflow: Bootflow providing info on where to read from + * @file_path: Path to file (may be absolute or relative) + * @addr: Address to load file + * @sizep: On entry provides the maximum permitted size; on exit + * returns the size of the file + * @return 0 if OK, -ENOSPC if the file is too large for @sizep, other + * -ve value if something else goes wrong + */ +int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow, + const char *file_path, ulong addr, ulong *sizep); + +/** + * bootmeth_boot() - boot a bootflow + * + * @dev: Bootmethod device to boot + * @bflow: Bootflow to boot + * @return does not return on success, since it should boot the + * Operating Systemn. Returns -EFAULT if that fails, other -ve on + * other error + */ +int bootmeth_boot(struct udevice *dev, struct bootflow *bflow); + +#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 03912cb0db8..1f977672a37 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -39,6 +39,7 @@ enum uclass_id { UCLASS_BLK, /* Block device */ UCLASS_BOOTCOUNT, /* Bootcount backing store */ UCLASS_BOOTDEV, /* Boot device for locating an OS to boot */ + UCLASS_BOOTMETH, /* Bootmethod for booting an OS */ UCLASS_BOOTSTD, /* Standard boot driver */ UCLASS_BUTTON, /* Button */ UCLASS_CACHE, /* Cache controller */ -- 2.33.0.1079.g6e70778dc9-goog