summaryrefslogtreecommitdiffstats
path: root/arch/efi/efi/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/efi/efi/efi.c')
-rw-r--r--arch/efi/efi/efi.c74
1 files changed, 68 insertions, 6 deletions
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index d351775a28..d3f520f60f 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -52,7 +52,7 @@ void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size)
efi_status_t efiret;
void *buf;
unsigned long size = 0;
- s16 *name16 = strdup_char_to_wchar(name);
+ s16 *name16 = xstrdup_char_to_wchar(name);
efiret = RT->get_variable(name16, vendor, NULL, &size, NULL);
@@ -83,6 +83,33 @@ out:
return buf;
}
+int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes,
+ void *buf, unsigned long size)
+{
+ efi_status_t efiret = EFI_SUCCESS;
+ s16 *name16 = xstrdup_char_to_wchar(name);
+
+ efiret = RT->set_variable(name16, vendor, attributes, size, buf);
+
+ free(name16);
+
+ return -efi_errno(efiret);
+}
+
+int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec)
+{
+ char buf[20];
+ wchar_t buf16[40];
+
+ snprintf(buf, sizeof(buf), "%lld", usec);
+ strcpy_char_to_wchar(buf16, buf);
+
+ return efi_set_variable(name, vendor,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS, buf16,
+ (strlen(buf)+1) * sizeof(wchar_t));
+}
+
struct efi_boot {
u32 attributes;
u16 file_path_len;
@@ -98,7 +125,7 @@ struct efi_boot *efi_get_boot(int num)
int size;
char *name;
- name = asprintf("Boot%04X", num);
+ name = xasprintf("Boot%04X", num);
buf = efi_get_global_var(name, &size);
@@ -119,7 +146,7 @@ struct efi_boot *efi_get_boot(int num)
ptr += sizeof(u16);
- boot->description = strdup_wchar_to_char(ptr);
+ boot->description = xstrdup_wchar_to_char(ptr);
ptr += (strlen(boot->description) + 1) * 2;
@@ -299,8 +326,13 @@ static void fixup_tables(void)
static int efi_init(void)
{
+ char *env;
+
defaultenv_append_directory(env_efi);
+ env = xasprintf("/efivars/barebox-env-%pUl", &efi_barebox_vendor_guid);
+ default_environment_path_set(env);
+
return 0;
}
device_initcall(efi_init);
@@ -310,8 +342,10 @@ device_initcall(efi_init);
*/
efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
{
- void *mem;
+ efi_physical_addr_t mem;
+ size_t memsize;
efi_status_t efiret;
+ char *uuid;
#ifdef DEBUG
sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
@@ -332,10 +366,38 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
fixup_tables();
- BS->allocate_pool(efi_loaded_image->image_data_type, SZ_16M, &mem);
- mem_malloc_init(mem, mem + SZ_16M);
+ mem = 0x3fffffff;
+ for (memsize = SZ_256M; memsize >= SZ_8M; memsize /= 2) {
+ efiret = BS->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_LOADER_DATA,
+ memsize/PAGE_SIZE, &mem);
+ if (!EFI_ERROR(efiret))
+ break;
+ if (efiret != EFI_OUT_OF_RESOURCES)
+ panic("failed to allocate malloc pool: %s\n",
+ efi_strerror(efiret));
+ }
+ if (EFI_ERROR(efiret))
+ panic("failed to allocate malloc pool: %s\n",
+ efi_strerror(efiret));
+ mem_malloc_init((void *)mem, (void *)mem + memsize);
efi_clocksource_init();
+ efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
+ get_time_ns()/1000);
+
+ uuid = device_path_to_partuuid(device_path_from_handle(
+ efi_loaded_image->device_handle));
+ if (uuid) {
+ wchar_t *uuid16 = xstrdup_char_to_wchar(uuid);
+ efi_set_variable("LoaderDevicePartUUID",
+ &efi_systemd_vendor_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ uuid16, (strlen(uuid)+1) * sizeof(wchar_t));
+ free(uuid);
+ free(uuid16);
+ }
start_barebox();