From patchwork Mon Nov 5 09:06:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 150155 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2353513ljp; Mon, 5 Nov 2018 01:06:04 -0800 (PST) X-Google-Smtp-Source: AJdET5c9wQuqVBGJ7C4WuL/GpbYdnN1ZS/+8eredBa8LyxtrQKzBYBPUFrvXqlwcRUOnx0WT4Cqt X-Received: by 2002:a50:9226:: with SMTP id i35-v6mr17678892eda.50.1541408764456; Mon, 05 Nov 2018 01:06:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541408764; cv=none; d=google.com; s=arc-20160816; b=EoFvlZ87iBYwIv4B5V5sbOnfveRqVfZM3uzLnpBes5ZVJLQiuoDA7hPH5DDj2gnFz9 zJE8QTIfCbdooLNpGuwuGm29Vng5Xf1Bq7kzLClx/pZhZim/6KydJo/aVayyun6txPbZ xA9EemYRr/994tZ4e//zVBBUG1j9j6xHHvYtkgl1Us/scHLhnDpG6LF9GH6YLVHSUXaC /8r4ZkYZo+ztZQKqn5IUyNu8WaurSzpcvqc3qKJkJaoiM6ESt/0dztD7pm6iKGtC62T2 vSiMimxMhNGm3qMxcIjGQ7K3Mr99lATcZjjUzNHdLv7tHleqWjxRv5yRte4WoIiDEmPk IkDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :cc:mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature; bh=9HrXMzLX4XCR2kKUS5pzzOJ+Bx6aMRZ/G2M+wn3UW3E=; b=U3hvVVHGhBeZrMtApHe7laHADKFSupIuNHkwxTGPqjx/DYRLBo1AOX6jBBFs25/wG6 mFTQLr3+g7M24SuUHEThNlA2W7QcSyY6pNUrNbp+ifnHpJ6ypjCeGD698QKnXjhHMqPX n3j60pDut8bLX272VYhfi8d7aX9TwdDciRHyEMAfrnSJvpdzrqzs1SZn/NACOs/txIRE DbULcrLeLLHhrt+9SnpuP7QlUmp7XouJS7hmS8KbTwkVaGh5ETXuVqoMDVmGB9QqFIOL pVSTkX2COFh9ffy6omy08Qlh8ZTn3DSF4+2Le9zBL7X+KYJNHXQ7tKTHd+3m6rwmpaQh v5yQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=IyzwsOiB; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id k20-v6si61993eds.404.2018.11.05.01.06.04; Mon, 05 Nov 2018 01:06:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=IyzwsOiB; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.denx.de (Postfix, from userid 105) id 1E549C22228; Mon, 5 Nov 2018 09:05:13 +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_MSPIKE_H2, 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 74A37C22200; Mon, 5 Nov 2018 09:04:59 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 97B2BC22203; Mon, 5 Nov 2018 09:04:45 +0000 (UTC) Received: from mail-yb1-f196.google.com (mail-yb1-f196.google.com [209.85.219.196]) by lists.denx.de (Postfix) with ESMTPS id C5BF2C2220C for ; Mon, 5 Nov 2018 09:04:40 +0000 (UTC) Received: by mail-yb1-f196.google.com with SMTP id d18-v6so3483433yba.4 for ; Mon, 05 Nov 2018 01:04:40 -0800 (PST) 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=aAJuju1gf7kE1vPYxvgHd5jxNpIuDodKUm7Ta67btms=; b=IyzwsOiBOgZ2ERdQfus8Bq3lvpmVJtdiyXRxfCBBVhAfXOpFyzIlD2Ip5zNXJmBDfg Gv9997ea6Egecp3SY8XE6R3/uMtcJwUbr//vbASX+fRfFB3IhMaP4wnfVY0VvAr1y7GD prylOjBzLEaYTwcyCezFd1WxNqAplRLk65MGM= 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=aAJuju1gf7kE1vPYxvgHd5jxNpIuDodKUm7Ta67btms=; b=NpcaTgQ6tjkbhFpg5uk6ic6586jHiTETAuzFV36SSR1DdVu5sL8t+a3xUdrqf2uTgC N/95NfgIsdbJ6ajrJ7+GrmGvx6cpkHhrOstuQJ4BKBBVJDuLhb/lwUe1KcCripOSRzZH dWSUBqaGlyE+2/elAqDu4cvLiuggMOYlBTiuyh+7NlRnM/8BM7mpV+sASt8tCpukgwyU 12/uU4TlKb4jLYaYl19VR0nvByVMk7gc0JvyMF8usDjYTHgpz/GjKb3ICD8mqDTR5BbK o8i+YE/Hv9mmGsRz3Qxr0u0rO+ZM6JUkw0ioKxULZsb4Pjwz6i2Rnj8jHFM9L9HPhLRb h8XQ== X-Gm-Message-State: AGRZ1gKzlxLl/AqCH2Mya0MuP1iazv4o6inp3WI0ZDCHENfV/kSxrPwC 9TWJHk8zbN4ewkAHcCLc278vmA== X-Received: by 2002:a25:81c4:: with SMTP id n4-v6mr535560ybm.455.1541408679660; Mon, 05 Nov 2018 01:04:39 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id f203-v6sm7059210ywa.45.2018.11.05.01.04.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Nov 2018 01:04:39 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Mon, 5 Nov 2018 18:06:41 +0900 Message-Id: <20181105090653.7409-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181105090653.7409-1-takahiro.akashi@linaro.org> References: <20181105090653.7409-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: xypron.glpk@gmx.de, u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 02/14] 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_deserialize_load_option(): parse a string into load_option data (renamed from parse_load_option and exported) * efi_serialize_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 | 23 +++++++++ lib/efi_loader/efi_bootmgr.c | 93 +++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 33 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 5c2485bd03e4..d83de906fbce 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -517,6 +517,29 @@ 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 efi_load_option { + u32 attributes; + u16 file_path_length; + u16 *label; + struct efi_device_path *file_path; + u8 *optional_data; +}; + +void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data); +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **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 2aae12e15456..a095df3f540b 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -9,6 +9,7 @@ #include #include #include +#include static const struct efi_boot_services *bs; static const struct efi_runtime_services *rs; @@ -30,42 +31,68 @@ 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) +/* Parse serialized data and transform it into efi_load_option structure */ +void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data) { - lo->attributes = *(u32 *)ptr; - ptr += sizeof(u32); + lo->attributes = get_unaligned_le32(data); + data += sizeof(u32); + + lo->file_path_length = get_unaligned_le16(data); + data += sizeof(u16); - lo->file_path_length = *(u16 *)ptr; - ptr += sizeof(u16); + /* FIXME */ + lo->label = (u16 *)data; + data += (u16_strlen(lo->label) + 1) * sizeof(u16); - lo->label = ptr; - ptr += (u16_strlen(lo->label) + 1) * 2; + /* FIXME */ + lo->file_path = (struct efi_device_path *)data; + data += lo->file_path_length; - lo->file_path = ptr; - ptr += lo->file_path_length; + lo->optional_data = data; +} - lo->optional_data = ptr; +/* + * Serialize efi_load_option structure into byte stream for BootXXXX. + * Return a size of allocated data. + */ +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) +{ + unsigned long label_len, option_len; + unsigned long size; + u8 *p; + + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); + option_len = strlen((char *)lo->optional_data); + + /* total size */ + size = sizeof(lo->attributes); + size += sizeof(lo->file_path_length); + size += label_len; + size += lo->file_path_length; + size += option_len + 1; + p = malloc(size); + if (!p) + return 0; + + /* copy data */ + *data = p; + memcpy(p, &lo->attributes, sizeof(lo->attributes)); + p += sizeof(lo->attributes); + + memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); + p += sizeof(lo->file_path_length); + + memcpy(p, lo->label, label_len); + p += label_len; + + memcpy(p, lo->file_path, lo->file_path_length); + p += lo->file_path_length; + + memcpy(p, lo->optional_data, option_len); + p += option_len; + *(char *)p = '\0'; + + return size; } /* free() the result */ @@ -100,7 +127,7 @@ static void *get_var(u16 *name, const efi_guid_t *vendor, static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, struct efi_device_path **file_path) { - struct load_option lo; + struct efi_load_option lo; u16 varname[] = L"Boot0000"; u16 hexmap[] = L"0123456789ABCDEF"; void *load_option, *image = NULL; @@ -115,7 +142,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_deserialize_load_option(&lo, load_option); if (lo.attributes & LOAD_OPTION_ACTIVE) { efi_status_t ret;