123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * efi_selftest_start_image
- *
- * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
- *
- * This test checks the StartImage boot service.
- * The efi_selftest_miniapp_exit.efi application is loaded into memory
- * and started.
- */
- #include <efi_selftest.h>
- /* Include containing the miniapp.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
- static efi_handle_t image_handle;
- static struct efi_boot_services *boottime;
- /* 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[];
- };
- static struct compressed_file_image img = EFI_ST_DISK_IMG;
- /* Decompressed file image */
- static u8 *image;
- /*
- * 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;
- return ret;
- }
- /*
- * Setup unit test.
- *
- * @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)
- {
- image_handle = handle;
- boottime = systable->boottime;
- /* Load the application image into memory */
- decompress(&image);
- return EFI_ST_SUCCESS;
- }
- /*
- * Tear down unit test.
- *
- * @return: EFI_ST_SUCCESS for success
- */
- static int teardown(void)
- {
- efi_status_t r = EFI_ST_SUCCESS;
- if (image) {
- r = efi_free_pool(image);
- if (r != EFI_SUCCESS) {
- efi_st_error("Failed to free image\n");
- return EFI_ST_FAILURE;
- }
- }
- return r;
- }
- /*
- * 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, image_handle, NULL, image,
- img.length, &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;
- }
- return EFI_ST_SUCCESS;
- }
- EFI_UNIT_TEST(startimage_exit) = {
- .name = "start image exit",
- .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
- .setup = setup,
- .execute = execute,
- .teardown = teardown,
- };
|