[PATCH v5 00/12] efi_loader: more tightly integrate UEFI disks to driver model

With this patch set[1] applied, UEFI subsystem maintains a list of its disk objects dynamically at runtime based on block device's probing. (See "issues" and "prerequisite" below.)
[1] https://github.com/t-akashi/u-boot/tree/efi/dm_disk
For instance, => dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ ] ahci_pci | |-- ahci_pci scsi 0 [ ] ahci_scsi | | `-- ahci_scsi usb 0 [ ] xhci_pci | `-- xhci_pci ... => efi devices Missing RNG device for EFI_RNG_PROTOCOL No EFI system partition Unable to find TPMv2 device Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) => scsi rescan ... => efi devices Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) 000000013eefb730 /VenHw(..)/Scsi(0,0) 000000013eefb840 /VenHw(..)/Scsi(0,0)/HD(1,GPT,ce86c5a7-b32a-488f-a346-88fe698e0edc,0x22,0x4c2a) 000000013eefbc80 /VenHw(..)/Scsi(0,0)/HD(2,GPT,aa80aab9-33e6-42b6-b5db-def2cb8d7844,0x5000,0x1a800) => usb start ... => efi devices Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) 000000013eefb730 /VenHw(..)/Scsi(0,0) 000000013eefb840 /VenHw(..)/Scsi(0,0)/HD(1,GPT,ce86c5a7-b32a-488f-a346-88fe698e0edc,0x22,0x4c2a) 000000013eefbc80 /VenHw(..)/Scsi(0,0)/HD(2,GPT,aa80aab9-33e6-42b6-b5db-def2cb8d7844,0x5000,0x1a800) 000000013ef01330 /VenHw(..)/UsbClass(0x0,0x0,0x9,0x0,0x3)/UsbClass(0x46f4,0x1,0x0,0x0,0x0) 000000013ef014b0 /VenHw(..)/UsbClass(0x0,0x0,0x9,0x0,0x3)/UsbClass(0x46f4,0x1,0x0,0x0,0x0)/HD(1,GPT,ce86c5a7-b32a-488f-a346-88fe698e0edc,0x22,0x4c2a) 000000013ef018f0 /VenHw(..)/UsbClass(0x0,0x0,0x9,0x0,0x3)/UsbClass(0x46f4,0x1,0x0,0x0,0x0)/HD(2,GPT,aa80aab9-33e6-42b6-b5db-def2cb8d7844,0x5000,0x1a800) => dm tree ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ + ] ahci_pci | |-- ahci_pci scsi 0 [ + ] ahci_scsi | | `-- ahci_scsi blk 2 [ + ] scsi_blk | | `-- ahci_scsi.id0lun0 partition 0 [ + ] blk_partition | | |-- ahci_scsi.id0lun0:1 partition 1 [ + ] blk_partition | | `-- ahci_scsi.id0lun0:2 usb 0 [ + ] xhci_pci | `-- xhci_pci usb_hub 0 [ + ] usb_hub | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | |-- usb_mass_storage blk 3 [ + ] usb_storage_blk | | `-- usb_mass_storage.lun0 partition 2 [ + ] blk_partition | | |-- usb_mass_storage.lun0:1 partition 3 [ + ] blk_partition | | `-- usb_mass_storage.lun0:2 ...
=> usb stop stopping USB.. => efi devices Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) 000000013eefb730 /VenHw(..)/Scsi(0,0) 000000013eefb840 /VenHw(..)/Scsi(0,0)/HD(1,GPT,ce86c5a7-b32a-488f-a346-88fe698e0edc,0x22,0x4c2a) 000000013eefbc80 /VenHw(..)/Scsi(0,0)/HD(2,GPT,aa80aab9-33e6-42b6-b5db-def2cb8d7844,0x5000,0x1a800)
Issues: ======= * For removal case, we may need more consideration since removing handles unconditionally may end up breaking integrity of handles (as some may still be held and referenced to by a UEFI app).
Prerequisite: ============= * my patch, "disk: don't compile in partition support for spl/tpl if not really necessary"[2]
[2] https://lists.denx.de/pipermail/u-boot/2022-April/481745.html
Patchs: ======= For easy understandings, patches may be categorized into separate groups of changes.
Patch#1-#3: DM: add a new feature (DM tag) Patch#4-#10: UEFI: dynamically create/remove efi_disk's for a raw disk and its partitions Patch#11-#12: UEFI: use udevice read/write interfaces
Change history: =============== v5 (Apr, 19, 2022) * modify patch#12 so that CONFIG_PARTITIONS can be treated as optional (patch#12)
v4 (Apr, 15, 2022) * rebased on pre-2022.07-rc1 * removed already-merged patches * added patch#1 (for better error code) * merged v3's patch#19 to patch#7 to make bisect work * split v3's patch#13 into patch#8(create) and patch#10(delete) * move a function prototype out of "#ifdef CONFIG_PARTITIONS" (patch#4) * move function prototypes out of "#ifdef CONFIG_PARTITIONS" (patch#11)
v3 (Mar 8, 2022) * rebased on 2022.04-rc3 * rebased on v2 of Simon's event patch (hence removed his patch from this patch set) * fix a spl-build error in mmc_blk_probe() (patch#3) * fix a build warning in fsl_ata_probe()/sil_pci_probe() (patch#5) * remove a problematic log message in efi_disk_probe() (patch#14)
v2 (Feb 10, 2022) * add/revise an error message if device_probe() fails (patch#3,#5) * fix a build error in sandbox_spl_defconfig (patch#8) * fix warnings in 'make htmldocs' (patch#8,#9,#18) * new commit: split efi_init_obj_list() (patch#14) * new commit: simplify efi_capsule pytest (patch#21)
v1 (Feb 2, 2022) * rebased on 2022.04-rc1 * drop patches that have already been merged * modify a tag-range check with "tag >= DM_TAG_COUNT" (patch#9) * move dmtag_list to GD (global data) (patch#9) * add function descriptions and a document about DM tag feature (patch#9,10) * add tests for DM tag support (patch#11) * change 'depends on EVENT' to 'select EVENT' for EFI_LOADER (patch#14) * migrate IF_TYPE_EFI to IF_TYPE_EFI_LOADER (patch#18)
RFCv2 (Dec 10, 2021) * rebased on 2022-rc3 * re-order and merge some related commits into ones * call device_probe() in MMC (not bind, but) probe hook (patch#5) * fix a wrong name of variable (patch#7) * add patch#9 * invoke device_probe() for virtio devices (patch#10) * add DM event notification (from Simon) (patch#11) * add DM tag support (patch#12) * move UCLASS_PARTITION driver under disk/ (patch#13) * create partition's dp using its parent's. This change is necessary in particular for 'efi_blk' efi_disk (patch#13) * modify the code so that we will use new features like tags and event notification (patch#13,15,16,20) * rename new functions from blk_read/write() to dev_read/write() (patch#17,18) * isolate changes in efi_driver from the rest (in efi_loader) (patch#19) * drop the previous patch#22 ("efi_selftest: block device: adjust dp for a test") due to the fix in patch#13
RFC (Nov 16, 2021) * initial RFC
AKASHI Takahiro (12): dm: tag: change ENOSPC to ENOMEM dm: tag: add some document test: dm: add tests for tag support dm: disk: add UCLASS_PARTITION dm: blk: add a device-probe hook for scanning disk partitions efi_loader: split efi_init_obj_list() into two stages efi_loader: disk: a helper function to create efi_disk objects from udevice efi_loader: disk: not create BLK device for BLK(IF_TYPE_EFI_LOADER) devices efi_loader: disk: a helper function to delete efi_disk objects efi_loader: disk: not delete BLK device for BLK(IF_TYPE_EFI_LOADER) devices dm: disk: add read/write interfaces with udevice efi_loader: disk: use udevice instead of blk_desc
common/board_r.c | 2 +- common/main.c | 7 +- disk/Makefile | 3 + disk/disk-uclass.c | 247 +++++++++++++++++++++ doc/develop/driver-model/design.rst | 20 ++ drivers/block/blk-uclass.c | 4 + drivers/core/tag.c | 4 +- include/dm/uclass-id.h | 1 + include/efi_loader.h | 6 +- include/part.h | 17 ++ lib/efi_driver/efi_block_device.c | 34 +-- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 321 +++++++++++++++++++++------- lib/efi_loader/efi_setup.c | 62 ++++-- test/dm/Makefile | 1 + test/dm/tag.c | 84 ++++++++ 16 files changed, 694 insertions(+), 122 deletions(-) create mode 100644 disk/disk-uclass.c create mode 100644 test/dm/tag.c

ENOMEM is a more common error code for memory starvation.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- drivers/core/tag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/core/tag.c b/drivers/core/tag.c index 6829bcd8806c..22999193a5a3 100644 --- a/drivers/core/tag.c +++ b/drivers/core/tag.c @@ -29,7 +29,7 @@ int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr)
node = calloc(sizeof(*node), 1); if (!node) - return -ENOSPC; + return -ENOMEM;
node->dev = dev; node->tag = tag; @@ -53,7 +53,7 @@ int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val)
node = calloc(sizeof(*node), 1); if (!node) - return -ENOSPC; + return -ENOMEM;
node->dev = dev; node->tag = tag;

Some basic stuff about tag support is explained under doc/devlop/driver-model.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- doc/develop/driver-model/design.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/doc/develop/driver-model/design.rst b/doc/develop/driver-model/design.rst index b0e6337030a1..3e88dc40e6fd 100644 --- a/doc/develop/driver-model/design.rst +++ b/doc/develop/driver-model/design.rst @@ -1042,6 +1042,26 @@ data structure might be worthwhile in some rare cases, once we understand what the bottlenecks are.
+Tag Support +----------- + +It is sometimes useful for a subsystem to associate its own private +data (or object) to a DM device, i.e. struct udevice, to support +additional features. + +Tag support in driver model will give us the ability to do so dynamically +instead of modifying "udevice" data structure. In the initial release, we +will support two type of attributes: +- a pointer with dm_tag_set_ptr(), and +- an unsigned long with dm_tag_set_val() + +For example, UEFI subsystem utilizes the feature to maintain efi_disk +objects depending on linked udevice's lifecycle. + +While the current implementation is quite simple, it will get evolved +as the feature is more extensively used in U-Boot subsystems. + + Changes since v1 ----------------

The new test covers all tag-related interfaces.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- test/dm/Makefile | 1 + test/dm/tag.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 test/dm/tag.c
diff --git a/test/dm/Makefile b/test/dm/Makefile index d46552fbf320..dc3177dbb7f4 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -102,6 +102,7 @@ obj-y += syscon.o obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o obj-$(CONFIG_SYSINFO) += sysinfo.o obj-$(CONFIG_SYSINFO_GPIO) += sysinfo-gpio.o +obj-$(CONFIG_UT_DM) += tag.o obj-$(CONFIG_TEE) += tee.o obj-$(CONFIG_TIMER) += timer.o obj-$(CONFIG_DM_USB) += usb.o diff --git a/test/dm/tag.c b/test/dm/tag.c new file mode 100644 index 000000000000..8289954e7c26 --- /dev/null +++ b/test/dm/tag.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DM tag test + * + * Copyright (c) 2021 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include <common.h> +#include <dm/tag.h> +#include <dm/test.h> /* DM_TEST() */ +#include <test/test.h> /* struct unit_test_state */ +#include <test/ut.h> /* assertions */ + +/* + * Test dm_tag_ptr() API + */ +static int dm_test_tag_ptr(struct unit_test_state *uts) +{ + ulong val; + void *ptr = NULL; + + ut_assertok(dev_tag_set_ptr(uts->root, DM_TAG_EFI, &val)); + + ut_assertok(dev_tag_get_ptr(uts->root, DM_TAG_EFI, &ptr)); + + ut_asserteq_ptr(&val, ptr); + + ut_assertok(dev_tag_del(uts->root, DM_TAG_EFI)); + + return 0; +} + +DM_TEST(dm_test_tag_ptr, 0); + +/* + * Test dm_tag_val() API + */ +static int dm_test_tag_val(struct unit_test_state *uts) +{ + ulong val1 = 0x12345678, val2 = 0; + + ut_assertok(dev_tag_set_val(uts->root, DM_TAG_EFI, val1)); + + ut_assertok(dev_tag_get_val(uts->root, DM_TAG_EFI, &val2)); + + ut_asserteq_64(val1, val2); + + ut_assertok(dev_tag_del(uts->root, DM_TAG_EFI)); + + return 0; +} + +DM_TEST(dm_test_tag_val, 0); + +/* + * Test against an invalid tag + */ +static int dm_test_tag_inval(struct unit_test_state *uts) +{ + ulong val; + + ut_asserteq(-EINVAL, dev_tag_set_ptr(uts->root, DM_TAG_COUNT, &val)); + + return 0; +} + +DM_TEST(dm_test_tag_inval, 0); + +/* + * Test dm_tag_del_all() AP: + */ +static int dm_test_tag_del_all(struct unit_test_state *uts) +{ + ulong val; + + ut_assertok(dev_tag_set_ptr(uts->root, DM_TAG_EFI, &val)); + + ut_assertok(dev_tag_del_all(uts->root)); + + return 0; +} + +DM_TEST(dm_test_tag_del_all, 0);

NOTE: probably we have to update config dependencies, in particular, SPL/TPL_PRINTF?
With this new function, UCLASS_PARTITION devices will be created as child nodes of UCLASS_BLK device.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- disk/Makefile | 3 + disk/disk-uclass.c | 153 +++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/part.h | 10 +++ 4 files changed, 167 insertions(+) create mode 100644 disk/disk-uclass.c
diff --git a/disk/Makefile b/disk/Makefile index 5ca10c55762b..ec148832b330 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -6,6 +6,9 @@ #ccflags-y += -DET_DEBUG -DDEBUG
obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += part.o +ifdef CONFIG_$(SPL_TPL_)BLK +obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += disk-uclass.o +endif obj-$(CONFIG_$(SPL_TPL_)MAC_PARTITION) += part_mac.o obj-$(CONFIG_$(SPL_TPL_)DOS_PARTITION) += part_dos.o obj-$(CONFIG_$(SPL_TPL_)ISO_PARTITION) += part_iso.o diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c new file mode 100644 index 000000000000..4918a2f72d1e --- /dev/null +++ b/disk/disk-uclass.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Software partition device (UCLASS_PARTITION) + * + * Copyright (c) 2021 Linaro Limited + * Author: AKASHI Takahiro + */ + +#define LOG_CATEGORY UCLASS_PARTITION + +#include <blk.h> +#include <dm.h> +#include <log.h> +#include <part.h> +#include <vsprintf.h> +#include <dm/device-internal.h> +#include <dm/lists.h> + +int part_create_block_devices(struct udevice *blk_dev) +{ + int part, count; + struct blk_desc *desc = dev_get_uclass_plat(blk_dev); + struct disk_partition info; + struct disk_part *part_data; + char devname[32]; + struct udevice *dev; + int ret; + + if (!CONFIG_IS_ENABLED(PARTITIONS) || + !CONFIG_IS_ENABLED(HAVE_BLOCK_DEVICE)) + return 0; + + if (device_get_uclass_id(blk_dev) != UCLASS_BLK) + return 0; + + /* Add devices for each partition */ + for (count = 0, part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { + if (part_get_info(desc, part, &info)) + continue; + snprintf(devname, sizeof(devname), "%s:%d", blk_dev->name, + part); + + ret = device_bind_driver(blk_dev, "blk_partition", + strdup(devname), &dev); + if (ret) + return ret; + + part_data = dev_get_uclass_plat(dev); + part_data->partnum = part; + part_data->gpt_part_info = info; + count++; + + ret = device_probe(dev); + if (ret) { + debug("Can't probe\n"); + count--; + device_unbind(dev); + + continue; + } + } + debug("%s: %d partitions found in %s\n", __func__, count, + blk_dev->name); + + return 0; +} + +static ulong blk_part_read(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, void *buffer) +{ + struct udevice *parent; + struct disk_part *part; + const struct blk_ops *ops; + + parent = dev_get_parent(dev); + ops = blk_get_ops(parent); + if (!ops->read) + return -ENOSYS; + + part = dev_get_uclass_plat(dev); + if (start >= part->gpt_part_info.size) + return 0; + + if ((start + blkcnt) > part->gpt_part_info.size) + blkcnt = part->gpt_part_info.size - start; + start += part->gpt_part_info.start; + + return ops->read(parent, start, blkcnt, buffer); +} + +static ulong blk_part_write(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, const void *buffer) +{ + struct udevice *parent; + struct disk_part *part; + const struct blk_ops *ops; + + parent = dev_get_parent(dev); + ops = blk_get_ops(parent); + if (!ops->write) + return -ENOSYS; + + part = dev_get_uclass_plat(dev); + if (start >= part->gpt_part_info.size) + return 0; + + if ((start + blkcnt) > part->gpt_part_info.size) + blkcnt = part->gpt_part_info.size - start; + start += part->gpt_part_info.start; + + return ops->write(parent, start, blkcnt, buffer); +} + +static ulong blk_part_erase(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt) +{ + struct udevice *parent; + struct disk_part *part; + const struct blk_ops *ops; + + parent = dev_get_parent(dev); + ops = blk_get_ops(parent); + if (!ops->erase) + return -ENOSYS; + + part = dev_get_uclass_plat(dev); + if (start >= part->gpt_part_info.size) + return 0; + + if ((start + blkcnt) > part->gpt_part_info.size) + blkcnt = part->gpt_part_info.size - start; + start += part->gpt_part_info.start; + + return ops->erase(parent, start, blkcnt); +} + +static const struct blk_ops blk_part_ops = { + .read = blk_part_read, + .write = blk_part_write, + .erase = blk_part_erase, +}; + +U_BOOT_DRIVER(blk_partition) = { + .name = "blk_partition", + .id = UCLASS_PARTITION, + .ops = &blk_part_ops, +}; + +UCLASS_DRIVER(partition) = { + .id = UCLASS_PARTITION, + .per_device_plat_auto = sizeof(struct disk_part), + .name = "partition", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 0e26e1d13824..230b1ea528cf 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -83,6 +83,7 @@ enum uclass_id { UCLASS_P2SB, /* (x86) Primary-to-Sideband Bus */ UCLASS_PANEL, /* Display panel, such as an LCD */ UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */ + UCLASS_PARTITION, /* Logical disk partition device */ UCLASS_PCH, /* x86 platform controller hub */ UCLASS_PCI, /* PCI bus */ UCLASS_PCI_EP, /* PCI endpoint device */ diff --git a/include/part.h b/include/part.h index e5806edb3452..c4e0bef7749d 100644 --- a/include/part.h +++ b/include/part.h @@ -296,6 +296,16 @@ part_get_info_by_dev_and_name_or_num(const char *dev_iface, } #endif
+struct udevice; +/** + * part_create_block_devices - Create block devices for disk partitions + * + * Create UCLASS_PARTITION udevices for each of disk partitions in @parent + * + * @blk_dev: Whole disk device + */ +int part_create_block_devices(struct udevice *blk_dev); + /* * We don't support printing partition information in SPL and only support * getting partition information in a few cases.

Now that all the block device drivers have enable a probe hook, we will call part_create_block_devices() to enumerate all the partitions and create associated udevices when a block device is detected.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- drivers/block/blk-uclass.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index f1e4a8564679..791e26c06ebe 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -741,6 +741,10 @@ static int blk_post_probe(struct udevice *dev) struct blk_desc *desc = dev_get_uclass_plat(dev);
part_init(desc); + + if (desc->part_type != PART_TYPE_UNKNOWN && + part_create_block_devices(dev)) + debug("*** creating partitions failed\n"); }
return 0;

In the next commit, CONFIG_EFI_SETUP_EARLY will become mandated in order to support dynamic enumeration of efi_disk objects.
This can, however, be problematic particularly in case of file-based variable storage (efi_variable.c, default). Non-volatile variables are to be restored from EFI system partition by efi_init_variables() in efi_init_obj_list(). When efi_init_obj_list() is called in board_init_r(), we don't know yet what disk devices we have since none of device probing commands (say, scsi rescan) has not been executed at that stage.
So in this commit, a preparatory change is made; efi_init_obj_list() is broken into the two functions; * efi_init_early(), and * new efi_init_obj_list()
Only efi_init_early() will be called in board_init_r(), which allows us to execute any of device probing commands, either though "preboot" variable or normal command line, before calling efi_init_obj_list() which is to be invoked at the first execution of an efi-related command (or at efi_launch_capsules()) as used to be.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- common/board_r.c | 2 +- common/main.c | 7 +++-- include/efi_loader.h | 2 ++ lib/efi_loader/efi_setup.c | 58 ++++++++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 12 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index 8dc87ed2be4c..7d0281f5447e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -795,7 +795,7 @@ static init_fnc_t init_sequence_r[] = { initr_mem, #endif #ifdef CONFIG_EFI_SETUP_EARLY - (init_fnc_t)efi_init_obj_list, + efi_init_early, #endif run_main_loop, }; diff --git a/common/main.c b/common/main.c index 3f5214fd44b8..682f3359ea38 100644 --- a/common/main.c +++ b/common/main.c @@ -54,8 +54,11 @@ void main_loop(void) if (IS_ENABLED(CONFIG_UPDATE_TFTP)) update_tftp(0UL, NULL, NULL);
- if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) - efi_launch_capsules(); + if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) { + /* efi_init_early() already called */ + if (efi_init_obj_list() == EFI_SUCCESS) + efi_launch_capsules(); + }
s = bootdelay_process(); if (cli_process_fdt(&s)) diff --git a/include/efi_loader.h b/include/efi_loader.h index c52ea59ec7ae..5bb8fb2acd04 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -493,6 +493,8 @@ struct efi_register_notify_event { /* List of all events registered by RegisterProtocolNotify() */ extern struct list_head efi_register_notify_events;
+/* called at pre-initialization */ +int efi_init_early(void); /* Initialize efi execution environment */ efi_status_t efi_init_obj_list(void); /* Install device tree */ diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index eee54e48784f..de2f34bab537 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -174,20 +174,18 @@ static efi_status_t efi_init_os_indications(void) &os_indications_supported, false); }
- /** - * efi_init_obj_list() - Initialize and populate EFI object list + * __efi_init_early() - handle initialization at early stage + * + * This function is called in efi_init_obj_list() only if + * !CONFIG_EFI_SETUP_EARLY. * * Return: status code */ -efi_status_t efi_init_obj_list(void) +static efi_status_t __efi_init_early(void) { efi_status_t ret = EFI_SUCCESS;
- /* Initialize once only */ - if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) - return efi_obj_list_initialized; - /* Allow unaligned memory access */ allow_unaligned();
@@ -202,9 +200,51 @@ efi_status_t efi_init_obj_list(void)
#ifdef CONFIG_PARTITIONS ret = efi_disk_register(); - if (ret != EFI_SUCCESS) - goto out; #endif +out: + return ret; +} + +/** + * efi_init_early() - handle initialization at early stage + * + * external version of __efi_init_early(); expected to be called in + * board_init_r(). + * + * Return: status code + */ +int efi_init_early(void) +{ + efi_status_t ret; + + ret = __efi_init_early(); + if (ret != EFI_SUCCESS) { + /* never re-init UEFI subsystem */ + efi_obj_list_initialized = ret; + return -1; + } + return 0; +} + +/** + * efi_init_obj_list() - Initialize and populate EFI object list + * + * Return: status code + */ +efi_status_t efi_init_obj_list(void) +{ + efi_status_t ret = EFI_SUCCESS; + + /* Initialize once only */ + if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) + return efi_obj_list_initialized; + + if (!IS_ENABLED(CONFIG_EFI_SETUP_EARLY)) { + ret = __efi_init_early(); + if (ret != EFI_SUCCESS) + goto out; + } + if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) { ret = efi_rng_register(); if (ret != EFI_SUCCESS)

Add efi_disk_probe() function. This function creates an efi_disk object for a raw disk device (UCLASS_BLK) and additional objects for related partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "probe" interface every time one raw disk device is detected and activated. We assume that partition devices (UCLASS_PARTITION) have been created when this function is invoked.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- include/efi_loader.h | 4 +- lib/efi_driver/efi_block_device.c | 34 ++--- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 201 +++++++++++++++++++----------- lib/efi_loader/efi_setup.c | 4 +- 5 files changed, 143 insertions(+), 103 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 5bb8fb2acd04..ba79a9afb404 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -525,8 +525,8 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by bootefi to make all disk storage accessible as EFI objects */ -efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to initialize efi_disks */ +efi_status_t efi_disk_init(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index 04cb3ef0d4e5..5baa6f87a375 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/root.h> +#include <dm/tag.h>
/* * EFI attributes of the udevice handled by this driver. @@ -106,25 +107,6 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; }
-/** - * Create partions for the block device. - * - * @handle: EFI handle of the block device - * @dev: udevice of the block device - * Return: number of partitions created - */ -static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) -{ - struct blk_desc *desc; - const char *if_typename; - - desc = dev_get_uclass_plat(dev); - if_typename = blk_get_if_type_name(desc->if_type); - - return efi_disk_create_partitions(handle, desc, if_typename, - desc->devnum, dev->name); -} - /** * Create a block device for a handle * @@ -139,7 +121,6 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface; - int disks; struct efi_blk_plat *plat;
EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io); @@ -173,15 +154,20 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) plat->handle = handle; plat->io = interface;
+ /* + * FIXME: necessary because we won't do almost nothing in + * efi_disk_create() when called from device_probe(). + */ + ret = dev_tag_set_ptr(bdev, DM_TAG_EFI, handle); + if (ret) + /* FIXME: cleanup for bdev */ + return ret; + ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- /* Create handles for the partions of the block device */ - disks = efi_bl_bind_partitions(handle, bdev); - EFI_PRINT("Found %d partitions\n", disks); - return 0; }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8 + select DM_EVENT + select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE @@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR
config EFI_SETUP_EARLY bool + default y
choice prompt "Store for non-volatile UEFI variables" diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc2f..d4a0edb458b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,9 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/tag.h> +#include <event.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -487,103 +490,153 @@ error: return ret; }
-/** - * efi_disk_create_partitions() - create handles and protocols for partitions +/* + * Create a handle for a whole raw disk + * + * @dev uclass device (UCLASS_BLK) * - * Create handles and protocols for the partitions of a block device. + * Create an efi_disk object which is associated with @dev. + * The type of @dev must be UCLASS_BLK. * - * @parent: handle of the parent disk - * @desc: block device - * @if_typename: interface type - * @diskid: device number - * @pdevname: device name - * Return: number of partitions created + * @return 0 on success, -1 otherwise */ -int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, - const char *if_typename, int diskid, - const char *pdevname) +static int efi_disk_create_raw(struct udevice *dev) { - int disks = 0; - char devname[32] = { 0 }; /* dp->str is u16[32] long */ - int part; - struct efi_device_path *dp = NULL; + struct efi_disk_obj *disk; + struct blk_desc *desc; + const char *if_typename; + int diskid; efi_status_t ret; - struct efi_handler *handler;
- /* Get the device path of the parent */ - ret = efi_search_protocol(parent, &efi_guid_device_path, &handler); - if (ret == EFI_SUCCESS) - dp = handler->protocol_interface; - - /* Add devices for each partition */ - for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { - struct disk_partition info; - - if (part_get_info(desc, part, &info)) - continue; - snprintf(devname, sizeof(devname), "%s:%x", pdevname, - part); - ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid, - &info, part, NULL); - if (ret != EFI_SUCCESS) { - log_err("Adding partition %s failed\n", pdevname); - continue; - } - disks++; + desc = dev_get_uclass_plat(dev); + if_typename = blk_get_if_type_name(desc->if_type); + diskid = desc->devnum; + + ret = efi_disk_add_dev(NULL, NULL, if_typename, desc, + diskid, NULL, 0, &disk); + if (ret != EFI_SUCCESS) { + if (ret == EFI_NOT_READY) + log_notice("Disk %s not ready\n", dev->name); + else + log_err("Adding disk for %s failed\n", dev->name); + + return -1; + } + if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { + efi_free_pool(disk->dp); + efi_delete_handle(&disk->header); + + return -1; }
- return disks; + return 0; }
-/** - * efi_disk_register() - register block devices - * - * U-Boot doesn't have a list of all online disk devices. So when running our - * EFI payload, we scan through all of the potentially available ones and - * store them in our object pool. +/* + * Create a handle for a disk partition * - * This function is called in efi_init_obj_list(). + * @dev uclass device (UCLASS_PARTITION) * - * TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this. - * Consider converting the code to look up devices as needed. The EFI device - * could be a child of the UCLASS_BLK block device, perhaps. + * Create an efi_disk object which is associated with @dev. + * The type of @dev must be UCLASS_PARTITION. * - * Return: status code + * @return 0 on success, -1 otherwise */ -efi_status_t efi_disk_register(void) +static int efi_disk_create_part(struct udevice *dev) { + efi_handle_t parent; + struct blk_desc *desc; + const char *if_typename; + struct disk_part *part_data; + struct disk_partition *info; + unsigned int part; + int diskid; + struct efi_handler *handler; + struct efi_device_path *dp_parent; struct efi_disk_obj *disk; - int disks = 0; efi_status_t ret; + + if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent)) + return -1; + + desc = dev_get_uclass_plat(dev_get_parent(dev)); + if_typename = blk_get_if_type_name(desc->if_type); + diskid = desc->devnum; + + part_data = dev_get_uclass_plat(dev); + part = part_data->partnum; + info = &part_data->gpt_part_info; + + ret = efi_search_protocol(parent, &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + return -1; + dp_parent = (struct efi_device_path *)handler->protocol_interface; + + ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid, + info, part, &disk); + if (ret != EFI_SUCCESS) { + log_err("Adding partition for %s failed\n", dev->name); + return -1; + } + if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { + efi_free_pool(disk->dp); + efi_delete_handle(&disk->header); + + return -1; + } + + return 0; +} + +/* + * Create efi_disk objects for a block device + * + * @dev uclass device (UCLASS_BLK) + * + * Create efi_disk objects for partitions as well as a raw disk + * which is associated with @dev. + * The type of @dev must be UCLASS_BLK. + * This function is expected to be called at EV_PM_POST_PROBE. + * + * @return 0 on success, -1 otherwise + */ +static int efi_disk_probe(void *ctx, struct event *event) +{ struct udevice *dev; + enum uclass_id id; + struct udevice *child; + int ret;
- for (uclass_first_device_check(UCLASS_BLK, &dev); dev; - uclass_next_device_check(&dev)) { - struct blk_desc *desc = dev_get_uclass_plat(dev); - const char *if_typename = blk_get_if_type_name(desc->if_type); + dev = event->data.dm.dev; + id = device_get_uclass_id(dev);
- /* Add block device for the full device */ - log_info("Scanning disk %s...\n", dev->name); - ret = efi_disk_add_dev(NULL, NULL, if_typename, - desc, desc->devnum, NULL, 0, &disk); - if (ret == EFI_NOT_READY) { - log_notice("Disk %s not ready\n", dev->name); - continue; - } - if (ret) { - log_err("ERROR: failure to add disk device %s, r = %lu\n", - dev->name, ret & ~EFI_ERROR_MASK); - continue; - } - disks++; + /* TODO: We won't support partitions in a partition */ + if (id != UCLASS_BLK) + return 0; + + ret = efi_disk_create_raw(dev); + if (ret) + return -1;
- /* Partitions show up as block devices in EFI */ - disks += efi_disk_create_partitions( - &disk->header, desc, if_typename, - desc->devnum, dev->name); + device_foreach_child(child, dev) { + ret = efi_disk_create_part(child); + if (ret) + return -1; }
- log_info("Found %d disks\n", disks); + return 0; +} + +efi_status_t efi_disk_init(void) +{ + int ret; + + ret = event_register("efi_disk add", EVT_DM_POST_PROBE, + efi_disk_probe, NULL); + if (ret) { + log_err("Event registration for efi_disk add failed\n"); + return EFI_OUT_OF_RESOURCES; + }
return EFI_SUCCESS; } diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index de2f34bab537..250eeb2fcd6b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,9 +198,7 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out;
-#ifdef CONFIG_PARTITIONS - ret = efi_disk_register(); -#endif + ret = efi_disk_init(); out: return ret; }

On 4/19/22 03:05, AKASHI Takahiro wrote:
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select DM_EVENT
- select EVENT_DYNAMIC
Hi,
The use of this select without EVENT leads to this warning:
WARNING: unmet direct dependencies detected for EVENT_DYNAMIC Depends on [n]: EVENT [=n] Selected by [y]: - EFI_LOADER [=y] && OF_LIBFDT [=y] && (ARM [=y] && (SYS_CPU [=armv7]=arm1136 || SYS_CPU [=armv7]=arm1176 || SYS_CPU [=armv7]=armv7 || SYS_CPU [=armv7]=armv8) || X86 [=n] || RISCV [=n] || SANDBOX [=n]) && (!EFI_STUB [=n] || !X86_64 [=n] || EFI_STUB_64BIT [=n]) && (!EFI_STUB [=n] || !X86 [=n] || X86_64 [=n] || EFI_STUB_32BIT [=n]) && BLK [=y] && (DM_ETH [=n] || !NET [=n]) && !EFI_APP [=n]
Previously there was no need for events on rk3066. Is that normal behavior or should we include "select EVENT" here as well?
Johan
select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE @@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR
config EFI_SETUP_EARLY bool
- default y
choice prompt "Store for non-volatile UEFI variables"

On 19/04/2022 03:05, AKASHI Takahiro wrote:
Add efi_disk_probe() function. This function creates an efi_disk object for a raw disk device (UCLASS_BLK) and additional objects for related partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "probe" interface every time one raw disk device is detected and activated. We assume that partition devices (UCLASS_PARTITION) have been created when this function is invoked.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org
include/efi_loader.h | 4 +- lib/efi_driver/efi_block_device.c | 34 ++--- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 201 +++++++++++++++++++----------- lib/efi_loader/efi_setup.c | 4 +- 5 files changed, 143 insertions(+), 103 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 5bb8fb2acd04..ba79a9afb404 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -525,8 +525,8 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by bootefi to make all disk storage accessible as EFI objects */ -efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to initialize efi_disks */ +efi_status_t efi_disk_init(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index 04cb3ef0d4e5..5baa6f87a375 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/root.h> +#include <dm/tag.h>
/*
- EFI attributes of the udevice handled by this driver.
@@ -106,25 +107,6 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; }
-/**
- Create partions for the block device.
- @handle: EFI handle of the block device
- @dev: udevice of the block device
- Return: number of partitions created
- */
-static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) -{
- struct blk_desc *desc;
- const char *if_typename;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- return efi_disk_create_partitions(handle, desc, if_typename,
desc->devnum, dev->name);
-}
- /**
- Create a block device for a handle
@@ -139,7 +121,6 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface;
int disks; struct efi_blk_plat *plat;
EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
@@ -173,15 +154,20 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) plat->handle = handle; plat->io = interface;
- /*
* FIXME: necessary because we won't do almost nothing in
* efi_disk_create() when called from device_probe().
*/
- ret = dev_tag_set_ptr(bdev, DM_TAG_EFI, handle);
- if (ret)
/* FIXME: cleanup for bdev */
return ret;
- ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- /* Create handles for the partions of the block device */
- disks = efi_bl_bind_partitions(handle, bdev);
- EFI_PRINT("Found %d partitions\n", disks);
- return 0; }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select DM_EVENT
- select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE
@@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR
config EFI_SETUP_EARLY bool
default y
choice prompt "Store for non-volatile UEFI variables"
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc2f..d4a0edb458b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,9 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/tag.h> +#include <event.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -487,103 +490,153 @@ error: return ret; }
-/**
- efi_disk_create_partitions() - create handles and protocols for partitions
+/*
- Create a handle for a whole raw disk
- @dev uclass device (UCLASS_BLK)
- Create handles and protocols for the partitions of a block device.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- @parent: handle of the parent disk
- @desc: block device
- @if_typename: interface type
- @diskid: device number
- @pdevname: device name
- Return: number of partitions created
*/
- @return 0 on success, -1 otherwise
-int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
const char *if_typename, int diskid,
const char *pdevname)
+static int efi_disk_create_raw(struct udevice *dev) {
- int disks = 0;
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
- int part;
- struct efi_device_path *dp = NULL;
- struct efi_disk_obj *disk;
- struct blk_desc *desc;
- const char *if_typename;
- int diskid; efi_status_t ret;
struct efi_handler *handler;
/* Get the device path of the parent */
ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
if (ret == EFI_SUCCESS)
dp = handler->protocol_interface;
/* Add devices for each partition */
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
struct disk_partition info;
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%x", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
&info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
}
disks++;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
diskid, NULL, 0, &disk);
- if (ret != EFI_SUCCESS) {
if (ret == EFI_NOT_READY)
log_notice("Disk %s not ready\n", dev->name);
else
log_err("Adding disk for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
}return -1;
- return disks;
- return 0; }
-/**
- efi_disk_register() - register block devices
- U-Boot doesn't have a list of all online disk devices. So when running our
- EFI payload, we scan through all of the potentially available ones and
- store them in our object pool.
+/*
- Create a handle for a disk partition
- This function is called in efi_init_obj_list().
- @dev uclass device (UCLASS_PARTITION)
- TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
- Consider converting the code to look up devices as needed. The EFI device
- could be a child of the UCLASS_BLK block device, perhaps.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_PARTITION.
- Return: status code
*/
- @return 0 on success, -1 otherwise
-efi_status_t efi_disk_register(void) +static int efi_disk_create_part(struct udevice *dev) {
- efi_handle_t parent;
- struct blk_desc *desc;
- const char *if_typename;
- struct disk_part *part_data;
- struct disk_partition *info;
- unsigned int part;
- int diskid;
- struct efi_handler *handler;
- struct efi_device_path *dp_parent; struct efi_disk_obj *disk;
- int disks = 0; efi_status_t ret;
- if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent))
return -1;
- desc = dev_get_uclass_plat(dev_get_parent(dev));
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- part_data = dev_get_uclass_plat(dev);
- part = part_data->partnum;
- info = &part_data->gpt_part_info;
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
return -1;
- dp_parent = (struct efi_device_path *)handler->protocol_interface;
- ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid,
info, part, &disk);
- if (ret != EFI_SUCCESS) {
log_err("Adding partition for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
return -1;
- }
- return 0;
+}
+/*
- Create efi_disk objects for a block device
- @dev uclass device (UCLASS_BLK)
- Create efi_disk objects for partitions as well as a raw disk
- which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- This function is expected to be called at EV_PM_POST_PROBE.
- @return 0 on success, -1 otherwise
- */
+static int efi_disk_probe(void *ctx, struct event *event) +{ struct udevice *dev;
- enum uclass_id id;
- struct udevice *child;
- int ret;
- for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
uclass_next_device_check(&dev)) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
const char *if_typename = blk_get_if_type_name(desc->if_type);
- dev = event->data.dm.dev;
- id = device_get_uclass_id(dev);
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
}
if (ret) {
log_err("ERROR: failure to add disk device %s, r = %lu\n",
dev->name, ret & ~EFI_ERROR_MASK);
continue;
}
disks++;
- /* TODO: We won't support partitions in a partition */
- if (id != UCLASS_BLK)
return 0;
- ret = efi_disk_create_raw(dev);
- if (ret)
return -1;
/* Partitions show up as block devices in EFI */
disks += efi_disk_create_partitions(
&disk->header, desc, if_typename,
desc->devnum, dev->name);
- device_foreach_child(child, dev) {
ret = efi_disk_create_part(child);
if (ret)
}return -1;
- log_info("Found %d disks\n", disks);
- return 0;
+}
+efi_status_t efi_disk_init(void) +{
int ret;
ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
efi_disk_probe, NULL);
if (ret) {
log_err("Event registration for efi_disk add failed\n");
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS; }
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index de2f34bab537..250eeb2fcd6b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,9 +198,7 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out;
-#ifdef CONFIG_PARTITIONS
- ret = efi_disk_register();
-#endif
- ret = efi_disk_init(); out: return ret; }
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash: Found U-Boot script /boot.scr 449 bytes read in 2 ms (218.8 KiB/s) ## Executing script at 08000000 36500032 bytes read in 1554 ms (22.4 MiB/s) 42873252 bytes read in 1829 ms (22.4 MiB/s) 29092 bytes read in 4 ms (6.9 MiB/s) ## Booting kernel from Legacy Image at 13000000 ... Image Name: Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 36499968 Bytes = 34.8 MiB Load Address: 13000000 Entry Point: 13000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 06000000 ... Image Name: Image Type: AArch64 Linux RAMDisk Image (uncompressed) Data Size: 42873188 Bytes = 40.9 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 09000000 Booting using the fdt blob at 0x9000000 Loading Kernel Image Loading Ramdisk to 7965b000, end 7bf3e164 ... OK Loading Device Tree to 0000000079650000, end 000000007965a1a3 ... OK "Synchronous Abort" handler, esr 0x96000004 elr: 0000000001065150 lr : 0000000001054b18 (reloc) elr: 000000007dfb5150 lr : 000000007dfa4b18 x0 : d55d507f5dacfff5 x1 : 000000007dfbce48 x2 : 0000000000000010 x3 : 0000000000000000 x4 : 0000000000000000 x5 : d55d507f5dacfff5 x6 : 000000007bf55bb0 x7 : 0000000000000000 x8 : 0000000000000007 x9 : 0000000000000000 x10: 0000000000000178 x11: 000000007bf4211c x12: 00000000000000a4 x13: 000000007bf420d8 x14: 0000000079650000 x15: 0000000000000020 x16: 000000007df83454 x17: 0000000000000000 x18: 000000007bf4ddb0 x19: 000000007af42040 x20: 000000007df50b20 x21: 000000007dfbce48 x22: 0000000000001000 x23: 000000007bf55b00 x24: 000000007dfdb910 x25: 0000000001000000 x26: 0000000001000000 x27: 0000000001000000 x28: 0000000000001000 x29: 000000007bf420d0
Code: eb02009f 54000061 52800000 14000006 (386468a3) Resetting CPU ...
using libretech-cc_defconfig and the followin boot.scr: setenv autoload no setenv initrd_high 0xffffffff setenv fdt_high 0xffffffff load mmc 0:1 0x13000000 uImage load mmc 0:1 0x6000000 ramdisk.cpio.gz.uboot setenv initrd_size ${filesize} load mmc 0:1 0x9000000 meson-gxl-s905x-libretech-cc.dtb setenv bootargs 'console=ttyAML0,115200n8 root=/dev/ram0 console_msg_format=syslog earlycon ip=dhcp' bootm 0x13000000 0x6000000 0x9000000
bisect log: # bad: [c387e62614713d0cc9e3ed022b86c9f320b02853] Merge branch '2022-05-11-Kconfig-cleanups-etc' # good: [e4b6ebd3de982ae7185dbf689a030e73fd06e0d2] Prepare v2022.04 git bisect start 'c387e62614' 'v2022.04' # good: [4228023eff7e94500137ce9e30687c00ffb4dd4f] led: bcm6753: Drop duplicate OF "label" property parsing git bisect good 4228023eff7e94500137ce9e30687c00ffb4dd4f # bad: [3fbdd485fd87ce0d4e1b747aea3c433646f4ced2] ARM: dts: sam9x60: Add pit64b node git bisect bad 3fbdd485fd87ce0d4e1b747aea3c433646f4ced2 # good: [e50f66e364be80e02dd0834b84b830f3aade82ea] Merge https://source.denx.de/u-boot/custodians/u-boot-marvell git bisect good e50f66e364be80e02dd0834b84b830f3aade82ea # good: [9de612ae4ded53f742f5f99929c06d0839471ced] cmd: adc: Add support for storing ADC result in env variable git bisect good 9de612ae4ded53f742f5f99929c06d0839471ced # bad: [bc9da9fb50ac3ba7603487a0366d4db60b984812] Merge branch '2022-04-23-binman-updates' git bisect bad bc9da9fb50ac3ba7603487a0366d4db60b984812 # bad: [3c809dfed757c37b92ff543c8f1c941407bafc2e] efi_loader: disk: not create BLK device for BLK(IF_TYPE_EFI_LOADER) devices git bisect bad 3c809dfed757c37b92ff543c8f1c941407bafc2e # good: [38f255b96085d2e50558a16256c87ffd885f2f7e] efi_loader: disk: compile efi_disk when CONFIG_BLK git bisect good 38f255b96085d2e50558a16256c87ffd885f2f7e # good: [8ff50227befdc778eb2cb239b778ed1ed843bf33] test: dm: add tests for tag support git bisect good 8ff50227befdc778eb2cb239b778ed1ed843bf33 # good: [bf76031d19fa82041ae5ddc17214ec71858b0097] dm: blk: add a device-probe hook for scanning disk partitions git bisect good bf76031d19fa82041ae5ddc17214ec71858b0097 # bad: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice git bisect bad a9bf024b2933bba0e23038892970a18b72dfaeb4 # good: [a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4] efi_loader: split efi_init_obj_list() into two stages git bisect good a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4 # first bad commit: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice
Neil

On Wed, May 18, 2022 at 11:23:32AM +0200, Neil Armstrong wrote:
On 19/04/2022 03:05, AKASHI Takahiro wrote:
Add efi_disk_probe() function. This function creates an efi_disk object for a raw disk device (UCLASS_BLK) and additional objects for related partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "probe" interface every time one raw disk device is detected and activated. We assume that partition devices (UCLASS_PARTITION) have been created when this function is invoked.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org
include/efi_loader.h | 4 +- lib/efi_driver/efi_block_device.c | 34 ++--- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 201 +++++++++++++++++++----------- lib/efi_loader/efi_setup.c | 4 +- 5 files changed, 143 insertions(+), 103 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 5bb8fb2acd04..ba79a9afb404 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -525,8 +525,8 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by bootefi to make all disk storage accessible as EFI objects */ -efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to initialize efi_disks */ +efi_status_t efi_disk_init(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index 04cb3ef0d4e5..5baa6f87a375 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/root.h> +#include <dm/tag.h> /*
- EFI attributes of the udevice handled by this driver.
@@ -106,25 +107,6 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; } -/**
- Create partions for the block device.
- @handle: EFI handle of the block device
- @dev: udevice of the block device
- Return: number of partitions created
- */
-static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) -{
- struct blk_desc *desc;
- const char *if_typename;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- return efi_disk_create_partitions(handle, desc, if_typename,
desc->devnum, dev->name);
-}
- /**
- Create a block device for a handle
@@ -139,7 +121,6 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface;
- int disks; struct efi_blk_plat *plat; EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
@@ -173,15 +154,20 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) plat->handle = handle; plat->io = interface;
- /*
* FIXME: necessary because we won't do almost nothing in
* efi_disk_create() when called from device_probe().
*/
- ret = dev_tag_set_ptr(bdev, DM_TAG_EFI, handle);
- if (ret)
/* FIXME: cleanup for bdev */
return ret;
- ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- /* Create handles for the partions of the block device */
- disks = efi_bl_bind_partitions(handle, bdev);
- EFI_PRINT("Found %d partitions\n", disks);
- return 0; }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select DM_EVENT
- select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE
@@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR config EFI_SETUP_EARLY bool
- default y choice prompt "Store for non-volatile UEFI variables"
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc2f..d4a0edb458b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,9 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/tag.h> +#include <event.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -487,103 +490,153 @@ error: return ret; } -/**
- efi_disk_create_partitions() - create handles and protocols for partitions
+/*
- Create a handle for a whole raw disk
- @dev uclass device (UCLASS_BLK)
- Create handles and protocols for the partitions of a block device.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- @parent: handle of the parent disk
- @desc: block device
- @if_typename: interface type
- @diskid: device number
- @pdevname: device name
- Return: number of partitions created
*/
- @return 0 on success, -1 otherwise
-int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
const char *if_typename, int diskid,
const char *pdevname)
+static int efi_disk_create_raw(struct udevice *dev) {
- int disks = 0;
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
- int part;
- struct efi_device_path *dp = NULL;
- struct efi_disk_obj *disk;
- struct blk_desc *desc;
- const char *if_typename;
- int diskid; efi_status_t ret;
- struct efi_handler *handler;
- /* Get the device path of the parent */
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret == EFI_SUCCESS)
dp = handler->protocol_interface;
- /* Add devices for each partition */
- for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
struct disk_partition info;
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%x", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
&info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
}
disks++;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
diskid, NULL, 0, &disk);
- if (ret != EFI_SUCCESS) {
if (ret == EFI_NOT_READY)
log_notice("Disk %s not ready\n", dev->name);
else
log_err("Adding disk for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
}return -1;
- return disks;
- return 0; }
-/**
- efi_disk_register() - register block devices
- U-Boot doesn't have a list of all online disk devices. So when running our
- EFI payload, we scan through all of the potentially available ones and
- store them in our object pool.
+/*
- Create a handle for a disk partition
- This function is called in efi_init_obj_list().
- @dev uclass device (UCLASS_PARTITION)
- TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
- Consider converting the code to look up devices as needed. The EFI device
- could be a child of the UCLASS_BLK block device, perhaps.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_PARTITION.
- Return: status code
*/
- @return 0 on success, -1 otherwise
-efi_status_t efi_disk_register(void) +static int efi_disk_create_part(struct udevice *dev) {
- efi_handle_t parent;
- struct blk_desc *desc;
- const char *if_typename;
- struct disk_part *part_data;
- struct disk_partition *info;
- unsigned int part;
- int diskid;
- struct efi_handler *handler;
- struct efi_device_path *dp_parent; struct efi_disk_obj *disk;
- int disks = 0; efi_status_t ret;
- if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent))
return -1;
- desc = dev_get_uclass_plat(dev_get_parent(dev));
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- part_data = dev_get_uclass_plat(dev);
- part = part_data->partnum;
- info = &part_data->gpt_part_info;
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
return -1;
- dp_parent = (struct efi_device_path *)handler->protocol_interface;
- ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid,
info, part, &disk);
- if (ret != EFI_SUCCESS) {
log_err("Adding partition for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
return -1;
- }
- return 0;
+}
+/*
- Create efi_disk objects for a block device
- @dev uclass device (UCLASS_BLK)
- Create efi_disk objects for partitions as well as a raw disk
- which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- This function is expected to be called at EV_PM_POST_PROBE.
- @return 0 on success, -1 otherwise
- */
+static int efi_disk_probe(void *ctx, struct event *event) +{ struct udevice *dev;
- enum uclass_id id;
- struct udevice *child;
- int ret;
- for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
uclass_next_device_check(&dev)) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
const char *if_typename = blk_get_if_type_name(desc->if_type);
- dev = event->data.dm.dev;
- id = device_get_uclass_id(dev);
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
}
if (ret) {
log_err("ERROR: failure to add disk device %s, r = %lu\n",
dev->name, ret & ~EFI_ERROR_MASK);
continue;
}
disks++;
- /* TODO: We won't support partitions in a partition */
- if (id != UCLASS_BLK)
return 0;
- ret = efi_disk_create_raw(dev);
- if (ret)
return -1;
/* Partitions show up as block devices in EFI */
disks += efi_disk_create_partitions(
&disk->header, desc, if_typename,
desc->devnum, dev->name);
- device_foreach_child(child, dev) {
ret = efi_disk_create_part(child);
if (ret)
}return -1;
- log_info("Found %d disks\n", disks);
- return 0;
+}
+efi_status_t efi_disk_init(void) +{
- int ret;
- ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
efi_disk_probe, NULL);
- if (ret) {
log_err("Event registration for efi_disk add failed\n");
return EFI_OUT_OF_RESOURCES;
- } return EFI_SUCCESS; }
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index de2f34bab537..250eeb2fcd6b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,9 +198,7 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out; -#ifdef CONFIG_PARTITIONS
- ret = efi_disk_register();
-#endif
- ret = efi_disk_init(); out: return ret; }
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
Can you confirm that you do not use UEFI feature in your boot scenario here and yet you see a problem in UEFI subsystem?
Found U-Boot script /boot.scr 449 bytes read in 2 ms (218.8 KiB/s) ## Executing script at 08000000 36500032 bytes read in 1554 ms (22.4 MiB/s) 42873252 bytes read in 1829 ms (22.4 MiB/s) 29092 bytes read in 4 ms (6.9 MiB/s) ## Booting kernel from Legacy Image at 13000000 ... Image Name: Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 36499968 Bytes = 34.8 MiB Load Address: 13000000 Entry Point: 13000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 06000000 ... Image Name: Image Type: AArch64 Linux RAMDisk Image (uncompressed) Data Size: 42873188 Bytes = 40.9 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 09000000 Booting using the fdt blob at 0x9000000 Loading Kernel Image Loading Ramdisk to 7965b000, end 7bf3e164 ... OK Loading Device Tree to 0000000079650000, end 000000007965a1a3 ... OK "Synchronous Abort" handler, esr 0x96000004 elr: 0000000001065150 lr : 0000000001054b18 (reloc)
Can you check where (functions) those two addresses (elr,lr) come from?
elr: 000000007dfb5150 lr : 000000007dfa4b18 x0 : d55d507f5dacfff5 x1 : 000000007dfbce48 x2 : 0000000000000010 x3 : 0000000000000000 x4 : 0000000000000000 x5 : d55d507f5dacfff5 x6 : 000000007bf55bb0 x7 : 0000000000000000 x8 : 0000000000000007 x9 : 0000000000000000 x10: 0000000000000178 x11: 000000007bf4211c x12: 00000000000000a4 x13: 000000007bf420d8 x14: 0000000079650000 x15: 0000000000000020 x16: 000000007df83454 x17: 0000000000000000 x18: 000000007bf4ddb0 x19: 000000007af42040 x20: 000000007df50b20 x21: 000000007dfbce48 x22: 0000000000001000 x23: 000000007bf55b00 x24: 000000007dfdb910 x25: 0000000001000000 x26: 0000000001000000 x27: 0000000001000000 x28: 0000000000001000 x29: 000000007bf420d0
Code: eb02009f 54000061 52800000 14000006 (386468a3)
As far as my locally-built binary is concerned, the faulted instruction is located in memcpy().
000000000106xxxx <memcmp>: 106xxxx: aa0003e5 mov x5, x0 106xxxx: d2800004 mov x4, #0x0 // #0 106xxxx: eb02009f cmp x4, x2 106xxxx: 54000061 b.ne 10653d4 <memcmp+0x18> // b.any 106xxxx: 52800000 mov w0, #0x0 // #0 106xxxx: 14000006 b 10653e8 <memcmp+0x2c> 106xxxx: 386468a3 ldrb w3, [x5, x4]
'x5' seems to be bogus. The memory content might have been corrupted at this point.
-Takahiro Akashi
Resetting CPU ...
using libretech-cc_defconfig and the followin boot.scr: setenv autoload no setenv initrd_high 0xffffffff setenv fdt_high 0xffffffff load mmc 0:1 0x13000000 uImage load mmc 0:1 0x6000000 ramdisk.cpio.gz.uboot setenv initrd_size ${filesize} load mmc 0:1 0x9000000 meson-gxl-s905x-libretech-cc.dtb setenv bootargs 'console=ttyAML0,115200n8 root=/dev/ram0 console_msg_format=syslog earlycon ip=dhcp' bootm 0x13000000 0x6000000 0x9000000
bisect log: # bad: [c387e62614713d0cc9e3ed022b86c9f320b02853] Merge branch '2022-05-11-Kconfig-cleanups-etc' # good: [e4b6ebd3de982ae7185dbf689a030e73fd06e0d2] Prepare v2022.04 git bisect start 'c387e62614' 'v2022.04' # good: [4228023eff7e94500137ce9e30687c00ffb4dd4f] led: bcm6753: Drop duplicate OF "label" property parsing git bisect good 4228023eff7e94500137ce9e30687c00ffb4dd4f # bad: [3fbdd485fd87ce0d4e1b747aea3c433646f4ced2] ARM: dts: sam9x60: Add pit64b node git bisect bad 3fbdd485fd87ce0d4e1b747aea3c433646f4ced2 # good: [e50f66e364be80e02dd0834b84b830f3aade82ea] Merge https://source.denx.de/u-boot/custodians/u-boot-marvell git bisect good e50f66e364be80e02dd0834b84b830f3aade82ea # good: [9de612ae4ded53f742f5f99929c06d0839471ced] cmd: adc: Add support for storing ADC result in env variable git bisect good 9de612ae4ded53f742f5f99929c06d0839471ced # bad: [bc9da9fb50ac3ba7603487a0366d4db60b984812] Merge branch '2022-04-23-binman-updates' git bisect bad bc9da9fb50ac3ba7603487a0366d4db60b984812 # bad: [3c809dfed757c37b92ff543c8f1c941407bafc2e] efi_loader: disk: not create BLK device for BLK(IF_TYPE_EFI_LOADER) devices git bisect bad 3c809dfed757c37b92ff543c8f1c941407bafc2e # good: [38f255b96085d2e50558a16256c87ffd885f2f7e] efi_loader: disk: compile efi_disk when CONFIG_BLK git bisect good 38f255b96085d2e50558a16256c87ffd885f2f7e # good: [8ff50227befdc778eb2cb239b778ed1ed843bf33] test: dm: add tests for tag support git bisect good 8ff50227befdc778eb2cb239b778ed1ed843bf33 # good: [bf76031d19fa82041ae5ddc17214ec71858b0097] dm: blk: add a device-probe hook for scanning disk partitions git bisect good bf76031d19fa82041ae5ddc17214ec71858b0097 # bad: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice git bisect bad a9bf024b2933bba0e23038892970a18b72dfaeb4 # good: [a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4] efi_loader: split efi_init_obj_list() into two stages git bisect good a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4 # first bad commit: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice
Neil

Hi Neil,
On Thu, May 19, 2022 at 02:04:53PM +0900, AKASHI Takahiro wrote:
On Wed, May 18, 2022 at 11:23:32AM +0200, Neil Armstrong wrote:
On 19/04/2022 03:05, AKASHI Takahiro wrote:
Add efi_disk_probe() function. This function creates an efi_disk object for a raw disk device (UCLASS_BLK) and additional objects for related partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "probe" interface every time one raw disk device is detected and activated. We assume that partition devices (UCLASS_PARTITION) have been created when this function is invoked.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org
include/efi_loader.h | 4 +- lib/efi_driver/efi_block_device.c | 34 ++--- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 201 +++++++++++++++++++----------- lib/efi_loader/efi_setup.c | 4 +- 5 files changed, 143 insertions(+), 103 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 5bb8fb2acd04..ba79a9afb404 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -525,8 +525,8 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by bootefi to make all disk storage accessible as EFI objects */ -efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to initialize efi_disks */ +efi_status_t efi_disk_init(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index 04cb3ef0d4e5..5baa6f87a375 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/root.h> +#include <dm/tag.h> /*
- EFI attributes of the udevice handled by this driver.
@@ -106,25 +107,6 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; } -/**
- Create partions for the block device.
- @handle: EFI handle of the block device
- @dev: udevice of the block device
- Return: number of partitions created
- */
-static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) -{
- struct blk_desc *desc;
- const char *if_typename;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- return efi_disk_create_partitions(handle, desc, if_typename,
desc->devnum, dev->name);
-}
- /**
- Create a block device for a handle
@@ -139,7 +121,6 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface;
- int disks; struct efi_blk_plat *plat; EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
@@ -173,15 +154,20 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) plat->handle = handle; plat->io = interface;
- /*
* FIXME: necessary because we won't do almost nothing in
* efi_disk_create() when called from device_probe().
*/
- ret = dev_tag_set_ptr(bdev, DM_TAG_EFI, handle);
- if (ret)
/* FIXME: cleanup for bdev */
return ret;
- ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- /* Create handles for the partions of the block device */
- disks = efi_bl_bind_partitions(handle, bdev);
- EFI_PRINT("Found %d partitions\n", disks);
- return 0; }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select DM_EVENT
- select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE
@@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR config EFI_SETUP_EARLY bool
- default y choice prompt "Store for non-volatile UEFI variables"
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc2f..d4a0edb458b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,9 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/tag.h> +#include <event.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -487,103 +490,153 @@ error: return ret; } -/**
- efi_disk_create_partitions() - create handles and protocols for partitions
+/*
- Create a handle for a whole raw disk
- @dev uclass device (UCLASS_BLK)
- Create handles and protocols for the partitions of a block device.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- @parent: handle of the parent disk
- @desc: block device
- @if_typename: interface type
- @diskid: device number
- @pdevname: device name
- Return: number of partitions created
*/
- @return 0 on success, -1 otherwise
-int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
const char *if_typename, int diskid,
const char *pdevname)
+static int efi_disk_create_raw(struct udevice *dev) {
- int disks = 0;
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
- int part;
- struct efi_device_path *dp = NULL;
- struct efi_disk_obj *disk;
- struct blk_desc *desc;
- const char *if_typename;
- int diskid; efi_status_t ret;
- struct efi_handler *handler;
- /* Get the device path of the parent */
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret == EFI_SUCCESS)
dp = handler->protocol_interface;
- /* Add devices for each partition */
- for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
struct disk_partition info;
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%x", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
&info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
}
disks++;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
diskid, NULL, 0, &disk);
- if (ret != EFI_SUCCESS) {
if (ret == EFI_NOT_READY)
log_notice("Disk %s not ready\n", dev->name);
else
log_err("Adding disk for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
}return -1;
- return disks;
- return 0; }
-/**
- efi_disk_register() - register block devices
- U-Boot doesn't have a list of all online disk devices. So when running our
- EFI payload, we scan through all of the potentially available ones and
- store them in our object pool.
+/*
- Create a handle for a disk partition
- This function is called in efi_init_obj_list().
- @dev uclass device (UCLASS_PARTITION)
- TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
- Consider converting the code to look up devices as needed. The EFI device
- could be a child of the UCLASS_BLK block device, perhaps.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_PARTITION.
- Return: status code
*/
- @return 0 on success, -1 otherwise
-efi_status_t efi_disk_register(void) +static int efi_disk_create_part(struct udevice *dev) {
- efi_handle_t parent;
- struct blk_desc *desc;
- const char *if_typename;
- struct disk_part *part_data;
- struct disk_partition *info;
- unsigned int part;
- int diskid;
- struct efi_handler *handler;
- struct efi_device_path *dp_parent; struct efi_disk_obj *disk;
- int disks = 0; efi_status_t ret;
- if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent))
return -1;
- desc = dev_get_uclass_plat(dev_get_parent(dev));
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- part_data = dev_get_uclass_plat(dev);
- part = part_data->partnum;
- info = &part_data->gpt_part_info;
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
return -1;
- dp_parent = (struct efi_device_path *)handler->protocol_interface;
- ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid,
info, part, &disk);
- if (ret != EFI_SUCCESS) {
log_err("Adding partition for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
return -1;
- }
- return 0;
+}
+/*
- Create efi_disk objects for a block device
- @dev uclass device (UCLASS_BLK)
- Create efi_disk objects for partitions as well as a raw disk
- which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- This function is expected to be called at EV_PM_POST_PROBE.
- @return 0 on success, -1 otherwise
- */
+static int efi_disk_probe(void *ctx, struct event *event) +{ struct udevice *dev;
- enum uclass_id id;
- struct udevice *child;
- int ret;
- for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
uclass_next_device_check(&dev)) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
const char *if_typename = blk_get_if_type_name(desc->if_type);
- dev = event->data.dm.dev;
- id = device_get_uclass_id(dev);
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
}
if (ret) {
log_err("ERROR: failure to add disk device %s, r = %lu\n",
dev->name, ret & ~EFI_ERROR_MASK);
continue;
}
disks++;
- /* TODO: We won't support partitions in a partition */
- if (id != UCLASS_BLK)
return 0;
- ret = efi_disk_create_raw(dev);
- if (ret)
return -1;
/* Partitions show up as block devices in EFI */
disks += efi_disk_create_partitions(
&disk->header, desc, if_typename,
desc->devnum, dev->name);
- device_foreach_child(child, dev) {
ret = efi_disk_create_part(child);
if (ret)
}return -1;
- log_info("Found %d disks\n", disks);
- return 0;
+}
+efi_status_t efi_disk_init(void) +{
- int ret;
- ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
efi_disk_probe, NULL);
- if (ret) {
log_err("Event registration for efi_disk add failed\n");
return EFI_OUT_OF_RESOURCES;
- } return EFI_SUCCESS; }
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index de2f34bab537..250eeb2fcd6b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,9 +198,7 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out; -#ifdef CONFIG_PARTITIONS
- ret = efi_disk_register();
-#endif
- ret = efi_disk_init(); out: return ret; }
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
Can you confirm that you do not use UEFI feature in your boot scenario here and yet you see a problem in UEFI subsystem?
Found U-Boot script /boot.scr 449 bytes read in 2 ms (218.8 KiB/s) ## Executing script at 08000000 36500032 bytes read in 1554 ms (22.4 MiB/s) 42873252 bytes read in 1829 ms (22.4 MiB/s) 29092 bytes read in 4 ms (6.9 MiB/s) ## Booting kernel from Legacy Image at 13000000 ... Image Name: Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 36499968 Bytes = 34.8 MiB Load Address: 13000000 Entry Point: 13000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 06000000 ... Image Name: Image Type: AArch64 Linux RAMDisk Image (uncompressed) Data Size: 42873188 Bytes = 40.9 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 09000000 Booting using the fdt blob at 0x9000000 Loading Kernel Image Loading Ramdisk to 7965b000, end 7bf3e164 ... OK Loading Device Tree to 0000000079650000, end 000000007965a1a3 ... OK "Synchronous Abort" handler, esr 0x96000004 elr: 0000000001065150 lr : 0000000001054b18 (reloc)
Can you check where (functions) those two addresses (elr,lr) come from?
Do you still see the problem? If so, please check my questions above.
-Takahiro Akashi
elr: 000000007dfb5150 lr : 000000007dfa4b18 x0 : d55d507f5dacfff5 x1 : 000000007dfbce48 x2 : 0000000000000010 x3 : 0000000000000000 x4 : 0000000000000000 x5 : d55d507f5dacfff5 x6 : 000000007bf55bb0 x7 : 0000000000000000 x8 : 0000000000000007 x9 : 0000000000000000 x10: 0000000000000178 x11: 000000007bf4211c x12: 00000000000000a4 x13: 000000007bf420d8 x14: 0000000079650000 x15: 0000000000000020 x16: 000000007df83454 x17: 0000000000000000 x18: 000000007bf4ddb0 x19: 000000007af42040 x20: 000000007df50b20 x21: 000000007dfbce48 x22: 0000000000001000 x23: 000000007bf55b00 x24: 000000007dfdb910 x25: 0000000001000000 x26: 0000000001000000 x27: 0000000001000000 x28: 0000000000001000 x29: 000000007bf420d0
Code: eb02009f 54000061 52800000 14000006 (386468a3)
As far as my locally-built binary is concerned, the faulted instruction is located in memcpy().
000000000106xxxx <memcmp>: 106xxxx: aa0003e5 mov x5, x0 106xxxx: d2800004 mov x4, #0x0 // #0 106xxxx: eb02009f cmp x4, x2 106xxxx: 54000061 b.ne 10653d4 <memcmp+0x18> // b.any 106xxxx: 52800000 mov w0, #0x0 // #0 106xxxx: 14000006 b 10653e8 <memcmp+0x2c> 106xxxx: 386468a3 ldrb w3, [x5, x4]
'x5' seems to be bogus. The memory content might have been corrupted at this point.
-Takahiro Akashi
Resetting CPU ...
using libretech-cc_defconfig and the followin boot.scr: setenv autoload no setenv initrd_high 0xffffffff setenv fdt_high 0xffffffff load mmc 0:1 0x13000000 uImage load mmc 0:1 0x6000000 ramdisk.cpio.gz.uboot setenv initrd_size ${filesize} load mmc 0:1 0x9000000 meson-gxl-s905x-libretech-cc.dtb setenv bootargs 'console=ttyAML0,115200n8 root=/dev/ram0 console_msg_format=syslog earlycon ip=dhcp' bootm 0x13000000 0x6000000 0x9000000
bisect log: # bad: [c387e62614713d0cc9e3ed022b86c9f320b02853] Merge branch '2022-05-11-Kconfig-cleanups-etc' # good: [e4b6ebd3de982ae7185dbf689a030e73fd06e0d2] Prepare v2022.04 git bisect start 'c387e62614' 'v2022.04' # good: [4228023eff7e94500137ce9e30687c00ffb4dd4f] led: bcm6753: Drop duplicate OF "label" property parsing git bisect good 4228023eff7e94500137ce9e30687c00ffb4dd4f # bad: [3fbdd485fd87ce0d4e1b747aea3c433646f4ced2] ARM: dts: sam9x60: Add pit64b node git bisect bad 3fbdd485fd87ce0d4e1b747aea3c433646f4ced2 # good: [e50f66e364be80e02dd0834b84b830f3aade82ea] Merge https://source.denx.de/u-boot/custodians/u-boot-marvell git bisect good e50f66e364be80e02dd0834b84b830f3aade82ea # good: [9de612ae4ded53f742f5f99929c06d0839471ced] cmd: adc: Add support for storing ADC result in env variable git bisect good 9de612ae4ded53f742f5f99929c06d0839471ced # bad: [bc9da9fb50ac3ba7603487a0366d4db60b984812] Merge branch '2022-04-23-binman-updates' git bisect bad bc9da9fb50ac3ba7603487a0366d4db60b984812 # bad: [3c809dfed757c37b92ff543c8f1c941407bafc2e] efi_loader: disk: not create BLK device for BLK(IF_TYPE_EFI_LOADER) devices git bisect bad 3c809dfed757c37b92ff543c8f1c941407bafc2e # good: [38f255b96085d2e50558a16256c87ffd885f2f7e] efi_loader: disk: compile efi_disk when CONFIG_BLK git bisect good 38f255b96085d2e50558a16256c87ffd885f2f7e # good: [8ff50227befdc778eb2cb239b778ed1ed843bf33] test: dm: add tests for tag support git bisect good 8ff50227befdc778eb2cb239b778ed1ed843bf33 # good: [bf76031d19fa82041ae5ddc17214ec71858b0097] dm: blk: add a device-probe hook for scanning disk partitions git bisect good bf76031d19fa82041ae5ddc17214ec71858b0097 # bad: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice git bisect bad a9bf024b2933bba0e23038892970a18b72dfaeb4 # good: [a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4] efi_loader: split efi_init_obj_list() into two stages git bisect good a57ad20d07e82f9ddbbdf981c8f8dd5368b225e4 # first bad commit: [a9bf024b2933bba0e23038892970a18b72dfaeb4] efi_loader: disk: a helper function to create efi_disk objects from udevice
Neil

I has similar problem on axg meson64. Seems problem exists at least on 1Gb RAM devices, my device with 2 GB RAM did not hit this error.
19.05.2022 8:04, AKASHI Takahiro wrote:
On Wed, May 18, 2022 at 11:23:32AM +0200, Neil Armstrong wrote:
On 19/04/2022 03:05, AKASHI Takahiro wrote:
Add efi_disk_probe() function. This function creates an efi_disk object for a raw disk device (UCLASS_BLK) and additional objects for related partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "probe" interface every time one raw disk device is detected and activated. We assume that partition devices (UCLASS_PARTITION) have been created when this function is invoked.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org
include/efi_loader.h | 4 +- lib/efi_driver/efi_block_device.c | 34 ++--- lib/efi_loader/Kconfig | 3 + lib/efi_loader/efi_disk.c | 201 +++++++++++++++++++----------- lib/efi_loader/efi_setup.c | 4 +- 5 files changed, 143 insertions(+), 103 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 5bb8fb2acd04..ba79a9afb404 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -525,8 +525,8 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by bootefi to make all disk storage accessible as EFI objects */ -efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to initialize efi_disks */ +efi_status_t efi_disk_init(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index 04cb3ef0d4e5..5baa6f87a375 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,6 +35,7 @@ #include <malloc.h> #include <dm/device-internal.h> #include <dm/root.h> +#include <dm/tag.h> /* * EFI attributes of the udevice handled by this driver. @@ -106,25 +107,6 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; } -/**
- Create partions for the block device.
- @handle: EFI handle of the block device
- @dev: udevice of the block device
- Return: number of partitions created
- */
-static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) -{
- struct blk_desc *desc;
- const char *if_typename;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- return efi_disk_create_partitions(handle, desc, if_typename,
desc->devnum, dev->name);
-}
- /**
- Create a block device for a handle
@@ -139,7 +121,6 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) char *name; struct efi_object *obj = efi_search_obj(handle); struct efi_block_io *io = interface;
- int disks; struct efi_blk_plat *plat; EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
@@ -173,15 +154,20 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) plat->handle = handle; plat->io = interface;
- /*
* FIXME: necessary because we won't do almost nothing in
* efi_disk_create() when called from device_probe().
*/
- ret = dev_tag_set_ptr(bdev, DM_TAG_EFI, handle);
- if (ret)
/* FIXME: cleanup for bdev */
return ret;
- ret = device_probe(bdev); if (ret) return ret; EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- /* Create handles for the partions of the block device */
- disks = efi_bl_bind_partitions(handle, bdev);
- EFI_PRINT("Found %d partitions\n", disks);
- return 0; }
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc518d7a413b..6b245f50a726 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -14,6 +14,8 @@ config EFI_LOADER depends on DM_ETH || !NET depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select DM_EVENT
- select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS select HAVE_BLOCK_DEVICE
@@ -40,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR config EFI_SETUP_EARLY bool
- default y choice prompt "Store for non-volatile UEFI variables"
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc2f..d4a0edb458b8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -10,6 +10,9 @@ #include <common.h> #include <blk.h> #include <dm.h> +#include <dm/device-internal.h> +#include <dm/tag.h> +#include <event.h> #include <efi_loader.h> #include <fs.h> #include <log.h> @@ -487,103 +490,153 @@ error: return ret; } -/**
- efi_disk_create_partitions() - create handles and protocols for partitions
+/*
- Create a handle for a whole raw disk
- @dev uclass device (UCLASS_BLK)
- Create handles and protocols for the partitions of a block device.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- @parent: handle of the parent disk
- @desc: block device
- @if_typename: interface type
- @diskid: device number
- @pdevname: device name
- Return: number of partitions created
- @return 0 on success, -1 otherwise */
-int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
const char *if_typename, int diskid,
const char *pdevname)
+static int efi_disk_create_raw(struct udevice *dev) {
- int disks = 0;
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
- int part;
- struct efi_device_path *dp = NULL;
- struct efi_disk_obj *disk;
- struct blk_desc *desc;
- const char *if_typename;
- int diskid; efi_status_t ret;
- struct efi_handler *handler;
- /* Get the device path of the parent */
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret == EFI_SUCCESS)
dp = handler->protocol_interface;
- /* Add devices for each partition */
- for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
struct disk_partition info;
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%x", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
&info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
}
disks++;
- desc = dev_get_uclass_plat(dev);
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
diskid, NULL, 0, &disk);
- if (ret != EFI_SUCCESS) {
if (ret == EFI_NOT_READY)
log_notice("Disk %s not ready\n", dev->name);
else
log_err("Adding disk for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
}return -1;
- return disks;
- return 0; }
-/**
- efi_disk_register() - register block devices
- U-Boot doesn't have a list of all online disk devices. So when running our
- EFI payload, we scan through all of the potentially available ones and
- store them in our object pool.
+/*
- Create a handle for a disk partition
- This function is called in efi_init_obj_list().
- @dev uclass device (UCLASS_PARTITION)
- TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
- Consider converting the code to look up devices as needed. The EFI device
- could be a child of the UCLASS_BLK block device, perhaps.
- Create an efi_disk object which is associated with @dev.
- The type of @dev must be UCLASS_PARTITION.
- Return: status code
- @return 0 on success, -1 otherwise */
-efi_status_t efi_disk_register(void) +static int efi_disk_create_part(struct udevice *dev) {
- efi_handle_t parent;
- struct blk_desc *desc;
- const char *if_typename;
- struct disk_part *part_data;
- struct disk_partition *info;
- unsigned int part;
- int diskid;
- struct efi_handler *handler;
- struct efi_device_path *dp_parent; struct efi_disk_obj *disk;
- int disks = 0; efi_status_t ret;
- if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent))
return -1;
- desc = dev_get_uclass_plat(dev_get_parent(dev));
- if_typename = blk_get_if_type_name(desc->if_type);
- diskid = desc->devnum;
- part_data = dev_get_uclass_plat(dev);
- part = part_data->partnum;
- info = &part_data->gpt_part_info;
- ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
- if (ret != EFI_SUCCESS)
return -1;
- dp_parent = (struct efi_device_path *)handler->protocol_interface;
- ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid,
info, part, &disk);
- if (ret != EFI_SUCCESS) {
log_err("Adding partition for %s failed\n", dev->name);
return -1;
- }
- if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
efi_free_pool(disk->dp);
efi_delete_handle(&disk->header);
return -1;
- }
- return 0;
+}
+/*
- Create efi_disk objects for a block device
- @dev uclass device (UCLASS_BLK)
- Create efi_disk objects for partitions as well as a raw disk
- which is associated with @dev.
- The type of @dev must be UCLASS_BLK.
- This function is expected to be called at EV_PM_POST_PROBE.
- @return 0 on success, -1 otherwise
- */
+static int efi_disk_probe(void *ctx, struct event *event) +{ struct udevice *dev;
- enum uclass_id id;
- struct udevice *child;
- int ret;
- for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
uclass_next_device_check(&dev)) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
const char *if_typename = blk_get_if_type_name(desc->if_type);
- dev = event->data.dm.dev;
- id = device_get_uclass_id(dev);
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
}
if (ret) {
log_err("ERROR: failure to add disk device %s, r = %lu\n",
dev->name, ret & ~EFI_ERROR_MASK);
continue;
}
disks++;
- /* TODO: We won't support partitions in a partition */
- if (id != UCLASS_BLK)
return 0;
- ret = efi_disk_create_raw(dev);
- if (ret)
return -1;
/* Partitions show up as block devices in EFI */
disks += efi_disk_create_partitions(
&disk->header, desc, if_typename,
desc->devnum, dev->name);
- device_foreach_child(child, dev) {
ret = efi_disk_create_part(child);
if (ret)
}return -1;
- log_info("Found %d disks\n", disks);
- return 0;
+}
+efi_status_t efi_disk_init(void) +{
- int ret;
- ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
efi_disk_probe, NULL);
- if (ret) {
log_err("Event registration for efi_disk add failed\n");
return EFI_OUT_OF_RESOURCES;
- } return EFI_SUCCESS; }
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index de2f34bab537..250eeb2fcd6b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,9 +198,7 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out; -#ifdef CONFIG_PARTITIONS
- ret = efi_disk_register();
-#endif
- ret = efi_disk_init(); out: return ret; }
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
Can you confirm that you do not use UEFI feature in your boot scenario here and yet you see a problem in UEFI subsystem?
Found U-Boot script /boot.scr 449 bytes read in 2 ms (218.8 KiB/s) ## Executing script at 08000000 36500032 bytes read in 1554 ms (22.4 MiB/s) 42873252 bytes read in 1829 ms (22.4 MiB/s) 29092 bytes read in 4 ms (6.9 MiB/s) ## Booting kernel from Legacy Image at 13000000 ... Image Name: Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 36499968 Bytes = 34.8 MiB Load Address: 13000000 Entry Point: 13000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 06000000 ... Image Name: Image Type: AArch64 Linux RAMDisk Image (uncompressed) Data Size: 42873188 Bytes = 40.9 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 09000000 Booting using the fdt blob at 0x9000000 Loading Kernel Image Loading Ramdisk to 7965b000, end 7bf3e164 ... OK Loading Device Tree to 0000000079650000, end 000000007965a1a3 ... OK "Synchronous Abort" handler, esr 0x96000004 elr: 0000000001065150 lr : 0000000001054b18 (reloc)
Can you check where (functions) those two addresses (elr,lr) come from?
elr: 000000007dfb5150 lr : 000000007dfa4b18 x0 : d55d507f5dacfff5 x1 : 000000007dfbce48 x2 : 0000000000000010 x3 : 0000000000000000 x4 : 0000000000000000 x5 : d55d507f5dacfff5 x6 : 000000007bf55bb0 x7 : 0000000000000000 x8 : 0000000000000007 x9 : 0000000000000000 x10: 0000000000000178 x11: 000000007bf4211c x12: 00000000000000a4 x13: 000000007bf420d8 x14: 0000000079650000 x15: 0000000000000020 x16: 000000007df83454 x17: 0000000000000000 x18: 000000007bf4ddb0 x19: 000000007af42040 x20: 000000007df50b20 x21: 000000007dfbce48 x22: 0000000000001000 x23: 000000007bf55b00 x24: 000000007dfdb910 x25: 0000000001000000 x26: 0000000001000000 x27: 0000000001000000 x28: 0000000000001000 x29: 000000007bf420d0
Code: eb02009f 54000061 52800000 14000006 (386468a3)
As far as my locally-built binary is concerned, the faulted instruction is located in memcpy().
000000000106xxxx <memcmp>: 106xxxx: aa0003e5 mov x5, x0 106xxxx: d2800004 mov x4, #0x0 // #0 106xxxx: eb02009f cmp x4, x2 106xxxx: 54000061 b.ne 10653d4 <memcmp+0x18> // b.any 106xxxx: 52800000 mov w0, #0x0 // #0 106xxxx: 14000006 b 10653e8 <memcmp+0x2c> 106xxxx: 386468a3 ldrb w3, [x5, x4]
'x5' seems to be bogus. The memory content might have been corrupted at this point.
Same place:
"Synchronous Abort" handler, esr 0x96000004 elr: 000000000105ff48 lr : 00000000010504d4 (reloc) elr: 000000003ffa4f48 lr : 000000003ff954d4 x0 : 5695c9ebf0a7d8b1 x1 : 000000003ffac700 x2 : 0000000000000010 x3 : 0000000000000000 x4 : 0000000000000000 x5 : 5695c9ebf0a7d8b1 x6 : 000000003df4e3b0 x7 : 0000000000000007 x8 : 0000000000000000 x9 : 0000000000000008 x10: 0000000000008030 x11: 000000003df3496c x12: 0000000000007fa8 x13: 000000003df34928 x14: 000000003ce18000 x15: 0000000000000020 x16: 000000003ff75d74 x17: 0000000000000000 x18: 000000003df42dc0 x19: 000000003cf34040 x20: 000000003ff45b20 x21: 000000003ffac700 x22: 0000000000000300 x23: 000000003df4e300 x24: 000000003ffca5e8 x25: 0000000005300000 x26: 0000000000300000 x27: 0000000000000000 x28: 0000000000000300 x29: 000000003df34930
Code: eb02009f 54000061 52800000 14000006 (386468a3) 000000000105ff30 <memcmp>: 105ff30: aa0003e5 mov x5, x0 105ff34: d2800004 mov x4, #0x0 // #0 105ff38: eb02009f cmp x4, x2 105ff3c: 54000061 b.ne 105ff48 <memcmp+0x18> // b.any 105ff40: 52800000 mov w0, #0x0 // #0 105ff44: 14000006 b 105ff5c <memcmp+0x2c> *105ff48: 386468a3 ldrb w3, [x5, x4] 105ff4c: 38646820 ldrb w0, [x1, x4]
I don't know how to get the call stack from this information. What else can I do to investigate the problem?

Config for jethub_j100 did't contain any EFI* options. But build .config has these lines: CONFIG_BOOTMETH_EFILOADER=y CONFIG_CMD_BOOTEFI=y CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y CONFIG_EFI_PARTITION=y CONFIG_EFI_LOADER=y CONFIG_CMD_BOOTEFI_BOOTMGR=y CONFIG_EFI_SETUP_EARLY=y CONFIG_EFI_VARIABLE_FILE_STORE=y CONFIG_EFI_GET_TIME=y CONFIG_EFI_DEVICE_PATH_TO_TEXT=y CONFIG_EFI_DEVICE_PATH_UTIL=y CONFIG_EFI_DT_FIXUP=y CONFIG_EFI_LOADER_HII=y CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2=y CONFIG_EFI_UNICODE_CAPITALIZATION=y CONFIG_EFI_HAVE_RUNTIME_RESET=y CONFIG_EFI_RNG_PROTOCOL=y CONFIG_EFI_LOAD_FILE2_INITRD=y
If I set it all to "n" bug dissapears and board boots normally.
24.08.2022 12:00, Vyacheslav wrote:
I has similar problem on axg meson64. Seems problem exists at least on 1Gb RAM devices, my device with 2 GB RAM did not hit this error.

On Wed, May 18, 2022 at 6:23 AM Neil Armstrong narmstrong@baylibre.com wrote:
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
This change also causes issues on a kontron-sl-mx8mm and imx8mn ddr3 evk boards.
The problem on these boards is that serial console garbage is seen:
Net: eth0: ethernet@30be0000 Hit any key to stop autoboot: 0 u-boot=> [25;88R Unknown command '[25' - try 'help' Unknown command '88R' - try 'help'
These extraneous characters stop the boot process.
As a workaround, I disabled CONFIG_EFI_LOADER, and then the serial garbage does not happen and the board can boot normally.
Heiko confirmed the same behavior on an imx8mn evk ddr3 board.

On Mon, Jun 13, 2022 at 04:54:45PM -0300, Fabio Estevam wrote:
On Wed, May 18, 2022 at 6:23 AM Neil Armstrong narmstrong@baylibre.com wrote:
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
This change also causes issues on a kontron-sl-mx8mm and imx8mn ddr3 evk boards.
The problem on these boards is that serial console garbage is seen:
Net: eth0: ethernet@30be0000 Hit any key to stop autoboot: 0 u-boot=> [25;88R Unknown command '[25' - try 'help' Unknown command '88R' - try 'help'
These extraneous characters stop the boot process.
As a workaround, I disabled CONFIG_EFI_LOADER, and then the serial garbage does not happen and the board can boot normally.
Heiko confirmed the same behavior on an imx8mn evk ddr3 board.
What happens if you increase logging so that you can see other errors that happen as it feels like we're probably overflowing some buffer or something along the way.

Date: Mon, 13 Jun 2022 16:10:57 -0400 From: Tom Rini trini@konsulko.com
On Mon, Jun 13, 2022 at 04:54:45PM -0300, Fabio Estevam wrote:
On Wed, May 18, 2022 at 6:23 AM Neil Armstrong narmstrong@baylibre.com wrote:
This change as commit a9bf024b2933bba0e23038892970a18b72dfaeb4 in master makes Amlogic S905X board libretech-cc to crash:
This change also causes issues on a kontron-sl-mx8mm and imx8mn ddr3 evk boards.
The problem on these boards is that serial console garbage is seen:
Net: eth0: ethernet@30be0000 Hit any key to stop autoboot: 0 u-boot=> [25;88R Unknown command '[25' - try 'help' Unknown command '88R' - try 'help'
These extraneous characters stop the boot process.
This looks like the reply the terminal sends in response to the "Query cursor position" command that is sent in lib/efi_loader/efi_console.c:query_console_serial().
It might be worth trying to increase the timeout in term_get_char().
If that doesn't help, it probably means the initial ESC character gets lost because the serial port has a very small (or no) FIFO and u-boot isn't reading characters fast enough. If that is the case, maybe we we should make the query_console_serial() call optional and only enable it on SoCs that have a large enough FIFO for this to be safe.
Cheers,
Mark

Hi Mark,
On Mon, Jun 13, 2022 at 7:21 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
This looks like the reply the terminal sends in response to the "Query cursor position" command that is sent in lib/efi_loader/efi_console.c:query_console_serial().
It might be worth trying to increase the timeout in term_get_char().
I did as you suggested and increased the timeout from 100ms to 1000ms.
After that, I no longer see the problem, thanks!
Would this be an acceptable fix?

Am 14. Juni 2022 00:48:01 MESZ schrieb Fabio Estevam festevam@gmail.com:
Hi Mark,
On Mon, Jun 13, 2022 at 7:21 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
This looks like the reply the terminal sends in response to the "Query cursor position" command that is sent in lib/efi_loader/efi_console.c:query_console_serial().
It might be worth trying to increase the timeout in term_get_char().
I did as you suggested and increased the timeout from 100ms to 1000ms.
After that, I no longer see the problem, thanks!
Would this be an acceptable fix?
Slowing down every boot without connected serial by 1000ms seems to be a bad idea.
What baud rate are you using?
What terminal software are you using giving the late response?
Does printf() return before the last byte is sent by the serial IO transfer buffer? What size has that buffer?
I suggest that the EFI console should not query the screen size before starting the first EFI binary.
Best regards
Heinrich

Hi Heinrich,
On Mon, Jun 13, 2022 at 8:39 PM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
Slowing down every boot without connected serial by 1000ms seems to be a bad idea.
What baud rate are you using?
115200.
What terminal software are you using giving the late response?
I will check. I am accessing the board remotely.
Heiko also sees the problem. Maybe he could share what terminal software he uses.
Does printf() return before the last byte is sent by the serial IO transfer buffer? What size has that buffer?
Looks like I would need to instrument the code to answer this.
I suggest that the EFI console should not query the screen size before starting the first EFI binary.
Could you please propose I patch doing this?
To be honest, I don't need EFI, but it gets automatically selected, and that's why I see the problem.
For the moment, I am disabling CONFIG_EFI_LOADER as a workaround.
I can help to test patches, but I am not familiar with EFI to propose a fix.
Thanks,
Fabio Estevam

Hi,
Am Di., 14. Juni 2022 um 01:54 Uhr schrieb Fabio Estevam festevam@gmail.com:
Hi Heinrich,
On Mon, Jun 13, 2022 at 8:39 PM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
Slowing down every boot without connected serial by 1000ms seems to be a bad idea.
What baud rate are you using?
What terminal software are you using giving the late response?
I will check. I am accessing the board remotely.
Heiko also sees the problem. Maybe he could share what terminal software he uses.
I use ser2net and connect with the linux telnet client.
Does printf() return before the last byte is sent by the serial IO transfer buffer? What size has that buffer?
Looks like I would need to instrument the code to answer this.
I suggest that the EFI console should not query the screen size before starting the first EFI binary.
Could you please propose I patch doing this?
To be honest, I don't need EFI, but it gets automatically selected, and that's why I see the problem.
For the moment, I am disabling CONFIG_EFI_LOADER as a workaround.
I can help to test patches, but I am not familiar with EFI to propose a fix.
Thanks,
Fabio Estevam

On Mon, Jun 13, 2022 at 07:48:01PM -0300, Fabio Estevam wrote:
Hi Mark,
On Mon, Jun 13, 2022 at 7:21 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
This looks like the reply the terminal sends in response to the "Query cursor position" command that is sent in lib/efi_loader/efi_console.c:query_console_serial().
It might be worth trying to increase the timeout in term_get_char().
I did as you suggested and increased the timeout from 100ms to 1000ms.
After that, I no longer see the problem, thanks!
So I hope that my patch has broken nothing.
-Takahiro Akashi
Would this be an acceptable fix?

When we create an efi_disk device with an UEFI application using driver binding protocol, the 'efi_driver' framework tries to create a corresponding block device(UCLASS_BLK/IF_TYPE_EFI). This will lead to calling a PROBE callback, efi_disk_probe(). In this case, however, we don't need to create another "efi_disk" device as we already have this device instance.
So we should avoid recursively invoke further processing in the callback function.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- lib/efi_loader/efi_disk.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index d4a0edb458b8..037f8594a727 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -604,6 +604,7 @@ static int efi_disk_probe(void *ctx, struct event *event) { struct udevice *dev; enum uclass_id id; + struct blk_desc *desc; struct udevice *child; int ret;
@@ -614,9 +615,16 @@ static int efi_disk_probe(void *ctx, struct event *event) if (id != UCLASS_BLK) return 0;
- ret = efi_disk_create_raw(dev); - if (ret) - return -1; + /* + * avoid creating duplicated objects now that efi_driver + * has already created an efi_disk at this moment. + */ + desc = dev_get_uclass_plat(dev); + if (desc->if_type != IF_TYPE_EFI_LOADER) { + ret = efi_disk_create_raw(dev); + if (ret) + return -1; + }
device_foreach_child(child, dev) { ret = efi_disk_create_part(child);

This function is expected to be called, in particular from dm's pre_remove hook, when associated block devices no longer exist.
Add efi_disk_remove() function. This function removes an efi_disk object for a raw disk device (UCLASS_BLK) and related objects for its partitions (UCLASS_PARTITION).
So this function is expected to be called through driver model's "remove" interface every time a raw disk device is to be disconnected.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- lib/efi_loader/efi_disk.c | 88 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 037f8594a727..940390ac8bcc 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -635,6 +635,87 @@ static int efi_disk_probe(void *ctx, struct event *event) return 0; }
+/* + * Delete an efi_disk object for a whole raw disk + * + * @dev uclass device (UCLASS_BLK) + * + * Delete an efi_disk object which is associated with @dev. + * The type of @dev must be UCLASS_BLK. + * + * @return 0 on success, -1 otherwise + */ +static int efi_disk_delete_raw(struct udevice *dev) +{ + efi_handle_t handle; + struct efi_disk_obj *diskobj; + + if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) + return -1; + + diskobj = container_of(handle, struct efi_disk_obj, header); + efi_free_pool(diskobj->dp); + + efi_delete_handle(handle); + dev_tag_del(dev, DM_TAG_EFI); + + return 0; +} + +/* + * Delete an efi_disk object for a disk partition + * + * @dev uclass device (UCLASS_PARTITION) + * + * Delete an efi_disk object which is associated with @dev. + * The type of @dev must be UCLASS_PARTITION. + * + * @return 0 on success, -1 otherwise + */ +static int efi_disk_delete_part(struct udevice *dev) +{ + efi_handle_t handle; + struct efi_disk_obj *diskobj; + + if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) + return -1; + + diskobj = container_of(handle, struct efi_disk_obj, header); + + efi_free_pool(diskobj->dp); + efi_delete_handle(handle); + dev_tag_del(dev, DM_TAG_EFI); + + return 0; +} + +/* + * Delete an efi_disk object for a block device + * + * @dev uclass device (UCLASS_BLK or UCLASS_PARTITION) + * + * Delete an efi_disk object which is associated with @dev. + * The type of @dev must be either UCLASS_BLK or UCLASS_PARTITION. + * This function is expected to be called at EV_PM_PRE_REMOVE. + * + * @return 0 on success, -1 otherwise + */ +static int efi_disk_remove(void *ctx, struct event *event) +{ + enum uclass_id id; + struct udevice *dev; + + dev = event->data.dm.dev; + id = device_get_uclass_id(dev); + + if (id == UCLASS_BLK) + return efi_disk_delete_raw(dev); + else if (id == UCLASS_PARTITION) + return efi_disk_delete_part(dev); + else + return 0; +} + efi_status_t efi_disk_init(void) { int ret; @@ -646,5 +727,12 @@ efi_status_t efi_disk_init(void) return EFI_OUT_OF_RESOURCES; }
+ ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE, + efi_disk_remove, NULL); + if (ret) { + log_err("Event registration for efi_disk del failed\n"); + return EFI_OUT_OF_RESOURCES; + } + return EFI_SUCCESS; }

When we create an efi_disk device with an UEFI application using driver binding protocol, the 'efi_driver' framework tries to create a corresponding block device(UCLASS_BLK/IF_TYPE_EFI). This will lead to calling a PROBE callback, efi_disk_probe(). In this case, however, we don't need to create another "efi_disk" device as we already have this device instance.
So we should avoid recursively invoke further processing in the callback function.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- lib/efi_loader/efi_disk.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 940390ac8bcc..34bb662e9cc0 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -648,13 +648,17 @@ static int efi_disk_probe(void *ctx, struct event *event) static int efi_disk_delete_raw(struct udevice *dev) { efi_handle_t handle; + struct blk_desc *desc; struct efi_disk_obj *diskobj;
if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) return -1;
- diskobj = container_of(handle, struct efi_disk_obj, header); - efi_free_pool(diskobj->dp); + desc = dev_get_uclass_plat(dev); + if (desc->if_type != IF_TYPE_EFI_LOADER) { + diskobj = container_of(handle, struct efi_disk_obj, header); + efi_free_pool(diskobj->dp); + }
efi_delete_handle(handle); dev_tag_del(dev, DM_TAG_EFI);

In include/blk.h, Simon suggested: ===> /* * These functions should take struct udevice instead of struct blk_desc, * but this is convenient for migration to driver model. Add a 'd' prefix * to the function operations, so that blk_read(), etc. can be reserved for * functions with the correct arguments. */ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *buffer); unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *buffer); unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt); <===
So new interfaces are provided with this patch.
They are expected to be used everywhere in U-Boot at the end. The exceptions are block device drivers, partition drivers and efi_disk which should know details of blk_desc structure.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- disk/disk-uclass.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 7 ++++ 2 files changed, 101 insertions(+)
diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c index 4918a2f72d1e..72ff62ebf581 100644 --- a/disk/disk-uclass.c +++ b/disk/disk-uclass.c @@ -146,6 +146,100 @@ U_BOOT_DRIVER(blk_partition) = { .ops = &blk_part_ops, };
+/* + * BLOCK IO APIs + */ +static struct blk_desc *dev_get_blk(struct udevice *dev) +{ + struct blk_desc *block_dev; + + switch (device_get_uclass_id(dev)) { + /* + * We won't support UCLASS_BLK with dev_* interfaces. + */ + case UCLASS_PARTITION: + block_dev = dev_get_uclass_plat(dev_get_parent(dev)); + break; + default: + block_dev = NULL; + break; + } + + return block_dev; +} + +unsigned long dev_read(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, void *buffer) +{ + struct blk_desc *block_dev; + const struct blk_ops *ops; + struct disk_part *part; + lbaint_t start_in_disk; + ulong blks_read; + + block_dev = dev_get_blk(dev); + if (!block_dev) + return -ENOSYS; + + ops = blk_get_ops(dev); + if (!ops->read) + return -ENOSYS; + + start_in_disk = start; + if (device_get_uclass_id(dev) == UCLASS_PARTITION) { + part = dev_get_uclass_plat(dev); + start_in_disk += part->gpt_part_info.start; + } + + if (blkcache_read(block_dev->if_type, block_dev->devnum, + start_in_disk, blkcnt, block_dev->blksz, buffer)) + return blkcnt; + blks_read = ops->read(dev, start, blkcnt, buffer); + if (blks_read == blkcnt) + blkcache_fill(block_dev->if_type, block_dev->devnum, + start_in_disk, blkcnt, block_dev->blksz, buffer); + + return blks_read; +} + +unsigned long dev_write(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, const void *buffer) +{ + struct blk_desc *block_dev; + const struct blk_ops *ops; + + block_dev = dev_get_blk(dev); + if (!block_dev) + return -ENOSYS; + + ops = blk_get_ops(dev); + if (!ops->write) + return -ENOSYS; + + blkcache_invalidate(block_dev->if_type, block_dev->devnum); + + return ops->write(dev, start, blkcnt, buffer); +} + +unsigned long dev_erase(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt) +{ + struct blk_desc *block_dev; + const struct blk_ops *ops; + + block_dev = dev_get_blk(dev); + if (!block_dev) + return -ENOSYS; + + ops = blk_get_ops(dev); + if (!ops->erase) + return -ENOSYS; + + blkcache_invalidate(block_dev->if_type, block_dev->devnum); + + return ops->erase(dev, start, blkcnt); +} + UCLASS_DRIVER(partition) = { .id = UCLASS_PARTITION, .per_device_plat_auto = sizeof(struct disk_part), diff --git a/include/part.h b/include/part.h index c4e0bef7749d..4956cec314ed 100644 --- a/include/part.h +++ b/include/part.h @@ -306,6 +306,13 @@ struct udevice; */ int part_create_block_devices(struct udevice *blk_dev);
+unsigned long dev_read(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, void *buffer); +unsigned long dev_write(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt, const void *buffer); +unsigned long dev_erase(struct udevice *dev, lbaint_t start, + lbaint_t blkcnt); + /* * We don't support printing partition information in SPL and only support * getting partition information in a few cases.

In most of all cases, we can avoid using blk_desc which is expected to be private to udevice(UCLASS_BLK), that is, the data should not be manipulated outside the device driver unless really needed.
Now efi_disk's internally use dev_read/write() interfaces if CONFIG_PARTITIONS is enabled.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- lib/efi_loader/efi_disk.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 34bb662e9cc0..8fb5b2363c45 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -36,7 +36,7 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID; * @part: partition * @volume: simple file system protocol of the partition * @offset: offset into disk for simple partition - * @desc: internal block device descriptor + * @dev: associated DM device */ struct efi_disk_obj { struct efi_object header; @@ -48,7 +48,7 @@ struct efi_disk_obj { unsigned int part; struct efi_simple_file_system_protocol *volume; lbaint_t offset; - struct blk_desc *desc; + struct udevice *dev; /* TODO: move it to efi_object */ };
/** @@ -83,14 +83,12 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this, void *buffer, enum efi_disk_direction direction) { struct efi_disk_obj *diskobj; - struct blk_desc *desc; int blksz; int blocks; unsigned long n;
diskobj = container_of(this, struct efi_disk_obj, ops); - desc = (struct blk_desc *) diskobj->desc; - blksz = desc->blksz; + blksz = diskobj->media.block_size; blocks = buffer_size / blksz; lba += diskobj->offset;
@@ -101,10 +99,21 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this, if (buffer_size & (blksz - 1)) return EFI_BAD_BUFFER_SIZE;
+#if CONFIG_IS_ENABLED(PARTITIONS) + if (direction == EFI_DISK_READ) + n = dev_read(diskobj->dev, lba, blocks, buffer); + else + n = dev_write(diskobj->dev, lba, blocks, buffer); +#else + /* dev is always a block device (UCLASS_BLK) */ + struct blk_desc *desc; + + desc = dev_get_uclass_plat(diskobj->dev); if (direction == EFI_DISK_READ) n = blk_dread(desc, lba, blocks, buffer); else n = blk_dwrite(desc, lba, blocks, buffer); +#endif
/* We don't do interrupts, so check for timers cooperatively */ efi_timer_check(); @@ -446,7 +455,6 @@ static efi_status_t efi_disk_add_dev( diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diskobj->dev_index = dev_index; - diskobj->desc = desc;
/* Fill in EFI IO Media info (for read/write callbacks) */ diskobj->media.removable_media = desc->removable; @@ -522,6 +530,7 @@ static int efi_disk_create_raw(struct udevice *dev)
return -1; } + disk->dev = dev; if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { efi_free_pool(disk->dp); efi_delete_handle(&disk->header); @@ -578,6 +587,7 @@ static int efi_disk_create_part(struct udevice *dev) log_err("Adding partition for %s failed\n", dev->name); return -1; } + disk->dev = dev; if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { efi_free_pool(disk->dp); efi_delete_handle(&disk->header);

On 4/19/22 03:05, AKASHI Takahiro wrote:
With this patch set[1] applied, UEFI subsystem maintains a list of its disk objects dynamically at runtime based on block device's probing. (See "issues" and "prerequisite" below.)
[1] https://github.com/t-akashi/u-boot/tree/efi/dm_disk
For instance, => dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ ] ahci_pci | |-- ahci_pci scsi 0 [ ] ahci_scsi | | `-- ahci_scsi usb 0 [ ] xhci_pci | `-- xhci_pci ... => efi devices Missing RNG device for EFI_RNG_PROTOCOL No EFI system partition Unable to find TPMv2 device Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) => scsi rescan
With the series binding block devices after initializing the UEFI sub-system works fine. Also unbinding is reflected in the EFI devices.
But this series breaks UEFI compliance. All block devices must be probed before booting. Without this GRUB will not be able to read the boot partition with vmlinuz and initrd.
Will you provide the missing patch?
Best regards
Heinrich

On Mon, Apr 25, 2022 at 10:43:44PM +0200, Heinrich Schuchardt wrote:
On 4/19/22 03:05, AKASHI Takahiro wrote:
With this patch set[1] applied, UEFI subsystem maintains a list of its disk objects dynamically at runtime based on block device's probing. (See "issues" and "prerequisite" below.)
[1] https://github.com/t-akashi/u-boot/tree/efi/dm_disk
For instance, => dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ ] ahci_pci | |-- ahci_pci scsi 0 [ ] ahci_scsi | | `-- ahci_scsi usb 0 [ ] xhci_pci | `-- xhci_pci ... => efi devices Missing RNG device for EFI_RNG_PROTOCOL No EFI system partition Unable to find TPMv2 device Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) => scsi rescan
With the series binding block devices after initializing the UEFI sub-system works fine. Also unbinding is reflected in the EFI devices.
But this series breaks UEFI compliance.
I don't think so.
All block devices must be probed before booting.
This (not enumerating all the devices) is also true even before my patch.
Without this GRUB will not be able to read the boot partition with vmlinuz and initrd.
I'm not sure what you expect here, but is it enough to define "preboot" variables with any number of enumerating commands, like "scsi rescan", "usb start" and so on?
# Again, this method can also be applied even without my patch.
-Takahiro Akashi
Will you provide the missing patch?
Best regards
Heinrich

On 4/26/22 01:44, AKASHI Takahiro wrote:
On Mon, Apr 25, 2022 at 10:43:44PM +0200, Heinrich Schuchardt wrote:
On 4/19/22 03:05, AKASHI Takahiro wrote:
With this patch set[1] applied, UEFI subsystem maintains a list of its disk objects dynamically at runtime based on block device's probing. (See "issues" and "prerequisite" below.)
[1] https://github.com/t-akashi/u-boot/tree/efi/dm_disk
For instance, => dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ ] ahci_pci | |-- ahci_pci scsi 0 [ ] ahci_scsi | | `-- ahci_scsi usb 0 [ ] xhci_pci | `-- xhci_pci ... => efi devices Missing RNG device for EFI_RNG_PROTOCOL No EFI system partition Unable to find TPMv2 device Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) => scsi rescan
With the series binding block devices after initializing the UEFI sub-system works fine. Also unbinding is reflected in the EFI devices.
But this series breaks UEFI compliance.
I don't think so.
All block devices must be probed before booting.
This (not enumerating all the devices) is also true even before my patch.
Without this GRUB will not be able to read the boot partition with vmlinuz and initrd.
I'm not sure what you expect here, but is it enough to define "preboot" variables with any number of enumerating commands, like "scsi rescan", "usb start" and so on?
I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB!
error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles. But that function is missing now.
Best regards
Heinrich
# Again, this method can also be applied even without my patch.
-Takahiro Akashi
Will you provide the missing patch?
Best regards
Heinrich

On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote:
On Mon, Apr 25, 2022 at 10:43:44PM +0200, Heinrich Schuchardt wrote:
On 4/19/22 03:05, AKASHI Takahiro wrote:
With this patch set[1] applied, UEFI subsystem maintains a list of its disk objects dynamically at runtime based on block device's probing. (See "issues" and "prerequisite" below.)
[1] https://github.com/t-akashi/u-boot/tree/efi/dm_disk
For instance, => dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver ... pci 0 [ + ] pci_generic_ecam |-- pcie@10000000 ... ahci 0 [ ] ahci_pci | |-- ahci_pci scsi 0 [ ] ahci_scsi | | `-- ahci_scsi usb 0 [ ] xhci_pci | `-- xhci_pci ... => efi devices Missing RNG device for EFI_RNG_PROTOCOL No EFI system partition Unable to find TPMv2 device Device Device Path ================ ==================== 000000013eee88d0 /VenHw(..) 000000013ffeb798 /VenHw(..)/Uart(0,0,D,D) 000000013eeeb810 /VenHw(..)/MAC(525252525252,1) => scsi rescan
With the series binding block devices after initializing the UEFI sub-system works fine. Also unbinding is reflected in the EFI devices.
But this series breaks UEFI compliance.
I don't think so.
All block devices must be probed before booting.
This (not enumerating all the devices) is also true even before my patch.
Without this GRUB will not be able to read the boot partition with vmlinuz and initrd.
I'm not sure what you expect here, but is it enough to define "preboot" variables with any number of enumerating commands, like "scsi rescan", "usb start" and so on?
I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
Best regards
Heinrich
# Again, this method can also be applied even without my patch.
-Takahiro Akashi
Will you provide the missing patch?
Best regards
Heinrich

On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology ------------------------------------------------------------------
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr --------
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3 bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Best regards
Heinrich

Date: Tue, 26 Apr 2022 19:02:46 +0200 From: Heinrich Schuchardt xypron.glpk@gmx.de
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3 bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Also see the breakage I just found concerning raw disk access.
Should this series be reverted?

On Tue, Apr 26, 2022 at 07:18:13PM +0200, Mark Kettenis wrote:
Date: Tue, 26 Apr 2022 19:02:46 +0200 From: Heinrich Schuchardt xypron.glpk@gmx.de
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3 bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Also see the breakage I just found concerning raw disk access.
Should this series be reverted?
We're at -rc1, there's plenty of time to figure out what the right solution is.

Heinrich,
On Tue, Apr 26, 2022 at 07:02:46PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
Okay.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
Nothing special done here.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk
A block device detected here.
partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3
Apparently, there are three partition devices, then we should definitely have corresponding efi_disk objects as an efi_loader hook is registered against *POST_PROBE* event (of a *block* device).
In my patch c822c1a50bd7 ("mmc: call device_probe() after scanning"), device_probe() has already been installed to mmc_blk_probe().
Thinking of those circumstances, the natural guess is a *probe* function for "mmc@1c0f000.blk" device has never been called in your use case (even when loading an image from a specific partition, /boot/efi?).
To confirm this, you may simply try the followings: => mmc list ... => mmc dev 0 (<- the device number from 'mmc list') => efi devices
Then you will find three more efi_disk objects now that the parent block device is *probed*.
bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
Actually, loading an image does *not* invoke a probe function at all under the current implementation (of either "part" command, scan_dev_for_boot_part or even mmc drivers?).
I think that this is weird as the purpose of "probe" is to activate the device, or "probe - make a device ready for use" according to doc/develop/driver-model/design.rst
So my conclusion is that the current implementation has already broken the driver model even before my patch was applied. -> Simon, you should have a comment here?
That said, fixing a problem is a different matter. Probably, we will have to modify "part" command or mmc drivers themselves.
-Takahiro Akashi
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Best regards
Heinrich

On Wed, Apr 27, 2022 at 12:26:09PM +0900, AKASHI Takahiro wrote:
Heinrich,
On Tue, Apr 26, 2022 at 07:02:46PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
Okay.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
Nothing special done here.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk
A block device detected here.
partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3
Apparently, there are three partition devices, then we should definitely have corresponding efi_disk objects as an efi_loader hook is registered against *POST_PROBE* event (of a *block* device).
In my patch c822c1a50bd7 ("mmc: call device_probe() after scanning"), device_probe() has already been installed to mmc_blk_probe().
Thinking of those circumstances, the natural guess is a *probe* function for "mmc@1c0f000.blk" device has never been called in your use case (even when loading an image from a specific partition, /boot/efi?).
To confirm this, you may simply try the followings: => mmc list ... => mmc dev 0 (<- the device number from 'mmc list') => efi devices
Then you will find three more efi_disk objects now that the parent block device is *probed*.
bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
Actually, loading an image does *not* invoke a probe function at all under the current implementation (of either "part" command, scan_dev_for_boot_part or even mmc drivers?).
I think that this is weird as the purpose of "probe" is to activate the device, or "probe - make a device ready for use" according to doc/develop/driver-model/design.rst
So my conclusion is that the current implementation has already broken the driver model even before my patch was applied. -> Simon, you should have a comment here?
That said, fixing a problem is a different matter. Probably, we will have to modify "part" command or mmc drivers themselves.
Can you figure out an easy way to reproduce the issue? (either on sandbox or qemu-arm) Otherwise, it is difficult for me to investigate it.
-Takahiro Akashi
-Takahiro Akashi
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Best regards
Heinrich

On 4/28/22 06:52, AKASHI Takahiro wrote:
On Wed, Apr 27, 2022 at 12:26:09PM +0900, AKASHI Takahiro wrote:
Heinrich,
On Tue, Apr 26, 2022 at 07:02:46PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
Okay.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
Nothing special done here.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk
A block device detected here.
partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3
Apparently, there are three partition devices, then we should definitely have corresponding efi_disk objects as an efi_loader hook is registered against *POST_PROBE* event (of a *block* device).
In my patch c822c1a50bd7 ("mmc: call device_probe() after scanning"), device_probe() has already been installed to mmc_blk_probe().
Thinking of those circumstances, the natural guess is a *probe* function for "mmc@1c0f000.blk" device has never been called in your use case (even when loading an image from a specific partition, /boot/efi?).
To confirm this, you may simply try the followings: => mmc list ... => mmc dev 0 (<- the device number from 'mmc list') => efi devices
Then you will find three more efi_disk objects now that the parent block device is *probed*.
bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
Actually, loading an image does *not* invoke a probe function at all under the current implementation (of either "part" command, scan_dev_for_boot_part or even mmc drivers?).
We call efi_disk_init() after the MMC device is probed. Therefore probing of the MCC device does not trigger EVT_DM_POST_PROBE.
We have to move the efi_disk_init() call before initr_dm().
[PATCH 1/1] efi_loader: call efi_init_early() earlier https://lists.denx.de/pipermail/u-boot/2022-April/482701.html
With the patch GRUB now sees the MMC device but it is still not seeing the partitions:
grub rescue> ls (hd0) (hd1)
This is strange because devices and protocols look rather normal now:
=> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3 usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev
=> efidebug devices Device Device Path ======== ==================== 79f701e8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f70cd8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0) 79f70de0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(1,MBR,0xb6b4facb,0x800,0x200000) 79f711b0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(2,MBR,0xb6b4facb,0x200800,0x200000) 79f71538 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(3,MBR,0xb6b4facb,0x400800,0x379f800) 79f811b8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f81260 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdd748 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1)
=> efidebug dh Handle Protocols ======== ==================== 79f701e8 Device Path, Device Path To Text, Device Path Utilities, Device-Tree Fixup, Unicode Collation 2, HII String, HII Database, Simple Text Output, Simple Text Input, Simple Text Input Ex 7dffc7ec Device Path 79f70cd8 Device Path, Block IO 79f70de0 Device Path, Block IO, System Partition, Simple File System 79f711b0 Device Path, Block IO, Simple File System 79f71538 Device Path, Block IO, Simple File System 79f811b8 Device Path, Block IO 79f81260 Device Path, Block IO, System Partition, Simple File System 79f84978 Driver Binding 79fdd748 Simple Network, Device Path, PXE Base Code
This is the console log *before* the patch:
U-Boot 2022.07-rc1-00082-g8b2b125e95-dirty (Apr 28 2022 - 06:01:10 +0000) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Xunlong Orange Pi PC DRAM: 1 GiB drivers/mmc/sunxi_mmc.c(723)sunxi_mmc_bind: sunxi_set_gate: (CLK#54) unhandled Core: 70 devices, 20 uclasses, devicetree: separate WDT: Not starting watchdog@1c20ca0 MMC: drivers/mmc/sunxi_mmc.c(667)sunxi_mmc_probe: mmc@1c0f000: 0 Loading Environment from FAT... drivers/mmc/mmc-uclass.c(487)mmc_blk_probe: drivers/block/blk-uclass.c(746)blk_post_probe: drivers/block/blk-uclass.c(752)blk_post_probe: disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 part_create_block_devices: 3 partitions found in mmc@1c0f000.blk disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 Unable to read "uboot.env" from mmc0:1... In: serial Out: serial Err: serial Net: phy interface1 eth0: ethernet@1c30000 lib/efi_loader/efi_disk.c(739)efi_disk_init: starting USB... Bus usb@1c1a000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1a400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1b000: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: sunxi_set_gate: (CLK#9) unhandled lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1b400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1c000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1c400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1d000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1d400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: scanning bus usb@1c1a000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1a400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1b000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1b400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1c000 for devices... drivers/block/blk-uclass.c(746)blk_post_probe: drivers/block/blk-uclass.c(752)blk_post_probe: disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: part_create_block_devices: 1 partitions found in usb_mass_storage.lun0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(568)efi_disk_create_part: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: 2 USB Device(s) found scanning bus usb@1c1c400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1d000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1d400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Hit any key to stop autoboot: 0
Best regards
Heinrich
I think that this is weird as the purpose of "probe" is to activate the device, or "probe - make a device ready for use" according to doc/develop/driver-model/design.rst
So my conclusion is that the current implementation has already broken the driver model even before my patch was applied. -> Simon, you should have a comment here?
That said, fixing a problem is a different matter. Probably, we will have to modify "part" command or mmc drivers themselves.
Can you figure out an easy way to reproduce the issue? (either on sandbox or qemu-arm) Otherwise, it is difficult for me to investigate it.
-Takahiro Akashi
-Takahiro Akashi
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Best regards
Heinrich

Date: Thu, 28 Apr 2022 08:45:51 +0200 Content-Language: en-US From: Heinrich Schuchardt xypron.glpk@gmx.de Cc: masami.hiramatsu@linaro.org, u-boot@lists.denx.de, sjg@chromium.org, ilias.apalodimas@linaro.org, Tom Rini trini@konsulko.com, Mark Kettenis mark.kettenis@xs4all.nl Content-Type: text/plain; charset=UTF-8; format=flowed
On 4/28/22 06:52, AKASHI Takahiro wrote:
On Wed, Apr 27, 2022 at 12:26:09PM +0900, AKASHI Takahiro wrote:
Heinrich,
On Tue, Apr 26, 2022 at 07:02:46PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 16:44, AKASHI Takahiro wrote:
On Tue, Apr 26, 2022 at 03:57:26PM +0200, Heinrich Schuchardt wrote:
On 4/26/22 01:44, AKASHI Takahiro wrote: I expect that boards that booted with previous versions of U-Boot using the respective defconfig still boot. But they don't. Here is one example (orangepi_pc_defconfig):
Found U-Boot script /boot.scr.uimg 189 bytes read in 2 ms (91.8 KiB/s) ## Executing script at 43100000 22979 bytes read in 8 ms (2.7 MiB/s) 98304 bytes read in 8 ms (11.7 MiB/s) Booting /EFI\debian\grubarm.efi Welcome to GRUB! error: disk `,msdos2' not found. grub rescue>
In U-Boot v2022.04 function efi_disk_register() ensured that all block devices and their partitions were added as EFI handles.
Not the all block devices, but the block devices which have already enumerated when efi_init_obj_list() is called.
But that function is missing now.
What (boot) device are you using here?
Please show me the values of env variables, particularly, "boot_targets".
Please show me the content of boot.scr.uimg, too.
Please show me the output from => dm tree => efidebug devices for 2022.04 and 2022.07-rc1.
-Takahiro Akashi
I am booting from mmc. Boot.scr just loads the device-tree from mmc-
mmcblk0 179:0 0 29.8G 0 disk ├─mmcblk0p1 179:1 0 1G 0 part /boot/efi ├─mmcblk0p2 179:2 0 1G 0 part /boot └─mmcblk0p3 179:3 0 27.8G 0 part /
Okay.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
grub> ls (hd0) (hd0,msdos1) (hd1) (hd1,msdos3) (hd1,msdos2) (hd1,msdos1)
hd0 is a USB stick hd1 is the SD card
boot.scr
# # flash-kernel: bootscr.sunxi #
# boot script for Allwinner SunXi-based devices
# Mainline u-boot v2014.10 introduces a new default environment and # a new common bootcmd handling for all platforms, which is not fully # compatible with the old-style environment used by u-boot-sunxi. # This script therefore needs to check in which environment it # is running and set some variables accordingly.
# On u-boot-sunxi, this script assumes that ${device} and ${partition} # are set.
# The new-style environment predefines ${boot_targets}, the old-style # environment does not. if test -n "${boot_targets}" then echo "Mainline u-boot / new-style environment detected." # Mainline u-boot v2014.10 uses ${devtype}, ${devnum} and # ${bootpart} where u-boot-sunxi uses ${device} and ${partition}. # ${distro_bootpart} replaced ${bootpart} in u-boot v2016.01. if test -z "${device}"; then setenv device "${devtype}"; fi if test -z "${partition}${distro_bootpart}"; then setenv partition "${devnum}:${bootpart}"; fi if test -z "${partition}"; then setenv partition "${devnum}:${distro_bootpart}"; fi else echo "U-boot-sunxi / old-style environment detected." # U-boot-sunxi does not predefine kernel_addr_r, fdt_addr_r and # ramdisk_addr_r, so they have to be manually set. Use the values # from mainline u-boot v2014.10, except for ramdisk_addr_r, # which is set to 0x44300000 to allow for initrds larger than # 13MB on u-boot-sunxi. setenv kernel_addr_r 0x42000000 setenv fdt_addr_r 0x43000000 setenv ramdisk_addr_r 0x44300000 fi
if test -n "${console}"; then setenv bootargs "${bootargs} console=${console}" fi
setenv bootargs ${bootargs} quiet
if test -z "${image_locations}"; then setenv image_locations ${prefix} fi if test -z "${image_locations}"; then setenv image_locations /boot/ / fi
if test -z "${fk_kvers}"; then setenv fk_kvers '5.16.0-4-armmp-lpae' fi
if test -n "${fdtfile}"; then setenv fdtpath dtbs/${fk_kvers}/${fdtfile} else setenv fdtpath dtb-${fk_kvers} fi
for pathprefix in ${image_locations} do if test -e ${device} ${partition} ${pathprefix}vmlinuz-${fk_kvers} then load ${device} ${partition} ${kernel_addr_r} ${pathprefix}vmlinuz-${fk_kvers} \ && load ${device} ${partition} ${fdt_addr_r} ${pathprefix}${fdtpath} \ && load ${device} ${partition} ${ramdisk_addr_r} ${pathprefix}initrd.img-${fk_kvers} \ && echo "Booting Debian ${fk_kvers} from ${device} ${partition}..." \ && bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} fi done
Nothing special done here.
U-Boot 2022.04 (Apr 26 2022 - 16:02:27 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | `-- mmc@1c0f000.blk phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ ] usb_storage_blk | | `-- usb_mass_storage.lun0 usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset gpio 0 [ + ] gpio_sunxi | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | |-- PA gpio 2 [ + ] gpio_sunxi | | |-- PB gpio 3 [ + ] gpio_sunxi | | |-- PC gpio 4 [ + ] gpio_sunxi | | |-- PD gpio 5 [ + ] gpio_sunxi | | |-- PE gpio 6 [ + ] gpio_sunxi | | |-- PF gpio 7 [ + ] gpio_sunxi | | |-- PG gpio 8 [ + ] gpio_sunxi | | |-- PH gpio 9 [ + ] gpio_sunxi | | `-- PI ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 gpio 10 [ + ] gpio_sunxi | `-- pinctrl@1f02c00 gpio 11 [ + ] gpio_sunxi | `-- PL clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock `-- osc32k_clk
U-Boot 2022.07-rc1 (Apr 26 2022 - 07:00:52 +0000) Allwinner Technology
=> echo $boot_targets fel mmc0 usb0 pxe dhcp
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver video 0 [ ] sunxi_de2 |-- sunxi_de2 display 0 [ ] sunxi_dw_hdmi |-- sunxi_dw_hdmi simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk
A block device detected here.
partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3
Apparently, there are three partition devices, then we should definitely have corresponding efi_disk objects as an efi_loader hook is registered against *POST_PROBE* event (of a *block* device).
In my patch c822c1a50bd7 ("mmc: call device_probe() after scanning"), device_probe() has already been installed to mmc_blk_probe().
Thinking of those circumstances, the natural guess is a *probe* function for "mmc@1c0f000.blk" device has never been called in your use case (even when loading an image from a specific partition, /boot/efi?).
To confirm this, you may simply try the followings: => mmc list ... => mmc dev 0 (<- the device number from 'mmc list') => efi devices
Then you will find three more efi_disk objects now that the parent block device is *probed*.
bootdev 0 [ ] mmc_bootdev | | `-- mmc@1c0f000.bootdev phy 0 [ + ] sun4i_usb_phy | |-- phy@1c19400 usb 0 [ + ] ehci_generic | |-- usb@1c1a000 usb_hub 0 [ + ] usb_hub | | `-- usb_hub usb 1 [ + ] ohci_generic | |-- usb@1c1a400 usb_hub 1 [ + ] usb_hub | | `-- usb_hub usb 2 [ + ] ehci_generic | |-- usb@1c1b000 usb_hub 2 [ + ] usb_hub | | `-- usb_hub usb 3 [ + ] ohci_generic | |-- usb@1c1b400 usb_hub 3 [ + ] usb_hub | | `-- usb_hub usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev usb 5 [ + ] ohci_generic | |-- usb@1c1c400 usb_hub 5 [ + ] usb_hub | | `-- usb_hub usb 6 [ + ] ehci_generic | |-- usb@1c1d000 usb_hub 6 [ + ] usb_hub | | `-- usb_hub usb 7 [ + ] ohci_generic | |-- usb@1c1d400 usb_hub 7 [ + ] usb_hub | | `-- usb_hub clk 0 [ + ] sun8i_h3_ccu | |-- clock@1c20000 reset 0 [ + ] sunxi_reset | | `-- reset pinctrl 0 [ + ] sunxi-pinctrl | |-- pinctrl@1c20800 gpio 0 [ + ] gpio_sunxi | | |-- pinctrl@1c20800 gpio 1 [ + ] gpio_sunxi | | | |-- PA gpio 2 [ + ] gpio_sunxi | | | |-- PB gpio 3 [ + ] gpio_sunxi | | | |-- PC gpio 4 [ + ] gpio_sunxi | | | |-- PD gpio 5 [ + ] gpio_sunxi | | | |-- PE gpio 6 [ + ] gpio_sunxi | | | |-- PF gpio 7 [ + ] gpio_sunxi | | | `-- PG pinconfig 0 [ ] pinconfig | | |-- csi-pins pinconfig 1 [ ] pinconfig | | |-- emac-rgmii-pins pinconfig 2 [ ] pinconfig | | |-- i2c0-pins pinconfig 3 [ ] pinconfig | | |-- i2c1-pins pinconfig 4 [ ] pinconfig | | |-- i2c2-pins pinconfig 5 [ + ] pinconfig | | |-- mmc0-pins pinconfig 6 [ ] pinconfig | | |-- mmc1-pins pinconfig 7 [ ] pinconfig | | |-- mmc2-8bit-pins pinconfig 8 [ ] pinconfig | | |-- spdif-tx-pin pinconfig 9 [ ] pinconfig | | |-- spi0-pins pinconfig 10 [ ] pinconfig | | |-- spi1-pins pinconfig 11 [ + ] pinconfig | | |-- uart0-pa-pins pinconfig 12 [ ] pinconfig | | |-- uart1-pins pinconfig 13 [ ] pinconfig | | |-- uart1-rts-cts-pins pinconfig 14 [ ] pinconfig | | |-- uart2-pins pinconfig 15 [ ] pinconfig | | |-- uart2-rts-cts-pins pinconfig 16 [ ] pinconfig | | |-- uart3-pins pinconfig 17 [ ] pinconfig | | |-- uart3-rts-cts-pins pinconfig 18 [ ] pinconfig | | |-- ahci_pwr_pin@0 pinconfig 19 [ ] pinconfig | | |-- usb0_vbus_pin@0 pinconfig 20 [ ] pinconfig | | |-- usb1_vbus_pin@0 pinconfig 21 [ ] pinconfig | | `-- usb2_vbus_pin@0 ethernet 0 [ + ] eth_sun8i_emac | |-- ethernet@1c30000 bootdev 1 [ ] eth_bootdev | | `-- ethernet@1c30000.bootdev watchdog 0 [ + ] sunxi_wdt | |-- watchdog@1c20ca0 sysreset 0 [ ] wdt_reboot | | `-- watchdog@1c20ca0 serial 0 [ + ] ns16550_serial | |-- serial@1c28000 clk 1 [ + ] clk_sun6i_rtc | |-- rtc@1f00000 clk 2 [ + ] sun6i_a31_r_ccu | |-- clock@1f01400 reset 1 [ ] sunxi_reset | | `-- reset i2c 0 [ ] i2c_mvtwsi | |-- i2c@1f02400 pinctrl 1 [ + ] sunxi-pinctrl | `-- pinctrl@1f02c00 gpio 8 [ + ] gpio_sunxi | |-- pinctrl@1f02c00 gpio 9 [ + ] gpio_sunxi | | `-- PL pinconfig 22 [ ] pinconfig | |-- r-ir-rx-pin pinconfig 23 [ ] pinconfig | |-- r-i2c-pins pinconfig 24 [ ] pinconfig | `-- r-pwm-pin clk 3 [ + ] fixed_clock |-- osc24M_clk clk 4 [ ] fixed_clock |-- osc32k_clk bootstd 0 [ ] bootstd_drv `-- bootstd bootmeth 0 [ ] bootmeth_distro |-- distro bootmeth 1 [ ] bootmeth_efi |-- efi bootmeth 2 [ ] bootmeth_pxe |-- pxe bootdev 2 [ ] system_bootdev `-- system-bootdev
grub rescue> ls (hd0)
Grub does not see any partition at all.
Loading a device from a partition does not create a handle for the device:
Actually, loading an image does *not* invoke a probe function at all under the current implementation (of either "part" command, scan_dev_for_boot_part or even mmc drivers?).
We call efi_disk_init() after the MMC device is probed. Therefore probing of the MCC device does not trigger EVT_DM_POST_PROBE.
We have to move the efi_disk_init() call before initr_dm().
[PATCH 1/1] efi_loader: call efi_init_early() earlier https://lists.denx.de/pipermail/u-boot/2022-April/482701.html
With the patch GRUB now sees the MMC device but it is still not seeing the partitions:
grub rescue> ls (hd0) (hd1)
This is strange because devices and protocols look rather normal now:
Do you have the fix for the raw disk support in your tree? I suspect that GRUB needs that to read the partition table.
=> dm tree Class Index Probed Driver Name
root 0 [ + ] root_driver root_driver simple_bus 0 [ + ] simple_bus |-- soc mmc 0 [ + ] sunxi_mmc | |-- mmc@1c0f000 blk 0 [ + ] mmc_blk | | |-- mmc@1c0f000.blk partition 0 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:1 partition 1 [ + ] blk_partition | | | |-- mmc@1c0f000.blk:2 partition 2 [ + ] blk_partition | | | `-- mmc@1c0f000.blk:3 usb 4 [ + ] ehci_generic | |-- usb@1c1c000 usb_hub 4 [ + ] usb_hub | | `-- usb_hub usb_mass_s 0 [ + ] usb_mass_storage | | `-- usb_mass_storage blk 1 [ + ] usb_storage_blk | | |-- usb_mass_storage.lun0 partition 3 [ + ] blk_partition | | | `-- usb_mass_storage.lun0:1 bootdev 3 [ ] usb_bootdev | | `-- usb_mass_storage.lun0.bootdev
=> efidebug devices Device Device Path ======== ==================== 79f701e8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f70cd8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0) 79f70de0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(1,MBR,0xb6b4facb,0x800,0x200000) 79f711b0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(2,MBR,0xb6b4facb,0x200800,0x200000) 79f71538 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(0)/HD(3,MBR,0xb6b4facb,0x400800,0x379f800) 79f811b8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f81260 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdd748 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1)
=> efidebug dh Handle Protocols ======== ==================== 79f701e8 Device Path, Device Path To Text, Device Path Utilities, Device-Tree Fixup, Unicode Collation 2, HII String, HII Database, Simple Text Output, Simple Text Input, Simple Text Input Ex 7dffc7ec Device Path 79f70cd8 Device Path, Block IO 79f70de0 Device Path, Block IO, System Partition, Simple File System 79f711b0 Device Path, Block IO, Simple File System 79f71538 Device Path, Block IO, Simple File System 79f811b8 Device Path, Block IO 79f81260 Device Path, Block IO, System Partition, Simple File System 79f84978 Driver Binding 79fdd748 Simple Network, Device Path, PXE Base Code
This is the console log *before* the patch:
U-Boot 2022.07-rc1-00082-g8b2b125e95-dirty (Apr 28 2022 - 06:01:10 +0000) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Xunlong Orange Pi PC DRAM: 1 GiB drivers/mmc/sunxi_mmc.c(723)sunxi_mmc_bind: sunxi_set_gate: (CLK#54) unhandled Core: 70 devices, 20 uclasses, devicetree: separate WDT: Not starting watchdog@1c20ca0 MMC: drivers/mmc/sunxi_mmc.c(667)sunxi_mmc_probe: mmc@1c0f000: 0 Loading Environment from FAT... drivers/mmc/mmc-uclass.c(487)mmc_blk_probe: drivers/block/blk-uclass.c(746)blk_post_probe: drivers/block/blk-uclass.c(752)blk_post_probe: disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 part_create_block_devices: 3 partitions found in mmc@1c0f000.blk disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 Unable to read "uboot.env" from mmc0:1... In: serial Out: serial Err: serial Net: phy interface1 eth0: ethernet@1c30000 lib/efi_loader/efi_disk.c(739)efi_disk_init: starting USB... Bus usb@1c1a000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1a400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1b000: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: sunxi_set_gate: (CLK#9) unhandled lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1b400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1c000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1c400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1d000: USB EHCI 1.00 lib/efi_loader/efi_disk.c(622)efi_disk_probe: Bus usb@1c1d400: USB OHCI 1.0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: scanning bus usb@1c1a000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1a400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1b000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1b400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1c000 for devices... drivers/block/blk-uclass.c(746)blk_post_probe: drivers/block/blk-uclass.c(752)blk_post_probe: disk/part.c(242)part_init: part_init: try 'EFI': ret=-1 part_init: try 'DOS': ret=0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: part_create_block_devices: 1 partitions found in usb_mass_storage.lun0 lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(568)efi_disk_create_part: lib/efi_loader/efi_disk.c(622)efi_disk_probe: lib/efi_loader/efi_disk.c(622)efi_disk_probe: 2 USB Device(s) found scanning bus usb@1c1c400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1d000 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning bus usb@1c1d400 for devices... lib/efi_loader/efi_disk.c(622)efi_disk_probe: 1 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Hit any key to stop autoboot: 0
Best regards
Heinrich
I think that this is weird as the purpose of "probe" is to activate the device, or "probe - make a device ready for use" according to doc/develop/driver-model/design.rst
So my conclusion is that the current implementation has already broken the driver model even before my patch was applied. -> Simon, you should have a comment here?
That said, fixing a problem is a different matter. Probably, we will have to modify "part" command or mmc drivers themselves.
Can you figure out an easy way to reproduce the issue? (either on sandbox or qemu-arm) Otherwise, it is difficult for me to investigate it.
-Takahiro Akashi
-Takahiro Akashi
=> efidebug devices ** Unable to read file ubootefi.var ** Failed to load EFI variables Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) => bootefi $kernel_addr_r Booting /helloworld.efi invalid image type: 0 Hello, world! => efidebug devices Device Device Path ======== ==================== 79f80f08 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b) 7dffc7ec /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Uart(0,0,D,D) 79f7f1f8 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0) 79f7f2a0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x0,0x0,0x9,0x0,0x1)/UsbClass(0x781,0x5571,0x0,0x0,0x0)/HD(1,MBR,0x0c449046,0x800,0x800) 79fdc188 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/MAC(0281431d5371,1) =>
So the current state is a complete mess.
Best regards
Heinrich

On 4/28/22 11:09, Mark Kettenis wrote:
We call efi_disk_init() after the MMC device is probed. Therefore probing of the MCC device does not trigger EVT_DM_POST_PROBE.
We have to move the efi_disk_init() call before initr_dm().
[PATCH 1/1] efi_loader: call efi_init_early() earlier https://lists.denx.de/pipermail/u-boot/2022-April/482701.html
With the patch GRUB now sees the MMC device but it is still not seeing the partitions:
grub rescue> ls (hd0) (hd1)
This is strange because devices and protocols look rather normal now:
Do you have the fix for the raw disk support in your tree? I suspect that GRUB needs that to read the partition table.
Do you relate to an existing patch or only to the bug that you reported?
Best regards
Heinrich

Date: Thu, 28 Apr 2022 11:42:19 +0200 From: Heinrich Schuchardt xypron.glpk@gmx.de
On 4/28/22 11:09, Mark Kettenis wrote:
We call efi_disk_init() after the MMC device is probed. Therefore probing of the MCC device does not trigger EVT_DM_POST_PROBE.
We have to move the efi_disk_init() call before initr_dm().
[PATCH 1/1] efi_loader: call efi_init_early() earlier https://lists.denx.de/pipermail/u-boot/2022-April/482701.html
With the patch GRUB now sees the MMC device but it is still not seeing the partitions:
grub rescue> ls (hd0) (hd1)
This is strange because devices and protocols look rather normal now:
Do you have the fix for the raw disk support in your tree? I suspect that GRUB needs that to read the partition table.
Do you relate to an existing patch or only to the bug that you reported?
There is a patch now:
https://patchwork.ozlabs.org/project/uboot/patch/20220428044916.52250-1-taka...
Cheers,
Mark
participants (10)
-
AKASHI Takahiro
-
AKASHI, Takahiro
-
Fabio Estevam
-
Heiko Thiery
-
Heinrich Schuchardt
-
Johan Jonker
-
Mark Kettenis
-
Neil Armstrong
-
Tom Rini
-
Vyacheslav