diff options
author | Tom Rini <trini@konsulko.com> | 2023-08-27 11:04:02 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-08-27 11:04:02 -0400 |
commit | 6a1d3f64c201ed3f6df819cfcf08154b6ec1c02e (patch) | |
tree | 566da16c29bc65dabc09afeea06c9840bbb37a90 | |
parent | e508b930021168c788f14977fc101ccc1151b3c8 (diff) | |
parent | cc889bd0754e50a3cd50e8ed3094388480fbec86 (diff) | |
download | u-boot-WIP/27Aug2023.zip u-boot-WIP/27Aug2023.tar.gz u-boot-WIP/27Aug2023.tar.bz2 |
Merge tag 'efi-2023-10-rc4' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/27Aug2023
Pull request efi-2023-10-rc4
Documentation:
* describe TPL/VPL/SPL boot
* Add support for sphinx-prompt and convert TI K3 to use it
* board: sdm845: Explicitly add boot.img flashing command
EFI:
* remove handle from events when deleting it
Others:
* fix gpt sub-commands setenv and enumerate
* add a parameter check in hash_calculate()
-rw-r--r-- | cmd/gpt.c | 22 | ||||
-rw-r--r-- | doc/board/qualcomm/sdm845.rst | 11 | ||||
-rw-r--r-- | doc/board/ti/k3.rst | 112 | ||||
-rw-r--r-- | doc/conf.py | 2 | ||||
-rw-r--r-- | doc/sphinx/requirements.txt | 1 | ||||
-rw-r--r-- | doc/usage/index.rst | 1 | ||||
-rw-r--r-- | doc/usage/spl_boot.rst | 321 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 89 | ||||
-rw-r--r-- | lib/hash-checksum.c | 6 |
9 files changed, 469 insertions, 96 deletions
@@ -691,12 +691,13 @@ static int gpt_enumerate(struct blk_desc *desc) int ret; int i; + if (part_drv->test(desc)) + continue; + for (i = 1; i < part_drv->max_entries; i++) { ret = part_drv->get_info(desc, i, &pinfo); - if (ret) { - /* no more entries in table */ - break; - } + if (ret) + continue; ptr = &part_list[str_len]; tmp_len = strlen((const char *)pinfo.name); @@ -711,9 +712,10 @@ static int gpt_enumerate(struct blk_desc *desc) /* One byte for space(" ") delimiter */ ptr[tmp_len] = ' '; } + if (*part_list) + part_list[strlen(part_list) - 1] = 0; + break; } - if (*part_list) - part_list[strlen(part_list) - 1] = 0; debug("setenv gpt_partition_list %s\n", part_list); return env_set("gpt_partition_list", part_list); @@ -742,7 +744,7 @@ static int gpt_setenv_part_variables(struct disk_partition *pinfo, int i) if (ret) goto fail; - ret = env_set_ulong("gpt_partition_entry", i); + ret = env_set_hex("gpt_partition_entry", i); if (ret) goto fail; @@ -786,10 +788,8 @@ static int gpt_setenv(struct blk_desc *desc, const char *name) for (i = 1; i < part_drv->max_entries; i++) { ret = part_drv->get_info(desc, i, &pinfo); - if (ret) { - /* no more entries in table */ - break; - } + if (ret) + continue; if (!strcmp(name, (const char *)pinfo.name)) { /* match found, setup environment variables */ diff --git a/doc/board/qualcomm/sdm845.rst b/doc/board/qualcomm/sdm845.rst index 71879c2..d3f218e 100644 --- a/doc/board/qualcomm/sdm845.rst +++ b/doc/board/qualcomm/sdm845.rst @@ -38,9 +38,10 @@ and FIT image instead of ``initramfs``. Android bootloader expect gzipped kernel with appended dtb, so let's mimic linux to satisfy stock bootloader. Boards ------------- +------ + starqlte -^^^^^^^^^^^^ +^^^^^^^^ The starqltechn is a production board for Samsung S9 (SM-G9600) phone, based on the Qualcomm SDM845 SoC. @@ -149,7 +150,11 @@ Steps: mkbootimg --kernel u-boot.bin.gz-dtb --ramdisk db845c.itb \ --output boot.img --pagesize 4096 --base 0x80000000 -- Flash boot.img using db845c fastboot method. +- Flash boot.img using db845c fastboot method: + + .. code-block:: bash + + sudo fastboot flash boot boot.img More information can be found on the `DragonBoard 845c page`_. diff --git a/doc/board/ti/k3.rst b/doc/board/ti/k3.rst index 1175b77..ec44735 100644 --- a/doc/board/ti/k3.rst +++ b/doc/board/ti/k3.rst @@ -194,13 +194,13 @@ All of that to say you will need both a 32bit and 64bit cross compiler .. k3_rst_include_end_common_env_vars_desc .. k3_rst_include_start_common_env_vars_defn -.. code-block:: bash +.. prompt:: bash - $ export CC32=arm-linux-gnueabihf- - $ export CC64=aarch64-linux-gnu- - $ export LNX_FW_PATH=path/to/ti-linux-firmware - $ export TFA_PATH=path/to/trusted-firmware-a - $ export OPTEE_PATH=path/to/optee_os + export CC32=arm-linux-gnueabihf- + export CC64=aarch64-linux-gnu- + export LNX_FW_PATH=path/to/ti-linux-firmware + export TFA_PATH=path/to/trusted-firmware-a + export OPTEE_PATH=path/to/optee_os .. k3_rst_include_end_common_env_vars_defn We will also need some common environment variables set up for the various @@ -244,11 +244,11 @@ Building tiboot3.bin uses the split binary flow) .. k3_rst_include_start_build_steps_spl_r5 -.. code-block:: bash +.. prompt:: bash - $ # inside u-boot source - $ make $UBOOT_CFG_CORTEXR - $ make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH + # inside u-boot source + make $UBOOT_CFG_CORTEXR + make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH .. k3_rst_include_end_build_steps_spl_r5 At this point you should have all the needed binaries to boot the wakeup @@ -280,11 +280,11 @@ firmware if your device using a split firmware. application cores on the main domain. .. k3_rst_include_start_build_steps_tfa -.. code-block:: bash +.. prompt:: bash - $ # inside trusted-firmware-a source - $ make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS \ - TARGET_BOARD=$TFA_BOARD + # inside trusted-firmware-a source + make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS \ + TARGET_BOARD=$TFA_BOARD .. k3_rst_include_end_build_steps_tfa Typically all `j7*` devices will use `TARGET_BOARD=generic` or `TARGET_BOARD @@ -296,11 +296,11 @@ use the `lite` option. using the TrustZone technology built into the core. .. k3_rst_include_start_build_steps_optee -.. code-block:: bash +.. prompt:: bash - $ # inside optee_os source - $ make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS \ - PLATFORM=$OPTEE_PLATFORM + # inside optee_os source + make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS \ + PLATFORM=$OPTEE_PLATFORM .. k3_rst_include_end_build_steps_optee 4. Finally, after TF-A has initialized the main domain and OP-TEE has @@ -308,11 +308,11 @@ use the `lite` option. 64bit core in the main domain. .. k3_rst_include_start_build_steps_uboot -.. code-block:: bash +.. prompt:: bash - $ # inside u-boot source - $ make $UBOOT_CFG_CORTEXA - $ make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \ + # inside u-boot source + make $UBOOT_CFG_CORTEXA + make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \ BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \ TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin .. k3_rst_include_end_build_steps_uboot @@ -407,14 +407,14 @@ and the same can be extended to other platforms be passing to mkimage for signing the fitImage and embedding the key in the u-boot dtb. - .. code-block:: bash + .. prompt:: bash mkimage -r -f fitImage.its -k $UBOOT_PATH/board/ti/keys -K $UBOOT_PATH/build/a72/dts/dt.dtb For signing a secondary platform, pass the -K parameter to that DTB - .. code-block:: bash + .. prompt:: bash mkimage -f fitImage.its -k $UBOOT_PATH/board/ti/keys -K $UBOOT_PATH/build/a72/arch/arm/dts/k3-j721e-sk.dtb @@ -473,10 +473,11 @@ then the saveenv command and can be used across various bootmodes too. **Writing to MMC/EMMC** -.. code-block:: +.. prompt:: bash + :prompts: => - => env export -t $loadaddr <list of variables> - => fatwrite mmc ${mmcdev} ${loadaddr} ${bootenvfile} ${filesize} + env export -t $loadaddr <list of variables> + fatwrite mmc ${mmcdev} ${loadaddr} ${bootenvfile} ${filesize} **Reading from MMC/EMMC** @@ -486,10 +487,11 @@ mmcdev) and set the environments. If manually needs to be done then the environment can be read from the filesystem and then imported -.. code-block:: +.. prompt:: bash + :prompts: => - => fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile} - => env import -t ${loadaddr} ${filesize} + fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile} + env import -t ${loadaddr} ${filesize} .. _k3_rst_refer_openocd: @@ -546,7 +548,7 @@ Refer to the release notes corresponding to the `OpenOCD version box support by OpenOCD. The board-specific documentation will cover the details and any adapter/dongle recommendations. -.. code-block:: bash +.. prompt:: bash openocd -v @@ -564,21 +566,21 @@ systems, but equivalent instructions should exist for systems with other package managers. Please refer to the `OpenOCD Documentation <https://openocd.org/>`_ for more recent installation steps. -.. code-block:: bash +.. prompt:: bash - $ # Check the packages to be installed: needs deb-src in sources.list - $ sudo apt build-dep openocd - $ # The following list is NOT complete - please check the latest - $ sudo apt-get install libtool pkg-config texinfo libusb-dev \ + # Check the packages to be installed: needs deb-src in sources.list + sudo apt build-dep openocd + # The following list is NOT complete - please check the latest + sudo apt-get install libtool pkg-config texinfo libusb-dev \ libusb-1.0.0-dev libftdi-dev libhidapi-dev autoconf automake - $ git clone https://github.com/openocd-org/openocd.git openocd - $ cd openocd - $ git submodule init - $ git submodule update - $ ./bootstrap - $ ./configure --prefix=/usr/local/ - $ make -j`nproc` - $ sudo make install + git clone https://github.com/openocd-org/openocd.git openocd + cd openocd + git submodule init + git submodule update + ./bootstrap + ./configure --prefix=/usr/local/ + make -j`nproc` + sudo make install .. note:: @@ -594,28 +596,28 @@ The step is not necessary if the distribution supports the OpenOCD, but if building from a source, ensure that the udev rules are installed correctly to ensure a sane system. -.. code-block:: bash +.. prompt:: bash # Go to the OpenOCD source directory - $ cd openocd - # Copy the udev rules to the correct system location - $ sudo cp ./contrib/60-openocd.rules \ + cd openocd + Copy the udev rules to the correct system location + sudo cp ./contrib/60-openocd.rules \ ./src/jtag/drivers/libjaylink/contrib/99-libjaylink.rules \ /etc/udev/rules.d/ # Get Udev to load the new rules up - $ sudo udevadm control --reload-rules + sudo udevadm control --reload-rules # Use the new rules on existing connected devices - $ sudo udevadm trigger + sudo udevadm trigger Step 2: Setup GDB ^^^^^^^^^^^^^^^^^ Most systems come with gdb-multiarch package. -.. code-block:: bash +.. prompt:: bash # Install gdb-multiarch package - $ sudo apt-get install gdb-multiarch + sudo apt-get install gdb-multiarch Though using GDB natively is normal, developers with interest in using IDE may find a few of these interesting: @@ -828,7 +830,7 @@ Startup OpenOCD to debug the platform as follows: .. k3_rst_include_start_openocd_cfg_XDS110 -.. code-block:: bash +.. prompt:: bash openocd -f board/{board_of_choice}.cfg @@ -842,7 +844,7 @@ Startup OpenOCD to debug the platform as follows: <https://github.com/openocd-org/openocd/blob/master/tcl/target/ti_k3.cfg#L59>`_ to decide if the SoC is supported or not. -.. code-block:: bash +.. prompt:: bash openocd -f openocd_connect.cfg @@ -917,7 +919,7 @@ To debug using this server, use GDB directly or your preferred GDB-based IDE. To start up GDB in the terminal, run the following command. -.. code-block:: bash +.. prompt:: bash gdb-multiarch diff --git a/doc/conf.py b/doc/conf.py index 00f2413..5e2ff1c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -39,7 +39,7 @@ needs_sphinx = '2.4.4' extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'kfigure', 'sphinx.ext.ifconfig', # 'automarkup', 'maintainers_include', 'sphinx.ext.autosectionlabel', - 'kernel_abi', 'kernel_feat'] + 'kernel_abi', 'kernel_feat', 'sphinx-prompt'] # # cdomain is badly broken in Sphinx 3+. Leaving it out generates *most* diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt index 4f411f7..6ccbe52 100644 --- a/doc/sphinx/requirements.txt +++ b/doc/sphinx/requirements.txt @@ -15,6 +15,7 @@ requests==2.31.0 six==1.16.0 snowballstemmer==2.2.0 Sphinx==3.4.3 +sphinx-prompt==1.5.0 sphinx-rtd-theme==1.0.0 sphinxcontrib-applehelp==1.0.2 sphinxcontrib-devhelp==1.0.2 diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 3326ec8..f45a7f5 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -4,6 +4,7 @@ Use U-Boot .. toctree:: :maxdepth: 1 + spl_boot blkmap dfu environment diff --git a/doc/usage/spl_boot.rst b/doc/usage/spl_boot.rst new file mode 100644 index 0000000..93419f1 --- /dev/null +++ b/doc/usage/spl_boot.rst @@ -0,0 +1,321 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +Booting from TPL/SPL +==================== + +The main U-Boot binary may be too large to be loaded directly by the Boot ROM. +This was the original driver for splitting up U-Boot into multiple boot stages. + +U-Boot typically goes through the following boot phases where TPL, VPL, and SPL +are optional. While many boards use SPL only few use TPL. + +TPL + Tertiary Program Loader. Very early init, as tiny as possible. This loads SPL + (or VPL if enabled). + +VPL + Verifying Program Loader. Optional verification step, which can select one of + several SPL binaries, if A/B verified boot is enabled. Implementation of the + VPL logic is work-in-progress. For now it just boots into SPL. + +SPL + Secondary Program Loader. Sets up SDRAM and loads U-Boot proper. It may also + load other firmware components. + +U-Boot + U-Boot proper. This is the only stage containing command. It also implements + logic to load an operating system, e.g. via UEFI. + +.. note:: + + The naming convention on the PowerPC architecture deviates from the other + archtitectures. Here the boot sequence is SPL->TPL->U-Boot. + +Further usages for U-Boot SPL comprise: + +* launching BL31 of ARM Trusted Firmware which invokes U-Boot as BL33 +* launching EDK II +* launching Linux, e.g. :doc:`Falcon Mode <../develop/falcon>` +* launching RISC-V OpenSBI which invokes main U-Boot + +Target binaries +--------------- + +Binaries loaded by SPL/TPL can be: + +* raw binaries where the entry address equals the start address. This is the + only binary format supported by TPL. +* :doc:`FIT <fit/index>` images +* legacy U-Boot images + +Configuration +~~~~~~~~~~~~~ + +Raw images are only supported in SPL if CONFIG_SPL_RAW_IMAGE_SUPPORT=y. + +CONFIG_SPL_FIT=y and CONFIG_SPL_LOAD_FIT=y are needed to load FIT images. + +CONFIG_SPL_LEGACY_IMAGE_FORMAT=y is needed to load legacy U-Boot images. +CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK=y enables checking the CRC32 of legacy U-Boot +images. + +Image load methods +------------------ + +The image boot methods available for a board must be defined in two places: + +The board code implements a function board_boot_order() enumerating up to +five boot methods and the sequence in which they are tried. (The maximum +number of boot methods is currently hard coded as variable spl_boot_list[]). +If there is only one boot method function, spl_boot_device() may be implemented +instead. + +The configuration controls which of these boot methods are actually available. + +Loading from block devices +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +MMC1, MMC2, MMC2_2 + These methods read an image from SD card or eMMC. The first digit after + 'MMC' indicates the device number. Required configuration settings include: + + * CONFIG_SPL_MMC=y or CONFIG_TPL_MMC=y + + To use a PCI connected MMC controller you need to additionally specify: + + * CONFIG_SPL_PCI=y + + * CONFIG_SPL_PCI_PNP=y + + * CONFIG_MMC=y + + * CONFIG_MMC_PCI=y + + * CONFIG_MMC_SDHCI=y + + To load from a file system use: + + * CONFIG_SPL_FS_FAT=y or CONFIG_SPL_FS_EXT=y + + * CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="<filepath>" + +NVMe + This methods load the image from an NVMe drive. + Required configuration settings include: + + * CONFIG_SPL_PCI=y + + * CONFIG_SPL_PCI_PNP=y + + * CONFIG_SPL_NVME=y + + * CONFIG_SPL_NVME_PCI=y + + * CONFIG_SPL_NVME_BOOT_DEVICE (number of the NVMe device) + + * CONFIG_SYS_NVME_BOOT_PARTITION (partition to read from) + + To load from a file system use: + + * CONFIG_SPL_FS_FAT=y or CONFIG_SPL_FS_EXT=y + + * CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="<filepath>" + +SATA + This method reads an image from a SATA drive. + Required configuration settings include: + + * CONFIG_SPL_SATA=y or CONFIG_TPL_SATA=y + + To use a PCIe connecte SATA controller you additionally need: + + * CONFIG_SPL_PCI=y + + * CONFIG_SPL_SATA=y + + * CONFIG_SPL_AHCI_PCI=y + + * CONFIG_SPL_PCI_PNP=y + + To load from a file system use: + + * CONFIG_SPL_FS_FAT=y + + * CONFIG_SYS_SATA_FAT_BOOT_PARTITION=<partition number> + + * CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="<filepath>" + +USB + The USB method loads an image from a USB block device. + Required configuration settings include: + + * CONFIG_SPL_USB_HOST=y + + * CONFIG_SPL_USB_STORAGE=y + + To use a PCI connected USB 3.0 controller you additionally need: + + * CONFIG_SPL_FS_FAT=y + + * CONFIG_SPL_PCI=y + + * CONFIG_SPL_PCI_PNP=y + + * CONFIG_USB=y + + * CONFIG_USB_XHCI_HCD=y + + * CONFIG_USB_XHCI_PCI=y + + To load from a file system use: + + * CONFIG_SPL_FS_FAT=y or CONFIG_SPL_FS_EXT=y + + * CONFIG_SYS_USB_FAT_BOOT_PARTITION=<partition number> + + * CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="<filepath>" + +Loading from raw flash devices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +NAND + This method loads the image from NAND flash. To read from raw NAND the + following configuration settings are required: + + * CONFIG_SPL_NAND_SUPPORT=y or CONFIG_TPL_NAND_SUPPORT=y + + If CONFIG_SPL_NAND_RAW_ONLY=y only raw images can be loaded. + + For using UBI (Unsorted Block Images) volumes to read from NAND the + following configuration settings are required: + + * CONFIG_SPL_UBI=y or CONFIG_TPL_UBI=y + + The UBI volume to read can either be specified + + * by name using CONFIG_SPL_UBI_LOAD_BY_VOLNAME or + + * by number using CONFIG_SPL_UBI_LOAD_MONITOR_ID. + +NOR + This method loads the image from NOR flash. + Required configuration settings include: + + * CONFIG_SPL_NOR_SUPPORT=y or CONFIG_TPL_NOR_SUPPORT=y + +OneNAND + This methods loads the image from a OneNAND device. To read from raw OneNAND + the following configuration settings are required: + + * CONFIG_SPL_ONENAND_SUPPORT=y or CONFIG_TPL_ONENAND_SUPPORT=y + + For using the Ubi file system to read from NAND the following configuration + settings are required: + + * CONFIG_SPL_UBI=y or CONFIG_TPL_UBI=y + +SPI + This method loads an image form SPI NOR flash. + Required configuration settings include: + + * CONFIG_SPL_DM_SPI=y + + * CONFIG_SPL_SPI_FLASH=y + + * CONFIG_SPI_LOAD=y or CONFIG_TPL_SPI_LOAD=y + + +Sunxi SPI + This method which is specific to Allwinner SoCs loads an image form SPI NOR + flash. Required configuration settings include: + + * CONFIG_SPL_SPI_SUNXI=y + +Loading from other devices +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +BOOTROM + The binary is loaded by the boot ROM. + Required configuration settings include: + + * CONFIG_SPL_BOOTROM_SUPPORT=y or CONFIG_TPL_BOOTROM_SUPPORT=y + +DFU + :doc:`Device Firmware Upgrade <dfu>` is used to load the binary into RAM. + Required configuration settings include: + + * CONFIG_DFU=y + + * CONFIG_SPL_RAM_SUPPORT=y or CONFIG TPL_RAM_SUPPORT=y + +Ethernet + This method loads an image over Ethernet. The BOOTP protocol is used to find + a TFTP server and binary name. The binary is downloaded via the TFTP + protocol. Required configuration settings include: + + * CONFIG_SPL_NET=y or CONFIG_TPL_NET=y + + * CONFIG_SPL_ETH_DEVICE=y or CONFIG_DM_USB_GADGET=y + +FEL + This method does not actually load an image for U-Boot. + FEL is a routine contained in the boot ROM of Allwinner SoCs which serves + for the initial programming or recovery via USB + +RAM + This method uses an image preloaded into RAM. + Required configuration settings include: + + * CONFIG_SPL_RAM_SUPPORT=y or CONFIG_TPL_RAM_SUPPORT=y + + * CONFIG_RAM_DEVICE=y + +Sandbox file + On the sandbox this method loads an image from the host file system. + +Sandbox image + On the sandbox this method loads an image from the host file system. + +Semihosting + When running in an ARM or RISC-V virtual machine the semihosting method can + be used to load an image from the host file system. + Required configuration settings include: + + * CONFIG_SPL_SEMIHOSTING=y + + * CONFIG_SPL_SEMIHOSTING_FALLBACK=y + + * CONFIG_SPL_FS_LOAD_PAYLOAD_NAME=<path to file> + +UART + This method loads an image via the Y-Modem protocol from the UART. + Required configuration settings include: + + * CONFIG_SPL_YMODEM_SUPPORT=y or CONFIG_TPL_YMODEM_SUPPORT=y + +USB SDP + This method loads the image using the Serial Download Protocol as + implemented by the boot ROM of the i.MX family of SoCs. + + Required configuration settings include: + + * CONFIG_SPL_SERIAL=y + + * CONFIG_SPL_USB_SDP_SUPPORT=y or CONFIG_TPL_USB_SDP_SUPPORT + +VBE Simple + This method is used by the VPL stage to extract the next stage image from + the loaded image. + + Required configuration settings include: + + * CONFIG_VPL=y + + * CONFIG_SPL_BOOTMETH_VBE_SIMPLE_FW=y or CONFIG_TPL_BOOTMETH_VBE_SIMPLE_FW=y + +XIP + This method executes an image in place. + + Required configuration settings include: + + * CONFIG_SPL_XIP_SUPPORT diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 0e89c85..0b7579c 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -61,7 +61,7 @@ static volatile gd_t *efi_gd, *app_gd; static efi_status_t efi_uninstall_protocol (efi_handle_t handle, const efi_guid_t *protocol, - void *protocol_interface); + void *protocol_interface, bool preserve); /* 1 if inside U-Boot code, 0 if inside EFI payload code */ static int entry_count = 1; @@ -208,6 +208,36 @@ static bool efi_event_is_queued(struct efi_event *event) } /** + * efi_purge_handle() - Clean the deleted handle from the various lists + * @handle: handle to remove + * + * Return: status code + */ +static efi_status_t efi_purge_handle(efi_handle_t handle) +{ + struct efi_register_notify_event *item; + + if (!list_empty(&handle->protocols)) + return EFI_ACCESS_DENIED; + /* The handle is about to be freed. Remove it from events */ + list_for_each_entry(item, &efi_register_notify_events, link) { + struct efi_protocol_notification *hitem, *hnext; + + list_for_each_entry_safe(hitem, hnext, &item->handles, link) { + if (handle == hitem->handle) { + list_del(&hitem->link); + free(hitem); + } + } + } + /* The last protocol has been removed, delete the handle. */ + list_del(&handle->link); + free(handle); + + return EFI_SUCCESS; +} + +/** * efi_process_event_queue() - process event queue */ static void efi_process_event_queue(void) @@ -615,7 +645,7 @@ static efi_status_t efi_remove_all_protocols(const efi_handle_t handle) efi_status_t ret; ret = efi_uninstall_protocol(handle, &protocol->guid, - protocol->protocol_interface); + protocol->protocol_interface, true); if (ret != EFI_SUCCESS) return ret; } @@ -639,10 +669,7 @@ efi_status_t efi_delete_handle(efi_handle_t handle) return ret; } - list_del(&handle->link); - free(handle); - - return ret; + return efi_purge_handle(handle); } /** @@ -1356,6 +1383,8 @@ reconnect: * @handle: handle from which the protocol shall be removed * @protocol: GUID of the protocol to be removed * @protocol_interface: interface to be removed + * @preserve: preserve or delete the handle and remove it from any + * list it participates if no protocols remain * * This function DOES NOT delete a handle without installed protocol. * @@ -1363,7 +1392,7 @@ reconnect: */ static efi_status_t efi_uninstall_protocol (efi_handle_t handle, const efi_guid_t *protocol, - void *protocol_interface) + void *protocol_interface, bool preserve) { struct efi_handler *handler; struct efi_open_protocol_info_item *item; @@ -1397,6 +1426,14 @@ static efi_status_t efi_uninstall_protocol goto out; } r = efi_remove_protocol(handle, protocol, protocol_interface); + if (r != EFI_SUCCESS) + return r; + /* + * We don't care about the return value here since the + * handle might have more protocols installed + */ + if (!preserve) + efi_purge_handle(handle); out: return r; } @@ -1422,15 +1459,10 @@ static efi_status_t EFIAPI efi_uninstall_protocol_interface EFI_ENTRY("%p, %pUs, %p", handle, protocol, protocol_interface); - ret = efi_uninstall_protocol(handle, protocol, protocol_interface); + ret = efi_uninstall_protocol(handle, protocol, protocol_interface, false); if (ret != EFI_SUCCESS) goto out; - /* If the last protocol has been removed, delete the handle. */ - if (list_empty(&handle->protocols)) { - list_del(&handle->link); - free(handle); - } out: return EFI_EXIT(ret); } @@ -2785,7 +2817,7 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle, efi_va_list argptr) { - const efi_guid_t *protocol; + const efi_guid_t *protocol, *next_protocol; void *protocol_interface; efi_status_t ret = EFI_SUCCESS; size_t i = 0; @@ -2795,25 +2827,34 @@ efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle, return EFI_INVALID_PARAMETER; efi_va_copy(argptr_copy, argptr); + protocol = efi_va_arg(argptr, efi_guid_t*); for (;;) { - protocol = efi_va_arg(argptr, efi_guid_t*); + /* + * If efi_uninstall_protocol() fails we need to be able to + * reinstall the previously uninstalled protocols on the same + * handle. + * Instead of calling efi_uninstall_protocol(...,..., false) + * and potentially removing the handle, only allow the handle + * removal on the last protocol that we requested to uninstall. + * That way we can preserve the handle in case the latter fails + */ + bool preserve = true; + if (!protocol) break; protocol_interface = efi_va_arg(argptr, void*); + next_protocol = efi_va_arg(argptr, efi_guid_t*); + if (!next_protocol) + preserve = false; ret = efi_uninstall_protocol(handle, protocol, - protocol_interface); + protocol_interface, preserve); if (ret != EFI_SUCCESS) break; i++; + protocol = next_protocol; } - if (ret == EFI_SUCCESS) { - /* If the last protocol has been removed, delete the handle. */ - if (list_empty(&handle->protocols)) { - list_del(&handle->link); - free(handle); - } + if (ret == EFI_SUCCESS) goto out; - } /* If an error occurred undo all changes. */ for (; i; --i) { @@ -3712,7 +3753,7 @@ static efi_status_t EFIAPI efi_reinstall_protocol_interface( new_interface); /* Uninstall protocol but do not delete handle */ - ret = efi_uninstall_protocol(handle, protocol, old_interface); + ret = efi_uninstall_protocol(handle, protocol, old_interface, true); if (ret != EFI_SUCCESS) goto out; diff --git a/lib/hash-checksum.c b/lib/hash-checksum.c index 8f2a42f..68c290d 100644 --- a/lib/hash-checksum.c +++ b/lib/hash-checksum.c @@ -23,8 +23,10 @@ int hash_calculate(const char *name, struct hash_algo *algo; int ret = 0; void *ctx; - uint32_t i; - i = 0; + int i; + + if (region_count < 1) + return -EINVAL; ret = hash_progressive_lookup_algo(name, &algo); if (ret) |