From patchwork Fri Mar 27 05:27:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 1262568 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.a=rsa-sha256 header.s=badeba3b8450 header.b=k4xc/ZRs; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48pVnr4p1xz9sR4 for ; Fri, 27 Mar 2020 16:31:12 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 330FA818FD; Fri, 27 Mar 2020 06:29:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.b="k4xc/ZRs"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 739B1818AF; Fri, 27 Mar 2020 06:28:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 46677818A0 for ; Fri, 27 Mar 2020 06:28:26 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xypron.glpk@gmx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1585286892; bh=EeOqwmz03m94FFBHzk9ddX9A4wXT5LgYC8O2UZgcknk=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=k4xc/ZRscsBLcTLbC7536nZKupQRDd8hu/OOHgAYmFLMwC0HN+si0X4FaCyoNUO12 b/z1qp1R0d5CwhZqJtRFR/jlulB88Q/t7MPrqwXL26chYm3PN+rbIgfD5czZWvwabh eSXZt0jRx2LIkU8ZJLC5mknechbTS6cH3C/fjDHc= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from LT02.fritz.box ([84.119.33.226]) by mail.gmx.com (mrgmx105 [212.227.17.174]) with ESMTPSA (Nemesis) id 1MtfJX-1jWBwx0KhL-00v8sK; Fri, 27 Mar 2020 06:28:12 +0100 From: Heinrich Schuchardt To: Alexander Graf , AKASHI Takahiro Cc: Ilias Apalodimas , Sughosh Ganu , Alexey Brodkin , Paul Emge , Faiz Abbas , Eugeniu Rosca , Urja Rannikko , Kever Yang , Simon Glass , Alistair Strachan , Ruslan Trofymenko , Igor Opaniuk , u-boot@lists.denx.de, Heinrich Schuchardt Subject: [PATCH 03/16] efi_loader: eliminate EFI_CALL() for variable access Date: Fri, 27 Mar 2020 06:27:47 +0100 Message-Id: <20200327052800.11022-4-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200327052800.11022-1-xypron.glpk@gmx.de> References: <20200327052800.11022-1-xypron.glpk@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:7628qVyZV7GxZ0CfsSvqksmHXCHIWxTAKG1PB2lqarwWW0WF5uv P39HVeNiZ6qfHKoaWcUpkbcdUvcZWPUsj7sTwTczVbvWB8sIZMJg0MmUOscE9vq8mnvyVOM unkGbrHKNzsJUaXnt92pKCh8reOVlhFa0KK96HeH6YGhVQ483tDkMhoqY7Oj2Ncdk1UpqxP M8Cib/YjjQR9oRKK6CZsA== X-UI-Out-Filterresults: notjunk:1; V03:K0:X7PZUMo6XJA=:C2t3qk4gSfhlWwUaVjK4Fj bmTX6Z5qaMJ9MLWaEtZyEf35saryvRzcRoGHMD6gmF8Ir0j2srahNupoLvu6xoV3xipoxriFL r+PfIUYP5KzJjpUva+FDGDJUg1PVMiFlA6axEakaYAaUcaBytbHWoWUd++hDrzT6AIr5wwhns /SHh1pfCdvPZ71x7CfzQ31XJwvRlCEnHzelQ2RCDSjJ3emacoE5LXXjyyExNMyATRi+As80Lq 2kV+uDa9In0yBdDciDKiRh/eeFOBFxUmfrk6oQzweDk3mP6RiczChMM/VSarOZA4f1BJBfPnM 4/KHcpTiHEMyOdBNpAZ+Z1fTahuolfocaVwyzixe7nTHH7Qeq5ayDxDXzSdvQfPcJl6V42TgC 3CBF3AOJn7vpgdm4ED4z1hMABbBKiQm0CI44fP72IHKYZFXja/pItCKjoMIWg44f2b0fHnBbO rEQE24YUtfX2rthUEwSKYjhBUD6MtAufWEITzQF8uXIrZem5k74V38aHeuB3gJjwGVQYAfvPw 4SLPCSTzCfko9qR41A2V84wvlVTNWzTNolNMzEU7fsWLzXsqOvfOqhPGi/g9iKYYDhTcM7yXD 5MozyOP8uxRLG6BktXUEmHQFkySfr9XYTOLzNW9ohVJPBZoJna5PpNx/iiSJDw7X+UTT8sNLl tzatRPWX763T2gybnReLCrfLMzsEzYmb4fspCjost59hmdn3Xg5CXLL2SKMmH52yN4uXHAXxL m3NSSuOIbdf8RKvHpa0lNmzdVNmqCPT93nms4WD9NvZSjqg/5US2Qm4QtINFp9H00FQHM6j93 Gbjkc1uR+Ez7zLyYXabd0nhlJh5j3bh1b7Mj1n+zbBwxXXu7NtaJjpha2mMINt21CaCzP+fUl R9kctbpmTY3i6kI0joHducZZlgJGdLq/edkgmnORRRqFHOw7WRV85kGhRCQgcjKfL5H+XlGOk LMMibP2I4waGtsIkWqLM8PtcrDjdtKk7WXUqPH8gH/1mvywj/jTXieRBrFvSFrITxwMXFbIhv ozZW1jfRYUqiULwjv7n4YyTCy7MVeslY3r8wenp5/xcjTrAsG+VTQC9ecZ3Kxppv7cHKr6Z9E RUrwd3EEHVX/pOhC0ANqvzg6aOZaWNDvJfkH3zOHRETtAI99p1oflZy5cqwH94kNKRTQ7UVZn bH7Ysuh/72TTrU10ZcTXFWXbLJ8Q22symUXnZntj1Mnm8T7pSK7UL2zULwwh5NlrVYW2bb8Rc 4p9B0/gWsYhJt7KcH X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean In several places of the UEFI sub-system UEFI variables as accessed via runtime services functions. These functions require being called via EFI_CALL() to restore the register holding the gd variable. Some code even calls the functions via the runtime services table. By making the functions exposing the variable runtime services wrappers for exported functions that we can use internally we get rid of this clumsy code. Signed-off-by: Heinrich Schuchardt --- cmd/efidebug.c | 63 +++++++++---------- cmd/nvedit_efi.c | 18 +++--- include/efi_loader.h | 9 +++ lib/efi_loader/efi_bootmgr.c | 20 +++--- lib/efi_loader/efi_setup.c | 42 ++++++------- lib/efi_loader/efi_variable.c | 114 +++++++++++++++++++++++++++------- 6 files changed, 168 insertions(+), 98 deletions(-) -- 2.25.1 diff --git a/cmd/efidebug.c b/cmd/efidebug.c index c1bb76477a..f89c1d2db7 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -17,7 +17,6 @@ #include #define BS systab.boottime -#define RT systab.runtime /** * efi_get_device_handle_info() - get information of UEFI device @@ -614,11 +613,11 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag, goto out; } - ret = EFI_CALL(RT->set_variable(var_name16, &guid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - size, data)); + ret = efi_set_variable_int(var_name16, &guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, data); if (ret != EFI_SUCCESS) { printf("Cannot set %ls\n", var_name16); r = CMD_RET_FAILURE; @@ -669,7 +668,8 @@ static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag, p = var_name16; utf8_utf16_strncpy(&p, var_name, 9); - ret = EFI_CALL(RT->set_variable(var_name16, &guid, 0, 0, NULL)); + ret = efi_set_variable_int(var_name16, &guid, 0, 0, + NULL); if (ret) { printf("Cannot remove %ls\n", var_name16); return CMD_RET_FAILURE; @@ -749,11 +749,11 @@ static void show_efi_boot_opt(int id) guid = efi_global_variable_guid; size = 0; - ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL)); + ret = efi_get_variable_int(var_name16, &guid, NULL, &size, NULL); if (ret == EFI_BUFFER_TOO_SMALL) { data = malloc(size); - ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, - data)); + ret = efi_get_variable_int(var_name16, &guid, NULL, &size, + data); } if (ret == EFI_SUCCESS) show_efi_boot_opt_data(id, data, size); @@ -808,8 +808,7 @@ static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag, var_name16[0] = 0; for (;;) { size = buf_size; - ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16, - &guid)); + ret = efi_get_next_variable_name_int(&size, var_name16, &guid); if (ret == EFI_NOT_FOUND) break; if (ret == EFI_BUFFER_TOO_SMALL) { @@ -820,9 +819,8 @@ static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } var_name16 = p; - ret = EFI_CALL(efi_get_next_variable_name(&size, - var_name16, - &guid)); + ret = efi_get_next_variable_name_int(&size, var_name16, + &guid); } if (ret != EFI_SUCCESS) { free(var_name16); @@ -870,12 +868,11 @@ static int show_efi_boot_order(void) guid = efi_global_variable_guid; size = 0; - ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, &size, - NULL)); + ret = efi_get_variable_int(L"BootOrder", &guid, NULL, &size, NULL); if (ret == EFI_BUFFER_TOO_SMALL) { bootorder = malloc(size); - ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, - &size, bootorder)); + ret = efi_get_variable_int(L"BootOrder", &guid, NULL, + &size, bootorder); } if (ret == EFI_NOT_FOUND) { printf("BootOrder not defined\n"); @@ -893,8 +890,8 @@ static int show_efi_boot_order(void) utf8_utf16_strncpy(&p16, var_name, 9); size = 0; - ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, - NULL)); + ret = efi_get_variable_int(var_name16, &guid, NULL, &size, + NULL); if (ret != EFI_BUFFER_TOO_SMALL) { printf("%2d: Boot%04X: (not defined)\n", i + 1, bootorder[i]); @@ -906,8 +903,8 @@ static int show_efi_boot_order(void) ret = CMD_RET_FAILURE; goto out; } - ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, - data)); + ret = efi_get_variable_int(var_name16, &guid, NULL, &size, + data); if (ret != EFI_SUCCESS) { free(data); ret = CMD_RET_FAILURE; @@ -974,11 +971,11 @@ static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag, guid = efi_global_variable_guid; size = sizeof(u16); - ret = EFI_CALL(RT->set_variable(L"BootNext", &guid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - size, &bootnext)); + ret = efi_set_variable_int(L"BootNext", &guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, &bootnext); if (ret != EFI_SUCCESS) { printf("Cannot set BootNext\n"); r = CMD_RET_FAILURE; @@ -1035,11 +1032,11 @@ static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag, } guid = efi_global_variable_guid; - ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - size, bootorder)); + ret = efi_set_variable_int(L"BootOrder", &guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, bootorder); if (ret != EFI_SUCCESS) { printf("Cannot set BootOrder\n"); r = CMD_RET_FAILURE; diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c index 8ea0da0128..9d338478d3 100644 --- a/cmd/nvedit_efi.c +++ b/cmd/nvedit_efi.c @@ -87,14 +87,14 @@ static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose) data = NULL; size = 0; - ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size, data)); + ret = efi_get_variable_int(name, guid, &attributes, &size, data); if (ret == EFI_BUFFER_TOO_SMALL) { data = malloc(size); if (!data) goto out; - ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size, - data)); + ret = efi_get_variable_int(name, guid, &attributes, &size, + data); } if (ret == EFI_NOT_FOUND) { printf("Error: \"%ls\" not defined\n", name); @@ -224,8 +224,7 @@ static int efi_dump_var_all(int argc, char * const argv[], var_name16[0] = 0; for (;;) { size = buf_size; - ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16, - &guid)); + ret = efi_get_next_variable_name_int(&size, var_name16, &guid); if (ret == EFI_NOT_FOUND) break; if (ret == EFI_BUFFER_TOO_SMALL) { @@ -236,9 +235,8 @@ static int efi_dump_var_all(int argc, char * const argv[], return CMD_RET_FAILURE; } var_name16 = p; - ret = EFI_CALL(efi_get_next_variable_name(&size, - var_name16, - &guid)); + ret = efi_get_next_variable_name_int(&size, var_name16, + &guid); } if (ret != EFI_SUCCESS) { free(var_name16); @@ -576,8 +574,8 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) p = var_name16; utf8_utf16_strncpy(&p, var_name, len + 1); - ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes, - size, value)); + ret = efi_set_variable_int(var_name16, &guid, attributes, size, + value); unmap_sysmem(value); if (ret == EFI_SUCCESS) { ret = CMD_RET_SUCCESS; diff --git a/include/efi_loader.h b/include/efi_loader.h index 3f2792892f..b1d2feab61 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -643,12 +643,21 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, efi_status_t EFIAPI efi_get_variable(u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data); +efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor, + u32 *attributes, + efi_uintn_t *data_size, void *data); efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, u16 *variable_name, efi_guid_t *vendor); +efi_status_t efi_get_next_variable_name_int(efi_uintn_t *variable_name_size, + u16 *variable_name, + efi_guid_t *vendor); efi_status_t EFIAPI efi_set_variable(u16 *variable_name, const efi_guid_t *vendor, u32 attributes, efi_uintn_t data_size, const void *data); +efi_status_t efi_set_variable_int(u16 *variable_name, + const efi_guid_t *vendor, u32 attributes, + efi_uintn_t data_size, const void *data); efi_status_t EFIAPI efi_query_variable_info( u32 attributes, u64 *maximum_variable_storage_size, diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 2ea21448f0..c87f38e46c 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -12,7 +12,6 @@ #include static const struct efi_boot_services *bs; -static const struct efi_runtime_services *rs; /* * bootmgr implements the logic of trying to find a payload to boot @@ -123,10 +122,10 @@ static void *get_var(u16 *name, const efi_guid_t *vendor, void *buf = NULL; *size = 0; - EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf)); + ret = efi_get_variable_int(name, v, NULL, size, buf); if (ret == EFI_BUFFER_TOO_SMALL) { buf = malloc(*size); - EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf)); + ret = efi_get_variable_int(name, v, NULL, size, buf); } if (ret != EFI_SUCCESS) { @@ -186,10 +185,10 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle) attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; size = sizeof(n); - ret = EFI_CALL(efi_set_variable( + ret = efi_set_variable_int( L"BootCurrent", (efi_guid_t *)&efi_global_variable_guid, - attributes, size, &n)); + attributes, size, &n); if (ret != EFI_SUCCESS) { if (EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS) @@ -226,25 +225,24 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle) efi_status_t ret; bs = systab.boottime; - rs = systab.runtime; /* BootNext */ bootnext = 0; size = sizeof(bootnext); - ret = EFI_CALL(efi_get_variable(L"BootNext", - (efi_guid_t *)&efi_global_variable_guid, - NULL, &size, &bootnext)); + ret = efi_get_variable_int(L"BootNext", + (efi_guid_t *)&efi_global_variable_guid, + NULL, &size, &bootnext); if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) { /* BootNext does exist here */ if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) printf("BootNext must be 16-bit integer\n"); /* delete BootNext */ - ret = EFI_CALL(efi_set_variable( + ret = efi_set_variable_int( L"BootNext", (efi_guid_t *)&efi_global_variable_guid, EFI_VARIABLE_NON_VOLATILE, 0, - &bootnext)); + &bootnext); /* load BootNext */ if (ret == EFI_SUCCESS) { diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index b458093dfb..d1884e4dae 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -40,12 +40,12 @@ static efi_status_t efi_init_platform_lang(void) * Variable PlatformLangCodes defines the language codes that the * machine can support. */ - ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes", - &efi_global_variable_guid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(CONFIG_EFI_PLATFORM_LANG_CODES), - CONFIG_EFI_PLATFORM_LANG_CODES)); + ret = efi_set_variable_int(L"PlatformLangCodes", + &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(CONFIG_EFI_PLATFORM_LANG_CODES), + CONFIG_EFI_PLATFORM_LANG_CODES); if (ret != EFI_SUCCESS) goto out; @@ -53,9 +53,9 @@ static efi_status_t efi_init_platform_lang(void) * Variable PlatformLang defines the language that the machine has been * configured for. */ - ret = EFI_CALL(efi_get_variable(L"PlatformLang", - &efi_global_variable_guid, - NULL, &data_size, &pos)); + ret = efi_get_variable_int(L"PlatformLang", + &efi_global_variable_guid, + NULL, &data_size, &pos); if (ret == EFI_BUFFER_TOO_SMALL) { /* The variable is already set. Do not change it. */ ret = EFI_SUCCESS; @@ -70,12 +70,12 @@ static efi_status_t efi_init_platform_lang(void) if (pos) *pos = 0; - ret = EFI_CALL(efi_set_variable(L"PlatformLang", - &efi_global_variable_guid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - 1 + strlen(lang), lang)); + ret = efi_set_variable_int(L"PlatformLang", + &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 1 + strlen(lang), lang); out: if (ret != EFI_SUCCESS) printf("EFI: cannot initialize platform language settings\n"); @@ -113,12 +113,12 @@ efi_status_t efi_init_obj_list(void) goto out; /* Indicate supported features */ - ret = EFI_CALL(efi_set_variable(L"OsIndicationsSupported", - &efi_global_variable_guid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(os_indications_supported), - &os_indications_supported)); + ret = efi_set_variable_int(L"OsIndicationsSupported", + &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(os_indications_supported), + &os_indications_supported); if (ret != EFI_SUCCESS) goto out; diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index fe2f264591..4fae1fa4c7 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -165,6 +165,30 @@ static const char *parse_attr(const char *str, u32 *attrp) efi_status_t EFIAPI efi_get_variable(u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data) +{ + EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes, + data_size, data); + + return EFI_EXIT(efi_get_variable_int(variable_name, vendor, attributes, + data_size, data)); +} + +/** + * efi_get_variable_int() - retrieve value of a UEFI variable + * + * This function allows to retrieve the value of a UEFI variable without using + * EFI_CALL(). + * + * @variable_name: name of the variable + * @vendor: vendor GUID + * @attributes: attributes of the variable + * @data_size: size of the buffer to which the variable value is copied + * @data: buffer to which the variable value is copied + * Return: status code + */ +efi_status_t efi_get_variable_int(u16 *variable_name, + const efi_guid_t *vendor, u32 *attributes, + efi_uintn_t *data_size, void *data) { char *native_name; efi_status_t ret; @@ -172,22 +196,20 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, const char *val, *s; u32 attr; - EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes, - data_size, data); if (!variable_name || !vendor || !data_size) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; ret = efi_to_native(&native_name, variable_name, vendor); if (ret) - return EFI_EXIT(ret); + return ret; EFI_PRINT("get '%s'\n", native_name); val = env_get(native_name); free(native_name); if (!val) - return EFI_EXIT(EFI_NOT_FOUND); + return EFI_NOT_FOUND; val = parse_attr(val, &attr); @@ -198,7 +220,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, /* number of hexadecimal digits must be even */ if (len & 1) - return EFI_EXIT(EFI_DEVICE_ERROR); + return EFI_DEVICE_ERROR; /* two characters per byte: */ len /= 2; @@ -210,10 +232,10 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, } if (!data) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; if (hex2bin(data, s, len)) - return EFI_EXIT(EFI_DEVICE_ERROR); + return EFI_DEVICE_ERROR; EFI_PRINT("got value: \"%s\"\n", s); } else if ((s = prefix(val, "(utf8)"))) { @@ -227,7 +249,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, } if (!data) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; memcpy(data, s, len); ((char *)data)[len] = '\0'; @@ -235,14 +257,14 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, EFI_PRINT("got value: \"%s\"\n", (char *)data); } else { EFI_PRINT("invalid value: '%s'\n", val); - return EFI_EXIT(EFI_DEVICE_ERROR); + return EFI_DEVICE_ERROR; } out: if (attributes) *attributes = attr & EFI_VARIABLE_MASK; - return EFI_EXIT(ret); + return ret; } static char *efi_variables_list; @@ -331,6 +353,33 @@ static efi_status_t parse_uboot_variable(char *variable, efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, u16 *variable_name, efi_guid_t *vendor) +{ + EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); + + return EFI_EXIT(efi_get_next_variable_name_int(variable_name_size, + variable_name, vendor)); +} + +/** + * efi_get_next_variable_name_int() - enumerate the current variable names + * + * This function can be used to enumerate UEFI variable without using + * EFI_CALL(). + * + * @variable_name_size: size of variable_name buffer in byte + * @variable_name: name of uefi variable's name in u16 + * @vendor: vendor's guid + * + * This function implements the GetNextVariableName service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * Return: status code + */ +efi_status_t efi_get_next_variable_name_int(efi_uintn_t *variable_name_size, + u16 *variable_name, + efi_guid_t *vendor) { char *native_name, *variable; ssize_t name_len, list_len; @@ -340,10 +389,8 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, int i; efi_status_t ret; - EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); - if (!variable_name_size || !variable_name || !vendor) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; if (variable_name[0]) { /* check null-terminated string */ @@ -351,12 +398,12 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, if (!variable_name[i]) break; if (i >= *variable_name_size) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; /* search for the last-returned variable */ ret = efi_to_native(&native_name, variable_name, vendor); if (ret) - return EFI_EXIT(ret); + return ret; name_len = strlen(native_name); for (variable = efi_variables_list; variable && *variable;) { @@ -371,14 +418,14 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, free(native_name); if (!(variable && *variable)) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; /* next variable */ variable = strchr(variable, '\n'); if (variable) variable++; if (!(variable && *variable)) - return EFI_EXIT(EFI_NOT_FOUND); + return EFI_NOT_FOUND; } else { /* *new search: free a list used in the previous search @@ -393,7 +440,7 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, &efi_variables_list, 0, 1, regexlist); /* 1 indicates that no match was found */ if (list_len <= 1) - return EFI_EXIT(EFI_NOT_FOUND); + return EFI_NOT_FOUND; variable = efi_variables_list; } @@ -401,7 +448,7 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, ret = parse_uboot_variable(variable, variable_name_size, variable_name, vendor, &attributes); - return EFI_EXIT(ret); + return ret; } /** @@ -422,6 +469,29 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, efi_status_t EFIAPI efi_set_variable(u16 *variable_name, const efi_guid_t *vendor, u32 attributes, efi_uintn_t data_size, const void *data) +{ + EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes, + data_size, data); + + return EFI_EXIT(efi_set_variable_int(variable_name, vendor, attributes, + data_size, data)); +} + +/** + * efi_set_variable_int() - set value of a UEFI variable internal + * + * This function can be used to set a UEFI variable without using EFI_CALL(). + * + * @variable_name: name of the variable + * @vendor: vendor GUID + * @attributes: attributes of the variable + * @data_size: size of the buffer with the variable value + * @data: buffer with the variable value + * Return: status code + */ +efi_status_t efi_set_variable_int(u16 *variable_name, + const efi_guid_t *vendor, u32 attributes, + efi_uintn_t data_size, const void *data) { char *native_name = NULL, *val = NULL, *s; const char *old_val; @@ -429,8 +499,6 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_status_t ret = EFI_SUCCESS; u32 attr; - EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes, - data_size, data); if (!variable_name || !*variable_name || !vendor || ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) && @@ -540,7 +608,7 @@ out: free(native_name); free(val); - return EFI_EXIT(ret); + return ret; } /**