aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-04-10 11:21:39 -0400
committerTom Rini <trini@konsulko.com>2022-04-10 11:21:39 -0400
commit33ae8c5bebba0874fbc432914406e63fbc219080 (patch)
tree050e8c63351c2efd654930e59a6fd2fe031c52c2
parent5c7399ec90513bc0310801c9f852ea7697a91759 (diff)
parent6b7a6210fde96bb95c8168af4ebf4eb83401df9e (diff)
downloadu-boot-WIP/10Apr2022.zip
u-boot-WIP/10Apr2022.tar.gz
u-boot-WIP/10Apr2022.tar.bz2
Merge tag 'efi-2022-07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/10Apr2022
Pull request for efi-2022-07-rc1 Documentation: * Describe how enable DM_SERIAL for a board UEFI * Preparatory patches for better integration of DM and UEFI * Use sysreset after capsule updates instead of do_reset * Allow to disable persisting non-volatile variables
-rw-r--r--cmd/efidebug.c4
-rw-r--r--cmd/virtio.c21
-rw-r--r--common/usb_storage.c4
-rw-r--r--doc/board/emulation/qemu-riscv.rst10
-rw-r--r--doc/develop/distro.rst3
-rw-r--r--doc/develop/driver-model/serial-howto.rst153
-rw-r--r--doc/usage/cmd/bootefi.rst9
-rw-r--r--drivers/ata/dwc_ahsata.c5
-rw-r--r--drivers/ata/fsl_sata.c11
-rw-r--r--drivers/ata/sata_mv.c5
-rw-r--r--drivers/ata/sata_sil.c12
-rw-r--r--drivers/block/ide.c4
-rw-r--r--drivers/core/Makefile2
-rw-r--r--drivers/core/root.c2
-rw-r--r--drivers/core/tag.c139
-rw-r--r--drivers/mmc/mmc-uclass.c12
-rw-r--r--drivers/nvme/nvme.c4
-rw-r--r--drivers/scsi/scsi.c5
-rw-r--r--include/asm-generic/global_data.h4
-rw-r--r--include/dm/tag.h110
-rw-r--r--lib/efi_loader/Kconfig10
-rw-r--r--lib/efi_loader/efi_capsule.c65
22 files changed, 552 insertions, 42 deletions
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 3cc6f2b..df928ce 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 3dace53..ea3ed2e 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 c9e2d73..291728f 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 ae99881..782f372 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 c522be6..0113a3d 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 1469131..8af79a9 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 282f22a..31279fc 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 6d42548..d9fd850 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 e44db0a..d1bab93 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 003222d..a187796 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 a4f0dae..b213eba 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 63c4cfd..e8518ff 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 5edd4e4..3742e75 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 8efb425..86b3884 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 0000000..6829bcd
--- /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 b80e838..57da788 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 1d56517..a305305 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 d7b3301..78d729d 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 beb8bb9..805a6fd 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 0000000..54fc31e
--- /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 28657f5..559b95a 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 f004401..a107f28 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 */