diff options
| author | Tom Rini <[email protected]> | 2018-07-30 16:02:29 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2018-07-30 16:02:29 -0400 |
| commit | 406fd7e207d3593f150079514a371dccdc651ce7 (patch) | |
| tree | 005f94b428abc454efd05f56364ee052cb16ac39 /lib/efi_loader | |
| parent | 3a8c8bffd767abb350010f3892c0029c54cef725 (diff) | |
| parent | 0b8a88ab6aa24de0ef2bf1e8109409f71e770a8e (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/Kconfig | 2 | ||||
| -rw-r--r-- | lib/efi_loader/Makefile | 3 | ||||
| -rw-r--r-- | lib/efi_loader/efi_boottime.c | 169 | ||||
| -rw-r--r-- | lib/efi_loader/efi_console.c | 9 | ||||
| -rw-r--r-- | lib/efi_loader/efi_image_loader.c | 12 | ||||
| -rw-r--r-- | lib/efi_loader/efi_memory.c | 65 | ||||
| -rw-r--r-- | lib/efi_loader/efi_runtime.c | 81 | ||||
| -rw-r--r-- | lib/efi_loader/efi_smbios.c | 11 |
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 |
