From patchwork Wed Oct 17 07:32:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 985156 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ZzCe3PbC"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42ZkTr1C7Zz9s9h for ; Wed, 17 Oct 2018 18:34:56 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id C1E38C21E08; Wed, 17 Oct 2018 07:32:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 594AFC21C2C; Wed, 17 Oct 2018 07:31:15 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A6183C21BE5; Wed, 17 Oct 2018 07:30:49 +0000 (UTC) Received: from mail-yw1-f67.google.com (mail-yw1-f67.google.com [209.85.161.67]) by lists.denx.de (Postfix) with ESMTPS id 971D7C21DCA for ; Wed, 17 Oct 2018 07:30:44 +0000 (UTC) Received: by mail-yw1-f67.google.com with SMTP id l79-v6so9953717ywc.7 for ; Wed, 17 Oct 2018 00:30:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OREM892Y+bGO/OGQjV2MrIj2U+HDOOJvcy8xMXO5xZw=; b=ZzCe3PbC2afb6SV9FM0v0VR/QMRsqMRmuEIy8v0CS+yZkf/p34QEOoghQwsOKRTQD2 xooHInkhOUzdTDjECcWVxDXTmtdHrTdGlkh2kEWsIM37i6PZ5z/shMEra7uZpfAF49YW BfuqaaJ2lIc12oSPEKdASz8kImJKezBpPYIzU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OREM892Y+bGO/OGQjV2MrIj2U+HDOOJvcy8xMXO5xZw=; b=rdUMVhSqBtT2n5x/M6a5jQnb2tx3eUFFWflUa2GHTNx2fbTQX64TyLxnxpRAUVBneL +ww53/sxLm8OHYWGtXBN+XW2Q5qwUZgY1Ya+Jy5fb/ghvQy9hJgJgX+6UH2zzIKzqWp+ IwTrDFN05DWcrjP9s2e6ULkFKMnwHvLZgRuM7GASU2kjnrzWYqq3ArlwmtcPZMvSszMK iw7H1tnVGSOeOjtDdkFTgO3JXbZUd5/ZjvD0JZSrB1fO6cCMp0OdATXMqJdHl1CSQGhq qs+VV+FWkmIH5i9orY98mIDM2BBrzkVJWln82IdYJxtG73/8k62mkZceXmcxDGgZusCK MjBA== X-Gm-Message-State: ABuFfoguZnhePmNIC7ysaubsD/n+33A8QZDwwMMnXPCzVUEQFPyL/WQI Qn6knogmEYXS9VuVoGITGpc7FQ== X-Google-Smtp-Source: ACcGV62ZkD0GQM7BbEd3pe1NRKO8rMTFUcXmpkZ4oRlUXjE3LUKSHU9Jzx+uxJDLnVJg1WLNGI06KQ== X-Received: by 2002:a81:9148:: with SMTP id i69-v6mr13867465ywg.371.1539761443502; Wed, 17 Oct 2018 00:30:43 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id r5-v6sm6645288ywr.80.2018.10.17.00.30.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Oct 2018 00:30:42 -0700 (PDT) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Wed, 17 Oct 2018 16:32:04 +0900 Message-Id: <20181017073207.13150-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181017073207.13150-1-takahiro.akashi@linaro.org> References: <20181017073207.13150-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 3/6] efi_loader: bootmgr: add load option helper functions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" In this patch, helper functions for an load option variable (BootXXXX) are added: * efi_parse_load_option(): parse a string into load_option data (renamed from parse_load_option and exported) * efi_marshel_load_option(): convert load_option data into a string Those functions will be used to implement efishell command. Signed-off-by: AKASHI Takahiro --- include/efi_loader.h | 25 +++++++++++++ lib/efi_loader/efi_bootmgr.c | 68 ++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index b73fbb6de23f..1cabb1680d20 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -502,6 +502,31 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, u32 attributes, efi_uintn_t data_size, void *data); +/* + * See section 3.1.3 in the v2.7 UEFI spec for more details on + * the layout of EFI_LOAD_OPTION. In short it is: + * + * typedef struct _EFI_LOAD_OPTION { + * UINT32 Attributes; + * UINT16 FilePathListLength; + * // CHAR16 Description[]; <-- variable length, NULL terminated + * // EFI_DEVICE_PATH_PROTOCOL FilePathList[]; + * <-- FilePathListLength bytes + * // UINT8 OptionalData[]; + * } EFI_LOAD_OPTION; + */ +struct load_option { + u32 attributes; + u16 file_path_length; + u16 *label; + struct efi_device_path *file_path; + u8 *optional_data; +}; + +void efi_parse_load_option(struct load_option *lo, void *ptr); +unsigned long efi_marshal_load_option(u32 attr, u16 *label, + struct efi_device_path *file_path, + char *option, void **data); void *efi_bootmgr_load(struct efi_device_path **device_path, struct efi_device_path **file_path); diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 0c5764db127b..c2d29f956065 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -30,28 +30,8 @@ static const struct efi_runtime_services *rs; */ -/* - * See section 3.1.3 in the v2.7 UEFI spec for more details on - * the layout of EFI_LOAD_OPTION. In short it is: - * - * typedef struct _EFI_LOAD_OPTION { - * UINT32 Attributes; - * UINT16 FilePathListLength; - * // CHAR16 Description[]; <-- variable length, NULL terminated - * // EFI_DEVICE_PATH_PROTOCOL FilePathList[]; <-- FilePathListLength bytes - * // UINT8 OptionalData[]; - * } EFI_LOAD_OPTION; - */ -struct load_option { - u32 attributes; - u16 file_path_length; - u16 *label; - struct efi_device_path *file_path; - u8 *optional_data; -}; - /* parse an EFI_LOAD_OPTION, as described above */ -static void parse_load_option(struct load_option *lo, void *ptr) +void efi_parse_load_option(struct load_option *lo, void *ptr) { lo->attributes = *(u32 *)ptr; ptr += sizeof(u32); @@ -60,7 +40,7 @@ static void parse_load_option(struct load_option *lo, void *ptr) ptr += sizeof(u16); lo->label = ptr; - ptr += (u16_strlen(lo->label) + 1) * 2; + ptr += (u16_strlen(lo->label) + 1) * sizeof(u16); lo->file_path = ptr; ptr += lo->file_path_length; @@ -68,6 +48,48 @@ static void parse_load_option(struct load_option *lo, void *ptr) lo->optional_data = ptr; } +unsigned long efi_marshal_load_option(u32 attr, u16 *label, + struct efi_device_path *file_path, + char *option, void **data) +{ + unsigned long size; + unsigned long label_len, option_len; + u16 file_path_len; + void *p; + + label_len = (u16_strlen(label) + 1) * sizeof(u16); + file_path_len = efi_dp_size(file_path) + + sizeof(struct efi_device_path); /* for END */ + option_len = strlen(option); + + /* total size */ + size = sizeof(attr); + size += file_path_len; + size += label_len; + size += option_len + 1; + p = malloc(size); + if (!p) + return 0; + + /* copy data */ + *data = p; + memcpy(p, &attr, sizeof(attr)); + p += sizeof(attr); + memcpy(p, &file_path_len, sizeof(file_path_len)); + p += sizeof(file_path_len); + memcpy(p, label, label_len); + p += label_len; + + memcpy(p, file_path, file_path_len); + p += file_path_len; + + memcpy(p, option, option_len); + p += option_len; + *(char *)p = '\0'; + + return size; +} + /* free() the result */ static void *get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size) @@ -115,7 +137,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, if (!load_option) return NULL; - parse_load_option(&lo, load_option); + efi_parse_load_option(&lo, load_option); if (lo.attributes & LOAD_OPTION_ACTIVE) { efi_status_t ret;