diff options
31 files changed, 990 insertions, 261 deletions
diff --git a/Documentation/efi.rst b/Documentation/efi.rst index 51c1de24f8..5337a55c3b 100644 --- a/Documentation/efi.rst +++ b/Documentation/efi.rst @@ -9,6 +9,12 @@ Boot services .. kernel-doc:: lib/efi_loader/efi_boottime.c :internal: +Image relocation +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: lib/efi_loader/efi_image_loader.c + :internal: + Runtime services ---------------- diff --git a/MAINTAINERS b/MAINTAINERS index 29449ffed6..f1f8818d6b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -114,7 +114,7 @@ F: include/configs/meson64.h N: meson ARM BROADCOM BCM283X -M: Alexander Graf <agraf@suse.de> +M: Matthias Brugger <mbrugger@suse.com> S: Maintained F: arch/arm/mach-bcm283x/ F: drivers/gpio/bcm2835_gpio.c @@ -453,8 +453,8 @@ F: include/dm/ F: test/dm/ EFI PAYLOAD -M: Alexander Graf <agraf@suse.de> -R: Heinrich Schuchardt <xypron.glpk@gmx.de> +M: Heinrich Schuchardt <xypron.glpk@gmx.de> +R: Alexander Graf <agraf@csgraf.de> S: Maintained T: git git://github.com/agraf/u-boot.git F: doc/README.uefi @@ -3,7 +3,7 @@ VERSION = 2019 PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = # *DOCUMENTATION* diff --git a/cmd/bootefi.c b/cmd/bootefi.c index ee685d8644..3619a20e64 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -133,20 +133,6 @@ done: return ret; } -static efi_status_t efi_do_enter( - efi_handle_t image_handle, struct efi_system_table *st, - EFIAPI efi_status_t (*entry)( - efi_handle_t image_handle, - struct efi_system_table *st)) -{ - efi_status_t ret = EFI_LOAD_ERROR; - - if (entry) - ret = entry(image_handle, st); - st->boottime->exit(image_handle, ret, 0, NULL); - return ret; -} - /* * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges * @@ -266,9 +252,6 @@ static efi_status_t do_bootefi_exec(void *efi, struct efi_loaded_image_obj *image_obj = NULL; struct efi_loaded_image *loaded_image_info = NULL; - EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, - struct efi_system_table *st); - /* * Special case for efi payload not loaded from disk, such as * 'bootefi hello' or for example payload loaded directly into @@ -300,11 +283,9 @@ static efi_status_t do_bootefi_exec(void *efi, goto err_prepare; /* Load the EFI payload */ - entry = efi_load_pe(image_obj, efi, loaded_image_info); - if (!entry) { - ret = EFI_LOAD_ERROR; + ret = efi_load_pe(image_obj, efi, loaded_image_info); + if (ret != EFI_SUCCESS) goto err_prepare; - } if (memdp) { struct efi_device_path_memory *mdp = (void *)memdp; @@ -319,14 +300,8 @@ static efi_status_t do_bootefi_exec(void *efi, "{ro,boot}(blob)0000000000000000"); /* Call our payload! */ - debug("%s: Jumping to 0x%p\n", __func__, entry); - - if (setjmp(&image_obj->exit_jmp)) { - ret = image_obj->exit_status; - goto err_prepare; - } - - ret = efi_do_enter(&image_obj->header, &systab, entry); + debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry); + ret = EFI_CALL(efi_start_image(&image_obj->header, NULL, NULL)); err_prepare: /* image has returned, loaded-image obj goes *poof*: */ @@ -343,38 +318,46 @@ err_add_protocol: /** * bootefi_test_prepare() - prepare to run an EFI test * - * This sets things up so we can call EFI functions. This involves preparing - * the 'gd' pointer and setting up the load ed image data structures. + * Prepare to run a test as if it were provided by a loaded image. * - * @image_objp: loaded_image_infop: Pointer to a struct which will hold the - * loaded image object. This struct will be inited by this function before - * use. - * @loaded_image_infop: Pointer to a struct which will hold the loaded image - * info. This struct will be inited by this function before use. - * @path: File path to the test being run (often just the test name with a - * backslash before it - * @test_func: Address of the test function that is being run - * @load_options_path: U-Boot environment variable to use as load options - * @return 0 if OK, -ve on error + * @image_objp: pointer to be set to the loaded image handle + * @loaded_image_infop: pointer to be set to the loaded image protocol + * @path: dummy file path used to construct the device path + * set in the loaded image protocol + * @load_options_path: name of a U-Boot environment variable. Its value is + * set as load options in the loaded image protocol. + * Return: status code */ static efi_status_t bootefi_test_prepare (struct efi_loaded_image_obj **image_objp, - struct efi_loaded_image **loaded_image_infop, const char *path, - ulong test_func, const char *load_options_path) + struct efi_loaded_image **loaded_image_infop, const char *path, + const char *load_options_path) { + efi_status_t ret; + /* Construct a dummy device path */ - bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, - (uintptr_t)test_func, - (uintptr_t)test_func); + bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0); if (!bootefi_device_path) return EFI_OUT_OF_RESOURCES; + bootefi_image_path = efi_dp_from_file(NULL, 0, path); - if (!bootefi_image_path) - return EFI_OUT_OF_RESOURCES; + if (!bootefi_image_path) { + ret = EFI_OUT_OF_RESOURCES; + goto failure; + } - return bootefi_run_prepare(load_options_path, bootefi_device_path, - bootefi_image_path, image_objp, - loaded_image_infop); + ret = bootefi_run_prepare(load_options_path, bootefi_device_path, + bootefi_image_path, image_objp, + loaded_image_infop); + if (ret == EFI_SUCCESS) + return ret; + + efi_free_pool(bootefi_image_path); + bootefi_image_path = NULL; +failure: + efi_free_pool(bootefi_device_path); + bootefi_device_path = NULL; + return ret; } #endif /* CONFIG_CMD_BOOTEFI_SELFTEST */ @@ -456,13 +439,13 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) struct efi_loaded_image_obj *image_obj; struct efi_loaded_image *loaded_image_info; - if (bootefi_test_prepare(&image_obj, &loaded_image_info, - "\\selftest", (uintptr_t)&efi_selftest, - "efi_selftest")) + r = bootefi_test_prepare(&image_obj, &loaded_image_info, + "\\selftest", "efi_selftest"); + if (r != EFI_SUCCESS) return CMD_RET_FAILURE; /* Execute the test */ - r = efi_selftest(&image_obj->header, &systab); + r = EFI_CALL(efi_selftest(&image_obj->header, &systab)); bootefi_run_finish(image_obj, loaded_image_info); return r != EFI_SUCCESS; } else diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig index 8404d71d86..748682036e 100644 --- a/configs/am57xx_evm_defconfig +++ b/configs/am57xx_evm_defconfig @@ -8,6 +8,7 @@ CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_ARMV7_LPAE=y +CONFIG_AHCI=y CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL_LOAD_FIT=y @@ -39,8 +40,7 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y -CONFIG_SCSI_AHCI=y -# CONFIG_BLK is not set +CONFIG_DWC_AHCI=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_USB_FUNCTION_FASTBOOT=y @@ -70,6 +70,7 @@ CONFIG_DM_PMIC=y CONFIG_PMIC_PALMAS=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_PALMAS=y +CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig index 7a0fd927b8..9124adabdd 100644 --- a/configs/am57xx_hs_evm_defconfig +++ b/configs/am57xx_hs_evm_defconfig @@ -12,6 +12,7 @@ CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_ARMV7_LPAE=y +CONFIG_AHCI=y CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=2 CONFIG_FIT_IMAGE_POST_PROCESS=y @@ -42,8 +43,7 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y -CONFIG_SCSI_AHCI=y -# CONFIG_BLK is not set +CONFIG_DWC_AHCI=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_USB_FUNCTION_FASTBOOT=y @@ -73,6 +73,7 @@ CONFIG_DM_PMIC=y CONFIG_PMIC_PALMAS=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_PALMAS=y +CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index f2d8220126..6b0d0242f2 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -75,8 +75,9 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y +CONFIG_PHY_NATSEMI=y CONFIG_DM_ETH=y -# CONFIG_NETDEVICES is not set +CONFIG_DRIVER_TI_CPSW=y CONFIG_DM_SERIAL=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig index 275727d11f..4578f74a62 100644 --- a/configs/brppt1_nand_defconfig +++ b/configs/brppt1_nand_defconfig @@ -79,8 +79,9 @@ CONFIG_MISC=y CONFIG_NAND=y CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y CONFIG_SYS_NAND_U_BOOT_OFFS=0x80000 +CONFIG_PHY_NATSEMI=y CONFIG_DM_ETH=y -# CONFIG_NETDEVICES is not set +CONFIG_DRIVER_TI_CPSW=y CONFIG_DM_SERIAL=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig index 668c4c22c2..12bb8cd5cc 100644 --- a/configs/brppt1_spi_defconfig +++ b/configs/brppt1_spi_defconfig @@ -86,8 +86,9 @@ CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_PHY_NATSEMI=y CONFIG_DM_ETH=y -# CONFIG_NETDEVICES is not set +CONFIG_DRIVER_TI_CPSW=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index c518b707a5..838b6f14b6 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -34,7 +34,6 @@ CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y -# CONFIG_BLK is not set CONFIG_DFU_MMC=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_MISC=y diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 76225b7939..a9c8f335c1 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -368,6 +368,19 @@ static int mmc_blk_probe(struct udevice *dev) return 0; } +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +static int mmc_blk_remove(struct udevice *dev) +{ + struct udevice *mmc_dev = dev_get_parent(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev); + struct mmc *mmc = upriv->mmc; + + return mmc_deinit(mmc); +} +#endif + static const struct blk_ops mmc_blk_ops = { .read = mmc_bread, #if CONFIG_IS_ENABLED(MMC_WRITE) @@ -382,6 +395,12 @@ U_BOOT_DRIVER(mmc_blk) = { .id = UCLASS_BLK, .ops = &mmc_blk_ops, .probe = mmc_blk_probe, +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + .remove = mmc_blk_remove, + .flags = DM_FLAG_OS_PREPARE, +#endif }; #endif /* CONFIG_BLK */ diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b04345a1e1..1c1527cc74 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2781,6 +2781,32 @@ int mmc_init(struct mmc *mmc) return err; } +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +int mmc_deinit(struct mmc *mmc) +{ + u32 caps_filtered; + + if (!mmc->has_init) + return 0; + + if (IS_SD(mmc)) { + caps_filtered = mmc->card_caps & + ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) | + MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) | + MMC_CAP(UHS_SDR104)); + + return sd_select_mode_and_width(mmc, caps_filtered); + } else { + caps_filtered = mmc->card_caps & + ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400)); + + return mmc_select_mode_and_width(mmc, caps_filtered); + } +} +#endif + int mmc_set_dsr(struct mmc *mmc, u16 val) { mmc->dsr = val; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index a556acd5cb..923f846370 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -148,6 +148,9 @@ static int renesas_sdhi_hs400(struct udevice *dev) tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET); } + tmio_sd_writel(priv, hs400 ? 0x704 : 0x300, + RENESAS_SDHI_SCC_DT2FF); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 2421915a07..6e656e5a9b 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -705,10 +705,14 @@ static void tmio_sd_host_init(struct tmio_sd_priv *priv) * This register dropped backward compatibility at version 0x10. * Write an appropriate value depending on the IP version. */ - if (priv->version >= 0x10) - tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE); - else + if (priv->version >= 0x10) { + if (priv->caps & TMIO_SD_CAP_64BIT) + tmio_sd_writel(priv, 0x100, TMIO_SD_HOST_MODE); + else + tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE); + } else { tmio_sd_writel(priv, 0x0, TMIO_SD_HOST_MODE); + } if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL) { tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE); diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c index 6dd9bec351..46436b88c5 100644 --- a/drivers/video/sunxi/sunxi_display.c +++ b/drivers/video/sunxi/sunxi_display.c @@ -113,6 +113,13 @@ static int sunxi_hdmi_hpd_detect(int hpd_delay) writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl); writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0); + /* Enable PLLs for eventual DDC */ + writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, + &hdmi->pad_ctrl1); + writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15), + &hdmi->pll_ctrl); + writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); + while (timer_get_us() < tmo) { if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT) return 1; @@ -203,7 +210,8 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf) return r; } -static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) +static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode, + bool verbose_mode) { struct edid1_info edid1; struct edid_cea861_info cea681[4]; @@ -215,13 +223,6 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; int i, r, ext_blocks = 0; - /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */ - writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, - &hdmi->pad_ctrl1); - writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15), - &hdmi->pll_ctrl); - writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); - /* Reset i2c controller */ setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); writel(SUNXI_HMDI_DDC_CTRL_ENABLE | @@ -241,7 +242,8 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) if (r == 0) { r = edid_check_info(&edid1); if (r) { - printf("EDID: invalid EDID data\n"); + if (verbose_mode) + printf("EDID: invalid EDID data\n"); r = -EINVAL; } } @@ -1082,7 +1084,8 @@ void *video_hw_init(void) struct ctfb_res_modes custom; const char *options; #ifdef CONFIG_VIDEO_HDMI - int ret, hpd, hpd_delay, edid; + int hpd, hpd_delay, edid; + bool hdmi_present; #endif int i, overscan_offset, overscan_x, overscan_y; unsigned int fb_dma_addr; @@ -1118,12 +1121,23 @@ void *video_hw_init(void) if (sunxi_display.monitor == sunxi_monitor_dvi || sunxi_display.monitor == sunxi_monitor_hdmi) { /* Always call hdp_detect, as it also enables clocks, etc. */ - ret = sunxi_hdmi_hpd_detect(hpd_delay); - if (ret) { + hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1); + if (hdmi_present && edid) { printf("HDMI connected: "); - if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) + if (sunxi_hdmi_edid_get_mode(&custom, true) == 0) mode = &custom; - } else if (hpd) { + else + hdmi_present = false; + } + /* Fall back to EDID in case HPD failed */ + if (edid && !hdmi_present) { + if (sunxi_hdmi_edid_get_mode(&custom, false) == 0) { + mode = &custom; + hdmi_present = true; + } + } + /* Shut down when display was not found */ + if ((hpd || edid) && !hdmi_present) { sunxi_hdmi_shutdown(); sunxi_display.monitor = sunxi_get_default_mon(false); } /* else continue with hdmi/dvi without a cable connected */ diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index 2898b0b55d..193f37d275 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -229,11 +229,12 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, } /* - * We support displaying 8bpp BMPs on 16bpp LCDs + * We support displaying 8bpp and 24bpp BMPs on 16bpp LCDs * and displaying 24bpp BMPs on 32bpp LCDs - * */ + */ if (bpix != bmp_bpix && !(bmp_bpix == 8 && bpix == 16) && + !(bmp_bpix == 24 && bpix == 16) && !(bmp_bpix == 24 && bpix == 32)) { printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", bpix, get_unaligned_le16(&bmp->header.bit_count)); @@ -318,12 +319,22 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, case 24: for (i = 0; i < height; ++i) { for (j = 0; j < width; j++) { - *(fb++) = *(bmap++); - *(fb++) = *(bmap++); - *(fb++) = *(bmap++); - *(fb++) = 0; + if (bpix == 16) { + /* 16bit 555RGB format */ + *(u16 *)fb = ((bmap[2] >> 3) << 10) | + ((bmap[1] >> 3) << 5) | + (bmap[0] >> 3); + bmap += 3; + fb += 2; + } else { + *(fb++) = *(bmap++); + *(fb++) = *(bmap++); + *(fb++) = *(bmap++); + *(fb++) = 0; + } } fb -= priv->line_length + width * (bpix / 8); + bmap += (padded_width - width) * 3; } break; #endif /* CONFIG_BMP_24BPP */ diff --git a/include/efi_loader.h b/include/efi_loader.h index 9dd933dae7..512880ab8f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -301,8 +301,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout); /* Called from places to check whether a timer expired */ void efi_timer_check(void); /* PE loader implementation */ -void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, - struct efi_loaded_image *loaded_image_info); +efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, + struct efi_loaded_image *loaded_image_info); /* Called once to store the pristine gd pointer */ void efi_save_gd(void); /* Special case handler for error/abort that just tries to dtrt to get @@ -320,6 +320,10 @@ efi_status_t efi_create_handle(efi_handle_t *handle); void efi_delete_handle(efi_handle_t obj); /* Call this to validate a handle and find the EFI object for it */ struct efi_object *efi_search_obj(const efi_handle_t handle); +/* Start image */ +efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, + efi_uintn_t *exit_data_size, + u16 **exit_data); /* Find a protocol on a handle */ efi_status_t efi_search_protocol(const efi_handle_t handle, const efi_guid_t *protocol_guid, @@ -397,7 +401,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, struct efi_loaded_image_obj **handle_ptr, struct efi_loaded_image **info_ptr); efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, - void **buffer); + void **buffer, efi_uintn_t *size); /* Print information about all loaded images */ void efi_print_image_infos(void *pc); diff --git a/include/mmc.h b/include/mmc.h index d84e4fca73..1f30f71d25 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -690,6 +690,12 @@ int mmc_initialize(bd_t *bis); int mmc_init(struct mmc *mmc); int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error); +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +int mmc_deinit(struct mmc *mmc); +#endif + /** * mmc_of_parse() - Parse the device tree to get the capabilities of the host * diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index a095df3f54..196116b547 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -150,7 +150,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, debug("%s: trying to load \"%ls\" from %pD\n", __func__, lo.label, lo.file_path); - ret = efi_load_image_from_path(lo.file_path, &image); + ret = efi_load_image_from_path(lo.file_path, &image, &size); if (ret != EFI_SUCCESS) goto error; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index f74f989e0a..bd8b8a17ae 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -44,7 +44,8 @@ static bool efi_is_direct_boot = true; static volatile void *efi_gd, *app_gd; #endif -static int entry_count; +/* 1 if inside U-Boot code, 0 if inside EFI payload code */ +static int entry_count = 1; static int nesting_level; /* GUID of the device tree table */ const efi_guid_t efi_guid_fdt = EFI_FDT_GUID; @@ -1497,15 +1498,18 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, /** * efi_setup_loaded_image() - initialize a loaded image - * @info: loaded image info to be passed to the entry point of the image - * @obj: internal object associated with the loaded image - * @device_path: device path of the loaded image - * @file_path: file path of the loaded image * * Initialize a loaded_image_info and loaded_image_info object with correct * protocols, boot-device, etc. * - * Return: status code + * In case of an error *handle_ptr and *info_ptr are set to NULL and an error + * code is returned. + * + * @device_path: device path of the loaded image + * @file_path: file path of the loaded image + * @handle_ptr: handle of the loaded image + * @info_ptr: loaded image protocol + * Return: status code */ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, struct efi_device_path *file_path, @@ -1513,8 +1517,12 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, struct efi_loaded_image **info_ptr) { efi_status_t ret; - struct efi_loaded_image *info; - struct efi_loaded_image_obj *obj; + struct efi_loaded_image *info = NULL; + struct efi_loaded_image_obj *obj = NULL; + + /* In case of EFI_OUT_OF_RESOURCES avoid illegal free by caller. */ + *handle_ptr = NULL; + *info_ptr = NULL; info = calloc(1, sizeof(*info)); if (!info) @@ -1528,11 +1536,6 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, /* Add internal object to object list */ efi_add_handle(&obj->header); - if (info_ptr) - *info_ptr = info; - if (handle_ptr) - *handle_ptr = obj; - info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; info->file_path = file_path; info->system_table = &systab; @@ -1578,58 +1581,87 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, goto failure; #endif + if (info_ptr) + *info_ptr = info; + if (handle_ptr) + *handle_ptr = obj; + return ret; failure: printf("ERROR: Failure to install protocols for loaded image\n"); + efi_delete_handle(&obj->header); + free(info); return ret; } /** * efi_load_image_from_path() - load an image using a file path - * @file_path: the path of the image to load - * @buffer: buffer containing the loaded image * - * Return: status code + * Read a file into a buffer allocated as EFI_BOOT_SERVICES_DATA. It is the + * callers obligation to update the memory type as needed. + * + * @file_path: the path of the image to load + * @buffer: buffer containing the loaded image + * @size: size of the loaded image + * Return: status code */ efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, - void **buffer) + void **buffer, efi_uintn_t *size) { struct efi_file_info *info = NULL; struct efi_file_handle *f; static efi_status_t ret; + u64 addr; efi_uintn_t bs; + /* In case of failure nothing is returned */ + *buffer = NULL; + *size = 0; + + /* Open file */ f = efi_file_from_path(file_path); if (!f) return EFI_DEVICE_ERROR; + /* Get file size */ bs = 0; EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, &bs, info)); - if (ret == EFI_BUFFER_TOO_SMALL) { - info = malloc(bs); - EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, - &bs, info)); - } - if (ret != EFI_SUCCESS) + if (ret != EFI_BUFFER_TOO_SMALL) { + ret = EFI_DEVICE_ERROR; goto error; + } - ret = efi_allocate_pool(EFI_LOADER_DATA, info->file_size, buffer); - if (ret) + info = malloc(bs); + EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, &bs, + info)); + if (ret != EFI_SUCCESS) goto error; + /* + * When reading the file we do not yet know if it contains an + * application, a boottime driver, or a runtime driver. So here we + * allocate a buffer as EFI_BOOT_SERVICES_DATA. The caller has to + * update the reservation according to the image type. + */ bs = info->file_size; - EFI_CALL(ret = f->read(f, &bs, *buffer)); - -error: - free(info); - EFI_CALL(f->close(f)); - + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_BOOT_SERVICES_DATA, + efi_size_in_pages(bs), &addr); if (ret != EFI_SUCCESS) { - efi_free_pool(*buffer); - *buffer = NULL; + ret = EFI_OUT_OF_RESOURCES; + goto error; } + /* Read file */ + EFI_CALL(ret = f->read(f, &bs, (void *)(uintptr_t)addr)); + if (ret != EFI_SUCCESS) + efi_free_pages(addr, efi_size_in_pages(bs)); + *buffer = (void *)(uintptr_t)addr; + *size = bs; +error: + EFI_CALL(f->close(f)); + free(info); return ret; } @@ -1656,6 +1688,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_uintn_t source_size, efi_handle_t *image_handle) { + struct efi_device_path *dp, *fp; struct efi_loaded_image *info = NULL; struct efi_loaded_image_obj **image_obj = (struct efi_loaded_image_obj **)image_handle; @@ -1675,36 +1708,51 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, } if (!source_buffer) { - struct efi_device_path *dp, *fp; - - ret = efi_load_image_from_path(file_path, &source_buffer); + ret = efi_load_image_from_path(file_path, &source_buffer, + &source_size); if (ret != EFI_SUCCESS) - goto failure; + goto error; /* * split file_path which contains both the device and * file parts: */ efi_dp_split_file_path(file_path, &dp, &fp); - ret = efi_setup_loaded_image(dp, fp, image_obj, &info); - if (ret != EFI_SUCCESS) - goto failure; } else { /* In this case, file_path is the "device" path, i.e. * something like a HARDWARE_DEVICE:MEMORY_MAPPED */ - ret = efi_setup_loaded_image(file_path, NULL, image_obj, &info); + u64 addr; + void *dest_buffer; + + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_RUNTIME_SERVICES_CODE, + efi_size_in_pages(source_size), &addr); if (ret != EFI_SUCCESS) goto error; + dest_buffer = (void *)(uintptr_t)addr; + memcpy(dest_buffer, source_buffer, source_size); + source_buffer = dest_buffer; + + dp = file_path; + fp = NULL; } - (*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info); - if (!(*image_obj)->entry) { - ret = EFI_UNSUPPORTED; - goto failure; - } + ret = efi_setup_loaded_image(dp, fp, image_obj, &info); + if (ret != EFI_SUCCESS) + goto error_invalid_image; + ret = efi_load_pe(*image_obj, source_buffer, info); + if (ret != EFI_SUCCESS) + goto error_invalid_image; + /* Update the type of the allocated memory */ + efi_add_memory_map((uintptr_t)source_buffer, + efi_size_in_pages(source_size), + info->image_code_type, false); info->system_table = &systab; info->parent_handle = parent_image; return EFI_EXIT(EFI_SUCCESS); -failure: +error_invalid_image: + /* The image is invalid. Release all associated resources. */ + efi_free_pages((uintptr_t)source_buffer, + efi_size_in_pages(source_size)); efi_delete_handle(*image_handle); *image_handle = NULL; free(info); @@ -1725,9 +1773,9 @@ error: * * Return: status code */ -static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, - efi_uintn_t *exit_data_size, - u16 **exit_data) +efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, + efi_uintn_t *exit_data_size, + u16 **exit_data) { struct efi_loaded_image_obj *image_obj = (struct efi_loaded_image_obj *)image_handle; diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index d94982314a..98c36e798f 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -910,9 +910,17 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, return start; } -/* - * Helper to split a full device path (containing both device and file - * parts) into it's constituent parts. +/** + * efi_dp_split_file_path() - split of relative file path from device path + * + * Given a device path indicating a file on a device, separate the device + * path in two: the device path of the actual device and the file path + * relative to this device. + * + * @full_path: device path including device and file path + * @device_path: path of the device + * @file_path: relative path of the file + * Return: status code */ efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path, struct efi_device_path **device_path, @@ -929,7 +937,7 @@ efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path, while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) { p = efi_dp_next(p); if (!p) - return EFI_OUT_OF_RESOURCES; + return EFI_INVALID_PARAMETER; } fp = efi_dp_dup(p); if (!fp) diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 4b4422205d..3a7323765b 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -641,6 +641,12 @@ static const struct efi_file_handle efi_file_handle_protocol = { .flush = efi_file_flush, }; +/** + * efi_file_from_path() - open file via device path + * + * @fp: device path + * @return: EFI_FILE_PROTOCOL for the file or NULL + */ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) { struct efi_simple_file_system_protocol *v; @@ -655,10 +661,14 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) if (ret != EFI_SUCCESS) return NULL; - /* skip over device-path nodes before the file path: */ + /* Skip over device-path nodes before the file path. */ while (fp && !EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) fp = efi_dp_next(fp); + /* + * Step through the nodes of the directory path until the actual file + * node is reached which is the final node in the device path. + */ while (fp) { struct efi_device_path_file_path *fdp = container_of(fp, struct efi_device_path_file_path, dp); diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index a18ce0a570..fe66e7b9ff 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -42,8 +42,8 @@ static int machines[] = { #endif 0 }; -/* - * Print information about a loaded image. +/** + * efi_print_image_info() - print information about a loaded image * * If the program counter is located within the image the offset to the base * address is shown. @@ -51,7 +51,7 @@ static int machines[] = { * @obj: EFI object * @image: loaded image * @pc: program counter (use NULL to suppress offset output) - * @return: status code + * Return: status code */ static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj, struct efi_loaded_image *image, @@ -69,8 +69,8 @@ static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj, return EFI_SUCCESS; } -/* - * Print information about all loaded images. +/** + * efi_print_image_infos() - print information about all loaded images * * @pc: program counter (use NULL to suppress offset output) */ @@ -90,6 +90,15 @@ void efi_print_image_infos(void *pc) } } +/** + * efi_loader_relocate() - relocate UEFI binary + * + * @rel: pointer to the relocation table + * @rel_size: size of the relocation table in bytes + * @efi_reloc: actual load address of the image + * @pref_address: preferred load address of the image + * Return: status code + */ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, unsigned long rel_size, void *efi_reloc, unsigned long pref_address) @@ -102,7 +111,7 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, return EFI_SUCCESS; end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size); - while (rel < end - 1 && rel->SizeOfBlock) { + while (rel < end && rel->SizeOfBlock) { const uint16_t *relocs = (const uint16_t *)(rel + 1); i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t); while (i--) { @@ -159,11 +168,12 @@ void __weak invalidate_icache_all(void) /* If the system doesn't support icache_all flush, cross our fingers */ } -/* - * Determine the memory types to be used for code and data. +/** + * efi_set_code_and_data_type() - determine the memory types to be used for code + * and data. * - * @loaded_image_info image descriptor - * @image_type field Subsystem of the optional header for + * @loaded_image_info: image descriptor + * @image_type: field Subsystem of the optional header for * Windows specific field */ static void efi_set_code_and_data_type( @@ -193,13 +203,19 @@ static void efi_set_code_and_data_type( } } -/* +/** + * efi_load_pe() - relocate EFI binary + * * This function loads all sections from a PE binary into a newly reserved - * piece of memory. On successful load it then returns the entry point for - * the binary. Otherwise NULL. + * piece of memory. On success the entry point is returned as handle->entry. + * + * @handle: loaded image handle + * @efi: pointer to the EFI binary + * @loaded_image_info: loaded image protocol + * Return: status code */ -void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, - struct efi_loaded_image *loaded_image_info) +efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, + struct efi_loaded_image *loaded_image_info) { IMAGE_NT_HEADERS32 *nt; IMAGE_DOS_HEADER *dos; @@ -210,7 +226,6 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, const IMAGE_BASE_RELOCATION *rel; unsigned long rel_size; int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC; - void *entry; uint64_t image_base; uint64_t image_size; unsigned long virt_size = 0; @@ -219,13 +234,13 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, dos = efi; if (dos->e_magic != IMAGE_DOS_SIGNATURE) { printf("%s: Invalid DOS Signature\n", __func__); - return NULL; + return EFI_LOAD_ERROR; } nt = (void *) ((char *)efi + dos->e_lfanew); if (nt->Signature != IMAGE_NT_SIGNATURE) { printf("%s: Invalid NT Signature\n", __func__); - return NULL; + return EFI_LOAD_ERROR; } for (i = 0; machines[i]; i++) @@ -237,7 +252,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!supported) { printf("%s: Machine type 0x%04x is not supported\n", __func__, nt->FileHeader.Machine); - return NULL; + return EFI_LOAD_ERROR; } /* Calculate upper virtual address boundary */ @@ -263,9 +278,9 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!efi_reloc) { printf("%s: Could not allocate %lu bytes\n", __func__, virt_size); - return NULL; + return EFI_OUT_OF_RESOURCES; } - entry = efi_reloc + opt->AddressOfEntryPoint; + handle->entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; virt_size = ALIGN(virt_size, opt->SectionAlignment); @@ -279,16 +294,16 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, if (!efi_reloc) { printf("%s: Could not allocate %lu bytes\n", __func__, virt_size); - return NULL; + return EFI_OUT_OF_RESOURCES; } - entry = efi_reloc + opt->AddressOfEntryPoint; + handle->entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; virt_size = ALIGN(virt_size, opt->SectionAlignment); } else { printf("%s: Invalid optional header magic %x\n", __func__, nt->OptionalHeader.Magic); - return NULL; + return EFI_LOAD_ERROR; } /* Load sections into RAM */ @@ -306,7 +321,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, (unsigned long)image_base) != EFI_SUCCESS) { efi_free_pages((uintptr_t) efi_reloc, (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT); - return NULL; + return EFI_LOAD_ERROR; } /* Flush cache */ @@ -320,5 +335,5 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi, handle->reloc_base = efi_reloc; handle->reloc_size = virt_size; - return entry; + return EFI_SUCCESS; } diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 7f4eafb2fe..c9720c9da8 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -51,6 +51,7 @@ endif ifeq ($(CONFIG_SANDBOX)$(CONFIG_CPU_V7M)$(CONFIG_X86_64),) obj-y += \ +efi_selftest_loadimage.o \ efi_selftest_startimage_exit.o \ efi_selftest_startimage_return.o @@ -68,6 +69,8 @@ $(obj)/efi_miniapp_file_image_return.h: $(obj)/efi_selftest_miniapp_return.efi $(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp_return.efi > \ $(obj)/efi_miniapp_file_image_return.h +$(obj)/efi_selftest_loadimage.o: $(obj)/efi_miniapp_file_image_exit.h + $(obj)/efi_selftest_startimage_exit.o: $(obj)/efi_miniapp_file_image_exit.h $(obj)/efi_selftest_startimage_return.o: $(obj)/efi_miniapp_file_image_return.h diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index 1cdd8307f4..21409aed6f 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -264,7 +264,7 @@ static int teardown(void) } if (image) { - r = efi_free_pool(image); + r = boottime->free_pool(image); if (r != EFI_SUCCESS) { efi_st_error("Failed to free image\n"); return EFI_ST_FAILURE; diff --git a/lib/efi_selftest/efi_selftest_hii.c b/lib/efi_selftest/efi_selftest_hii.c index e38af7dbf8..8a0b3bc353 100644 --- a/lib/efi_selftest/efi_selftest_hii.c +++ b/lib/efi_selftest/efi_selftest_hii.c @@ -8,7 +8,6 @@ */ #include <efi_selftest.h> -#include <malloc.h> #include "efi_selftest_hii_data.c" #define PRINT_TESTNAME efi_st_printf("%s:\n", __func__) @@ -192,9 +191,10 @@ static int test_hii_database_list_package_lists(void) (unsigned int)ret); goto out; } - handles = malloc(handles_size); - if (!handles) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, + (void **)&handles); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_database_protocol->list_package_lists(hii_database_protocol, @@ -205,7 +205,11 @@ static int test_hii_database_list_package_lists(void) (unsigned int)ret); goto out; } - free(handles); + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + goto out; + } /* STRINGS */ handles = NULL; @@ -219,9 +223,10 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - handles = malloc(handles_size); - if (!handles) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, + (void **)&handles); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); ret = EFI_ST_FAILURE; goto out; } @@ -234,7 +239,11 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - free(handles); + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + goto out; + } /* GUID */ handles = NULL; @@ -248,9 +257,10 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - handles = malloc(handles_size); - if (!handles) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, + (void **)&handles); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); ret = EFI_ST_FAILURE; goto out; } @@ -263,7 +273,12 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - free(handles); + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + ret = EFI_ST_FAILURE; + goto out; + } /* KEYBOARD_LAYOUT */ handles = NULL; @@ -277,9 +292,10 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - handles = malloc(handles_size); - if (!handles) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, + (void **)&handles); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); ret = EFI_ST_FAILURE; goto out; } @@ -292,7 +308,12 @@ static int test_hii_database_list_package_lists(void) ret = EFI_ST_FAILURE; goto out; } - free(handles); + ret = boottime->free_pool(handles); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + ret = EFI_ST_FAILURE; + goto out; + } result = EFI_ST_SUCCESS; @@ -398,9 +419,10 @@ static int test_hii_database_find_keyboard_layouts(void) (unsigned int)ret); goto out; } - guids = malloc(guids_size); - if (!guids) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, guids_size, + (void **)&guids); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_database_protocol->find_keyboard_layouts( @@ -410,7 +432,11 @@ static int test_hii_database_find_keyboard_layouts(void) (unsigned int)ret); goto out; } - free(guids); + ret = boottime->free_pool(guids); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + goto out; + } result = EFI_ST_SUCCESS; @@ -479,9 +505,10 @@ static int test_hii_database_get_keyboard_layout(void) (unsigned int)ret); goto out; } - kb_layout = malloc(kb_layout_size); - if (!kb_layout) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, kb_layout_size, + (void **)&kb_layout); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol, @@ -491,7 +518,11 @@ static int test_hii_database_get_keyboard_layout(void) (unsigned int)ret); goto out; } - free(kb_layout); + ret = boottime->free_pool(kb_layout); + if (ret != EFI_SUCCESS) { + efi_st_error("FreePool failed\n"); + goto out; + } /* current */ kb_layout = NULL; @@ -738,9 +769,10 @@ static int test_hii_string_get_string(void) goto out; } string_len += sizeof(u16); - string = malloc(string_len); - if (!string) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, string_len, + (void **)&string); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_string_protocol->get_string(hii_string_protocol, @@ -875,9 +907,10 @@ static int test_hii_string_get_languages(void) (unsigned int)ret); goto out; } - languages = malloc(languages_len); - if (!languages) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len, + (void **)&languages); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_string_protocol->get_languages(hii_string_protocol, handle, @@ -947,9 +980,10 @@ static int test_hii_string_get_secondary_languages(void) (unsigned int)ret); goto out; } - languages = malloc(languages_len); - if (!languages) { - efi_st_error("malloc failed\n"); + ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len, + (void **)&languages); + if (ret != EFI_SUCCESS) { + efi_st_error("AllocatePool failed\n"); goto out; } ret = hii_string_protocol->get_secondary_languages(hii_string_protocol, diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c new file mode 100644 index 0000000000..96faa67a15 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_loadimage.c @@ -0,0 +1,529 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * efi_selftest_loadimage + * + * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * This test checks the LoadImage and StartImage boot service. + * + * The efi_selftest_miniapp_exit.efi application is loaded via a file device + * path and started. + */ + +#include <efi_selftest.h> +/* Include containing the efi_selftest_miniapp_exit.efi application */ +#include "efi_miniapp_file_image_exit.h" + +/* Block size of compressed disk image */ +#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 + +/* Binary logarithm of the block size */ +#define LB_BLOCK_SIZE 9 + +#define FILE_NAME L"app.efi" +#define VOLUME_NAME L"EfiDisk" + +static struct efi_boot_services *boottime; +static efi_handle_t handle_image; +static efi_handle_t handle_volume; + +static const efi_guid_t guid_device_path = DEVICE_PATH_GUID; +static const efi_guid_t guid_simple_file_system_protocol = + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +static const efi_guid_t guid_file_info = EFI_FILE_INFO_GUID; +static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID; + +/* One 8 byte block of the compressed disk image */ +struct line { + size_t addr; + char *line; +}; + +/* Compressed file image */ +struct compressed_file_image { + size_t length; + struct line lines[]; +}; + +/* File info including file name */ +struct file_info { + struct efi_file_info info; + u16 file_name[sizeof(FILE_NAME)]; +}; + +/* File system info including volume name */ +struct file_system_info { + struct efi_file_system_info info; + u16 file_name[sizeof(VOLUME_NAME)]; +}; + +/* Compressed file image */ +static struct compressed_file_image img = EFI_ST_DISK_IMG; + +/* Pointer to decompressed file image */ +static u8 *image; + +/* File info */ +static struct file_info priv_file_info = { + { + .size = sizeof(struct file_info), + .attribute = EFI_FILE_READ_ONLY, + }, + FILE_NAME, +}; + +/* Pointer to file info */ +struct efi_file_info *file_info = &priv_file_info.info; + +/* Volume device path */ +static struct { + struct efi_device_path_vendor vendor; + struct efi_device_path end; +} __packed dp_volume = { + .vendor = { + .dp = { + .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, + .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, + .length = sizeof(struct efi_device_path_vendor), + }, + .guid = EFI_GUID(0x4f9a0ebf, 0xa179, 0x88a6, 0x25, 0x68, + 0x10, 0x72, 0xb1, 0x93, 0x51, 0x71), + }, + .end = { + .type = DEVICE_PATH_TYPE_END, + .sub_type = DEVICE_PATH_SUB_TYPE_END, + .length = sizeof(struct efi_device_path), + } +}; + +/* File device path */ +static struct { + struct efi_device_path_vendor vendor; + struct efi_device_path path; + u16 file[sizeof(FILE_NAME)]; + struct efi_device_path end; +} __packed dp_file = { + .vendor = { + .dp = { + .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, + .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, + .length = sizeof(struct efi_device_path_vendor), + }, + .guid = EFI_GUID(0x4f9a0ebf, 0xa179, 0x88a6, 0x25, 0x68, + 0x10, 0x72, 0xb1, 0x93, 0x51, 0x71), + }, + .path = { + .type = DEVICE_PATH_TYPE_MEDIA_DEVICE, + .sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, + .length = sizeof(struct efi_device_path) + sizeof(dp_file.file), + }, + .file = FILE_NAME, + .end = { + .type = DEVICE_PATH_TYPE_END, + .sub_type = DEVICE_PATH_SUB_TYPE_END, + .length = sizeof(struct efi_device_path), + } +}; + +/* File system info */ +static struct file_system_info priv_file_system_info = { + { + .size = sizeof(struct file_system_info), + .read_only = true, + .volume_size = 0x100000, + .free_space = 0x0, + .block_size = 0x200, + }, + VOLUME_NAME +}; + +/* Pointer to file system info */ +static struct efi_file_system_info *file_system_info = + &priv_file_system_info.info; + +/* Forward definitions of file and file system functions */ +static efi_status_t EFIAPI open_volume + (struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); + +static efi_status_t EFIAPI open + (struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, u64 attributes); + +static efi_status_t EFIAPI close(struct efi_file_handle *this); + +static efi_status_t EFIAPI delete(struct efi_file_handle *this); + +static efi_status_t EFIAPI read + (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); + +static efi_status_t EFIAPI write + (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); + +static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos); + +static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos); + +static efi_status_t EFIAPI getinfo + (struct efi_file_handle *this, const efi_guid_t *info_type, + efi_uintn_t *buffer_size, void *buffer); + +static efi_status_t EFIAPI setinfo + (struct efi_file_handle *this, const efi_guid_t *info_type, + efi_uintn_t buffer_size, void *buffer); + +static efi_status_t EFIAPI flush(struct efi_file_handle *this); + +/* Internal information about status of file system */ +static struct { + /* Difference of volume open count minus volume close count */ + int volume_open_count; + /* Difference of file open count minus file close count */ + int file_open_count; + /* File size */ + u64 file_size; + /* Current position in file */ + u64 file_pos; +} priv; + +/* EFI_FILE_PROTOCOL for file */ +static struct efi_file_handle file = { + .rev = 0x00010000, + .open = open, + .close = close, + .delete = delete, + .read = read, + .write = write, + .getpos = getpos, + .setpos = setpos, + .getinfo = getinfo, + .setinfo = setinfo, + .flush = flush, +}; + +/* EFI_FILE_PROTOCOL for root directory */ +static struct efi_file_handle volume = { + .rev = 0x00010000, + .open = open, + .close = close, + .delete = delete, + .read = read, + .write = write, + .getpos = getpos, + .setpos = setpos, + .getinfo = getinfo, + .setinfo = setinfo, + .flush = flush, +}; + +/* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL of the block device */ +struct efi_simple_file_system_protocol file_system = { + .rev = 0x00010000, + .open_volume = open_volume, +}; + +static efi_status_t EFIAPI open_volume + (struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + if (this != &file_system || !root) + return EFI_INVALID_PARAMETER; + + *root = &volume; + priv.volume_open_count++; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI open + (struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, u64 attributes) +{ + if (this != &volume) + return EFI_INVALID_PARAMETER; + + *new_handle = &file; + priv.file_pos = 0; + priv.file_open_count++; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI close(struct efi_file_handle *this) +{ + if (this == &file) + priv.file_open_count--; + else if (this == &volume) + priv.volume_open_count--; + else + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI delete(struct efi_file_handle *this) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI read + (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + if (priv.file_pos >= img.length) + *buffer_size = 0; + else if (priv.file_pos + *buffer_size > img.length) + *buffer_size = img.length - priv.file_pos; + + boottime->copy_mem(buffer, &image[priv.file_pos], *buffer_size); + priv.file_pos += *buffer_size; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI write + (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + *pos = priv.file_pos; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + priv.file_pos = pos; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI getinfo + (struct efi_file_handle *this, const efi_guid_t *info_type, + efi_uintn_t *buffer_size, void *buffer) +{ + if (this == &file) { + if (efi_st_memcmp(info_type, &guid_file_info, + sizeof(efi_guid_t))) + return EFI_INVALID_PARAMETER; + if (*buffer_size >= sizeof(struct file_info)) { + boottime->copy_mem(buffer, file_info, + sizeof(struct file_info)); + } else { + *buffer_size = sizeof(struct file_info); + return EFI_BUFFER_TOO_SMALL; + } + } else if (this == &volume) { + if (efi_st_memcmp(info_type, &guid_file_system_info, + sizeof(efi_guid_t))) + return EFI_INVALID_PARAMETER; + if (*buffer_size >= sizeof(struct file_system_info)) { + boottime->copy_mem(buffer, file_system_info, + sizeof(struct file_system_info)); + } else { + *buffer_size = sizeof(struct file_system_info); + return EFI_BUFFER_TOO_SMALL; + } + } else { + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI setinfo + (struct efi_file_handle *this, const efi_guid_t *info_type, + efi_uintn_t buffer_size, void *buffer) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + return EFI_UNSUPPORTED; +} + +static efi_status_t EFIAPI flush(struct efi_file_handle *this) +{ + if (this != &file) + return EFI_INVALID_PARAMETER; + + return EFI_UNSUPPORTED; +} + +/* + * Decompress the disk image. + * + * @image decompressed disk image + * @return status code + */ +static efi_status_t decompress(u8 **image) +{ + u8 *buf; + size_t i; + size_t addr; + size_t len; + efi_status_t ret; + + ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length, + (void **)&buf); + if (ret != EFI_SUCCESS) { + efi_st_error("Out of memory\n"); + return ret; + } + boottime->set_mem(buf, img.length, 0); + + for (i = 0; ; ++i) { + if (!img.lines[i].line) + break; + addr = img.lines[i].addr; + len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE; + if (addr + len > img.length) + len = img.length - addr; + boottime->copy_mem(buf + addr, img.lines[i].line, len); + } + *image = buf; + priv.file_size = img.length; + file_info->file_size = img.length; + return ret; +} + +/* + * Setup unit test. + * + * Decompress application image and provide a handle for the in memory block + * device. + * + * @handle: handle of the loaded image + * @systable: system table + * @return: EFI_ST_SUCCESS for success + */ +static int setup(const efi_handle_t handle, + const struct efi_system_table *systable) +{ + efi_status_t ret; + + handle_image = handle; + boottime = systable->boottime; + + /* Load the application image into memory */ + decompress(&image); + + ret = boottime->install_protocol_interface + (&handle_volume, &guid_device_path, EFI_NATIVE_INTERFACE, + &dp_volume); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to install device path\n"); + return EFI_ST_FAILURE; + } + ret = boottime->install_protocol_interface + (&handle_volume, &guid_simple_file_system_protocol, + EFI_NATIVE_INTERFACE, &file_system); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to install simple file system protocol\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +/* + * Tear down unit test. + * + * Uninstall protocols and free memory. + * + * @return: EFI_ST_SUCCESS for success + */ +static int teardown(void) +{ + efi_status_t ret = EFI_ST_SUCCESS; + + if (handle_volume) { + ret = boottime->uninstall_protocol_interface + (handle_volume, &guid_simple_file_system_protocol, + &file_system); + if (ret != EFI_SUCCESS) { + efi_st_error + ("Failed to uninstall simple file system protocol\n"); + return EFI_ST_FAILURE; + } + ret = boottime->uninstall_protocol_interface + (handle_volume, &guid_device_path, &dp_volume); + if (ret != EFI_SUCCESS) { + efi_st_error + ("Failed to uninstall device path protocol\n"); + return EFI_ST_FAILURE; + } + } + + if (image) { + ret = boottime->free_pool(image); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to free image\n"); + return EFI_ST_FAILURE; + } + } + return ret; +} + +/* + * Execute unit test. + * + * Load and start the application image. + * + * @return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + efi_status_t ret; + efi_handle_t handle; + + ret = boottime->load_image(false, handle_image, &dp_file.vendor.dp, + NULL, 0, &handle); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to load image\n"); + return EFI_ST_FAILURE; + } + ret = boottime->start_image(handle, NULL, NULL); + if (ret != EFI_UNSUPPORTED) { + efi_st_error("Wrong return value from application\n"); + return EFI_ST_FAILURE; + } + + if (priv.file_open_count) { + efi_st_error("File open count = %d, expected 0\n", + priv.file_open_count); + return EFI_ST_FAILURE; + } + if (priv.volume_open_count) { + efi_st_error("Volume open count = %d, expected 0\n", + priv.volume_open_count); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(loadimage) = { + .name = "load image from file", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, + .teardown = teardown, +}; diff --git a/lib/efi_selftest/efi_selftest_startimage_exit.c b/lib/efi_selftest/efi_selftest_startimage_exit.c index 0d9e16437a..fa4b7d4a9b 100644 --- a/lib/efi_selftest/efi_selftest_startimage_exit.c +++ b/lib/efi_selftest/efi_selftest_startimage_exit.c @@ -103,7 +103,7 @@ static int teardown(void) efi_status_t r = EFI_ST_SUCCESS; if (image) { - r = efi_free_pool(image); + r = boottime->free_pool(image); if (r != EFI_SUCCESS) { efi_st_error("Failed to free image\n"); return EFI_ST_FAILURE; diff --git a/lib/efi_selftest/efi_selftest_startimage_return.c b/lib/efi_selftest/efi_selftest_startimage_return.c index 3c6249fdf1..fabf53d983 100644 --- a/lib/efi_selftest/efi_selftest_startimage_return.c +++ b/lib/efi_selftest/efi_selftest_startimage_return.c @@ -103,7 +103,7 @@ static int teardown(void) efi_status_t r = EFI_ST_SUCCESS; if (image) { - r = efi_free_pool(image); + r = boottime->free_pool(image); if (r != EFI_SUCCESS) { efi_st_error("Failed to free image\n"); return EFI_ST_FAILURE; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index de5db1aa5c..1b6c154d8d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -288,6 +288,8 @@ static char *string16(char *buf, char *end, u16 *s, int field_width, for (i = 0; i < len && buf + utf16_utf8_strnlen(str, 1) <= end; ++i) { s32 s = utf16_get(&str); + if (s < 0) + s = '?'; utf8_put(s, &buf); } for (; len < field_width; --field_width) diff --git a/test/unicode_ut.c b/test/unicode_ut.c index 84fc9a3b53..8e1efe6f69 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -50,7 +50,7 @@ static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00}; static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00}; static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00}; -static int ut_u16_strdup(struct unit_test_state *uts) +static int unicode_test_u16_strdup(struct unit_test_state *uts) { u16 *copy = u16_strdup(c4); @@ -59,9 +59,9 @@ static int ut_u16_strdup(struct unit_test_state *uts) free(copy); return 0; } -UNICODE_TEST(ut_u16_strdup); +UNICODE_TEST(unicode_test_u16_strdup); -static int ut_u16_strcpy(struct unit_test_state *uts) +static int unicode_test_u16_strcpy(struct unit_test_state *uts) { u16 *r; u16 copy[10]; @@ -71,11 +71,11 @@ static int ut_u16_strcpy(struct unit_test_state *uts) ut_assert(!memcmp(copy, c1, sizeof(c1))); return 0; } -UNICODE_TEST(ut_u16_strcpy); +UNICODE_TEST(unicode_test_u16_strcpy); /* U-Boot uses UTF-16 strings in the EFI context only. */ #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) -static int ut_string16(struct unit_test_state *uts) +static int unicode_test_string16(struct unit_test_state *uts) { char buf[20]; @@ -113,10 +113,10 @@ static int ut_string16(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_string16); +UNICODE_TEST(unicode_test_string16); #endif -static int ut_utf8_get(struct unit_test_state *uts) +static int unicode_test_utf8_get(struct unit_test_state *uts) { const char *s; s32 code; @@ -152,9 +152,9 @@ static int ut_utf8_get(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf8_get); +UNICODE_TEST(unicode_test_utf8_get); -static int ut_utf8_put(struct unit_test_state *uts) +static int unicode_test_utf8_put(struct unit_test_state *uts) { char buffer[8] = { 0, }; char *pos; @@ -190,9 +190,9 @@ static int ut_utf8_put(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf8_put); +UNICODE_TEST(unicode_test_utf8_put); -static int ut_utf8_utf16_strlen(struct unit_test_state *uts) +static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts) { ut_asserteq(6, utf8_utf16_strlen(d1)); ut_asserteq(8, utf8_utf16_strlen(d2)); @@ -206,9 +206,9 @@ static int ut_utf8_utf16_strlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf8_utf16_strlen); +UNICODE_TEST(unicode_test_utf8_utf16_strlen); -static int ut_utf8_utf16_strnlen(struct unit_test_state *uts) +static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts) { ut_asserteq(3, utf8_utf16_strnlen(d1, 3)); ut_asserteq(6, utf8_utf16_strnlen(d1, 13)); @@ -224,7 +224,7 @@ static int ut_utf8_utf16_strnlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf8_utf16_strnlen); +UNICODE_TEST(unicode_test_utf8_utf16_strnlen); /** * ut_u16_strcmp() - Compare to u16 strings. @@ -234,7 +234,7 @@ UNICODE_TEST(ut_utf8_utf16_strnlen); * @count: number of u16 to compare * Return: -1 if a1 < a2, 0 if a1 == a2, 1 if a1 > a2 */ -static int ut_u16_strcmp(const u16 *a1, const u16 *a2, size_t count) +static int unicode_test_u16_strcmp(const u16 *a1, const u16 *a2, size_t count) { for (; (*a1 || *a2) && count; ++a1, ++a2, --count) { if (*a1 < *a2) @@ -245,7 +245,7 @@ static int ut_u16_strcmp(const u16 *a1, const u16 *a2, size_t count) return 0; } -static int ut_utf8_utf16_strcpy(struct unit_test_state *uts) +static int unicode_test_utf8_utf16_strcpy(struct unit_test_state *uts) { u16 buf[16]; u16 *pos; @@ -253,44 +253,44 @@ static int ut_utf8_utf16_strcpy(struct unit_test_state *uts) pos = buf; utf8_utf16_strcpy(&pos, d1); ut_asserteq(6, pos - buf); - ut_assert(!ut_u16_strcmp(buf, c1, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c1, SIZE_MAX)); pos = buf; utf8_utf16_strcpy(&pos, d2); ut_asserteq(8, pos - buf); - ut_assert(!ut_u16_strcmp(buf, c2, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX)); pos = buf; utf8_utf16_strcpy(&pos, d3); ut_asserteq(3, pos - buf); - ut_assert(!ut_u16_strcmp(buf, c3, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c3, SIZE_MAX)); pos = buf; utf8_utf16_strcpy(&pos, d4); ut_asserteq(6, pos - buf); - ut_assert(!ut_u16_strcmp(buf, c4, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX)); /* Illegal utf-8 strings */ pos = buf; utf8_utf16_strcpy(&pos, j1); ut_asserteq(4, pos - buf); - ut_assert(!ut_u16_strcmp(buf, L"j1?l", SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, L"j1?l", SIZE_MAX)); pos = buf; utf8_utf16_strcpy(&pos, j2); ut_asserteq(4, pos - buf); - ut_assert(!ut_u16_strcmp(buf, L"j2?l", SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, L"j2?l", SIZE_MAX)); pos = buf; utf8_utf16_strcpy(&pos, j3); ut_asserteq(3, pos - buf); - ut_assert(!ut_u16_strcmp(buf, L"j3?", SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, L"j3?", SIZE_MAX)); return 0; } -UNICODE_TEST(ut_utf8_utf16_strcpy); +UNICODE_TEST(unicode_test_utf8_utf16_strcpy); -int ut_utf8_utf16_strncpy(struct unit_test_state *uts) +static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts) { u16 buf[16]; u16 *pos; @@ -300,41 +300,41 @@ int ut_utf8_utf16_strncpy(struct unit_test_state *uts) utf8_utf16_strncpy(&pos, d1, 4); ut_asserteq(4, pos - buf); ut_assert(!buf[4]); - ut_assert(!ut_u16_strcmp(buf, c1, 4)); + ut_assert(!unicode_test_u16_strcmp(buf, c1, 4)); pos = buf; memset(buf, 0, sizeof(buf)); utf8_utf16_strncpy(&pos, d2, 10); ut_asserteq(8, pos - buf); ut_assert(buf[4]); - ut_assert(!ut_u16_strcmp(buf, c2, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX)); pos = buf; memset(buf, 0, sizeof(buf)); utf8_utf16_strncpy(&pos, d3, 2); ut_asserteq(2, pos - buf); ut_assert(!buf[2]); - ut_assert(!ut_u16_strcmp(buf, c3, 2)); + ut_assert(!unicode_test_u16_strcmp(buf, c3, 2)); pos = buf; memset(buf, 0, sizeof(buf)); utf8_utf16_strncpy(&pos, d4, 2); ut_asserteq(4, pos - buf); ut_assert(!buf[4]); - ut_assert(!ut_u16_strcmp(buf, c4, 4)); + ut_assert(!unicode_test_u16_strcmp(buf, c4, 4)); pos = buf; memset(buf, 0, sizeof(buf)); utf8_utf16_strncpy(&pos, d4, 10); ut_asserteq(6, pos - buf); ut_assert(buf[5]); - ut_assert(!ut_u16_strcmp(buf, c4, SIZE_MAX)); + ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX)); return 0; } -UNICODE_TEST(ut_utf8_utf16_strncpy); +UNICODE_TEST(unicode_test_utf8_utf16_strncpy); -static int ut_utf16_get(struct unit_test_state *uts) +static int unicode_test_utf16_get(struct unit_test_state *uts) { const u16 *s; s32 code; @@ -358,9 +358,9 @@ static int ut_utf16_get(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_get); +UNICODE_TEST(unicode_test_utf16_get); -static int ut_utf16_put(struct unit_test_state *uts) +static int unicode_test_utf16_put(struct unit_test_state *uts) { u16 buffer[4] = { 0, }; u16 *pos; @@ -386,9 +386,9 @@ static int ut_utf16_put(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_put); +UNICODE_TEST(unicode_test_utf16_put); -int ut_utf16_strnlen(struct unit_test_state *uts) +static int unicode_test_utf16_strnlen(struct unit_test_state *uts) { ut_asserteq(3, utf16_strnlen(c1, 3)); ut_asserteq(6, utf16_strnlen(c1, 13)); @@ -404,9 +404,9 @@ int ut_utf16_strnlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_strnlen); +UNICODE_TEST(unicode_test_utf16_strnlen); -int ut_utf16_utf8_strlen(struct unit_test_state *uts) +static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts) { ut_asserteq(6, utf16_utf8_strlen(c1)); ut_asserteq(9, utf16_utf8_strlen(c2)); @@ -420,9 +420,9 @@ int ut_utf16_utf8_strlen(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_utf8_strlen); +UNICODE_TEST(unicode_test_utf16_utf8_strlen); -int ut_utf16_utf8_strnlen(struct unit_test_state *uts) +static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts) { ut_asserteq(3, utf16_utf8_strnlen(c1, 3)); ut_asserteq(6, utf16_utf8_strnlen(c1, 13)); @@ -432,9 +432,9 @@ int ut_utf16_utf8_strnlen(struct unit_test_state *uts) ut_asserteq(12, utf16_utf8_strnlen(c4, 3)); return 0; } -UNICODE_TEST(ut_utf16_utf8_strnlen); +UNICODE_TEST(unicode_test_utf16_utf8_strnlen); -int ut_utf16_utf8_strcpy(struct unit_test_state *uts) +static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts) { char buf[16]; char *pos; @@ -477,9 +477,9 @@ int ut_utf16_utf8_strcpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_utf8_strcpy); +UNICODE_TEST(unicode_test_utf16_utf8_strcpy); -int ut_utf16_utf8_strncpy(struct unit_test_state *uts) +static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts) { char buf[16]; char *pos; @@ -521,9 +521,9 @@ int ut_utf16_utf8_strncpy(struct unit_test_state *uts) return 0; } -UNICODE_TEST(ut_utf16_utf8_strncpy); +UNICODE_TEST(unicode_test_utf16_utf8_strncpy); -int ut_utf_to_lower(struct unit_test_state *uts) +static int unicode_test_utf_to_lower(struct unit_test_state *uts) { ut_asserteq('@', utf_to_lower('@')); ut_asserteq('a', utf_to_lower('A')); @@ -538,9 +538,9 @@ int ut_utf_to_lower(struct unit_test_state *uts) #endif return 0; } -UNICODE_TEST(ut_utf_to_lower); +UNICODE_TEST(unicode_test_utf_to_lower); -int ut_utf_to_upper(struct unit_test_state *uts) +static int unicode_test_utf_to_upper(struct unit_test_state *uts) { ut_asserteq('`', utf_to_upper('`')); ut_asserteq('A', utf_to_upper('a')); @@ -555,7 +555,7 @@ int ut_utf_to_upper(struct unit_test_state *uts) #endif return 0; } -UNICODE_TEST(ut_utf_to_upper); +UNICODE_TEST(unicode_test_utf_to_upper); int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { |