uboot/lib/efi_selftest/efi_selftest_startimage_exit.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * efi_selftest_start_image
   4 *
   5 * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
   6 *
   7 * This test checks the StartImage boot service.
   8 * The efi_selftest_miniapp_exit.efi application is loaded into memory
   9 * and started.
  10 */
  11
  12#include <efi_selftest.h>
  13/* Include containing the miniapp.efi application */
  14#include "efi_miniapp_file_image_exit.h"
  15
  16/* Block size of compressed disk image */
  17#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
  18
  19/* Binary logarithm of the block size */
  20#define LB_BLOCK_SIZE 9
  21
  22static efi_handle_t image_handle;
  23static struct efi_boot_services *boottime;
  24
  25/* One 8 byte block of the compressed disk image */
  26struct line {
  27        size_t addr;
  28        char *line;
  29};
  30
  31/* Compressed file image */
  32struct compressed_file_image {
  33        size_t length;
  34        struct line lines[];
  35};
  36
  37static struct compressed_file_image img = EFI_ST_DISK_IMG;
  38
  39/* Decompressed file image */
  40static u8 *image;
  41
  42/*
  43 * Decompress the disk image.
  44 *
  45 * @image       decompressed disk image
  46 * @return      status code
  47 */
  48static efi_status_t decompress(u8 **image)
  49{
  50        u8 *buf;
  51        size_t i;
  52        size_t addr;
  53        size_t len;
  54        efi_status_t ret;
  55
  56        ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length,
  57                                      (void **)&buf);
  58        if (ret != EFI_SUCCESS) {
  59                efi_st_error("Out of memory\n");
  60                return ret;
  61        }
  62        boottime->set_mem(buf, img.length, 0);
  63
  64        for (i = 0; ; ++i) {
  65                if (!img.lines[i].line)
  66                        break;
  67                addr = img.lines[i].addr;
  68                len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
  69                if (addr + len > img.length)
  70                        len = img.length - addr;
  71                boottime->copy_mem(buf + addr, img.lines[i].line, len);
  72        }
  73        *image = buf;
  74        return ret;
  75}
  76
  77/*
  78 * Setup unit test.
  79 *
  80 * @handle:     handle of the loaded image
  81 * @systable:   system table
  82 * @return:     EFI_ST_SUCCESS for success
  83 */
  84static int setup(const efi_handle_t handle,
  85                 const struct efi_system_table *systable)
  86{
  87        image_handle = handle;
  88        boottime = systable->boottime;
  89
  90        /* Load the application image into memory */
  91        decompress(&image);
  92
  93        return EFI_ST_SUCCESS;
  94}
  95
  96/*
  97 * Tear down unit test.
  98 *
  99 * @return:     EFI_ST_SUCCESS for success
 100 */
 101static int teardown(void)
 102{
 103        efi_status_t r = EFI_ST_SUCCESS;
 104
 105        if (image) {
 106                r = boottime->free_pool(image);
 107                if (r != EFI_SUCCESS) {
 108                        efi_st_error("Failed to free image\n");
 109                        return EFI_ST_FAILURE;
 110                }
 111        }
 112        return r;
 113}
 114
 115/*
 116 * Execute unit test.
 117 *
 118 * Load and start the application image.
 119 *
 120 * @return:     EFI_ST_SUCCESS for success
 121 */
 122static int execute(void)
 123{
 124        efi_status_t ret;
 125        efi_handle_t handle;
 126        efi_uintn_t exit_data_size = 0;
 127        u16 *exit_data = NULL;
 128        u16 expected_text[] = EFI_ST_SUCCESS_STR;
 129
 130        ret = boottime->load_image(false, image_handle, NULL, image,
 131                                   img.length, &handle);
 132        if (ret != EFI_SUCCESS) {
 133                efi_st_error("Failed to load image\n");
 134                return EFI_ST_FAILURE;
 135        }
 136        ret = boottime->start_image(handle, &exit_data_size, &exit_data);
 137        if (ret != EFI_UNSUPPORTED) {
 138                efi_st_error("Wrong return value from application\n");
 139                return EFI_ST_FAILURE;
 140        }
 141        if (!exit_data || exit_data_size != sizeof(expected_text) ||
 142            memcmp(exit_data, expected_text, sizeof(expected_text))) {
 143                efi_st_error("Incorrect exit data\n");
 144                return EFI_ST_FAILURE;
 145        }
 146        ret = boottime->free_pool(exit_data);
 147        if (ret != EFI_SUCCESS) {
 148                efi_st_error("Failed to free exit data\n");
 149                return EFI_ST_FAILURE;
 150        }
 151
 152        return EFI_ST_SUCCESS;
 153}
 154
 155EFI_UNIT_TEST(startimage_exit) = {
 156        .name = "start image exit",
 157        .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 158        .setup = setup,
 159        .execute = execute,
 160        .teardown = teardown,
 161};
 162