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