diff options
-rw-r--r-- | cmd/efidebug.c | 4 | ||||
-rw-r--r-- | cmd/virtio.c | 21 | ||||
-rw-r--r-- | common/usb_storage.c | 4 | ||||
-rw-r--r-- | doc/board/emulation/qemu-riscv.rst | 10 | ||||
-rw-r--r-- | doc/develop/distro.rst | 3 | ||||
-rw-r--r-- | doc/develop/driver-model/serial-howto.rst | 153 | ||||
-rw-r--r-- | doc/usage/cmd/bootefi.rst | 9 | ||||
-rw-r--r-- | drivers/ata/dwc_ahsata.c | 5 | ||||
-rw-r--r-- | drivers/ata/fsl_sata.c | 11 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 5 | ||||
-rw-r--r-- | drivers/ata/sata_sil.c | 12 | ||||
-rw-r--r-- | drivers/block/ide.c | 4 | ||||
-rw-r--r-- | drivers/core/Makefile | 2 | ||||
-rw-r--r-- | drivers/core/root.c | 2 | ||||
-rw-r--r-- | drivers/core/tag.c | 139 | ||||
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 12 | ||||
-rw-r--r-- | drivers/nvme/nvme.c | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 5 | ||||
-rw-r--r-- | include/asm-generic/global_data.h | 4 | ||||
-rw-r--r-- | include/dm/tag.h | 110 | ||||
-rw-r--r-- | lib/efi_loader/Kconfig | 10 | ||||
-rw-r--r-- | lib/efi_loader/efi_capsule.c | 65 |
22 files changed, 552 insertions, 42 deletions
diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 3cc6f2bfcca..df928ce71dc 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -84,6 +84,7 @@ static int do_efi_capsule_update(struct cmd_tbl *cmdtp, int flag, return CMD_RET_SUCCESS; } +#ifdef CONFIG_EFI_CAPSULE_ON_DISK static int do_efi_capsule_on_disk_update(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { @@ -93,6 +94,7 @@ static int do_efi_capsule_on_disk_update(struct cmd_tbl *cmdtp, int flag, return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE; } +#endif /** * do_efi_capsule_show() - show capsule information @@ -303,8 +305,10 @@ static struct cmd_tbl cmd_efidebug_capsule_sub[] = { U_BOOT_CMD_MKENT(esrt, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_esrt, "", ""), #endif +#ifdef CONFIG_EFI_CAPSULE_ON_DISK U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update, "", ""), +#endif U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res, "", ""), }; diff --git a/cmd/virtio.c b/cmd/virtio.c index 3dace5344f7..ea3ed2e631e 100644 --- a/cmd/virtio.c +++ b/cmd/virtio.c @@ -17,8 +17,25 @@ static int do_virtio(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { if (argc == 2 && !strcmp(argv[1], "scan")) { - /* make sure all virtio devices are enumerated */ - virtio_init(); + /* + * make sure all virtio devices are enumerated. + * Do the same as virtio_init(), but also call + * device_probe() for children (i.e. virtio devices) + */ + struct udevice *bus, *child; + int ret; + + ret = uclass_first_device(UCLASS_VIRTIO, &bus); + if (ret) + return CMD_RET_FAILURE; + + while (bus) { + device_foreach_child_probe(child, bus) + ; + ret = uclass_next_device(&bus); + if (ret) + break; + } return CMD_RET_SUCCESS; } diff --git a/common/usb_storage.c b/common/usb_storage.c index c9e2d7343ce..291728f37e0 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -239,6 +239,10 @@ static int usb_stor_probe_device(struct usb_device *udev) if (ret) return ret; } + + ret = blk_probe_or_unbind(dev); + if (ret) + return ret; } #else /* We don't have space to even probe if we hit the maximum */ diff --git a/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index ae998810c87..782f37251c3 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -132,3 +132,13 @@ An attached disk can be emulated in RISC-V virt machine by adding:: -device ide-hd,drive=mydisk,bus=ahci.0 You will have to run 'scsi scan' to use it. + +Debug UART +---------- + +The following settings provide a debug UART for the virt machine:: + + CONFIG_DEBUG_UART=y + CONFIG_DEBUG_UART_NS16550=y + CONFIG_DEBUG_UART_BASE=0x10000000 + CONFIG_DEBUG_UART_CLOCK=3686400 diff --git a/doc/develop/distro.rst b/doc/develop/distro.rst index c522be69349..0113a3d4ec4 100644 --- a/doc/develop/distro.rst +++ b/doc/develop/distro.rst @@ -295,7 +295,8 @@ Each entry in the macro defines a single boot device (e.g. a specific eMMC device or SD card) or type of boot device (e.g. USB disk). The parameters to the func macro (passed in by the internal implementation of the header) are: -- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE, VIRTIO). +- Upper-case disk type (DHCP, HOST, IDE, MMC, NVME, PXE, SATA, SCSI, UBIFS, USB, + VIRTIO). - Lower-case disk type (same options as above). - ID of the specific disk (MMC only) or ignored for other types. diff --git a/doc/develop/driver-model/serial-howto.rst b/doc/develop/driver-model/serial-howto.rst index 1469131124b..8af79a90f46 100644 --- a/doc/develop/driver-model/serial-howto.rst +++ b/doc/develop/driver-model/serial-howto.rst @@ -34,7 +34,7 @@ In terms of patches a conversion series typically has these patches: - convert at least one existing board to use driver model serial - (if no boards remain that don't use driver model) remove the old code -This may be a good time to move your board to use device tree also. Mostly +This may be a good time to move your board to use the device tree too. Mostly this involves these steps: - define CONFIG_OF_CONTROL and CONFIG_OF_SEPARATE @@ -44,3 +44,154 @@ this involves these steps: - build and get u-boot-dtb.bin so you can test it - Your drivers can now use device tree - For device tree in SPL, define CONFIG_SPL_OF_CONTROL + + +Converting boards to CONFIG_DM_SERIAL +------------------------------------- + +If your SoC has a serial driver that uses driver model (has U_BOOT_DRIVER() in +it), then you may still find that your board has not been converted. To convert +your board, enable the option and see if you can get it working. + +Firstly you will have a lot more success if you have a method of debugging your +board, such as a JTAG connection. Failing that the debug UART is useful, +although since you are trying to get the UART driver running, it will interfere +with your efforts eventually. + +Secondly, while the UART is a relatively simple peripheral, it may need quite a +few pieces to be up and running before it will work, such as the correct pin +muxing, clocks, power domains and possibly even GPIOs, if an external +transceiver is used. Look at other boards that use the same SoC, for clues as to +what is needed. + +Thirdly, when added tags, put them in a xxx-u-boot.dtsi file, where xxx is your +board name, or SoC name. There may already be a file for your SoC which contains +what you need. U-Boot automatically includes these files: see :ref:`dttweaks`. + +Here are some things you might need to consider: + +1. The serial driver itself needs to be present before relocation, so that the + U-Boot banner appears. Make sure it has a u-boot,pre-reloc tag in the device + tree, so that the serial driver is bound when U-Boot starts. + + For example, on iMX8:: + + lpuart3: serial@5a090000 { + compatible = "fsl,imx8qm-lpuart"; + ... + }; + + put this in your xxx-u-boot.dtsi file:: + + &lpuart3 { + u-boot,dm-pre-proper; + }; + +2. If your serial port requires a particular pinmux configuration, you may need + a pinctrl driver. This needs to have a u-boot,pre-reloc tag also. Take care + that any subnodes have the same tag, if they are needed to make the correct + pinctrl available. + + For example, on RK3288, the UART2 uses uart2_xfer:: + + uart2: serial@ff690000 { + ... + pinctrl-0 = <&uart2_xfer>; + }; + + which is defined as follows:: + + pinctrl: pinctrl { + compatible = "rockchip,rk3228-pinctrl"; + + uart2: uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = <1 RK_PC2 RK_FUNC_2 &pcfg_pull_up>, + <1 RK_PC3 RK_FUNC_2 &pcfg_pull_none>; + }; + ... + }; + + This means you must make the uart2-xfer node available as well as all its + parents, so put this in your xxx-u-boot.dtsi file:: + + &pinctrl { + u-boot,dm-pre-reloc; + }; + + &uart2 { + u-boot,dm-pre-reloc; + }; + + &uart2_xfer { + u-boot,dm-pre-reloc; + }; + +3. The same applies to power domains. For example, if a particular power domain + must be enabled for the serial port to work, you need to ensure it is + available before relocation: + + For example, on iMX8, put this in your xxx-u-boot.dtsi file:: + + &pd_dma { + u-boot,dm-pre-proper; + }; + + &pd_dma_lpuart3 { + u-boot,dm-pre-proper; + }; + +4. The same applies to clocks, in the same way. Make sure that when your driver + requests a clock, typically with clk_get_by_index(), it is available. + + +Generally a failure to find a required device will cause an error which you can +catch, if you have the debug UART working. U-Boot outputs serial data to the +debug UART until the point where the real serial driver takes over. This point +is marked by gd->flags having the GD_FLG_SERIAL_READY flag set. This change +happens in serial_init() in serial-uclass.c so until that point the debug UART +is used. You can see the relevant code in putc() +, for example:: + + /* if we don't have a console yet, use the debug UART */ + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { + printch(c); + return; + } + ... carries on to use the console / serial driver + +Note that in device_probe() the call to pinctrl_select_state() silently fails +if the pinctrl driver fails. You can add a temporary check there if needed. + +Why do we have all these tags? The problem is that before relocation we don't +want to bind all the drivers since memory is limited and the CPU may be running +at a slow speed. So many boards will fail to boot without this optimisation, or +may take a long time to start up (e.g. hundreds of milliseconds). The tags tell +U-Boot which drivers to bind. + +The good news is that this problem is normally solved by the SoC, so that any +boards that use it will work as normal. But in some cases there are multiple +UARTs or multiple pinmux options, which means that each board may need to do +some customisation. + +Serial in SPL +------------- + +A similar process is needed in SPL, but in this case the u-boot,dm-spl or +u-boot,dm-tpl tags are used. Add these in the same way as above, to ensure that +the SPL device tree contains the required nodes (see spl/u-boot-spl.dtb for +what it actually contains). + +Removing old code +----------------- + +In some cases there may be initialisation code that is no-longer needed when +driver model is used, such as setting up the pin muxing, or enabling a clock. +Be sure to remove this. + +Example patch +------------- + +See this serial_patch_ for iMX7. + +.. _serial_patch: https://patchwork.ozlabs.org/project/uboot/patch/20220314232406.1945308-1-festevam@gmail.com/ diff --git a/doc/usage/cmd/bootefi.rst b/doc/usage/cmd/bootefi.rst index 282f22aac96..31279fc0cbf 100644 --- a/doc/usage/cmd/bootefi.rst +++ b/doc/usage/cmd/bootefi.rst @@ -24,7 +24,7 @@ The *bootefi* command is used to launch a UEFI binary which can be either of * UEFI run-time services driver An operating system requires a hardware description which can either be -presented as ACPI table (CONFIG\_GENERATE\_ACPI\_TABLE=y) or as device-tree +presented as ACPI table (CONFIG\_GENERATE\_ACPI\_TABLE=y) or as device-tree. The load address of the device-tree may be provided as parameter *fdt\_addr*. If this address is not specified, the bootefi command will try to fall back in sequence to: @@ -123,6 +123,7 @@ Configuration ------------- To use the *bootefi* command you must specify CONFIG\_CMD\_BOOTEFI=y. +The *bootefi bootmgr* sub-command requries CMD\_BOOTEFI\_BOOTMGR=y. The *bootefi hello* sub-command requries CMD\_BOOTEFI\_HELLO=y. The *bootefi selftest* sub-command depends on CMD\_BOOTEFI\_SELFTEST=y. @@ -130,6 +131,6 @@ See also -------- * *bootm* for launching UEFI binaries packed in FIT images -* *booti*, *bootm*, *bootz* for launching a Linux kernel without using the - UEFI sub-system -* *efidebug* for setting UEFI boot variables +* :doc:`booti<booti>`, *bootm*, *bootz* for launching a Linux kernel without + using the UEFI sub-system +* *efidebug* for setting UEFI boot variables and boot options diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 6d42548087b..d9fd850c6fa 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -1026,6 +1026,11 @@ int dwc_ahsata_scan(struct udevice *dev) return ret; } + ret = blk_probe_or_unbind(dev); + if (ret < 0) + /* TODO: undo create */ + return ret; + return 0; } diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c index e44db0a3745..d1bab931895 100644 --- a/drivers/ata/fsl_sata.c +++ b/drivers/ata/fsl_sata.c @@ -982,6 +982,17 @@ static int fsl_ata_probe(struct udevice *dev) failed_number++; continue; } + + ret = device_probe(dev); + if (ret < 0) { + debug("Probing %s failed (%d)\n", dev->name, ret); + ret = fsl_unbind_device(blk); + if (ret) + return ret; + + failed_number++; + continue; + } } if (failed_number == nr_ports) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 003222d47be..a187796dfcd 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1099,6 +1099,11 @@ static int sata_mv_probe(struct udevice *dev) continue; } + ret = blk_probe_or_unbind(dev); + if (ret < 0) + /* TODO: undo create */ + continue; + /* If we got here, the current SATA port was probed * successfully, so set the probe status to successful. */ diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index a4f0dae4bbd..b213ebac2fb 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -753,6 +753,18 @@ static int sil_pci_probe(struct udevice *dev) failed_number++; continue; } + + ret = device_probe(dev); + if (ret < 0) { + debug("Probing %s failed (%d)\n", dev->name, ret); + ret = sil_unbind_device(blk); + device_unbind(dev); + if (ret) + return ret; + + failed_number++; + continue; + } } if (failed_number == sata_info.maxport) diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 63c4cfdc1c2..e8518ff3a11 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1123,6 +1123,10 @@ static int ide_probe(struct udevice *udev) blksz, size, &blk_dev); if (ret) return ret; + + ret = blk_probe_or_unbind(blk_dev); + if (ret) + return ret; } } diff --git a/drivers/core/Makefile b/drivers/core/Makefile index 5edd4e41357..3742e757452 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -2,7 +2,7 @@ # # Copyright (c) 2013 Google, Inc -obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o +obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o tag.o obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o diff --git a/drivers/core/root.c b/drivers/core/root.c index 8efb4256b27..86b3884fc67 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -199,6 +199,8 @@ int dm_init(bool of_live) return ret; } + INIT_LIST_HEAD((struct list_head *)&gd->dmtag_list); + return 0; } diff --git a/drivers/core/tag.c b/drivers/core/tag.c new file mode 100644 index 00000000000..6829bcd8806 --- /dev/null +++ b/drivers/core/tag.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include <malloc.h> +#include <asm/global_data.h> +#include <dm/tag.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/types.h> + +struct udevice; + +DECLARE_GLOBAL_DATA_PTR; + +int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr) +{ + struct dmtag_node *node; + + if (!dev || tag >= DM_TAG_COUNT) + return -EINVAL; + + list_for_each_entry(node, &gd->dmtag_list, sibling) { + if (node->dev == dev && node->tag == tag) + return -EEXIST; + } + + node = calloc(sizeof(*node), 1); + if (!node) + return -ENOSPC; + + node->dev = dev; + node->tag = tag; + node->ptr = ptr; + list_add_tail(&node->sibling, (struct list_head *)&gd->dmtag_list); + + return 0; +} + +int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val) +{ + struct dmtag_node *node; + + if (!dev || tag >= DM_TAG_COUNT) + return -EINVAL; + + list_for_each_entry(node, &gd->dmtag_list, sibling) { + if (node->dev == dev && node->tag == tag) + return -EEXIST; + } + + node = calloc(sizeof(*node), 1); + if (!node) + return -ENOSPC; + + node->dev = dev; + node->tag = tag; + node->val = val; + list_add_tail(&node->sibling, (struct list_head *)&gd->dmtag_list); + + return 0; +} + +int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp) +{ + struct dmtag_node *node; + + if (!dev || tag >= DM_TAG_COUNT) + return -EINVAL; + + list_for_each_entry(node, &gd->dmtag_list, sibling) { + if (node->dev == dev && node->tag == tag) { + *ptrp = node->ptr; + return 0; + } + } + + return -ENOENT; +} + +int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp) +{ + struct dmtag_node *node; + + if (!dev || tag >= DM_TAG_COUNT) + return -EINVAL; + + list_for_each_entry(node, &gd->dmtag_list, sibling) { + if (node->dev == dev && node->tag == tag) { + *valp = node->val; + return 0; + } + } + + return -ENOENT; +} + +int dev_tag_del(struct udevice *dev, enum dm_tag_t tag) +{ + struct dmtag_node *node, *tmp; + + if (!dev || tag >= DM_TAG_COUNT) + return -EINVAL; + + list_for_each_entry_safe(node, tmp, &gd->dmtag_list, sibling) { + if (node->dev == dev && node->tag == tag) { + list_del(&node->sibling); + free(node); + + return 0; + } + } + + return -ENOENT; +} + +int dev_tag_del_all(struct udevice *dev) +{ + struct dmtag_node *node, *tmp; + bool found = false; + + if (!dev) + return -EINVAL; + + list_for_each_entry_safe(node, tmp, &gd->dmtag_list, sibling) { + if (node->dev == dev) { + list_del(&node->sibling); + free(node); + found = true; + } + } + + if (found) + return 0; + + return -ENOENT; +} diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index b80e838066c..57da788ad80 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -467,6 +467,18 @@ static int mmc_blk_probe(struct udevice *dev) return ret; } + ret = device_probe(dev); + if (ret) { + debug("Probing %s failed (err=%d)\n", dev->name, ret); + + if (CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)) + mmc_deinit(mmc); + + return ret; + } + return 0; } diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 1d56517e996..a305305885e 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -884,6 +884,10 @@ int nvme_init(struct udevice *udev) -1, 512, 0, &ns_udev); if (ret) goto free_id; + + ret = blk_probe_or_unbind(ns_udev); + if (ret) + goto free_id; } free(id); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index d7b33010e46..78d729d809d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -595,6 +595,11 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose) ata_swap_buf_le16((u16 *)&bdesc->revision, sizeof(bd.revision) / 2); } + ret = blk_probe_or_unbind(bdev); + if (ret < 0) + /* TODO: undo create */ + return ret; + if (verbose) { printf(" Device %d: ", bdesc->devnum); dev_print(bdesc); diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index beb8bb90a64..805a6fd6797 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -474,6 +474,10 @@ struct global_data { */ struct event_state event_state; #endif + /** + * @dmtag_list: List of DM tags + */ + struct list_head dmtag_list; }; #ifndef DO_DEPS_ONLY static_assert(sizeof(struct global_data) == GD_SIZE); diff --git a/include/dm/tag.h b/include/dm/tag.h new file mode 100644 index 00000000000..54fc31eb153 --- /dev/null +++ b/include/dm/tag.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Linaro Limited + * Author: AKASHI Takahiro + */ + +#ifndef _DM_TAG_H +#define _DM_TAG_H + +#include <linux/list.h> +#include <linux/types.h> + +struct udevice; + +enum dm_tag_t { + /* EFI_LOADER */ + DM_TAG_EFI = 0, + + DM_TAG_COUNT, +}; + +/** + * dmtag_node + * + * @sibling: List of dm-tag nodes + * @dev: Associated udevice + * @tag: Tag type + * @ptr: Pointer as a value + * @val: Value + */ +struct dmtag_node { + struct list_head sibling; + struct udevice *dev; + enum dm_tag_t tag; + union { + void *ptr; + ulong val; + }; +}; + +/** + * dev_tag_set_ptr() - set a tag's value as a pointer + * @dev: Device to operate + * @tag: Tag type + * @ptr: Pointer to set + * + * Set the value, @ptr, as of @tag associated with the device, @dev + * + * Return: 0 on success, -ve on error + */ +int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr); + +/** + * dev_tag_set_val() set a tag's value as an integer + * @dev: Device to operate + * @tag: Tag type + * @val: Value to set + * + * Set the value, @val, as of @tag associated with the device, @dev + * + * Return: on success, -ve on error + */ +int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val); + +/** + * dev_tag_get_ptr() - get a tag's value as a pointer + * @dev: Device to operate + * @tag: Tag type + * @ptrp: Pointer to tag's value (pointer) + * + * Get a tag's value as a pointer + * + * Return: on success, -ve on error + */ +int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp); + +/** + * dev_tag_get_val() - get a tag's value as an integer + * @dev: Device to operate + * @tag: Tag type + * @valp: Pointer to tag's value (ulong) + * + * Get a tag's value as an integer + * + * Return: 0 on success, -ve on error + */ +int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp); + +/** + * dev_tag_del() - delete a tag + * @dev: Device to operate + * @tag: Tag type + * + * Delete a tag of @tag associated with the device, @dev + * + * Return: 0 on success, -ve on error + */ +int dev_tag_del(struct udevice *dev, enum dm_tag_t tag); + +/** + * dev_tag_del_all() - delete all tags + * @dev: Device to operate + * + * Delete all the tags associated with the device, @dev + * + * Return: 0 on success, -ve on error + */ +int dev_tag_del_all(struct udevice *dev); + +#endif /* _DM_TAG_H */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 28657f50c96..559b95a599b 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -62,11 +62,18 @@ config EFI_MM_COMM_TEE variable related operations to that. The application will verify, authenticate and store the variables on an RPMB. +config EFI_VARIABLE_NO_STORE + bool "Don't persist non-volatile UEFI variables" + help + If you choose this option, non-volatile variables cannot be persisted. + You could still provide non-volatile variables via + EFI_VARIABLES_PRESEED. + endchoice config EFI_VARIABLES_PRESEED bool "Initial values for UEFI variables" - depends on EFI_VARIABLE_FILE_STORE + depends on !EFI_MM_COMM_TEE help Include a file with the initial values for non-volatile UEFI variables into the U-Boot binary. If this configuration option is set, changes @@ -129,6 +136,7 @@ config EFI_RUNTIME_UPDATE_CAPSULE config EFI_CAPSULE_ON_DISK bool "Enable capsule-on-disk support" + depends on SYSRESET select EFI_HAVE_CAPSULE_SUPPORT help Select this option if you want to use capsule-on-disk feature, diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f00440163d4..a107f285ddf 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -18,6 +18,7 @@ #include <malloc.h> #include <mapmem.h> #include <sort.h> +#include <sysreset.h> #include <asm/global_data.h> #include <crypto/pkcs7.h> @@ -619,6 +620,36 @@ out: return EFI_EXIT(ret); } +/** + * efi_load_capsule_drivers - initialize capsule drivers + * + * Generic FMP drivers backed by DFU + * + * Return: status code + */ +efi_status_t __weak efi_load_capsule_drivers(void) +{ + __maybe_unused efi_handle_t handle; + efi_status_t ret = EFI_SUCCESS; + + if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) { + handle = NULL; + ret = EFI_CALL(efi_install_multiple_protocol_interfaces( + &handle, &efi_guid_firmware_management_protocol, + &efi_fmp_fit, NULL)); + } + + if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) { + handle = NULL; + ret = EFI_CALL(efi_install_multiple_protocol_interfaces( + &handle, + &efi_guid_firmware_management_protocol, + &efi_fmp_raw, NULL)); + } + + return ret; +} + #ifdef CONFIG_EFI_CAPSULE_ON_DISK /** * get_dp_device - retrieve a device path from boot variable @@ -1015,36 +1046,6 @@ static void efi_capsule_scan_done(void) } /** - * efi_load_capsule_drivers - initialize capsule drivers - * - * Generic FMP drivers backed by DFU - * - * Return: status code - */ -efi_status_t __weak efi_load_capsule_drivers(void) -{ - __maybe_unused efi_handle_t handle; - efi_status_t ret = EFI_SUCCESS; - - if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) { - handle = NULL; - ret = EFI_CALL(efi_install_multiple_protocol_interfaces( - &handle, &efi_guid_firmware_management_protocol, - &efi_fmp_fit, NULL)); - } - - if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) { - handle = NULL; - ret = EFI_CALL(efi_install_multiple_protocol_interfaces( - &handle, - &efi_guid_firmware_management_protocol, - &efi_fmp_raw, NULL)); - } - - return ret; -} - -/** * check_run_capsules() - check whether capsule update should run * * The spec says OsIndications must be set in order to run the capsule update @@ -1157,9 +1158,9 @@ efi_status_t efi_launch_capsules(void) * UEFI spec requires to reset system after complete processing capsule * update on the storage. */ - log_info("Reboot after firmware update"); + log_info("Reboot after firmware update.\n"); /* Cold reset is required for loading the new firmware. */ - do_reset(NULL, 0, 0, NULL); + sysreset_walk_halt(SYSRESET_COLD); hang(); /* not reach here */ |