blob: 6e900a35dc22b7f182f75abf23e5aa222ce4dad7 [file] [log] [blame]
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * efi_selftest_exception
4 *
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +02005 * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +02006 *
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +02007 * This test checks the handling of exceptions.
8 *
9 * The efi_selftest_miniapp_exception.efi application is loaded into memory
10 * and started.
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +020011 */
12
13#include <efi_selftest.h>
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +020014/* 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
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +020022
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +020023/* 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
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +020067 */
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +020068static efi_status_t decompress(u8 **image)
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +020069{
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +020070 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;
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200114}
115
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +0200116/*
117 * Execute unit test.
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200118 *
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +0200119 * Load and start the application image.
120 *
121 * @return: EFI_ST_SUCCESS for success
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200122 */
123static int execute(void)
124{
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +0200125 efi_status_t ret;
126 efi_handle_t handle;
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200127
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +0200128 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");
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200137
138 return EFI_ST_FAILURE;
139}
140
141EFI_UNIT_TEST(exception) = {
142 .name = "exception",
143 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
Heinrich Schuchardtcafccfd2019-08-27 08:16:08 +0200144 .setup = setup,
Heinrich Schuchardte86d6ce2018-09-26 19:05:58 +0200145 .execute = execute,
146 .on_request = true,
147};