1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <binaries/efi/efi.h> 8#include <elfloader_common.h> 9 10void *__application_handle = NULL; // current efi application handler 11efi_system_table_t *__efi_system_table = NULL; // current efi system table 12 13extern void _start(void); 14unsigned int efi_main(uintptr_t application_handle, uintptr_t efi_system_table) 15{ 16 clear_bss(); 17 __application_handle = (void *)application_handle; 18 __efi_system_table = (efi_system_table_t *)efi_system_table; 19 _start(); 20 return 0; 21} 22 23void *efi_get_fdt(void) 24{ 25 efi_guid_t fdt_guid = make_efi_guid(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0); 26 efi_config_table_t *tables = (efi_config_table_t *)__efi_system_table->tables; 27 28 for (uint32_t i = 0; i < __efi_system_table->nr_tables; i++) { 29 if (!efi_guideq(fdt_guid, tables[i].guid)) 30 continue; 31 32 return (void *)tables[i].table; 33 } 34 35 return NULL; 36} 37 38/* Before starting the kernel we should notify the UEFI firmware about it 39 * otherwise the internal watchdog may reboot us after 5 min. 40 * 41 * This means boot time services are not available anymore. We should store 42 * system information e.g. current memory map and pass them to kernel. 43 */ 44unsigned long efi_exit_boot_services(void) 45{ 46 unsigned long status; 47 efi_memory_desc_t *memory_map; 48 unsigned long map_size; 49 unsigned long desc_size, key; 50 uint32_t desc_version; 51 52 efi_boot_services_t *bts = get_efi_boot_services(); 53 54 /* 55 * As the number of existing memeory segments are unknown, 56 * we need to resort to a trial and error to guess that. 57 * We start from 32 and increase it by one until get a valid value. 58 */ 59 map_size = sizeof(*memory_map) * 32; 60 61again: 62 status = bts->allocate_pool(EFI_LOADER_DATA, map_size, (void **)&memory_map); 63 64 if (status != EFI_SUCCESS) 65 return status; 66 67 status = bts->get_memory_map(&map_size, memory_map, &key, &desc_size, &desc_version); 68 if (status == EFI_BUFFER_TOO_SMALL) { 69 bts->free_pool(memory_map); 70 71 map_size += sizeof(*memory_map); 72 goto again; 73 } 74 75 if (status != EFI_SUCCESS){ 76 bts->free_pool(memory_map); 77 return status; 78 } 79 80 status = bts->exit_boot_services(__application_handle, key); 81 return status; 82} 83