summaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2018-07-30 16:02:29 -0400
committerTom Rini <[email protected]>2018-07-30 16:02:29 -0400
commit406fd7e207d3593f150079514a371dccdc651ce7 (patch)
tree005f94b428abc454efd05f56364ee052cb16ac39 /lib/efi_loader
parent3a8c8bffd767abb350010f3892c0029c54cef725 (diff)
parent0b8a88ab6aa24de0ef2bf1e8109409f71e770a8e (diff)
Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot
Patch queue for efi - 2018-07-25 Highlights this time: - Many small fixes to improve spec compatibility (found by SCT) - Almost enough to run with sandbox target - GetTime() improvements - Enable EFI_LOADER and HYP entry on ARMv7 with NONSEC=y
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/Kconfig2
-rw-r--r--lib/efi_loader/Makefile3
-rw-r--r--lib/efi_loader/efi_boottime.c169
-rw-r--r--lib/efi_loader/efi_console.c9
-rw-r--r--lib/efi_loader/efi_image_loader.c12
-rw-r--r--lib/efi_loader/efi_memory.c65
-rw-r--r--lib/efi_loader/efi_runtime.c81
-rw-r--r--lib/efi_loader/efi_smbios.c11
8 files changed, 240 insertions, 112 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index df58e633d1c..ce6a09f0b43 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,8 +1,6 @@
config EFI_LOADER
bool "Support running EFI Applications in U-Boot"
depends on (ARM || X86 || RISCV) && OF_LIBFDT
- # We do not support bootefi booting ARMv7 in non-secure mode
- depends on !ARMV7_NONSEC
# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index d6402c4615f..1ffbf52a898 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -6,6 +6,9 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
+CFLAGS_efi_boottime.o += \
+ -DFW_VERSION="0x$(VERSION)" \
+ -DFW_PATCHLEVEL="0x$(PATCHLEVEL)"
CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding
CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) -Os
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index eeefe0bdfe3..b9e54f551a4 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -35,16 +35,6 @@ LIST_HEAD(efi_events);
*/
static bool efi_is_direct_boot = true;
-/*
- * EFI can pass arbitrary additional "tables" containing vendor specific
- * information to the payload. One such table is the FDT table which contains
- * a pointer to a flattened device tree blob.
- *
- * In most cases we want to pass an FDT to the payload, so reserve one slot of
- * config table space for it. The pointer gets populated by do_bootefi_exec().
- */
-static struct efi_configuration_table __efi_runtime_data efi_conf_table[16];
-
#ifdef CONFIG_ARM
/*
* The "gd" pointer lives in a register on ARM and AArch64 that we declare
@@ -164,6 +154,18 @@ const char *__efi_nesting_dec(void)
}
/**
+ * efi_update_table_header_crc32() - Update CRC32 in table header
+ *
+ * @table: EFI table
+ */
+static void efi_update_table_header_crc32(struct efi_table_hdr *table)
+{
+ table->crc32 = 0;
+ table->crc32 = crc32(0, (const unsigned char *)table,
+ table->headersize);
+}
+
+/**
* efi_queue_event() - queue an EFI event
* @event: event to signal
* @check_tpl: check the TPL level
@@ -191,6 +193,25 @@ static void efi_queue_event(struct efi_event *event, bool check_tpl)
}
/**
+ * is_valid_tpl() - check if the task priority level is valid
+ *
+ * @tpl: TPL level to check
+ * ReturnValue: status code
+ */
+efi_status_t is_valid_tpl(efi_uintn_t tpl)
+{
+ switch (tpl) {
+ case TPL_APPLICATION:
+ case TPL_CALLBACK:
+ case TPL_NOTIFY:
+ case TPL_HIGH_LEVEL:
+ return EFI_SUCCESS;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
* efi_signal_event() - signal an EFI event
* @event: event to signal
* @check_tpl: check the TPL level
@@ -592,11 +613,21 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
if (event == NULL)
return EFI_INVALID_PARAMETER;
- if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
+ switch (type) {
+ case 0:
+ case EVT_TIMER:
+ case EVT_NOTIFY_SIGNAL:
+ case EVT_TIMER | EVT_NOTIFY_SIGNAL:
+ case EVT_NOTIFY_WAIT:
+ case EVT_TIMER | EVT_NOTIFY_WAIT:
+ case EVT_SIGNAL_EXIT_BOOT_SERVICES:
+ case EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE:
+ break;
+ default:
return EFI_INVALID_PARAMETER;
+ }
- if ((type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) &&
- notify_function == NULL)
+ if (is_valid_tpl(notify_tpl) != EFI_SUCCESS)
return EFI_INVALID_PARAMETER;
evt = calloc(1, sizeof(struct efi_event));
@@ -1361,9 +1392,9 @@ static efi_status_t EFIAPI efi_locate_handle_ext(
*/
static void efi_remove_configuration_table(int i)
{
- struct efi_configuration_table *this = &efi_conf_table[i];
- struct efi_configuration_table *next = &efi_conf_table[i + 1];
- struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
+ struct efi_configuration_table *this = &systab.tables[i];
+ struct efi_configuration_table *next = &systab.tables[i + 1];
+ struct efi_configuration_table *end = &systab.tables[systab.nr_tables];
memmove(this, next, (ulong)end - (ulong)next);
systab.nr_tables--;
@@ -1391,9 +1422,9 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
/* Check for guid override */
for (i = 0; i < systab.nr_tables; i++) {
- if (!guidcmp(guid, &efi_conf_table[i].guid)) {
+ if (!guidcmp(guid, &systab.tables[i].guid)) {
if (table)
- efi_conf_table[i].table = table;
+ systab.tables[i].table = table;
else
efi_remove_configuration_table(i);
goto out;
@@ -1404,15 +1435,18 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
return EFI_NOT_FOUND;
/* No override, check for overflow */
- if (i >= ARRAY_SIZE(efi_conf_table))
+ if (i >= EFI_MAX_CONFIGURATION_TABLES)
return EFI_OUT_OF_RESOURCES;
/* Add a new entry */
- memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
- efi_conf_table[i].table = table;
+ memcpy(&systab.tables[i].guid, guid, sizeof(*guid));
+ systab.tables[i].table = table;
systab.nr_tables = i + 1;
out:
+ /* systab.nr_tables may have changed. So we need to update the crc32 */
+ efi_update_table_header_crc32(&systab.hdr);
+
/* Notify that the configuration table was changed */
list_for_each_entry(evt, &efi_events, link) {
if (evt->group && !guidcmp(evt->group, guid)) {
@@ -1468,6 +1502,7 @@ efi_status_t efi_setup_loaded_image(
/* efi_exit() assumes that the handle points to the info */
obj->handle = info;
+ info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
info->file_path = file_path;
if (device_path) {
@@ -1825,6 +1860,10 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
EFI_ENTRY("%p, %ld", image_handle, map_key);
+ /* Check that the caller has read the current memory map */
+ if (map_key != efi_memory_map_key)
+ return EFI_INVALID_PARAMETER;
+
/* Make sure that notification functions are not called anymore */
efi_tpl = TPL_HIGH_LEVEL;
@@ -1867,9 +1906,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
systab.boottime = NULL;
/* Recalculate CRC32 */
- systab.hdr.crc32 = 0;
- systab.hdr.crc32 = crc32(0, (const unsigned char *)&systab,
- sizeof(struct efi_system_table));
+ efi_update_table_header_crc32(&systab.hdr);
/* Give the payload some time to boot */
efi_set_watchdog(0);
@@ -2302,7 +2339,7 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
{
EFI_ENTRY("%p", handle);
- va_list argptr;
+ efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_status_t r = EFI_SUCCESS;
@@ -2311,12 +2348,12 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (;;) {
- protocol = va_arg(argptr, efi_guid_t*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
- protocol_interface = va_arg(argptr, void*);
+ protocol_interface = efi_va_arg(argptr, void*);
r = EFI_CALL(efi_install_protocol_interface(
handle, protocol,
EFI_NATIVE_INTERFACE,
@@ -2325,19 +2362,19 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
break;
i++;
}
- va_end(argptr);
+ efi_va_end(argptr);
if (r == EFI_SUCCESS)
return EFI_EXIT(r);
/* If an error occurred undo all changes. */
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = va_arg(argptr, efi_guid_t*);
- protocol_interface = va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr, void*);
EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
protocol_interface));
}
- va_end(argptr);
+ efi_va_end(argptr);
return EFI_EXIT(r);
}
@@ -2361,7 +2398,7 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
{
EFI_ENTRY("%p", handle);
- va_list argptr;
+ efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_status_t r = EFI_SUCCESS;
@@ -2370,12 +2407,12 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (;;) {
- protocol = va_arg(argptr, efi_guid_t*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
- protocol_interface = va_arg(argptr, void*);
+ protocol_interface = efi_va_arg(argptr, void*);
r = EFI_CALL(efi_uninstall_protocol_interface(
handle, protocol,
protocol_interface));
@@ -2383,20 +2420,20 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
break;
i++;
}
- va_end(argptr);
+ efi_va_end(argptr);
if (r == EFI_SUCCESS)
return EFI_EXIT(r);
/* If an error occurred undo all changes. */
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = va_arg(argptr, efi_guid_t*);
- protocol_interface = va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr, void*);
EFI_CALL(efi_install_protocol_interface(&handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
}
- va_end(argptr);
+ efi_va_end(argptr);
return EFI_EXIT(r);
}
@@ -2414,11 +2451,11 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
*
* Return: status code
*/
-static efi_status_t EFIAPI efi_calculate_crc32(void *data,
- unsigned long data_size,
- uint32_t *crc32_p)
+static efi_status_t EFIAPI efi_calculate_crc32(const void *data,
+ efi_uintn_t data_size,
+ u32 *crc32_p)
{
- EFI_ENTRY("%p, %ld", data, data_size);
+ EFI_ENTRY("%p, %zu", data, data_size);
*crc32_p = crc32(0, data, data_size);
return EFI_EXIT(EFI_SUCCESS);
}
@@ -3022,9 +3059,11 @@ out:
return EFI_EXIT(r);
}
-static const struct efi_boot_services efi_boot_services = {
+static struct efi_boot_services efi_boot_services = {
.hdr = {
- .headersize = sizeof(struct efi_table_hdr),
+ .signature = EFI_BOOT_SERVICES_SIGNATURE,
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_boot_services),
},
.raise_tpl = efi_raise_tpl,
.restore_tpl = efi_restore_tpl,
@@ -3074,20 +3113,44 @@ static const struct efi_boot_services efi_boot_services = {
.create_event_ex = efi_create_event_ex,
};
-static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
+static u16 __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
struct efi_system_table __efi_runtime_data systab = {
.hdr = {
.signature = EFI_SYSTEM_TABLE_SIGNATURE,
- .revision = 2 << 16 | 70, /* 2.7 */
- .headersize = sizeof(struct efi_table_hdr),
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_system_table),
},
- .fw_vendor = (long)firmware_vendor,
+ .fw_vendor = firmware_vendor,
+ .fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8,
.con_in = (void *)&efi_con_in,
.con_out = (void *)&efi_con_out,
.std_err = (void *)&efi_con_out,
.runtime = (void *)&efi_runtime_services,
.boottime = (void *)&efi_boot_services,
.nr_tables = 0,
- .tables = (void *)efi_conf_table,
+ .tables = NULL,
};
+
+/**
+ * efi_initialize_system_table() - Initialize system table
+ *
+ * Return Value: status code
+ */
+efi_status_t efi_initialize_system_table(void)
+{
+ efi_status_t ret;
+
+ /* Allocate configuration table array */
+ ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
+ EFI_MAX_CONFIGURATION_TABLES *
+ sizeof(struct efi_configuration_table),
+ (void **)&systab.tables);
+
+ /* Set crc32 field in table headers */
+ efi_update_table_header_crc32(&systab.hdr);
+ efi_update_table_header_crc32(&efi_runtime_services.hdr);
+ efi_update_table_header_crc32(&efi_boot_services.hdr);
+
+ return ret;
+}
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index ce66c935ecb..3fd0d2fd516 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -335,6 +335,8 @@ static efi_status_t EFIAPI efi_cout_clear_screen(
EFI_ENTRY("%p", this);
printf(ESC"[2J");
+ efi_con_mode.cursor_column = 0;
+ efi_con_mode.cursor_row = 0;
return EFI_EXIT(EFI_SUCCESS);
}
@@ -381,7 +383,12 @@ static efi_status_t EFIAPI efi_cin_reset(
bool extended_verification)
{
EFI_ENTRY("%p, %d", this, extended_verification);
- return EFI_EXIT(EFI_UNSUPPORTED);
+
+ /* Empty input buffer */
+ while (tstc())
+ getc();
+
+ return EFI_EXIT(EFI_SUCCESS);
}
/*
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index ecdb77e5b6b..fdf40a62c8e 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -19,25 +19,25 @@ const efi_guid_t efi_simple_file_system_protocol_guid =
const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
static int machines[] = {
-#if defined(CONFIG_ARM64)
+#if defined(__aarch64__)
IMAGE_FILE_MACHINE_ARM64,
-#elif defined(CONFIG_ARM)
+#elif defined(__arm__)
IMAGE_FILE_MACHINE_ARM,
IMAGE_FILE_MACHINE_THUMB,
IMAGE_FILE_MACHINE_ARMNT,
#endif
-#if defined(CONFIG_X86_64)
+#if defined(__x86_64__)
IMAGE_FILE_MACHINE_AMD64,
-#elif defined(CONFIG_X86)
+#elif defined(__i386__)
IMAGE_FILE_MACHINE_I386,
#endif
-#if defined(CONFIG_CPU_RISCV_32)
+#if defined(__riscv) && (__riscv_xlen == 32)
IMAGE_FILE_MACHINE_RISCV32,
#endif
-#if defined(CONFIG_CPU_RISCV_64)
+#if defined(__riscv) && (__riscv_xlen == 64)
IMAGE_FILE_MACHINE_RISCV64,
#endif
0 };
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index ec66af98ea8..967c3f733e4 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -9,11 +9,14 @@
#include <efi_loader.h>
#include <inttypes.h>
#include <malloc.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <linux/list_sort.h>
DECLARE_GLOBAL_DATA_PTR;
+efi_uintn_t efi_memory_map_key;
+
struct efi_mem_list {
struct list_head link;
struct efi_mem_desc desc;
@@ -159,9 +162,13 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
start, pages, memory_type, overlap_only_ram ? "yes" : "no");
+ if (memory_type >= EFI_MAX_MEMORY_TYPE)
+ return EFI_INVALID_PARAMETER;
+
if (!pages)
return start;
+ ++efi_memory_map_key;
newlist = calloc(1, sizeof(*newlist));
newlist->desc.type = memory_type;
newlist->desc.physical_start = start;
@@ -292,10 +299,13 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
efi_status_t r = EFI_SUCCESS;
uint64_t addr;
+ if (!memory)
+ return EFI_INVALID_PARAMETER;
+
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = efi_find_free_memory(len, gd->start_addr_sp);
+ addr = efi_find_free_memory(len, -1ULL);
if (!addr) {
r = EFI_NOT_FOUND;
break;
@@ -325,7 +335,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
/* Reserve that map in our memory maps */
ret = efi_add_memory_map(addr, pages, memory_type, true);
if (ret == addr) {
- *memory = addr;
+ *memory = (uintptr_t)map_sysmem(addr, len);
} else {
/* Map would overlap, bail out */
r = EFI_OUT_OF_RESOURCES;
@@ -359,11 +369,12 @@ void *efi_alloc(uint64_t len, int memory_type)
efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
{
uint64_t r = 0;
+ uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
- r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
+ r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
/* Merging of adjacent free regions is missing */
- if (r == memory)
+ if (r == addr)
return EFI_SUCCESS;
return EFI_NOT_FOUND;
@@ -380,20 +391,22 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
{
efi_status_t r;
- efi_physical_addr_t t;
+ struct efi_pool_allocation *alloc;
u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+ if (!buffer)
+ return EFI_INVALID_PARAMETER;
+
if (size == 0) {
*buffer = NULL;
return EFI_SUCCESS;
}
r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
- &t);
+ (uint64_t *)&alloc);
if (r == EFI_SUCCESS) {
- struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
alloc->num_pages = num_pages;
*buffer = alloc->data;
}
@@ -446,6 +459,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
struct list_head *lhandle;
efi_uintn_t provided_map_size = *memory_map_size;
+ if (!memory_map_size)
+ return EFI_INVALID_PARAMETER;
+
list_for_each(lhandle, &efi_mem)
map_entries++;
@@ -456,6 +472,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
if (provided_map_size < map_size)
return EFI_BUFFER_TOO_SMALL;
+ if (!memory_map)
+ return EFI_INVALID_PARAMETER;
+
if (descriptor_size)
*descriptor_size = sizeof(struct efi_mem_desc);
@@ -463,19 +482,18 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
*descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION;
/* Copy list into array */
- if (memory_map) {
- /* Return the list in ascending order */
- memory_map = &memory_map[map_entries - 1];
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
+ /* Return the list in ascending order */
+ memory_map = &memory_map[map_entries - 1];
+ list_for_each(lhandle, &efi_mem) {
+ struct efi_mem_list *lmem;
- lmem = list_entry(lhandle, struct efi_mem_list, link);
- *memory_map = lmem->desc;
- memory_map--;
- }
+ lmem = list_entry(lhandle, struct efi_mem_list, link);
+ *memory_map = lmem->desc;
+ memory_map--;
}
- *map_key = 0;
+ if (map_key)
+ *map_key = efi_memory_map_key;
return EFI_SUCCESS;
}
@@ -496,14 +514,13 @@ __weak void efi_add_known_memory(void)
}
}
-int efi_memory_init(void)
+/* Add memory regions for U-Boot's memory and for the runtime services code */
+static void add_u_boot_and_runtime(void)
{
unsigned long runtime_start, runtime_end, runtime_pages;
unsigned long uboot_start, uboot_pages;
unsigned long uboot_stack_size = 16 * 1024 * 1024;
- efi_add_known_memory();
-
/* Add U-Boot */
uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
@@ -516,6 +533,14 @@ int efi_memory_init(void)
runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
efi_add_memory_map(runtime_start, runtime_pages,
EFI_RUNTIME_SERVICES_CODE, false);
+}
+
+int efi_memory_init(void)
+{
+ efi_add_known_memory();
+
+ if (!IS_ENABLED(CONFIG_SANDBOX))
+ add_u_boot_and_runtime();
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
/* Request a 32bit 64MB bounce buffer region */
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 4874eb602f7..06958f23fa1 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <command.h>
#include <dm.h>
+#include <elf.h>
#include <efi_loader.h>
#include <rtc.h>
@@ -32,19 +33,17 @@ static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
* TODO([email protected]): These defines and structs should come from the elf
* header for each arch (or a generic header) rather than being repeated here.
*/
-#if defined(CONFIG_ARM64)
-#define R_RELATIVE 1027
+#if defined(__aarch64__)
+#define R_RELATIVE R_AARCH64_RELATIVE
#define R_MASK 0xffffffffULL
#define IS_RELA 1
-#elif defined(CONFIG_ARM)
-#define R_RELATIVE 23
+#elif defined(__arm__)
+#define R_RELATIVE R_ARM_RELATIVE
#define R_MASK 0xffULL
-#elif defined(CONFIG_X86)
-#include <asm/elf.h>
+#elif defined(__x86_64__) || defined(__i386__)
#define R_RELATIVE R_386_RELATIVE
#define R_MASK 0xffULL
-#elif defined(CONFIG_RISCV)
-#include <elf.h>
+#elif defined(__riscv)
#define R_RELATIVE R_RISCV_RELATIVE
#define R_MASK 0xffULL
#define IS_RELA 1
@@ -55,12 +54,14 @@ struct dyn_sym {
u32 foo2;
u32 foo3;
};
-#ifdef CONFIG_CPU_RISCV_32
+#if (__riscv_xlen == 32)
#define R_ABSOLUTE R_RISCV_32
#define SYM_INDEX 8
-#else
+#elif (__riscv_xlen == 64)
#define R_ABSOLUTE R_RISCV_64
#define SYM_INDEX 32
+#else
+#error unknown riscv target
#endif
#else
#error Need to add relocation awareness
@@ -116,24 +117,41 @@ static void EFIAPI efi_reset_system_boottime(
while (1) { }
}
+/**
+ * efi_get_time_boottime - get current time
+ *
+ * This function implements the GetTime runtime service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @time: pointer to structure to receive current time
+ * @capabilities: pointer to structure to receive RTC properties
+ * Return Value: status code
+ */
static efi_status_t EFIAPI efi_get_time_boottime(
struct efi_time *time,
struct efi_time_cap *capabilities)
{
-#if defined(CONFIG_CMD_DATE) && defined(CONFIG_DM_RTC)
- struct rtc_time tm;
+#ifdef CONFIG_DM_RTC
+ efi_status_t ret = EFI_SUCCESS;
int r;
+ struct rtc_time tm;
struct udevice *dev;
EFI_ENTRY("%p %p", time, capabilities);
- r = uclass_get_device(UCLASS_RTC, 0, &dev);
- if (r)
- return EFI_EXIT(EFI_DEVICE_ERROR);
+ if (!time) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
- r = dm_rtc_get(dev, &tm);
- if (r)
- return EFI_EXIT(EFI_DEVICE_ERROR);
+ r = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (!r)
+ r = dm_rtc_get(dev, &tm);
+ if (r) {
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ }
memset(time, 0, sizeof(*time));
time->year = tm.tm_year;
@@ -141,11 +159,23 @@ static efi_status_t EFIAPI efi_get_time_boottime(
time->day = tm.tm_mday;
time->hour = tm.tm_hour;
time->minute = tm.tm_min;
- time->daylight = tm.tm_isdst;
+ time->second = tm.tm_sec;
+ time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
+ if (tm.tm_isdst > 0)
+ time->daylight |= EFI_TIME_IN_DAYLIGHT;
+ time->timezone = EFI_UNSPECIFIED_TIMEZONE;
- return EFI_EXIT(EFI_SUCCESS);
+ if (capabilities) {
+ /* Set reasonable dummy values */
+ capabilities->resolution = 1; /* 1 Hz */
+ capabilities->accuracy = 100000000; /* 100 ppm */
+ capabilities->sets_to_zero = false;
+ }
+out:
+ return EFI_EXIT(ret);
#else
- return EFI_DEVICE_ERROR;
+ EFI_ENTRY("%p %p", time, capabilities);
+ return EFI_EXIT(EFI_DEVICE_ERROR);
#endif
}
@@ -173,11 +203,6 @@ efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
return EFI_DEVICE_ERROR;
}
-efi_status_t __weak efi_get_time_init(void)
-{
- return EFI_SUCCESS;
-}
-
struct efi_runtime_detach_list_struct {
void *ptr;
void *patchto;
@@ -458,8 +483,8 @@ efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
.hdr = {
.signature = EFI_RUNTIME_SERVICES_SIGNATURE,
- .revision = EFI_RUNTIME_SERVICES_REVISION,
- .headersize = sizeof(struct efi_table_hdr),
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_runtime_services),
},
.get_time = &efi_get_time_boottime,
.set_time = (void *)&efi_device_error,
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c
index 7c3fc8af0b2..932f7582ec6 100644
--- a/lib/efi_loader/efi_smbios.c
+++ b/lib/efi_loader/efi_smbios.c
@@ -26,8 +26,15 @@ efi_status_t efi_smbios_register(void)
/* Reserve 4kiB page for SMBIOS */
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
- if (ret != EFI_SUCCESS)
- return ret;
+
+ if (ret != EFI_SUCCESS) {
+ /* Could not find space in lowmem, use highmem instead */
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
/*
* Generate SMBIOS tables - we know that efi_allocate_pages() returns