xref: /kvm-unit-tests/lib/efi.c (revision ad5fb8830150071487025b3594a7b1bf218d12d8)
10eaa5176SVarad Gautam /*
20eaa5176SVarad Gautam  * EFI-related functions to set up and run test cases in EFI
30eaa5176SVarad Gautam  *
40eaa5176SVarad Gautam  * Copyright (c) 2021, SUSE, Varad Gautam <varad.gautam@suse.com>
5*ad5fb883SZixuan Wang  * Copyright (c) 2021, Google Inc, Zixuan Wang <zixuanwang@google.com>
60eaa5176SVarad Gautam  *
70eaa5176SVarad Gautam  * SPDX-License-Identifier: LGPL-2.0-or-later
80eaa5176SVarad Gautam  */
90eaa5176SVarad Gautam 
10*ad5fb883SZixuan Wang #include "efi.h"
11*ad5fb883SZixuan Wang #include <libcflat.h>
12*ad5fb883SZixuan Wang #include <asm/setup.h>
13*ad5fb883SZixuan Wang 
14*ad5fb883SZixuan Wang /* From lib/argv.c */
15*ad5fb883SZixuan Wang extern int __argc, __envc;
16*ad5fb883SZixuan Wang extern char *__argv[100];
17*ad5fb883SZixuan Wang extern char *__environ[200];
18*ad5fb883SZixuan Wang 
19*ad5fb883SZixuan Wang extern int main(int argc, char **argv, char **envp);
20*ad5fb883SZixuan Wang 
210eaa5176SVarad Gautam efi_system_table_t *efi_system_table = NULL;
220eaa5176SVarad Gautam 
230eaa5176SVarad Gautam static void efi_free_pool(void *ptr)
240eaa5176SVarad Gautam {
250eaa5176SVarad Gautam 	efi_bs_call(free_pool, ptr);
260eaa5176SVarad Gautam }
270eaa5176SVarad Gautam 
28*ad5fb883SZixuan Wang efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
290eaa5176SVarad Gautam {
300eaa5176SVarad Gautam 	efi_memory_desc_t *m = NULL;
310eaa5176SVarad Gautam 	efi_status_t status;
320eaa5176SVarad Gautam 	unsigned long key = 0, map_size = 0, desc_size = 0;
330eaa5176SVarad Gautam 
340eaa5176SVarad Gautam 	status = efi_bs_call(get_memory_map, &map_size,
350eaa5176SVarad Gautam 			     NULL, &key, &desc_size, NULL);
360eaa5176SVarad Gautam 	if (status != EFI_BUFFER_TOO_SMALL || map_size == 0)
370eaa5176SVarad Gautam 		goto out;
380eaa5176SVarad Gautam 
390eaa5176SVarad Gautam 	/*
400eaa5176SVarad Gautam 	 * Pad map_size with additional descriptors so we don't need to
410eaa5176SVarad Gautam 	 * retry.
420eaa5176SVarad Gautam 	 */
430eaa5176SVarad Gautam 	map_size += 4 * desc_size;
440eaa5176SVarad Gautam 	*map->buff_size = map_size;
450eaa5176SVarad Gautam 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
460eaa5176SVarad Gautam 			     map_size, (void **)&m);
470eaa5176SVarad Gautam 	if (status != EFI_SUCCESS)
480eaa5176SVarad Gautam 		goto out;
490eaa5176SVarad Gautam 
500eaa5176SVarad Gautam 	/* Get the map. */
510eaa5176SVarad Gautam 	status = efi_bs_call(get_memory_map, &map_size,
520eaa5176SVarad Gautam 			     m, &key, &desc_size, NULL);
530eaa5176SVarad Gautam 	if (status != EFI_SUCCESS) {
540eaa5176SVarad Gautam 		efi_free_pool(m);
550eaa5176SVarad Gautam 		goto out;
560eaa5176SVarad Gautam 	}
570eaa5176SVarad Gautam 
580eaa5176SVarad Gautam 	*map->desc_size = desc_size;
590eaa5176SVarad Gautam 	*map->map_size = map_size;
600eaa5176SVarad Gautam 	*map->key_ptr = key;
610eaa5176SVarad Gautam out:
620eaa5176SVarad Gautam 	*map->map = m;
630eaa5176SVarad Gautam 	return status;
640eaa5176SVarad Gautam }
650eaa5176SVarad Gautam 
66*ad5fb883SZixuan Wang efi_status_t efi_exit_boot_services(void *handle, struct efi_boot_memmap *map)
670eaa5176SVarad Gautam {
680eaa5176SVarad Gautam 	return efi_bs_call(exit_boot_services, handle, *map->key_ptr);
690eaa5176SVarad Gautam }
700eaa5176SVarad Gautam 
71*ad5fb883SZixuan Wang efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
720eaa5176SVarad Gautam {
73*ad5fb883SZixuan Wang 	int ret;
74*ad5fb883SZixuan Wang 
750eaa5176SVarad Gautam 	efi_system_table = sys_tab;
760eaa5176SVarad Gautam 
77*ad5fb883SZixuan Wang 	setup_efi();
78*ad5fb883SZixuan Wang 	ret = main(__argc, __argv, __environ);
79*ad5fb883SZixuan Wang 	exit(ret);
80*ad5fb883SZixuan Wang 
81*ad5fb883SZixuan Wang 	/* Shutdown the guest VM in case exit() fails */
82*ad5fb883SZixuan Wang 	efi_rs_call(reset_system, EFI_RESET_SHUTDOWN, ret, 0, NULL);
83*ad5fb883SZixuan Wang 
84*ad5fb883SZixuan Wang 	/* Unreachable */
85*ad5fb883SZixuan Wang 	return EFI_UNSUPPORTED;
860eaa5176SVarad Gautam }
87