From patchwork Mon Nov 5 09:06:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 150153 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2352481ljp; Mon, 5 Nov 2018 01:05:09 -0800 (PST) X-Google-Smtp-Source: AJdET5fbF31fBCvg5neV3Rqhq/RQI/QXo4pN+R3N4BrYrhvA1lzO3OMGNqAMvQA0ZQMXCjMWT4DR X-Received: by 2002:a17:906:12d3:: with SMTP id l19-v6mr9253977ejb.74.1541408709589; Mon, 05 Nov 2018 01:05:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541408709; cv=none; d=google.com; s=arc-20160816; b=hXfWNvqdU6QAu36W7hiK7eKrGvbxu9iAsJkyhv4I+l0cS9LBgIFOA6uea0GTO6hJdC 4mD2w3r1XYmIwvrJA8LHusVwe5YkUGr8/awAru1bCoJlxCBdTMAgo960Zm5+kl/OX9D5 hE8GcoXVhhNIiZkVm9zfFPq8kCuW89E5mX5xEN01vJM4LeKXoB7ZFmAh3JWOv6ZGgW95 TCtMziidC4fyQy9a1BPw8wTgQN4KP09Wzo47QdRK8moX/l4006pV0IGITkhrFJAb+Ive Lx3+v3MNv93AUvZ4zxmhq2sjthYgnheg1yHrdnRY545N9xa/IfwY7hS/Sfaza/x6qebv yQRw== 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=WX3SmRPJ+SAvaCdwFbisTRYkevCT5VmWQG4aXoTQrBA=; b=IV3ILxgk4qwV1RA+a1VWjvokYunzuFYEg4+0ay/rnUyDkswzQ1eEhsFlEUGQ2BcroX aPq4wM+TD2iMkWuXV/IWFSzju71LNQf6jSe/+21sVhR+/e56rTGPoetv/fd9Cg3ti+Wh I/664ykyxmybNxtm2Z8NS9mEHY8bV5DSPq6NEDrqrfayhpEBqyV3alJQ+bSJm442en/o lRXuKpF2qU6CiyaicI3V6qIQxhfSR/xuWsICP8LiFevoV0rwhyDwOA6lDxw0oIvJN3Tb EdIExkuQbiY08+kQF7HgF9qHilx3QMNKO2VXrHzz5+SY2rQ0G6faPU5T8Nhu4PjNSFAl Iuig== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Cdl6S9W3; 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 u15-v6si6273311eds.450.2018.11.05.01.05.09; Mon, 05 Nov 2018 01:05:09 -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=Cdl6S9W3; 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 2F507C22204; Mon, 5 Nov 2018 09:04:55 +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 30723C2221A; Mon, 5 Nov 2018 09:04:46 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 55F87C22203; Mon, 5 Nov 2018 09:04:41 +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 01BCEC2220F for ; Mon, 5 Nov 2018 09:04:36 +0000 (UTC) Received: by mail-yb1-f196.google.com with SMTP id t13-v6so3469240ybb.8 for ; Mon, 05 Nov 2018 01:04:35 -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=RzoK5KV4imuacZlz2P/nz+AyGNQoWGbwxtWpUN+CwHw=; b=Cdl6S9W3WyPRigdiN439z+JFu6Eh5VkIFsBiDZnUzgDJQre3ANIZDKTag4cccOS6cp +0a1ONwb9JxWryc9OsrKP3FEpNEPzsR1Ovvs61p5ZvJQ8FO49VU7J4BZ5LkFf6tRH7XS UlDDTp0MmsZQQwT1dY47Zud7U7/E0nz1i3eqg= 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=RzoK5KV4imuacZlz2P/nz+AyGNQoWGbwxtWpUN+CwHw=; b=SHp+/7pjpZSFwUaUBHCNqlGGqVdHQ/C2AE5tcFnvoLK2mKjiHCoiFalw9dCJtVoSZq nBBrPkAbK4h1IU/nr5QfVKNDsxOYx0uxjRN8tIbMAC0xcF1TkeqKqSP62FGMJ3fFI2Uu 8zI443Ns/l9j2wLyoPYVAvyO/VXi7mz7qkGt798entapymEkOKNmLZrV2sTX2mYcKQbA 4wnOagT1zZBSsvFMM6yUm4BB5BmoUr+d8EKuBT024MuGw129VzOCVMCWqLfoPwqAzlN+ aPZ7/0uG+Fcnpbk7xVPxSjX3rdrVALxCZntcJ8AigCfpW+lbVZmGKPPjIKsgzpcu46PV igig== X-Gm-Message-State: AGRZ1gJk6G9jD5LwKZxAjIGjDGwJSSsjPFgcaW3ouihWQOZxNts6A+vQ HgZyrgaAy0yya9KVfTLNRWmaUg== X-Received: by 2002:a25:4f89:: with SMTP id d131-v6mr19956349ybb.379.1541408674849; Mon, 05 Nov 2018 01:04:34 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id c74-v6sm3555143ywc.90.2018.11.05.01.04.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Nov 2018 01:04:34 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Mon, 5 Nov 2018 18:06:40 +0900 Message-Id: <20181105090653.7409-2-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 01/14] efi_loader: allow device == NULL in efi_dp_from_name() 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" This is a preparatory patch for use in efi_serialize_load_option() as a load option's file_path should have both a device path and a file path. Signed-off-by: AKASHI Takahiro --- lib/efi_loader/efi_device_path.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index cdf7c7be8c5c..d94982314a3e 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -955,7 +955,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, char filename[32] = { 0 }; /* dp->str is u16[32] long */ char *s; - if (!device || (path && !file)) + if (path && !file) return EFI_INVALID_PARAMETER; is_net = !strcmp(dev, "Net"); @@ -965,10 +965,12 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, if (part < 0) return EFI_INVALID_PARAMETER; - *device = efi_dp_from_part(desc, part); + if (device) + *device = efi_dp_from_part(desc, part); } else { #ifdef CONFIG_NET - *device = efi_dp_from_eth(); + if (device) + *device = efi_dp_from_eth(); #endif } @@ -985,7 +987,8 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, s = filename; while ((s = strchr(s, '/'))) *s++ = '\\'; - *file = efi_dp_from_file(NULL, 0, filename); + *file = efi_dp_from_file(((!is_net && device) ? desc : NULL), + part, filename); return EFI_SUCCESS; } 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; From patchwork Mon Nov 5 09:06:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 150154 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2353489ljp; Mon, 5 Nov 2018 01:06:03 -0800 (PST) X-Google-Smtp-Source: AJdET5dNnNrApJbEAoG5LSL70WGPQmM0eckUvYTtOM5WZBEK2wQcP4S5epj3c7erxjEItAR1yPPp X-Received: by 2002:a50:b839:: with SMTP id j54-v6mr17706304ede.16.1541408763264; Mon, 05 Nov 2018 01:06:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541408763; cv=none; d=google.com; s=arc-20160816; b=O8SC/TXyZw+vMUQRRnbjQQgt0t9y2X9Yh96AKxT1CPM8Kw7DsYL2Uf+c+vtp/jMqyE cISUCqxa6q5TEHZ/NQZhsYBnZGk2pg4TZL+tAUu1yi6bq0moQpuZIvywRqDaCDWM+9wX IJemKvD0yYEZ9AAdqYGPIb9D9SDVAVWDi7aaOnylAMjDDG+D6YXpOIodO6cu/MQ2Ll/Q U/ZUt461mJ36bpQMHmHC7fqUs/gzRxkSdvh1aESjvjBIyb6pW/ouFxeiDpptH39opI+m IHYOf2j2HVdeAhg3LTMqu3vExEtfQsSmF+cjDr/Ideh4p3h9AQRKwuxmf32U0h2Bvpl/ HgIw== 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=EwHQv86LTCMYqGQXY+m+TYDyC+yxInq7dCLfmsG4Ru8=; b=slZ6oCGk77UAEHNHWVlI88MtF1AbnHU3HY/bWOtnczm5ATiggOb4KNH/eQZvbvg2WJ 2HJ9tbPSeatGNASOQnr9ZAuDS00KlC90BKxghRZr+ux/xZKxhb4P4TEnKqK6FVS4zJzK +7wCzerZtFjomtzMTtG7EMdGBOZXX+gyTIU5BGa1ePQNow8sHu/SVpIixDyU9wK/eN6V HKRhUj/lgatH3fmdK+gDPUAy4zJ4GdafNQC7ic6Jiwe9B6dzkP9hlOSyVKYqYH0hPSRQ B7mmQUd9SAIQOHxYIPYGn6wJA8x3hDZIoP/0dmzUCcELF6LVG2FKJFGkTsLlm1R72rZC 100g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=BP2Lkah9; 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 w19-v6si4148414ejv.41.2018.11.05.01.06.03; Mon, 05 Nov 2018 01:06:03 -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=BP2Lkah9; 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 D8FE2C221F2; Mon, 5 Nov 2018 09:05:33 +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 7D5F5C2220B; Mon, 5 Nov 2018 09:05:00 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id BC932C221FB; Mon, 5 Nov 2018 09:04:50 +0000 (UTC) Received: from mail-yb1-f195.google.com (mail-yb1-f195.google.com [209.85.219.195]) by lists.denx.de (Postfix) with ESMTPS id 67242C2220C for ; Mon, 5 Nov 2018 09:04:45 +0000 (UTC) Received: by mail-yb1-f195.google.com with SMTP id f15-v6so3460656ybq.13 for ; Mon, 05 Nov 2018 01:04:45 -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=HrMYuKGtMyWD8ckyvCWUWRftmFaZuWeVkkJCGjzisCY=; b=BP2Lkah9XKdt8UDK45/HGkeJC9yiAwSlbSdXp7FBB3+oOFVEb9maoYbsrSudpuJygV DrehjGM8VFHWDEsClqLyuuz+ODd/oPeiv66hzb3I+hAmYAMghG8dSlEhuCA93tz4BwmZ a5j4vNIx6YHmfx/4IQVQ7Q24lRN325edhaQzM= 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=HrMYuKGtMyWD8ckyvCWUWRftmFaZuWeVkkJCGjzisCY=; b=Y8ZZcWWZl8AO7shDnEJexEQ4PLJBbTg/wmOOo0GlzaK/KJD8gIwGVqoiuDITIdycM1 oOw18oKex40NEIaykBPdJlTHWxlRlAtVeS4zRFVGcXGbCG/Pi9d1rZV3oXEZird+beqB cqOTeo1ZBzC5dXX2FO/FY8EGkgNadqp9DoMCnbBmkyxEtJQtsf4WYpfyk/wtT/NgCWLx IKBp14L8+B86NFV907dFOvKxKvmmKt2ehJquLe5NgOAiKKVp+Lt3MhIiaJK+nwv9MvYc 2i6+28DraSHiluKj76qeSqE4b2QwJO9yX87fF0TR9PzLgktx65XoCuOND/VfpYrz3c6i vWWA== X-Gm-Message-State: AGRZ1gLvpyOelg/oVnBCJkEWFiEUpMMRzrD9N5aIuxM0X44Ve6kk8/ei LoVXRgVwKkrF4aGn3PKImOD+PA== X-Received: by 2002:a25:77d2:: with SMTP id s201-v6mr6039519ybc.236.1541408684304; Mon, 05 Nov 2018 01:04:44 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id d17-v6sm11147979ywe.68.2018.11.05.01.04.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Nov 2018 01:04:43 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Mon, 5 Nov 2018 18:06:42 +0900 Message-Id: <20181105090653.7409-4-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 03/14] efi_loader: bootmgr: allow for running a given load option 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" With an extra argument, efi_bootmgr_load() can now load an efi binary based on a "BootXXXX" variable specified. Signed-off-by: AKASHI Takahiro --- include/efi_loader.h | 3 ++- lib/efi_loader/efi_bootmgr.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index d83de906fbce..ce0f420b5004 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -540,7 +540,8 @@ struct efi_load_option { 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, +void *efi_bootmgr_load(int boot_id, + struct efi_device_path **device_path, struct efi_device_path **file_path); #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index a095df3f540b..74eb832a8c92 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -170,7 +170,8 @@ error: * available load-options, finding and returning the first one that can * be loaded successfully. */ -void *efi_bootmgr_load(struct efi_device_path **device_path, +void *efi_bootmgr_load(int boot_id, + struct efi_device_path **device_path, struct efi_device_path **file_path) { uint16_t *bootorder; @@ -183,6 +184,11 @@ void *efi_bootmgr_load(struct efi_device_path **device_path, bs = systab.boottime; rs = systab.runtime; + if (boot_id != -1) { + image = try_load_entry(boot_id, device_path, file_path); + goto error; + } + bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); if (!bootorder) goto error; From patchwork Mon Nov 5 09:06:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 150160 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2358212ljp; Mon, 5 Nov 2018 01:11:15 -0800 (PST) X-Google-Smtp-Source: AJdET5f4iC982wErI7TJhNeIB3TwFNXDGo2/+/OmrNLsq3UniIcJ1gjle7cx6xaRCq9HpbwakELc X-Received: by 2002:a17:906:e0d9:: with SMTP id gl25-v6mr7632612ejb.92.1541409074964; Mon, 05 Nov 2018 01:11:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541409074; cv=none; d=google.com; s=arc-20160816; b=vRNqZvPhnhKd2JOF+kgNmvFDOfXxHwEbNvxwtedgJUMcLzxZY4VpIflR6LqvQofDbR 32s0YVEp0azvw6PhVq8qmVeTnCgRFF5rPeOydfVKCOF8Tbdzqc6aBJ0dYBc1bMz/HV/L 78VVhlHi62AYGuToE/tht0PDVpuXBc2SECB7M8cI4RoaPq1qmbSWv6fd2yumFDKcrd9/ ZfuTDwbODaskTZjSAvm+NhrCOVED5tPECOQ733B1zly1hfXtfH3q9gWbC+N47HBDnAqg 67my9PEoT17e2Saus8Oct8c0n+r7KEY3HzoETPb5rogVQYm5rExIKwtaAn4wRHWlr5aw jKBw== 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=IGDTcSva7KOlegfRP/MN8KunDSoAZX9kMJBAlYYwvZ4=; b=p5EPMCUMk9vM0bqloI44WGlniuLMA0Fl0w2pHxctPWFwfHziGZZeJLyAYugMFwujtR mnZqnRhg1wVksoaAeQ0EHZM9GA/UojMkBhHCg7gmvNpZ/Ai31TraQlvtEKIBip+FDlM2 JLRYvo1ONvEj5D4AImm6i1tOGOvxTdujMJvdJllVBvT8RDEk7zqwH1VmqGz8w0Rzo9DT AYzOztiEBmeEgJnt3A5aFO5N1cPe2+Q66p1iXZ/nUjS4xo0X4o1sUQQT0sNCutzZw0Ps RCuGo1HjF1aWwWVeG/IIardm7tD12ZdJAo6/5dFnXYrOCRj5yh0/AZ9tdTxd3PCISIMM jbhg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=CvQ7nXQW; 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 b12-v6si21023ede.260.2018.11.05.01.11.14; Mon, 05 Nov 2018 01:11:14 -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=CvQ7nXQW; 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 8CCBDC22205; Mon, 5 Nov 2018 09:06:49 +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 85E7BC2222C; Mon, 5 Nov 2018 09:05:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id C9149C2220B; Mon, 5 Nov 2018 09:04:55 +0000 (UTC) Received: from mail-yb1-f194.google.com (mail-yb1-f194.google.com [209.85.219.194]) by lists.denx.de (Postfix) with ESMTPS id 4E4C9C22200 for ; Mon, 5 Nov 2018 09:04:51 +0000 (UTC) Received: by mail-yb1-f194.google.com with SMTP id p144-v6so3465748yba.11 for ; Mon, 05 Nov 2018 01:04:51 -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=9ak4G4dAV2VXp5WSTEcfmwa/6lPi2bolaU2Yz5P5ma0=; b=CvQ7nXQWf8dEhJeB7MozTVP6UOCHuQPpXgofIDULHmxEMgX60IkLZ+vZbAF+sWU6vU vOr7YkIHsqXtlMTij/6ltmTEuyfWr9xdEuRAEl9LHJmOTpYVxRdSUkCmRqUPnfhKUfL9 ajyuRWoyCuoPSoZFQJGubugDxMKHOAistqn/M= 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=9ak4G4dAV2VXp5WSTEcfmwa/6lPi2bolaU2Yz5P5ma0=; b=L7DpSbWixkVWkc91UpBgYEYOMnR8gVT3QGOCR6coBAoMJ2UjZiY+cRzYM922V5PxUF Z2QQ7rO7rZW06IdXJSaEe4LzOE9Ebh7rqzgMxbK6w6uupQWlNqvayxiUwhctqxjAslHX 01V1C4haodIY2tWJmw+PkqmZyaMiMSVnaqVuJWOwUrAgOCNirvGH1FJKTJXxEQUl5GCH 9t2ZOxGG2LWW4PX8oS2RGZXFZd2pszw36zZKK41YSEHtr2fFRjie++OzQvfokGeae8HV VzD3AQrffrJu7c9uHacui+DSLaBsIrLNwsaZ0rXHdmvKpDEuYhiDUeR9v+T3bgisNbor MO+Q== X-Gm-Message-State: AGRZ1gJYHC6VNkwj++MGQbn0zVwXZbRJinPHVmgwYnHFSGgRQG5M9MRD tJTi37lBpMwlnMikA9Ix7Lb3yA== X-Received: by 2002:a25:2f83:: with SMTP id v125-v6mr4154169ybv.465.1541408689882; Mon, 05 Nov 2018 01:04:49 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id s83-v6sm11294760yws.33.2018.11.05.01.04.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Nov 2018 01:04:49 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de Date: Mon, 5 Nov 2018 18:06:43 +0900 Message-Id: <20181105090653.7409-5-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 04/14] cmd: add efishell command 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" Currently, there is no easy way to add or modify UEFI variables. In particular, bootmgr supports BootOrder/BootXXXX variables, it is quite hard to define them as u-boot variables because they are represented in a complicated and encoded format. The new command, efishell, helps address these issues and give us more friendly interfaces: * efishell boot add: add BootXXXX variable * efishell boot rm: remove BootXXXX variable * efishell boot dump: display all BootXXXX variables * efishell boot order: set/display a boot order (BootOrder) * efishell setvar: set an UEFI variable (with limited functionality) * efishell dumpvar: display all UEFI variables As the name suggests, this command basically provides a subset fo UEFI shell commands with simplified functionality. Signed-off-by: AKASHI Takahiro --- cmd/Makefile | 2 +- cmd/efishell.c | 673 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/efishell.h | 5 + 3 files changed, 679 insertions(+), 1 deletion(-) create mode 100644 cmd/efishell.c create mode 100644 cmd/efishell.h diff --git a/cmd/Makefile b/cmd/Makefile index d9cdaf6064b8..bd531d505a8e 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_CMD_BINOP) += binop.o obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o obj-$(CONFIG_CMD_BMP) += bmp.o obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o -obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o +obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o efishell.o obj-$(CONFIG_CMD_BOOTMENU) += bootmenu.o obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o obj-$(CONFIG_CMD_BOOTZ) += bootz.o diff --git a/cmd/efishell.c b/cmd/efishell.c new file mode 100644 index 000000000000..abc8216c7bd6 --- /dev/null +++ b/cmd/efishell.c @@ -0,0 +1,673 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI Shell-like command + * + * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "efishell.h" + +DECLARE_GLOBAL_DATA_PTR; + +static void dump_var_data(char *data, unsigned long len) +{ + char *start, *end, *p; + unsigned long pos, count; + char hex[3], line[9]; + int i; + + end = data + len; + for (start = data, pos = 0; start < end; start += count, pos += count) { + count = end - start; + if (count > 16) + count = 16; + + /* count should be multiple of two */ + printf("%08lx: ", pos); + + /* in hex format */ + p = start; + for (i = 0; i < count / 2; p += 2, i++) + printf(" %c%c", *p, *(p + 1)); + for (; i < 8; i++) + printf(" "); + + /* in character format */ + p = start; + hex[2] = '\0'; + for (i = 0; i < count / 2; i++) { + hex[0] = *p++; + hex[1] = *p++; + line[i] = simple_strtoul(hex, 0, 16); + if (line[i] < 0x20 || line[i] > 0x7f) + line[i] = '.'; + } + line[i] = '\0'; + printf(" %s\n", line); + } +} + +/* + * From efi_variable.c, + * + * Mapping between EFI variables and u-boot variables: + * + * efi_$guid_$varname = {attributes}(type)value + */ +static int do_efi_dump_var(int argc, char * const argv[]) +{ + char regex[256]; + char * const regexlist[] = {regex}; + char *res = NULL, *start, *end; + int len; + + if (argc > 2) + return CMD_RET_USAGE; + + if (argc == 2) + snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_%s", argv[1]); + else + snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*"); + debug("%s:%d grep uefi var %s\n", __func__, __LINE__, regex); + + len = hexport_r(&env_htab, '\n', H_MATCH_REGEX | H_MATCH_KEY, + &res, 0, 1, regexlist); + + if (len < 0) + return CMD_RET_FAILURE; + + if (len > 0) { + end = res; + while (true) { + /* variable name */ + start = strchr(end, '_'); + if (!start) + break; + start = strchr(++start, '_'); + if (!start) + break; + end = strchr(++start, '='); + if (!end) + break; + printf("%.*s:", (int)(end - start), start); + end++; + + /* value */ + start = end; + end = strstr(start, "(blob)"); + if (!end) { + putc('\n'); + break; + } + end += 6; + printf(" %.*s\n", (int)(end - start), start); + + start = end; + end = strchr(start, '\n'); + if (!end) + break; + dump_var_data(start, end - start); + } + free(res); + + if (len < 2 && argc == 2) + printf("%s: not found\n", argv[1]); + } + + return CMD_RET_SUCCESS; +} + +static int append_value(char **bufp, unsigned long *sizep, char *data) +{ + char *tmp_buf = NULL, *new_buf = NULL, *value; + unsigned long len = 0; + + if (!strncmp(data, "=0x", 2)) { /* hexadecimal number */ + union { + u8 u8; + u16 u16; + u32 u32; + u64 u64; + } tmp_data; + unsigned long hex_value; + void *hex_ptr; + + data += 3; + len = strlen(data); + if ((len & 0x1)) /* not multiple of two */ + return -1; + + len /= 2; + if (len > 8) + return -1; + else if (len > 4) + len = 8; + else if (len > 2) + len = 4; + + /* convert hex hexadecimal number */ + if (strict_strtoul(data, 16, &hex_value) < 0) + return -1; + + tmp_buf = malloc(len); + if (!tmp_buf) + return -1; + + if (len == 1) { + tmp_data.u8 = hex_value; + hex_ptr = &tmp_data.u8; + } else if (len == 2) { + tmp_data.u16 = hex_value; + hex_ptr = &tmp_data.u16; + } else if (len == 4) { + tmp_data.u32 = hex_value; + hex_ptr = &tmp_data.u32; + } else { + tmp_data.u64 = hex_value; + hex_ptr = &tmp_data.u64; + } + memcpy(tmp_buf, hex_ptr, len); + value = tmp_buf; + + } else if (!strncmp(data, "=H", 2)) { /* hexadecimal-byte array */ + data += 2; + len = strlen(data); + if (len & 0x1) /* not multiple of two */ + return -1; + + len /= 2; + tmp_buf = malloc(len); + if (!tmp_buf) + return -1; + + if (hex2bin((u8 *)tmp_buf, data, len) < 0) + return -1; + + value = tmp_buf; + } else { /* string */ + if (!strncmp(data, "=\"", 2) || !strncmp(data, "=S\"", 3)) { + if (data[1] == '"') + data += 2; + else + data += 3; + value = data; + len = strlen(data) - 1; + if (data[len] != '"') + return -1; + } else { + value = data; + len = strlen(data); + } + } + + new_buf = realloc(*bufp, *sizep + len); + if (!new_buf) + goto out; + + memcpy(new_buf + *sizep, value, len); + *bufp = new_buf; + *sizep += len; + +out: + free(tmp_buf); + + return 0; +} + +static int do_efi_set_var(int argc, char * const argv[]) +{ + char *var_name, *value = NULL; + unsigned long size = 0; + u16 *var_name16, *p; + efi_guid_t guid; + efi_status_t ret; + + if (argc == 1) + return CMD_RET_SUCCESS; + + var_name = argv[1]; + if (argc == 2) { + /* remove */ + value = NULL; + size = 0; + } else { /* set */ + argc -= 2; + argv += 2; + + for ( ; argc > 0; argc--, argv++) + if (append_value(&value, &size, argv[0]) < 0) { + ret = CMD_RET_FAILURE; + goto out; + } + } + + var_name16 = malloc((strlen(var_name) + 1) * 2); + p = var_name16; + utf8_utf16_strncpy(&p, var_name, strlen(var_name) + 1); + + guid = efi_global_variable_guid; + ret = efi_set_variable(var_name16, &guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, size, value); + ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); +out: + return ret; +} + +static int do_efi_boot_add(int argc, char * const argv[]) +{ + int id; + char *endp; + char var_name[9]; + u16 var_name16[9], *p; + efi_guid_t guid; + size_t label_len, label_len16; + u16 *label; + struct efi_device_path *device_path = NULL, *file_path = NULL; + struct efi_load_option lo; + void *data = NULL; + unsigned long size; + int ret; + + if (argc < 6 || argc > 7) + return CMD_RET_USAGE; + + id = (int)simple_strtoul(argv[1], &endp, 0); + if (*endp != '\0' || id > 0xffff) + return CMD_RET_FAILURE; + + sprintf(var_name, "Boot%04X", id); + p = var_name16; + utf8_utf16_strncpy(&p, var_name, 9); + + guid = efi_global_variable_guid; + + /* attributes */ + lo.attributes = 0x1; /* always ACTIVE */ + + /* label */ + label_len = strlen(argv[2]); + label_len16 = utf8_utf16_strnlen(argv[2], label_len); + label = malloc((label_len16 + 1) * sizeof(u16)); + if (!label) + return CMD_RET_FAILURE; + lo.label = label; /* label will be changed below */ + utf8_utf16_strncpy(&label, argv[2], label_len); + + /* file path */ + ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path, + &file_path); + if (ret != EFI_SUCCESS) { + ret = CMD_RET_FAILURE; + goto out; + } + lo.file_path = file_path; + lo.file_path_length = efi_dp_size(file_path) + + sizeof(struct efi_device_path); /* for END */ + + /* optional data */ + lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]); + + size = efi_serialize_load_option(&lo, (u8 **)&data); + if (!size) { + ret = CMD_RET_FAILURE; + goto out; + } + + ret = efi_set_variable(var_name16, &guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, size, data); + ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); +out: + free(data); +#if 0 /* FIXME */ + free(device_path); + free(file_path); +#endif + free(lo.label); + return ret; +} + +static int do_efi_boot_rm(int argc, char * const argv[]) +{ + efi_guid_t guid; + int id, i; + char *endp; + char var_name[9]; + u16 var_name16[9]; + efi_status_t ret; + + if (argc == 1) + return CMD_RET_USAGE; + + guid = efi_global_variable_guid; + for (i = 1; i < argc; i++, argv++) { + id = (int)simple_strtoul(argv[1], &endp, 0); + if (*endp != '\0' || id > 0xffff) + return CMD_RET_FAILURE; + + sprintf(var_name, "Boot%04X", id); + utf8_utf16_strncpy((u16 **)&var_name16, var_name, 9); + + ret = efi_set_variable(var_name16, &guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); + if (ret) { + printf("cannot remove Boot%04X", id); + return CMD_RET_FAILURE; + } + } + + return CMD_RET_SUCCESS; +} + +static void show_efi_boot_opt_data(int id, void *data) +{ + struct efi_load_option lo; + char *label, *p; + size_t label_len16, label_len; + u16 *dp_str; + + efi_deserialize_load_option(&lo, data); + + label_len16 = u16_strlen(lo.label); + label_len = utf16_utf8_strnlen(lo.label, label_len16); + label = malloc(label_len + 1); + if (!label) + return; + p = label; + utf16_utf8_strncpy(&p, lo.label, label_len16); + + printf("Boot%04X:\n", id); + printf("\tattributes: %c%c%c (0x%08x)\n", + /* ACTIVE */ + lo.attributes & 0x1 ? 'A' : '-', + /* FORCE RECONNECT */ + lo.attributes & 0x2 ? 'R' : '-', + /* HIDDEN */ + lo.attributes & 0x8 ? 'H' : '-', + lo.attributes); + printf("\tlabel: %s\n", label); + + dp_str = efi_dp_str(lo.file_path); + printf("\tfile_path: %ls\n", dp_str); + efi_free_pool(dp_str); + + printf("\tdata: %s\n", lo.optional_data); + + free(label); +} + +static void show_efi_boot_opt(int id) +{ + char var_name[9]; + u16 var_name16[9], *p; + efi_guid_t guid; + void *data = NULL; + unsigned long size; + int ret; + + sprintf(var_name, "Boot%04X", id); + p = var_name16; + utf8_utf16_strncpy(&p, var_name, 9); + guid = efi_global_variable_guid; + + size = 0; + ret = efi_get_variable(var_name16, &guid, NULL, &size, NULL); + if (ret == (int)EFI_BUFFER_TOO_SMALL) { + data = malloc(size); + ret = efi_get_variable(var_name16, &guid, NULL, &size, data); + } + if (ret == EFI_SUCCESS) { + show_efi_boot_opt_data(id, data); + free(data); + } else if (ret == EFI_NOT_FOUND) { + printf("Boot%04X: not found\n", id); + } +} + +static int do_efi_boot_dump(int argc, char * const argv[]) +{ + char regex[256]; + char * const regexlist[] = {regex}; + char *variables = NULL, *boot, *value; + int len; + int id; + + if (argc > 1) + return CMD_RET_USAGE; + + snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_Boot[0-9A-F]+"); + + len = hexport_r(&env_htab, '\n', H_MATCH_REGEX | H_MATCH_KEY, + &variables, 0, 1, regexlist); + + if (!len) + return CMD_RET_SUCCESS; + + if (len < 0) + return CMD_RET_FAILURE; + + boot = variables; + while (*boot) { + value = strstr(boot, "Boot") + 4; + id = (int)simple_strtoul(value, NULL, 16); + show_efi_boot_opt(id); + boot = strchr(boot, '\n'); + if (!*boot) + break; + boot++; + } + free(variables); + + return CMD_RET_SUCCESS; +} + +static int show_efi_boot_order(void) +{ + efi_guid_t guid; + u16 *bootorder = NULL; + unsigned long size; + int num, i; + char var_name[9]; + u16 var_name16[9], *p16; + void *data; + struct efi_load_option lo; + char *label, *p; + size_t label_len16, label_len; + efi_status_t ret = CMD_RET_SUCCESS; + + guid = efi_global_variable_guid; + size = 0; + ret = efi_get_variable(L"BootOrder", &guid, NULL, &size, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + bootorder = malloc(size); + ret = efi_get_variable(L"BootOrder", &guid, NULL, &size, + bootorder); + } + if (ret != EFI_SUCCESS) { + printf("BootOrder not defined\n"); + return CMD_RET_SUCCESS; + } + + num = size / sizeof(u16); + for (i = 0; i < num; i++) { + sprintf(var_name, "Boot%04X", bootorder[i]); + p16 = var_name16; + utf8_utf16_strncpy(&p16, var_name, 9); + + size = 0; + ret = efi_get_variable(var_name16, &guid, NULL, &size, NULL); + if (ret != EFI_BUFFER_TOO_SMALL) { + printf("%2d: Boot%04X: (not defined)\n", + i + 1, bootorder[i]); + continue; + } + + data = malloc(size); + if (!data) { + ret = CMD_RET_FAILURE; + goto out; + } + ret = efi_get_variable(var_name16, &guid, NULL, &size, data); + if (ret != EFI_SUCCESS) { + free(data); + ret = CMD_RET_FAILURE; + goto out; + } + + efi_deserialize_load_option(&lo, data); + + label_len16 = u16_strlen(lo.label); + label_len = utf16_utf8_strnlen(lo.label, label_len16); + label = malloc(label_len + 1); + if (!label) { + free(data); + ret = CMD_RET_FAILURE; + goto out; + } + p = label; + utf16_utf8_strncpy(&p, lo.label, label_len16); + printf("%2d: Boot%04X: %s\n", i + 1, bootorder[i], label); + free(label); + + free(data); + } +out: + free(bootorder); + + return ret; +} + +static int do_efi_boot_order(int argc, char * const argv[]) +{ + u16 *bootorder = NULL; + unsigned long size; + int id, i; + char *endp; + efi_guid_t guid; + efi_status_t ret; + + if (argc == 1) + return show_efi_boot_order(); + + argc--; + argv++; + + size = argc * sizeof(u16); + bootorder = malloc(size); + if (!bootorder) + return CMD_RET_FAILURE; + + for (i = 0; i < argc; i++) { + id = (int)simple_strtoul(argv[i], &endp, 0); + if (*endp != '\0' || id > 0xffff) { + printf("invalid value: %s\n", argv[i]); + ret = CMD_RET_FAILURE; + goto out; + } + + bootorder[i] = (u16)id; + } + + guid = efi_global_variable_guid; + ret = efi_set_variable(L"BootOrder", &guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, size, bootorder); + ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); +out: + free(bootorder); + + return ret; +} + +static int do_efi_boot_opt(int argc, char * const argv[]) +{ + char *sub_command; + + if (argc < 2) + return CMD_RET_USAGE; + + argc--; argv++; + sub_command = argv[0]; + + if (!strcmp(sub_command, "add")) + return do_efi_boot_add(argc, argv); + else if (!strcmp(sub_command, "rm")) + return do_efi_boot_rm(argc, argv); + else if (!strcmp(sub_command, "dump")) + return do_efi_boot_dump(argc, argv); + else if (!strcmp(sub_command, "order")) + return do_efi_boot_order(argc, argv); + else + return CMD_RET_USAGE; +} + +/* Interpreter command to configure EFI environment */ +static int do_efishell(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + char *command; + efi_status_t r; + + if (argc < 2) + return CMD_RET_USAGE; + + argc--; argv++; + command = argv[0]; + + /* Initialize EFI drivers */ + r = efi_init_obj_list(); + if (r != EFI_SUCCESS) { + printf("Error: Cannot set up EFI drivers, r = %lu\n", + r & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + if (!strcmp(command, "boot")) + return do_efi_boot_opt(argc, argv); + else if (!strcmp(command, "dumpvar") || !strcmp(command, "dmpstore")) + return do_efi_dump_var(argc, argv); + else if (!strcmp(command, "setvar")) + return do_efi_set_var(argc, argv); + else + return CMD_RET_USAGE; +} + +#ifdef CONFIG_SYS_LONGHELP +static char efishell_help_text[] = + " - EFI Shell-like interface to configure EFI environment\n" + "\n" + "efishell boot add