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