From patchwork Wed Sep 13 22:05:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813637 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tyqY7LEP"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswkY3WRkz9sNw for ; Thu, 14 Sep 2017 08:07:17 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id EAAA0C225E2; Wed, 13 Sep 2017 22:06:11 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 2B2B3C2250A; Wed, 13 Sep 2017 22:06:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 91FC4C22534; Wed, 13 Sep 2017 22:05:57 +0000 (UTC) Received: from mail-qt0-f194.google.com (mail-qt0-f194.google.com [209.85.216.194]) by lists.denx.de (Postfix) with ESMTPS id 16273C223DA for ; Wed, 13 Sep 2017 22:05:54 +0000 (UTC) Received: by mail-qt0-f194.google.com with SMTP id b1so955243qtc.0 for ; Wed, 13 Sep 2017 15:05:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C8brqXExN7NxaVnn/oz5yvzer5LRFsZ1dCKpKCuxfPE=; b=tyqY7LEPxEDYuZqlY8P4V59dHn8cxJrMqVD+L1MI9Oazg4g9GMhNP7ZMK/PPutVfic A387l/PaQURAIynYP2oLUCh51yUVzs/k+NVeq2QVUP4NkzNKiqKcMEIbORpq/yKpck5R LVmwQ67k1DwPJ234IAR4NDSZkYnUyEoiP8/LAYTV9lnV9hZOeNNwZeg0DZTAel2gOv15 O0kxniHPzkltTDrO9x79ziL+AJj+Fka67Q9H5MbuG3d6WtwisUzFdoLOHatquBVy8JTm nIXzFsv3DsVmqjbBNnNdfb+DDVsc/TI59txzJ+etr3gVGW9Esj1IJ8L8FoCPmxeoca7W HOkw== 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; bh=C8brqXExN7NxaVnn/oz5yvzer5LRFsZ1dCKpKCuxfPE=; b=JcUKABbXhYDGpiFgb6UM5U96LGQmCTQ/38PD/zXeVt8N7yU20DrZPWgZyvdalIIqMH hj+69l3ddhuPlKAhAIRNrDLGHDVrCPkHxSkrmmzlHRGs7m9KvNi6b/N/08hsui8KXC39 DpXn7enyfrAvXWdDXSE7/XaUCx8C4/8XR8StY5hEQuvd9qAiiISjXPPMEjWvLAGZiruJ 7od8Al5DFUWsPtaSy94UTQfAUwB4gGYjaNvZo98qb6Z6ayHryKDGrmc6tebtC5HeBCue 1Tzt8KcUqEY+3p0P4LYAB4Ev8JmQXVDYZS5Xpm/lQtmnr+PRdEtmJYlkz1WLPHwu1NFe VEvg== X-Gm-Message-State: AHPjjUiKtHmu2syb47F16pR70q/vYhbLt+JVGXnR3DOXcDzSdbP8x2bC wmf5uMQE4p/iW9m21R8= X-Google-Smtp-Source: AOwi7QAI4ZXPFuTi2BNELdf6Yv/V5E4wY0fsGNcIIEwmw3DUL2zKYMByqLRtkKHcNC3krGhdKkSdAw== X-Received: by 10.200.52.232 with SMTP id x37mr29035974qtb.85.1505340352791; Wed, 13 Sep 2017 15:05:52 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id h58sm10265626qta.82.2017.09.13.15.05.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:05:51 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:24 -0400 Message-Id: <20170913220546.19560-2-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Petr Kulhavy , Heinrich Schuchardt , Alison Chaiken , Steve Rae , Maxime Ripard Subject: [U-Boot] [PATCH v3 01/21] part: move efi_guid_t 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Prep work for next patch. Signed-off-by: Rob Clark Reviewed-by: Heinrich Schuchardt --- include/efi.h | 4 ++++ include/part.h | 3 ++- include/part_efi.h | 4 ---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/efi.h b/include/efi.h index 02b78b31b1..87b0b43f20 100644 --- a/include/efi.h +++ b/include/efi.h @@ -28,6 +28,10 @@ struct efi_device_path; +typedef struct { + u8 b[16]; +} efi_guid_t; + #define EFI_BITS_PER_LONG BITS_PER_LONG /* diff --git a/include/part.h b/include/part.h index 86117a7ce5..b2e820ef8a 100644 --- a/include/part.h +++ b/include/part.h @@ -280,8 +280,9 @@ struct part_driver { #define U_BOOT_PART_TYPE(__name) \ ll_entry_declare(struct part_driver, __name, part_driver) -#if CONFIG_IS_ENABLED(EFI_PARTITION) #include + +#if CONFIG_IS_ENABLED(EFI_PARTITION) /* disk/part_efi.c */ /** * write_gpt_table() - Write the GUID Partition Table to disk diff --git a/include/part_efi.h b/include/part_efi.h index 317c044795..31e6bc6e14 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -58,10 +58,6 @@ /* linux/include/efi.h */ typedef u16 efi_char16_t; -typedef struct { - u8 b[16]; -} efi_guid_t; - /* based on linux/include/genhd.h */ struct partition { u8 boot_ind; /* 0x80 - active */ From patchwork Wed Sep 13 22:05:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813639 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UWmHfWUF"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswm33MzQz9ryQ for ; Thu, 14 Sep 2017 08:08:35 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1AFFAC2245A; Wed, 13 Sep 2017 22:06:42 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 4034EC2259B; Wed, 13 Sep 2017 22:06:29 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id EA81FC2256A; Wed, 13 Sep 2017 22:06:01 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 654EAC222F6 for ; Wed, 13 Sep 2017 22:05:57 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id f24so942178qte.5 for ; Wed, 13 Sep 2017 15:05:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bXVPZO0IiYE3zUISsLm4fk0OfB020ozBmqh5YtAiWL4=; b=UWmHfWUFyUi/AdRNXhVVNwD/LhpnENrwTnhXf99pJ11brofMcwGyJGWJLP+l5lC9fE ZmNBc1XD7Ge1mgPPWwEkjAsGCygzeulNTQvW4jx1i6svexBn8B3RSTNXhmiDrqu9VyCU FgFU2W0SPnK2qCLxn5UD+nd2/iTtNMh1UpR3WNX7erF2GpiGalV6xqmOzFg/eK/PD2Bc Dcrfk2lU4axYv+PbI8CCBKcax1R9H9B7YNllmS8YQqv3g7saEtna88xFG8eic1ZRs0ak Mr/9WpQvMTprgFnBolvNviQ2z7K60FuMYklPpPQefl5swjrmjmmwjGqIIVi5PMc/Xs+b u6jg== 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; bh=bXVPZO0IiYE3zUISsLm4fk0OfB020ozBmqh5YtAiWL4=; b=Lu1YR6eJAEjCTx9lg2cn2AD3qMaaxc03T9U2mWgcwXe8X+YwVDnF722Ql1489u34Pg EdP8st/eloiLx9TBP7LBCOoBH9BhYdcmue7KG19IpDhKhmy06lrE0xLV+OgUASqNAgo0 ZQWJy3ii4Z5mh8N3g0yEgJzXanmIqe19x5tfVDzdiT8pC9O6+omfp7jMI0fHOjS7m7wP 1uVlYtoY4mSlHmH8GqBDPchZHc0ga2ZABbUdR3Ejpg2Q4znHZ6odma0/vN5uXkaDtGFF 2AH5nwez2YVatY2VW3eKPnj9GUr20jyR9rmwf0RuFHJn6WQ7p2MZeURI01fQr1hGScig jhug== X-Gm-Message-State: AHPjjUg0aSZWhqlN9S4WJIVv2zV3JgvLoDKpJ0SxDdUPsC0phi8yQ4Pv 0gCjO3uNidRpKqxy66Y= X-Google-Smtp-Source: AOwi7QAMkBkMWaT9O/2vU2OSlrsql77Q5fgURwfvPay1s37VubMmen5z63JShS2NL/t7+0g3cbCpFA== X-Received: by 10.200.37.157 with SMTP id e29mr12160386qte.271.1505340356035; Wed, 13 Sep 2017 15:05:56 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id e39sm10445954qtb.67.2017.09.13.15.05.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:05:54 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:25 -0400 Message-Id: <20170913220546.19560-3-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Petr Kulhavy , Heinrich Schuchardt , Wenbin Song , Alison Chaiken , Peter Jones , Vincent Tinelli , Steve Rae , Maxime Ripard Subject: [U-Boot] [PATCH v3 02/21] part: extract MBR signature from partitions 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Peter Jones EFI client programs need the signature information from the partition table to determine the disk a partition is on, so we need to fill that in here. Signed-off-by: Peter Jones [separated from efi_loader part, and fixed build-errors for non- CONFIG_EFI_PARTITION case] Signed-off-by: Rob Clark Signed-off-by: Fabio Estevam --- disk/part_dos.c | 12 +++++++++--- disk/part_efi.c | 20 ++++++++++++++++++++ include/blk.h | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/disk/part_dos.c b/disk/part_dos.c index 7ede15ec26..850a538e83 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -89,14 +89,20 @@ static int test_block_type(unsigned char *buffer) static int part_test_dos(struct blk_desc *dev_desc) { - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); + ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz); - if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1) + if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) return -1; - if (test_block_type(buffer) != DOS_MBR) + if (test_block_type((unsigned char *)mbr) != DOS_MBR) return -1; + if (dev_desc->sig_type == SIG_TYPE_NONE && + mbr->unique_mbr_signature != 0) { + dev_desc->sig_type = SIG_TYPE_MBR; + dev_desc->mbr_sig = mbr->unique_mbr_signature; + } + return 0; } diff --git a/disk/part_efi.c b/disk/part_efi.c index 2973d52f6a..208bb14ee8 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -923,11 +923,19 @@ static int is_pmbr_valid(legacy_mbr * mbr) static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, gpt_header *pgpt_head, gpt_entry **pgpt_pte) { + ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz); + if (!dev_desc || !pgpt_head) { printf("%s: Invalid Argument(s)\n", __func__); return 0; } + /* Read MBR Header from device */ + if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) { + printf("*** ERROR: Can't read MBR header ***\n"); + return 0; + } + /* Read GPT Header from device */ if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) { printf("*** ERROR: Can't read GPT header ***\n"); @@ -937,6 +945,18 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) return 0; + if (dev_desc->sig_type == SIG_TYPE_NONE) { + efi_guid_t empty = {}; + if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) { + dev_desc->sig_type = SIG_TYPE_GUID; + memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid, + sizeof(empty)); + } else if (mbr->unique_mbr_signature != 0) { + dev_desc->sig_type = SIG_TYPE_MBR; + dev_desc->mbr_sig = mbr->unique_mbr_signature; + } + } + /* Read and allocate Partition Table Entries */ *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); if (*pgpt_pte == NULL) { diff --git a/include/blk.h b/include/blk.h index 1965812a9d..41b4d7efa8 100644 --- a/include/blk.h +++ b/include/blk.h @@ -8,6 +8,8 @@ #ifndef BLK_H #define BLK_H +#include + #ifdef CONFIG_SYS_64BIT_LBA typedef uint64_t lbaint_t; #define LBAFlength "ll" @@ -41,6 +43,17 @@ enum if_type { #define BLK_REV_SIZE 8 /* + * Identifies the partition table type (ie. MBR vs GPT GUID) signature + */ +enum sig_type { + SIG_TYPE_NONE, + SIG_TYPE_MBR, + SIG_TYPE_GUID, + + SIG_TYPE_COUNT /* Number of signature types */ +}; + +/* * With driver model (CONFIG_BLK) this is uclass platform data, accessible * with dev_get_uclass_platdata(dev) */ @@ -67,6 +80,11 @@ struct blk_desc { char vendor[BLK_VEN_SIZE + 1]; /* device vendor string */ char product[BLK_PRD_SIZE + 1]; /* device product number */ char revision[BLK_REV_SIZE + 1]; /* firmware revision */ + enum sig_type sig_type; /* Partition table signature type */ + union { + uint32_t mbr_sig; /* MBR integer signature */ + efi_guid_t guid_sig; /* GPT GUID Signature */ + }; #if CONFIG_IS_ENABLED(BLK) /* * For now we have a few functions which take struct blk_desc as a From patchwork Wed Sep 13 22:05:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813645 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GNXX2JoC"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswsV2TZ3z9sNw for ; Thu, 14 Sep 2017 08:13:17 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CC0FCC2261F; Wed, 13 Sep 2017 22:06:58 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 9120DC225AB; Wed, 13 Sep 2017 22:06:41 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 19711C2258E; Wed, 13 Sep 2017 22:06:04 +0000 (UTC) Received: from mail-qk0-f194.google.com (mail-qk0-f194.google.com [209.85.220.194]) by lists.denx.de (Postfix) with ESMTPS id 941D5C22534 for ; Wed, 13 Sep 2017 22:06:00 +0000 (UTC) Received: by mail-qk0-f194.google.com with SMTP id c69so937787qke.5 for ; Wed, 13 Sep 2017 15:06:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=czY6WGJALjtWSa/9yiEE+o7Vi2maM01LVTuVMqv+lKA=; b=GNXX2JoCj5hLIC/ZqHrwk3yrGWpsIG8FgiVlDbb+XSdJOVE5xxAhQxhsPWz5tm1j4V GNzFetKLyRiaGDYgjCk+oTFRk4AVIUswlZeHNt8I9DA0nNPYXmi5C3Mg8C3AglistLd1 AMywEGWu0kNYWT6SGoGrb+KrY64F6gvRSJbEQ9hhZkJiYieqjqnokmcTuclvOMorbv5T 57K29OUvwaJ/MBc8nLHbxeTcy8N5uKMfAAgZKRy+zyRMoYPrV8mRcx8wnzxqTYvjnl8T GuILZ9MtJHfuMv6s6lmeWoE55cQxR21SrIj3hkYFNFlwJYDsWQhNs0/bvooMscR4jYHa 8CAA== 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; bh=czY6WGJALjtWSa/9yiEE+o7Vi2maM01LVTuVMqv+lKA=; b=Mg5t31/7CAr+mQ+Fl7r/7L/WE7213xeSZ+tGv6apraiNWRA1kgvKDgg05tZpf14lgy JshaFJIfcifneQbRWGDUCGZ/KsKY2FEm86ZWWZwYN0XT60+9dcex07JdR0FxAhnML3y9 BTnrY3t8CfhzDP6HWFHSNF5ehRLf35BQJ9iT4DCQJitOh3fhTWlSIKbab3SpGcyfwILN I08/sOhMqes8CExMZnh2Q4zTay8/dzmCUBXnmuDzvq4Uhtwz4qPMScYMQG89Rl33WzOJ mVk2cOWHwmd01ngfw+JDXWqByQn2sI4sV5BS8JJpYD+u9bqyNuMLFFqjtR62W4Mf87xd l3EQ== X-Gm-Message-State: AHPjjUhbxookEyXyEYVObjJNW2FZUyRhsJtxg2osS4htU2aOclW3p0mL GcxcDTObjQ8KXKc0gTA= X-Google-Smtp-Source: AOwi7QDyuNnPOCgejgFDI+XLCF8dDPqlSuuRLrFTN0w0zCFSQVy+hTVGhQce3zzKr3lmIrXy2cA6aA== X-Received: by 10.55.163.201 with SMTP id m192mr25312833qke.27.1505340359227; Wed, 13 Sep 2017 15:05:59 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id l11sm10122669qke.19.2017.09.13.15.05.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:05:58 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:26 -0400 Message-Id: <20170913220546.19560-4-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 03/21] efi: add some missing __packed 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" All of the device-path related structures should be packed. UEFI defines the device-path as a byte-aligned data structure. Signed-off-by: Rob Clark --- include/efi_api.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index ec1b321e8e..175341348e 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -284,11 +284,11 @@ struct efi_device_path { u8 type; u8 sub_type; u16 length; -}; +} __packed; struct efi_mac_addr { u8 addr[32]; -}; +} __packed; #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b @@ -297,7 +297,7 @@ struct efi_device_path_mac_addr { struct efi_device_path dp; struct efi_mac_addr mac; u8 if_type; -}; +} __packed; #define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04 # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 @@ -305,7 +305,7 @@ struct efi_device_path_mac_addr { struct efi_device_path_file_path { struct efi_device_path dp; u16 str[32]; -}; +} __packed; #define BLOCK_IO_GUID \ EFI_GUID(0x964e5b21, 0x6459, 0x11d2, \ From patchwork Wed Sep 13 22:05:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813638 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nDmTdn7A"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswll3qT2z9sNV for ; Thu, 14 Sep 2017 08:08:19 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 3B804C22617; Wed, 13 Sep 2017 22:06:27 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 0B348C223DA; Wed, 13 Sep 2017 22:06:14 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id CC969C21EC9; Wed, 13 Sep 2017 22:06:06 +0000 (UTC) Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by lists.denx.de (Postfix) with ESMTPS id 56FB6C2222A for ; Wed, 13 Sep 2017 22:06:03 +0000 (UTC) Received: by mail-qk0-f195.google.com with SMTP id c69so937828qke.5 for ; Wed, 13 Sep 2017 15:06:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0HLerYTmPnGMALX7+280qm7VekjKZjPCzmGTASJHnXA=; b=nDmTdn7AenrfWBx4p0KVOn0mIRtwRgSZOEox7OJzOHElTuPPXjbrrXnEP07+7d2d68 cQSRHfYjLKSecuudJcjlHgyBylULSlBr4drAx01oDrB9/wckGmYeYuWjMrzeyzNdvTr3 YngiF79PIm6XGVhRZhktcPzWYUfpIUXtzBr59RUsi8OYlYfZR2oIw0GaG/56to1kpnwP Sg6IJ1zZ7vnQbx5MAsn27iRt6INeuJKFAypbRgVxpz5Y3rDoD97SReSleTdK0PSTTNkp Whm2C6M3bQWbaCWvnvNcrgGWMCSljjRR7bjaEzh9AzkiZs0LQj752MI1t8xrmFnfgiP8 ogrg== 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; bh=0HLerYTmPnGMALX7+280qm7VekjKZjPCzmGTASJHnXA=; b=cRzK0EZl2Xcti0lq9UM1pzcYYhxal6yGz+g3NqxFEZvl9VUkgWcyfcPOPr6MnqZn6C 2KPnBcSL9yoHlR9dStlGcxUxwnPBU0IgXDqQ13UtMflTEm7Iqj0YTZNux6e01iS+3OQU +lPBn4ZgpAqJXbgJ6aGU6iaJZVTRPFCkv5HKhBKvWgwCX+2fhjJu563c/wanafudqSMD 2icWWhpgp5O8ZfjVdnyZRCv+2ZTaOBMTmbSDAW5aH0EHpS9RnPfDCWiz4Ps7IE2s9YNY 3mxretx9A9+gZmYrbBlfeAoEwRlqCRWTOR2QCYLfkAvTG0c6c81SKO3jrZP356Qlye2F sIYg== X-Gm-Message-State: AHPjjUjGyH6LH2AfAEbaEs8aQJVa8hLyVNBPXc+jmFEU2htppOTG91id qnvVJUEjuTrXwHeY+UQ= X-Google-Smtp-Source: AOwi7QDTOWgCmUWftkvOsxTkRfKo0RDW3I7DpgZ4MsYzUlR/oIv3O3nIze0GF/IpgShLSQHMmOSl9A== X-Received: by 10.55.22.146 with SMTP id 18mr20697qkw.112.1505340362042; Wed, 13 Sep 2017 15:06:02 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id w31sm10318660qtg.48.2017.09.13.15.06.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:01 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:27 -0400 Message-Id: <20170913220546.19560-5-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 04/21] efi: add some more device path structures 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Peter Jones Signed-off-by: Peter Jones Signed-off-by: Rob Clark --- include/efi_api.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/include/efi_api.h b/include/efi_api.h index 175341348e..b761cf4822 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -290,8 +290,38 @@ struct efi_mac_addr { u8 addr[32]; } __packed; +#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01 +# define DEVICE_PATH_SUB_TYPE_VENDOR 0x04 + +struct efi_device_path_vendor { + struct efi_device_path dp; + efi_guid_t guid; + u8 vendor_data[]; +} __packed; + +#define DEVICE_PATH_TYPE_ACPI_DEVICE 0x02 +# define DEVICE_PATH_SUB_TYPE_ACPI_DEVICE 0x01 + +#define EFI_PNP_ID(ID) (u32)(((ID) << 16) | 0x41D0) +#define EISA_PNP_ID(ID) EFI_PNP_ID(ID) + +struct efi_device_path_acpi_path { + struct efi_device_path dp; + u32 hid; + u32 uid; +} __packed; + #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 +# define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05 # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b +# define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a +# define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d + +struct efi_device_path_usb { + struct efi_device_path dp; + u8 parent_port_number; + u8 usb_interface; +} __packed; struct efi_device_path_mac_addr { struct efi_device_path dp; @@ -299,9 +329,33 @@ struct efi_device_path_mac_addr { u8 if_type; } __packed; +struct efi_device_path_sd_mmc_path { + struct efi_device_path dp; + u8 slot_number; +} __packed; + #define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04 +# define DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH 0x01 +# define DEVICE_PATH_SUB_TYPE_CDROM_PATH 0x02 # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 +struct efi_device_path_hard_drive_path { + struct efi_device_path dp; + u32 partition_number; + u64 partition_start; + u64 partition_end; + u8 partition_signature[16]; + u8 partmap_type; + u8 signature_type; +} __packed; + +struct efi_device_path_cdrom_path { + struct efi_device_path dp; + u32 boot_entry; + u64 partition_start; + u64 partition_end; +} __packed; + struct efi_device_path_file_path { struct efi_device_path dp; u16 str[32]; From patchwork Wed Sep 13 22:05:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813641 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ckosl1Jy"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswmm6vCMz9sNV for ; Thu, 14 Sep 2017 08:09:12 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 8D63CC2208F; Wed, 13 Sep 2017 22:07:32 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 8D0C1C2257F; Wed, 13 Sep 2017 22:07:02 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A192EC21F60; Wed, 13 Sep 2017 22:06:11 +0000 (UTC) Received: from mail-qk0-f196.google.com (mail-qk0-f196.google.com [209.85.220.196]) by lists.denx.de (Postfix) with ESMTPS id D7629C2258B for ; Wed, 13 Sep 2017 22:06:06 +0000 (UTC) Received: by mail-qk0-f196.google.com with SMTP id r66so942216qke.4 for ; Wed, 13 Sep 2017 15:06:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6tVjFEhkD+n/lPFRMHZEy/F0zK8ykCSr4pMVfxeeooI=; b=Ckosl1JygCTrKrFCpK1SKR9Y7JdSIhrnECYFjQWlau7G29de1gg5ZsaXJtZxWBmgad FYi99Euaie8d/GP42CHbVo5q+/YA5dMaBmL83s7BHGGc0I7Wf0Y9G0ok/CSxeKD64sjT eGDg3O8nyNV0fXLs44BPco1FMgIS+BqO1foEn12c4KQqyvGQhDjFzNivjYxe5fWcTfYq /Q1tVTRH0pWrbZSBFYREI8i5eOEYu9bD0YlokatzVF4OnlrI/cKRGf0NZwy7h3iB0pA9 IONEETqT43HD1sIuUH6CeP9K8WsmYKC+ccYfuGoDv4Hy9Xf/xE505SxZzL7CYgn22r8P Y7Tg== 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; bh=6tVjFEhkD+n/lPFRMHZEy/F0zK8ykCSr4pMVfxeeooI=; b=WPxhVnu2iFVLD9PteTVFqaxAMU/wugPv9r/dl3lDi3T732mPdnCsNwGAmD624O4Aeg 6ExgrwYVcfmbbrRkiY6/3IYVEpBG/ygRoZaLJSrUH1l7pENrSCsc7jHMHm5Rdbm4vha5 M12O1ynYBsZhwixsNt3vTbYOHb+Tgb2/uq8CQX4TyF/mM51CtvOW7KN7TTIxf+d1K5Sf 3Y1fSICBPrDU4i9zbwtOCf53gUhxXNqYmCIooYNbvajZV5xAZ+NpaIm2jSrdySjwO67m f7oHtLTT+YHCiGp1gEPpPCn5E9HsQKSGrBUXADEtIJ3FcBcdjsIJFAPV94KLrmjBo8EX UTLQ== X-Gm-Message-State: AHPjjUi0NWt7Xzs829jZOhnnsI09SJ7wcJ/qr6rslgG8VH5TeifjnLiV Znda7ig+/nrDklUoA/M= X-Google-Smtp-Source: AOwi7QAQseY21mJlyIibSNUaX+KKJunPBMpifKKfsTwEK+6YTK35yUnbaOkckPvxNeQAplHgjbRNNw== X-Received: by 10.55.16.207 with SMTP id 76mr20281qkq.120.1505340365344; Wed, 13 Sep 2017 15:06:05 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id w5sm1595097qkd.47.2017.09.13.15.06.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:04 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:28 -0400 Message-Id: <20170913220546.19560-6-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 05/21] efi_loader: add device-path utils 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Helpers to construct device-paths from devices, partitions, files, and for parsing and manipulating device-paths. For non-legacy devices, this will use u-boot's device-model to construct device-paths which include bus hierarchy to construct device-paths. For legacy devices we still fake it, but slightly more convincingly. Signed-off-by: Rob Clark --- include/efi_api.h | 10 + include/efi_loader.h | 26 ++ lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_boottime.c | 13 +- lib/efi_loader/efi_device_path.c | 563 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 611 insertions(+), 3 deletions(-) create mode 100644 lib/efi_loader/efi_device_path.c diff --git a/include/efi_api.h b/include/efi_api.h index b761cf4822..4e27c82129 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -314,6 +314,7 @@ struct efi_device_path_acpi_path { #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 # define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05 # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b +# define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f # define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a # define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d @@ -329,6 +330,15 @@ struct efi_device_path_mac_addr { u8 if_type; } __packed; +struct efi_device_path_usb_class { + struct efi_device_path dp; + u16 vendor_id; + u16 product_id; + u8 device_class; + u8 device_subclass; + u8 device_protocol; +} __packed; + struct efi_device_path_sd_mmc_path { struct efi_device_path dp; u8 slot_number; diff --git a/include/efi_loader.h b/include/efi_loader.h index 1179234f68..d052b03ab7 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -197,6 +197,32 @@ extern void *efi_bounce_buffer; #define EFI_LOADER_BOUNCE_BUFFER_SIZE (64 * 1024 * 1024) #endif + +struct efi_device_path *efi_dp_next(const struct efi_device_path *dp); +int efi_dp_match(struct efi_device_path *a, struct efi_device_path *b); +struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, + struct efi_device_path **rem); +unsigned efi_dp_size(const struct efi_device_path *dp); +struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp); +struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1, + const struct efi_device_path *dp2); +struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, + const struct efi_device_path *node); + + +struct efi_device_path *efi_dp_from_dev(struct udevice *dev); +struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); +struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, + const char *path); +struct efi_device_path *efi_dp_from_eth(void); +void efi_dp_split_file_path(struct efi_device_path *full_path, + struct efi_device_path **device_path, + struct efi_device_path **file_path); + +#define EFI_DP_TYPE(_dp, _type, _subtype) \ + (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \ + ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype)) + /* Convert strings from normal C strings to uEFI strings */ static inline void ascii2unicode(u16 *unicode, const char *ascii) { diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 30bf343a36..f35e5ce8a8 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -15,7 +15,7 @@ always := $(efiprogs-y) obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o -obj-y += efi_memory.o efi_device_path_to_text.o +obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 43f32385fa..b962b62a97 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -665,8 +665,17 @@ static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol, struct efi_device_path **device_path, efi_handle_t *device) { - EFI_ENTRY("%p, %p, %p", protocol, device_path, device); - return EFI_EXIT(EFI_NOT_FOUND); + struct efi_object *efiobj; + + EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device); + + efiobj = efi_dp_find_obj(*device_path, device_path); + if (!efiobj) + return EFI_EXIT(EFI_NOT_FOUND); + + *device = efiobj->handle; + + return EFI_EXIT(EFI_SUCCESS); } /* Collapses configuration table entries, removing index i */ diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c new file mode 100644 index 0000000000..5d5c3b3464 --- /dev/null +++ b/lib/efi_loader/efi_device_path.c @@ -0,0 +1,563 @@ +/* + * EFI device path from u-boot device-model mapping + * + * (C) Copyright 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* template END node: */ +static const struct efi_device_path END = { + .type = DEVICE_PATH_TYPE_END, + .sub_type = DEVICE_PATH_SUB_TYPE_END, + .length = sizeof(END), +}; + +#define U_BOOT_GUID \ + EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \ + 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b) + +/* template ROOT node: */ +static const struct efi_device_path_vendor ROOT = { + .dp = { + .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, + .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, + .length = sizeof(ROOT), + }, + .guid = U_BOOT_GUID, +}; + +static void *dp_alloc(size_t sz) +{ + void *buf; + + if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) != EFI_SUCCESS) + return NULL; + + return buf; +} + +/* + * Iterate to next block in device-path, terminating (returning NULL) + * at /End* node. + */ +struct efi_device_path *efi_dp_next(const struct efi_device_path *dp) +{ + if (dp == NULL) + return NULL; + if (dp->type == DEVICE_PATH_TYPE_END) + return NULL; + dp = ((void *)dp) + dp->length; + if (dp->type == DEVICE_PATH_TYPE_END) + return NULL; + return (struct efi_device_path *)dp; +} + +/* + * Compare two device-paths, stopping when the shorter of the two hits + * an End* node. This is useful to, for example, compare a device-path + * representing a device with one representing a file on the device, or + * a device with a parent device. + */ +int efi_dp_match(struct efi_device_path *a, struct efi_device_path *b) +{ + while (1) { + int ret; + + ret = memcmp(&a->length, &b->length, sizeof(a->length)); + if (ret) + return ret; + + ret = memcmp(a, b, a->length); + if (ret) + return ret; + + a = efi_dp_next(a); + b = efi_dp_next(b); + + if (!a || !b) + return 0; + } +} + + +/* + * See UEFI spec (section 3.1.2, about short-form device-paths.. + * tl;dr: we can have a device-path that starts with a USB WWID + * or USB Class node, and a few other cases which don't encode + * the full device path with bus hierarchy: + * + * - MESSAGING:USB_WWID + * - MESSAGING:USB_CLASS + * - MEDIA:FILE_PATH + * - MEDIA:HARD_DRIVE + * - MESSAGING:URI + */ +static struct efi_device_path *shorten_path(struct efi_device_path *dp) +{ + while (dp) { + /* + * TODO: Add MESSAGING:USB_WWID and MESSAGING:URI.. + * in practice fallback.efi just uses MEDIA:HARD_DRIVE + * so not sure when we would see these other cases. + */ + if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) || + EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) || + EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH)) + return dp; + + dp = efi_dp_next(dp); + } + + return dp; +} + +static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path, + struct efi_device_path **rem) +{ + struct efi_object *efiobj; + + list_for_each_entry(efiobj, &efi_obj_list, link) { + int i; + + for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { + struct efi_handler *handler = &efiobj->protocols[i]; + struct efi_device_path *obj_dp; + + if (!handler->guid) + break; + + if (guidcmp(handler->guid, &efi_guid_device_path)) + continue; + + obj_dp = handler->protocol_interface; + + do { + if (efi_dp_match(dp, obj_dp) == 0) { + if (rem) { + *rem = ((void *)dp) + + efi_dp_size(obj_dp); + } + return efiobj; + } + + obj_dp = shorten_path(efi_dp_next(obj_dp)); + } while (short_path && obj_dp); + } + } + + return NULL; +} + + +/* + * Find an efiobj from device-path, if 'rem' is not NULL, returns the + * remaining part of the device path after the matched object. + */ +struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, + struct efi_device_path **rem) +{ + struct efi_object *efiobj; + + efiobj = find_obj(dp, false, rem); + + if (!efiobj) + efiobj = find_obj(dp, true, rem); + + return efiobj; +} + +/* return size not including End node: */ +unsigned efi_dp_size(const struct efi_device_path *dp) +{ + unsigned sz = 0; + + while (dp) { + sz += dp->length; + dp = efi_dp_next(dp); + } + + return sz; +} + +struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) +{ + struct efi_device_path *ndp; + unsigned sz = efi_dp_size(dp) + sizeof(END); + + if (!dp) + return NULL; + + ndp = dp_alloc(sz); + memcpy(ndp, dp, sz); + + return ndp; +} + +struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1, + const struct efi_device_path *dp2) +{ + struct efi_device_path *ret; + + if (!dp1) { + ret = efi_dp_dup(dp2); + } else if (!dp2) { + ret = efi_dp_dup(dp1); + } else { + /* both dp1 and dp2 are non-null */ + unsigned sz1 = efi_dp_size(dp1); + unsigned sz2 = efi_dp_size(dp2); + void *p = dp_alloc(sz1 + sz2 + sizeof(END)); + memcpy(p, dp1, sz1); + memcpy(p + sz1, dp2, sz2); + memcpy(p + sz1 + sz2, &END, sizeof(END)); + ret = p; + } + + return ret; +} + +struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, + const struct efi_device_path *node) +{ + struct efi_device_path *ret; + + if (!node && !dp) { + ret = efi_dp_dup(&END); + } else if (!node) { + ret = efi_dp_dup(dp); + } else if (!dp) { + unsigned sz = node->length; + void *p = dp_alloc(sz + sizeof(END)); + memcpy(p, node, sz); + memcpy(p + sz, &END, sizeof(END)); + ret = p; + } else { + /* both dp and node are non-null */ + unsigned sz = efi_dp_size(dp); + void *p = dp_alloc(sz + node->length + sizeof(END)); + memcpy(p, dp, sz); + memcpy(p + sz, node, node->length); + memcpy(p + sz + node->length, &END, sizeof(END)); + ret = p; + } + + return ret; +} + +#ifdef CONFIG_DM +/* size of device-path not including END node for device and all parents + * up to the root device. + */ +static unsigned dp_size(struct udevice *dev) +{ + if (!dev || !dev->driver) + return sizeof(ROOT); + + switch (dev->driver->id) { + case UCLASS_ROOT: + case UCLASS_SIMPLE_BUS: + /* stop traversing parents at this point: */ + return sizeof(ROOT); + case UCLASS_MMC: + return dp_size(dev->parent) + + sizeof(struct efi_device_path_sd_mmc_path); + case UCLASS_MASS_STORAGE: + case UCLASS_USB_HUB: + return dp_size(dev->parent) + + sizeof(struct efi_device_path_usb_class); + default: + /* just skip over unknown classes: */ + return dp_size(dev->parent); + } +} + +static void *dp_fill(void *buf, struct udevice *dev) +{ + if (!dev || !dev->driver) + return buf; + + switch (dev->driver->id) { + case UCLASS_ROOT: + case UCLASS_SIMPLE_BUS: { + /* stop traversing parents at this point: */ + struct efi_device_path_vendor *vdp = buf; + *vdp = ROOT; + return &vdp[1]; + } +#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC) + case UCLASS_MMC: { + struct efi_device_path_sd_mmc_path *sddp = + dp_fill(buf, dev->parent); + struct mmc *mmc = mmc_get_mmc_dev(dev); + struct blk_desc *desc = mmc_get_blk_desc(mmc); + + sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + sddp->dp.sub_type = (desc->if_type == IF_TYPE_MMC) ? + DEVICE_PATH_SUB_TYPE_MSG_MMC : + DEVICE_PATH_SUB_TYPE_MSG_SD; + sddp->dp.length = sizeof(*sddp); + sddp->slot_number = dev->seq; + + return &sddp[1]; + } +#endif + case UCLASS_MASS_STORAGE: + case UCLASS_USB_HUB: { + struct efi_device_path_usb_class *udp = + dp_fill(buf, dev->parent); + struct usb_device *udev = dev_get_parent_priv(dev); + struct usb_device_descriptor *desc = &udev->descriptor; + + udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS; + udp->dp.length = sizeof(*udp); + udp->vendor_id = desc->idVendor; + udp->product_id = desc->idProduct; + udp->device_class = desc->bDeviceClass; + udp->device_subclass = desc->bDeviceSubClass; + udp->device_protocol = desc->bDeviceProtocol; + + return &udp[1]; + } + default: + debug("unhandled device class: %s (%u)\n", + dev->name, dev->driver->id); + return dp_fill(buf, dev->parent); + } +} + +/* Construct a device-path from a device: */ +struct efi_device_path *efi_dp_from_dev(struct udevice *dev) +{ + void *buf, *start; + + start = buf = dp_alloc(dp_size(dev) + sizeof(END)); + buf = dp_fill(buf, dev); + *((struct efi_device_path *)buf) = END; + + return start; +} +#endif + +static unsigned dp_part_size(struct blk_desc *desc, int part) +{ + unsigned dpsize; + +#ifdef CONFIG_BLK + dpsize = dp_size(desc->bdev->parent); +#else + dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb); +#endif + + if (part == 0) /* the actual disk, not a partition */ + return dpsize; + + if (desc->part_type == PART_TYPE_ISO) + dpsize += sizeof(struct efi_device_path_cdrom_path); + else + dpsize += sizeof(struct efi_device_path_hard_drive_path); + + return dpsize; +} + +static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) +{ + disk_partition_t info; + +#ifdef CONFIG_BLK + buf = dp_fill(buf, desc->bdev->parent); +#else + /* + * We *could* make a more accurate path, by looking at if_type + * and handling all the different cases like we do for non- + * legacy (ie CONFIG_BLK=y) case. But most important thing + * is just to have a unique device-path for if_type+devnum. + * So map things to a fictional USB device: + */ + struct efi_device_path_usb *udp; + + memcpy(buf, &ROOT, sizeof(ROOT)); + buf += sizeof(ROOT); + + udp = buf; + udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB; + udp->dp.length = sizeof(*udp); + udp->parent_port_number = desc->if_type; + udp->usb_interface = desc->devnum; + buf = &udp[1]; +#endif + + if (part == 0) /* the actual disk, not a partition */ + return buf; + + part_get_info(desc, part, &info); + + if (desc->part_type == PART_TYPE_ISO) { + struct efi_device_path_cdrom_path *cddp = buf; + + cddp->boot_entry = part - 1; + cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH; + cddp->dp.length = sizeof(*cddp); + cddp->partition_start = info.start; + cddp->partition_end = info.size; + + buf = &cddp[1]; + } else { + struct efi_device_path_hard_drive_path *hddp = buf; + + hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH; + hddp->dp.length = sizeof(*hddp); + hddp->partition_number = part - 1; + hddp->partition_start = info.start; + hddp->partition_end = info.size; + if (desc->part_type == PART_TYPE_EFI) + hddp->partmap_type = 2; + else + hddp->partmap_type = 1; + hddp->signature_type = desc->sig_type; + if (hddp->signature_type != 0) + memcpy(hddp->partition_signature, &desc->guid_sig, + sizeof(hddp->partition_signature)); + + buf = &hddp[1]; + } + + return buf; +} + + +/* Construct a device-path from a partition on a blk device: */ +struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part) +{ + void *buf, *start; + + start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END)); + + buf = dp_part_fill(buf, desc, part); + + *((struct efi_device_path *)buf) = END; + + return start; +} + +/* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */ +static void path_to_uefi(u16 *uefi, const char *path) +{ + while (*path) { + char c = *(path++); + if (c == '/') + c = '\\'; + *(uefi++) = c; + } + *uefi = '\0'; +} + +/* + * If desc is NULL, this creates a path with only the file component, + * otherwise it creates a full path with both device and file components + */ +struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, + const char *path) +{ + struct efi_device_path_file_path *fp; + void *buf, *start; + unsigned dpsize = 0, fpsize; + + if (desc) + dpsize = dp_part_size(desc, part); + + fpsize = sizeof(struct efi_device_path) + 2 * (strlen(path) + 1); + dpsize += fpsize; + + start = buf = dp_alloc(dpsize + sizeof(END)); + + if (desc) + buf = dp_part_fill(buf, desc, part); + + /* add file-path: */ + fp = buf; + fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; + fp->dp.length = fpsize; + path_to_uefi(fp->str, path); + buf += fpsize; + + *((struct efi_device_path *)buf) = END; + + return start; +} + +#ifdef CONFIG_NET +struct efi_device_path *efi_dp_from_eth(void) +{ + struct efi_device_path_mac_addr *ndp; + void *buf, *start; + unsigned dpsize = 0; + + assert(eth_get_dev()); + +#ifdef CONFIG_DM_ETH + dpsize += dp_size(eth_get_dev()); +#else + dpsize += sizeof(ROOT); +#endif + dpsize += sizeof(*ndp); + + start = buf = dp_alloc(dpsize + sizeof(END)); + +#ifdef CONFIG_DM_ETH + buf = dp_fill(buf, eth_get_dev()); +#else + memcpy(buf, &ROOT, sizeof(ROOT)); + buf += sizeof(ROOT); +#endif + + ndp = buf; + ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR; + ndp->dp.length = sizeof(*ndp); + memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN); + buf = &ndp[1]; + + *((struct efi_device_path *)buf) = END; + + return start; +} +#endif + +/* + * Helper to split a full device path (containing both device and file + * parts) into it's constituent parts. + */ +void efi_dp_split_file_path(struct efi_device_path *full_path, + struct efi_device_path **device_path, + struct efi_device_path **file_path) +{ + struct efi_device_path *p, *dp, *fp; + + dp = efi_dp_dup(full_path); + p = dp; + while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) + p = efi_dp_next(p); + fp = efi_dp_dup(p); + + p->type = DEVICE_PATH_TYPE_END; + p->sub_type = DEVICE_PATH_SUB_TYPE_END; + p->length = sizeof(*p); + + *device_path = dp; + *file_path = fp; +} From patchwork Wed Sep 13 22:05:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813650 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="giMsnDfx"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswxt3KV5z9s76 for ; Thu, 14 Sep 2017 08:17:05 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id AEB13C22545; Wed, 13 Sep 2017 22:11:11 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 11236C225AC; Wed, 13 Sep 2017 22:08:32 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 984BFC225AD; Wed, 13 Sep 2017 22:06:13 +0000 (UTC) Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by lists.denx.de (Postfix) with ESMTPS id 04DFAC2258E for ; Wed, 13 Sep 2017 22:06:10 +0000 (UTC) Received: by mail-qk0-f195.google.com with SMTP id r66so942338qke.4 for ; Wed, 13 Sep 2017 15:06:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2JftUygffnM3ZyCQ7153jJthYKh2+pbQzFD4QOPpFJA=; b=giMsnDfxWFJeeNnZaB8qV04Z9ul9hHMbcthj3JLgpeTv6poyD7NdhfpdZIXh1l03+b wU5leocJtNL+ljMuB96Oec4GF3MdsAbE05TGhliUXZUYAUxdwWNqqGkhg9WKNP5AtVbE +780b+Bm/MAcE1V9hYwgYG37grvgXYxHl0UQ9KM8ccSEttBqDU5248xHNjowB/LIHXo/ LsggWXiMQ+ltiUHfWh5YSjachsGQZrvuIcO/NEJf1Y9pCKpbCm3HI8Ffu73KS0U63B/Z KUCH3tAM2FCyB5sDbNvJ0lkeKe9KinWlh40Wcc3/RbJ3PW6tDL0ouade4dY44n86c/vJ VGAA== 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; bh=2JftUygffnM3ZyCQ7153jJthYKh2+pbQzFD4QOPpFJA=; b=rpJCWehBPGybuKEmMOGO7gI5IHdQDOXUgPBDpM0qWTHeeJKNLzHsDVSQkJ5xFMZE3E QJcpGfsHgRKraj6wpLlNOJtQ8KCIfY4GC0t9b15WubK0zlaju6D5rqvKrMIQ6bHNCv3T BrJ1hVBHCj8esVu0NoqnngFwklUHg4qbnYIDeh5ysjwsbFGsptKEGEmObMekkZ3/S55N BoGyD3d2P/6CAsp10lCruvqLGu8S537nTwNklCyiIKDpjP4nCp+LOGnvJ8qUJ08D5B0L etXU9jdPsGINSXe7pymwmjjoxtNAs3wuqleO4rI1g/5znVyqc1Kv6fCkJ17t8somprS7 M3rw== X-Gm-Message-State: AHPjjUiof1JCkJ+kIPyCF/F0ZZeLdXKFg3/v47N9SLxe05yui9Xc+loX 68Nxo7Ka/yyPzyCREZo= X-Google-Smtp-Source: AOwi7QBfMW0I99KZ6dhLaFoMN0GQxMfYi6t2uHtNR/g6xqMttBpzlI2KnTe8cKN4ZL8tWM5Xy3pXFg== X-Received: by 10.55.7.1 with SMTP id 1mr26108615qkh.175.1505340368784; Wed, 13 Sep 2017 15:06:08 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id 36sm10602754qtz.89.2017.09.13.15.06.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:07 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:29 -0400 Message-Id: <20170913220546.19560-7-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 06/21] efi_loader: drop redundant efi_device_path_protocol 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This is really the same thing as the efi_device_path struct. Signed-off-by: Rob Clark --- include/efi_api.h | 12 ++---------- lib/efi_loader/efi_device_path_to_text.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 4e27c82129..ac58fd58de 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -487,22 +487,14 @@ struct efi_console_control_protocol EFI_GUID(0x8b843e20, 0x8132, 0x4852, \ 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c) -struct efi_device_path_protocol -{ - uint8_t type; - uint8_t sub_type; - uint16_t length; - uint8_t data[]; -}; - struct efi_device_path_to_text_protocol { uint16_t *(EFIAPI *convert_device_node_to_text)( - struct efi_device_path_protocol *device_node, + struct efi_device_path *device_node, bool display_only, bool allow_shortcuts); uint16_t *(EFIAPI *convert_device_path_to_text)( - struct efi_device_path_protocol *device_path, + struct efi_device_path *device_path, bool display_only, bool allow_shortcuts); }; diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 4b2f43f0c8..f9d071ac50 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -16,7 +16,7 @@ const efi_guid_t efi_guid_device_path_to_text_protocol = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; static uint16_t *efi_convert_device_node_to_text( - struct efi_device_path_protocol *device_node, + struct efi_device_path *device_node, bool display_only, bool allow_shortcuts) { @@ -55,15 +55,18 @@ static uint16_t *efi_convert_device_node_to_text( break; case DEVICE_PATH_TYPE_MEDIA_DEVICE: switch (device_node->sub_type) { - case DEVICE_PATH_SUB_TYPE_FILE_PATH: + case DEVICE_PATH_SUB_TYPE_FILE_PATH: { + struct efi_device_path_file_path *fp = + (struct efi_device_path_file_path *)device_node; buffer_size = device_node->length - 4; r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size, (void **) &buffer); if (r != EFI_SUCCESS) return NULL; - memcpy(buffer, device_node->data, buffer_size); + memcpy(buffer, fp->str, buffer_size); break; } + } break; } @@ -89,7 +92,7 @@ static uint16_t *efi_convert_device_node_to_text( } static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( - struct efi_device_path_protocol *device_node, + struct efi_device_path *device_node, bool display_only, bool allow_shortcuts) { @@ -105,7 +108,7 @@ static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( } static uint16_t EFIAPI *efi_convert_device_path_to_text( - struct efi_device_path_protocol *device_path, + struct efi_device_path *device_path, bool display_only, bool allow_shortcuts) { From patchwork Wed Sep 13 22:05:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813658 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TiyeYiRn"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx1r6nzlz9sxR for ; Thu, 14 Sep 2017 08:20:32 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id B425BC2258E; Wed, 13 Sep 2017 22:10:35 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 77A30C22545; Wed, 13 Sep 2017 22:08:16 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id CD3A4C22616; Wed, 13 Sep 2017 22:06:16 +0000 (UTC) Received: from mail-qt0-f193.google.com (mail-qt0-f193.google.com [209.85.216.193]) by lists.denx.de (Postfix) with ESMTPS id 4606FC225A4 for ; Wed, 13 Sep 2017 22:06:13 +0000 (UTC) Received: by mail-qt0-f193.google.com with SMTP id u48so943332qtc.4 for ; Wed, 13 Sep 2017 15:06:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9wvjK6cnE3C9klIJHwS9ip4xCU9ANtGDr0esnZ4NAhQ=; b=TiyeYiRnM5KH/ISgI+j7YX+CI3qqWxcz6b17yJznxpl1NhZ9j3vRLONKthx8PRmDb2 6ceRd1rIesDwNwoyW2vBhg86KhpIeOm5B2XuUFnDqpSVqpsLYDhnf9JYAc1lwlAANO5H Ht1IPBEnFwmwJ4TYXU6hxYG31IGacvBdlQTswB0gZqX/Cd8G1AiP6Ub0nBuXUOOS6Fam KYfCQk+eVxaXIoUyUhCiW4afHKXZDxzTYeG0aULX/N56k8EsvLDwzCb+e8xdtWiHYOQQ FxPKulJjMhHFrJGxncvxz8cy/qfz+NjABAeQ1FX9sZ0bg1PRr4fqC1DPpNw4Sl7OhJyw oPMA== 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; bh=9wvjK6cnE3C9klIJHwS9ip4xCU9ANtGDr0esnZ4NAhQ=; b=eUstutc1Fib7fLWyBCyOP7o0Eh4Nd2gs8dnbYLK2llGSAuKrkRjc4nEFOAGBrr0Tor rvF/n/mRQIj1mMRuDV/Djdo6u1D7y7yyqK/7vnfqg6BH/3UUrv1nuSiQiLZ1DLdyuwoo cJMM0zx5iFmAyI8mjlGzrA0mH169wFSWp2HRxjrjc9eWsyY2nXhW5jnYD5kIp5Paolis legHOFUzitlZnBYKSvOnxex6t/pooqxNJvNMnFQ6JS5+RUOPdFqjx71ERYYYCpnkRzqz Jw8TMlqlpSf1q9dnG1oE87QN2fX2RIakG3LqYK3eTRoVZx5DTd/13JgO7qFTN6PISjEn 2t3g== X-Gm-Message-State: AHPjjUhyVolv2Ozd6gLUgLfZFuxJBDEvRRBWjOYw7zkgovKm+vYpexAd dxRDxP1JXwdN+tKuuyM= X-Google-Smtp-Source: AOwi7QAAoNrSTCr+M80wyDhrFYyvd1NunSNCTxikgINSx5Srdy8zDBQFdlSnhP8DZuRZZ6UTrasYkg== X-Received: by 10.237.63.15 with SMTP id p15mr27677693qtf.117.1505340371941; Wed, 13 Sep 2017 15:06:11 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id 25sm10449778qtv.14.2017.09.13.15.06.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:10 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:30 -0400 Message-Id: <20170913220546.19560-8-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 07/21] efi_loader: flesh out device-path to text 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" It needs to handle more device-path node types, and also multiple levels of path hierarchy. To simplify this, initially construct utf8 string to a temporary buffer, and then allocate the real utf16 buffer that is returned. This should be mostly for debugging or at least not critical- path so an extra copy won't hurt, and is saner than the alternative. Signed-off-by: Rob Clark --- include/efi_api.h | 1 + include/efi_loader.h | 2 + lib/efi_loader/efi_device_path_to_text.c | 241 +++++++++++++++++++++++-------- 3 files changed, 181 insertions(+), 63 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index ac58fd58de..0c36122107 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -304,6 +304,7 @@ struct efi_device_path_vendor { #define EFI_PNP_ID(ID) (u32)(((ID) << 16) | 0x41D0) #define EISA_PNP_ID(ID) EFI_PNP_ID(ID) +#define EISA_PNP_NUM(ID) ((ID) >> 16) struct efi_device_path_acpi_path { struct efi_device_path dp; diff --git a/include/efi_loader.h b/include/efi_loader.h index d052b03ab7..f39c2ee6da 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -59,6 +59,8 @@ extern struct efi_simple_input_interface efi_con_in; extern const struct efi_console_control_protocol efi_console_control; extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; +uint16_t *efi_dp_str(struct efi_device_path *dp); + extern const efi_guid_t efi_guid_console_control; extern const efi_guid_t efi_guid_device_path; extern const efi_guid_t efi_guid_loaded_image; diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index f9d071ac50..1a5ef3919b 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -15,82 +15,197 @@ const efi_guid_t efi_guid_device_path_to_text_protocol = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; -static uint16_t *efi_convert_device_node_to_text( - struct efi_device_path *device_node, - bool display_only, - bool allow_shortcuts) +static char *dp_unknown(char *s, struct efi_device_path *dp) { - unsigned long buffer_size; - efi_status_t r; - uint16_t *buffer = NULL; - int i; + s += sprintf(s, "/UNKNOWN(%04x,%04x)", dp->type, dp->sub_type); + return s; +} - switch (device_node->type) { - case DEVICE_PATH_TYPE_END: - return NULL; - case DEVICE_PATH_TYPE_MESSAGING_DEVICE: - switch (device_node->sub_type) { - case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { - struct efi_device_path_mac_addr *dp = - (struct efi_device_path_mac_addr *)device_node; - - if (dp->if_type != 0 && dp->if_type != 1) - break; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - 2 * MAC_OUTPUT_LEN, - (void **)&buffer); - if (r != EFI_SUCCESS) - return NULL; - sprintf((char *)buffer, - "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", - dp->mac.addr[0], dp->mac.addr[1], - dp->mac.addr[2], dp->mac.addr[3], - dp->mac.addr[4], dp->mac.addr[5], - dp->if_type); - for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i) - buffer[i] = ((uint8_t *)buffer)[i]; +static char *dp_hardware(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_VENDOR: { + struct efi_device_path_vendor *vdp = + (struct efi_device_path_vendor *)dp; + s += sprintf(s, "/VenHw(%pUl)", &vdp->guid); + break; + } + default: + s = dp_unknown(s, dp); + break; + } + return s; +} + +static char *dp_acpi(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_ACPI_DEVICE: { + struct efi_device_path_acpi_path *adp = + (struct efi_device_path_acpi_path *)dp; + s += sprintf(s, "/Acpi(PNP%04x", EISA_PNP_NUM(adp->hid)); + if (adp->uid) + s += sprintf(s, ",%d", adp->uid); + s += sprintf(s, ")"); + break; + } + default: + s = dp_unknown(s, dp); + break; + } + return s; +} + +static char *dp_msging(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_MSG_USB: { + struct efi_device_path_usb *udp = + (struct efi_device_path_usb *)dp; + s += sprintf(s, "/Usb(0x%x,0x%x)", udp->parent_port_number, + udp->usb_interface); + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { + struct efi_device_path_mac_addr *mdp = + (struct efi_device_path_mac_addr *)dp; + + if (mdp->if_type != 0 && mdp->if_type != 1) break; - } - } + + s += sprintf(s, "/MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", + mdp->mac.addr[0], mdp->mac.addr[1], + mdp->mac.addr[2], mdp->mac.addr[3], + mdp->mac.addr[4], mdp->mac.addr[5], + mdp->if_type); + + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS: { + struct efi_device_path_usb_class *ucdp = + (struct efi_device_path_usb_class *)dp; + + s += sprintf(s, "/USBClass(%x,%x,%x,%x,%x)", + ucdp->vendor_id, ucdp->product_id, + ucdp->device_class, ucdp->device_subclass, + ucdp->device_protocol); + + break; + } + case DEVICE_PATH_SUB_TYPE_MSG_SD: + case DEVICE_PATH_SUB_TYPE_MSG_MMC: { + const char *typename = + (dp->sub_type == DEVICE_PATH_SUB_TYPE_MSG_SD) ? + "SDCard" : "MMC"; + struct efi_device_path_sd_mmc_path *sddp = + (struct efi_device_path_sd_mmc_path *)dp; + s += sprintf(s, "/%s(Slot%u)", typename, sddp->slot_number); + break; + } + default: + s = dp_unknown(s, dp); break; - case DEVICE_PATH_TYPE_MEDIA_DEVICE: - switch (device_node->sub_type) { - case DEVICE_PATH_SUB_TYPE_FILE_PATH: { - struct efi_device_path_file_path *fp = - (struct efi_device_path_file_path *)device_node; - buffer_size = device_node->length - 4; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - buffer_size, (void **) &buffer); - if (r != EFI_SUCCESS) - return NULL; - memcpy(buffer, fp->str, buffer_size); + } + return s; +} + +static char *dp_media(char *s, struct efi_device_path *dp) +{ + switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH: { + struct efi_device_path_hard_drive_path *hddp = + (struct efi_device_path_hard_drive_path *)dp; + void *sig = hddp->partition_signature; + + switch (hddp->signature_type) { + case SIG_TYPE_MBR: + s += sprintf(s, "/HD(Part%d,Sig%08x)", + hddp->partition_number, + *(uint32_t *)sig); break; + case SIG_TYPE_GUID: + s += sprintf(s, "/HD(Part%d,Sig%pUl)", + hddp->partition_number, sig); + default: + s += sprintf(s, "/HD(Part%d,MBRType=%02x,SigType=%02x)", + hddp->partition_number, hddp->partmap_type, + hddp->signature_type); } - } + + break; + } + case DEVICE_PATH_SUB_TYPE_CDROM_PATH: { + struct efi_device_path_cdrom_path *cddp = + (struct efi_device_path_cdrom_path *)dp; + s += sprintf(s, "/CDROM(0x%x)", cddp->boot_entry); + break; + } + case DEVICE_PATH_SUB_TYPE_FILE_PATH: { + struct efi_device_path_file_path *fp = + (struct efi_device_path_file_path *)dp; + int slen = (dp->length - sizeof(*dp)) / 2; + s += sprintf(s, "/%-*ls", slen, fp->str); + break; + } + default: + s = dp_unknown(s, dp); break; } + return s; +} - /* - * For all node types that we do not yet support return - * 'UNKNOWN(type,subtype)'. - */ - if (!buffer) { - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - 2 * UNKNOWN_OUTPUT_LEN, - (void **)&buffer); - if (r != EFI_SUCCESS) - return NULL; - sprintf((char *)buffer, - "UNKNOWN(%04x,%04x)", - device_node->type, - device_node->sub_type); - for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i) - buffer[i] = ((uint8_t *)buffer)[i]; +static uint16_t *efi_convert_device_node_to_text( + struct efi_device_path *dp, + bool display_only, + bool allow_shortcuts) +{ + unsigned long len; + efi_status_t r; + char buf[512]; /* this ought be be big enough for worst case */ + char *str = buf; + uint16_t *out; + + while (dp) { + switch (dp->type) { + case DEVICE_PATH_TYPE_HARDWARE_DEVICE: + str = dp_hardware(str, dp); + break; + case DEVICE_PATH_TYPE_ACPI_DEVICE: + str = dp_acpi(str, dp); + break; + case DEVICE_PATH_TYPE_MESSAGING_DEVICE: + str = dp_msging(str, dp); + break; + case DEVICE_PATH_TYPE_MEDIA_DEVICE: + str = dp_media(str, dp); + break; + default: + str = dp_unknown(str, dp); + } + + dp = efi_dp_next(dp); } - return buffer; + *str++ = '\0'; + + len = str - buf; + r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, 2 * len, (void **)&out); + if (r != EFI_SUCCESS) + return NULL; + + ascii2unicode(out, buf); + out[len - 1] = 0; + + return out; } +/* helper for debug prints.. efi_free_pool() the result. */ +uint16_t *efi_dp_str(struct efi_device_path *dp) +{ + return efi_convert_device_node_to_text(dp, true, true); +} + + static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( struct efi_device_path *device_node, bool display_only, From patchwork Wed Sep 13 22:05:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813648 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="a6361Evf"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswvw1JFdz9sNw for ; Thu, 14 Sep 2017 08:15:24 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id EF0B5C226EE; Wed, 13 Sep 2017 22:08:46 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 C1F1DC225E3; Wed, 13 Sep 2017 22:07:33 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 473C2C223DA; Wed, 13 Sep 2017 22:06:20 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id A80D0C225D3 for ; Wed, 13 Sep 2017 22:06:16 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id u48so943403qtc.4 for ; Wed, 13 Sep 2017 15:06:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LW9yGF0ynYV60VUCYLbdLatJq83GK/GcnBaKAgR139E=; b=a6361EvfVzvRN8D+upKxv9SI7AJBdjKsFBvIZOMQB8+RiQd/Cqj43RAsTtMFDObLXG BqkLg2uIhgMhoU3DBGmJ+ZDIxgjDajEQiZ07UxrAX+Vnr8svhB0izadr1FItXU6V89+e jYFwPh4X6iTu3Aj/m7OhpLep5zBNlZ0h4qvQxfqQrRvunSoo/cZAYTCuJkK1qQqbDu92 vj0FI296HDOqoxf4Nb3ymTdk0fwKaGmel7Yd+IIFs+vxfmCFh0vUcEUrTGWbuzbprC2+ BPmamWhQMxABrfIAicvc36r9f08ZmuoHSvoJuxQQ2KNJ6KpM7pyeGl2osXP0L0De0cZM 6qnw== 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; bh=LW9yGF0ynYV60VUCYLbdLatJq83GK/GcnBaKAgR139E=; b=aL5PcT4tJQ+sWtSjbJAR24+0vOZJXVhPoKwJv0JN3i4177aAXdIu2h/e+eOMgYuIF5 cDeiLsWhcFKDmFakQK0JotSpPapiVd+fWWwv68G+EPKcG0uL8wwDmG5+LO0/cAorYHEt MYo/pbK81icRGgEXMFAXJyXMn0akBoa6AoyvdBNYNAxUpW9/VW1pctnc8fYyBJqoUH6b oBOPms5/5dzELCHkP8kjWrvXpYY9LPFJz6Fz94xPG657DEyKN/30qwztPS/pHGil9zBT v8axzvO/MLd6MX6Pbiu4OMbvH5nMfgF+ncCHpN5wNchSeNvCwYxAXMFrYx2YqrYiYIWP Wmaw== X-Gm-Message-State: AHPjjUgroXr44P6wki+aahqnB8z6Mk/Th5joqmkELGUos/WjfXQjdHqW k/b5SxoDaHz5gQy7r2E= X-Google-Smtp-Source: AOwi7QDEZTMmurUOA8TAKjJM5VBd8JKZMehXve+HNR73tbfZRFmiDiYzTHYLmlWeE8aVVMO759Z+PA== X-Received: by 10.200.23.37 with SMTP id w34mr25462498qtj.166.1505340375272; Wed, 13 Sep 2017 15:06:15 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id n29sm7019637qta.61.2017.09.13.15.06.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:14 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:31 -0400 Message-Id: <20170913220546.19560-9-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 08/21] efi_loader: use proper device-paths for partitions 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Also, create disk objects for the disk itself, in addition to the partitions. (UEFI terminology is a bit confusing, a "disk" object is really a partition.) This helps grub properly identify the boot device since it is trying to match up partition "disk" object with it's parent device. Now instead of seeing devices like: /File(sdhci@07864000.blk)/EndEntire /File(usb_mass_storage.lun0)/EndEntire You see: /ACPI(133741d0,0)/UnknownMessaging(1d)/EndEntire /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(0,800,64000,dd904a8c00000000,1,1)/EndEntire /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(1,64800,200000,dd904a8c00000000,1,1)/EndEntire /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(2,264800,19a000,dd904a8c00000000,1,1)/EndEntire /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/EndEntire /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(0,800,60000,38ca680200000000,1,1)/EndEntire /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(1,61000,155000,38ca680200000000,1,1)/EndEntire /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(2,20fa800,1bbf8800,38ca680200000000,1,1)/EndEntire /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(3,1b6800,1f44000,38ca680200000000,1,1)/EndEntire This is on a board with single USB disk and single sd-card. The UnknownMessaging(1d) node in the device-path is the MMC device, but grub_efi_print_device_path() hasn't been updated yet for some of the newer device-path sub-types. This patch is inspired by a patch originally from Peter Jones, but re-worked to use efi_device_path, so it doesn't much resemble the original. Signed-off-by: Rob Clark --- lib/efi_loader/efi_disk.c | 54 +++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index ed06485e33..14f3e020c8 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -28,11 +28,13 @@ struct efi_disk_obj { /* EFI Interface Media descriptor struct, referenced by ops */ struct efi_block_io_media media; /* EFI device path to this block device */ - struct efi_device_path_file_path *dp; + struct efi_device_path *dp; + /* partition # */ + unsigned part; /* Offset into disk for simple partitions */ lbaint_t offset; /* Internal block device */ - const struct blk_desc *desc; + struct blk_desc *desc; }; static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this, @@ -172,26 +174,26 @@ static const struct efi_block_io block_io_disk_template = { static void efi_disk_add_dev(const char *name, const char *if_typename, - const struct blk_desc *desc, + struct blk_desc *desc, int dev_index, - lbaint_t offset) + lbaint_t offset, + unsigned part) { struct efi_disk_obj *diskobj; - struct efi_device_path_file_path *dp; - int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2); /* Don't add empty devices */ if (!desc->lba) return; - diskobj = calloc(1, objlen); + diskobj = calloc(1, sizeof(*diskobj)); /* Fill in object data */ - dp = (void *)&diskobj[1]; + diskobj->dp = efi_dp_from_part(desc, part); + diskobj->part = part; diskobj->parent.protocols[0].guid = &efi_block_io_guid; diskobj->parent.protocols[0].protocol_interface = &diskobj->ops; diskobj->parent.protocols[1].guid = &efi_guid_device_path; - diskobj->parent.protocols[1].protocol_interface = dp; + diskobj->parent.protocols[1].protocol_interface = diskobj->dp; diskobj->parent.handle = diskobj; diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; @@ -207,17 +209,6 @@ static void efi_disk_add_dev(const char *name, diskobj->media.last_block = desc->lba - offset; diskobj->ops.media = &diskobj->media; - /* Fill in device path */ - diskobj->dp = dp; - dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; - dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; - dp[0].dp.length = sizeof(*dp); - ascii2unicode(dp[0].str, name); - - dp[1].dp.type = DEVICE_PATH_TYPE_END; - dp[1].dp.sub_type = DEVICE_PATH_SUB_TYPE_END; - dp[1].dp.length = sizeof(*dp); - /* Hook up to the device list */ list_add_tail(&diskobj->parent.link, &efi_obj_list); } @@ -236,14 +227,18 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, if (desc->part_type != PART_TYPE_ISO) return 0; + /* and devices for each partition: */ while (!part_get_info(desc, part, &info)) { snprintf(devname, sizeof(devname), "%s:%d", pdevname, part); efi_disk_add_dev(devname, if_typename, desc, diskid, - info.start); + info.start, part); part++; disks++; } + + /* ... and add block device: */ + efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0); #endif return disks; @@ -271,9 +266,22 @@ int efi_disk_register(void) uclass_next_device_check(&dev)) { struct blk_desc *desc = dev_get_uclass_platdata(dev); const char *if_typename = dev->driver->name; + disk_partition_t info; + int part = 1; printf("Scanning disk %s...\n", dev->name); - efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0); + + /* add devices for each partition: */ + while (!part_get_info(desc, part, &info)) { + efi_disk_add_dev(dev->name, if_typename, desc, + desc->devnum, 0, part); + part++; + } + + /* ... and add block device: */ + efi_disk_add_dev(dev->name, if_typename, desc, + desc->devnum, 0, 0); + disks++; /* @@ -309,7 +317,7 @@ int efi_disk_register(void) snprintf(devname, sizeof(devname), "%s%d", if_typename, i); - efi_disk_add_dev(devname, if_typename, desc, i, 0); + efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); disks++; /* From patchwork Wed Sep 13 22:05:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813640 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ejDYyx6i"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswmD1BZPz9ryQ for ; Thu, 14 Sep 2017 08:08:44 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E657FC2259B; Wed, 13 Sep 2017 22:07:14 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 AD68EC22531; Wed, 13 Sep 2017 22:06:57 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 1BD12C222F6; Wed, 13 Sep 2017 22:06:22 +0000 (UTC) Received: from mail-qt0-f194.google.com (mail-qt0-f194.google.com [209.85.216.194]) by lists.denx.de (Postfix) with ESMTPS id 6CA43C22544 for ; Wed, 13 Sep 2017 22:06:19 +0000 (UTC) Received: by mail-qt0-f194.google.com with SMTP id u48so943441qtc.4 for ; Wed, 13 Sep 2017 15:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=q0Qolx1SkIrEQb3hYqzrxMkSkrB0yBal+ZscwQZLcmY=; b=ejDYyx6icK+ZX9iomj1i0vjj49bOO10slYzzBR7UNJPfPW1g1scM7ZRtG0ocMs/8rv 1g5nUM7jsjAeJ7ys7CsaDqPkTK811vmJpuaf50bg4YlHiohLtyb5kaj/0KhDbkv9MYNy q3WQFNfM8Mqgel0xEMj1qhLsiqoCKn45VSvP8fiy75ms5iO16UhI+iKyzU6QPYPBJ0U8 Ly5UbsFrKQ8OC0Ekd3JozbeRiT98u/6O4Ragnmyayn1xP1lAmwDZBB7DIDJp9vDreRwa +qtxOcUNii2BO3anXw76xvHCKD8Fdcp65YBTouz5YUZ9oTGMX/aJ4Jo0C6EWY5TsCgmZ 3N4w== 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; bh=q0Qolx1SkIrEQb3hYqzrxMkSkrB0yBal+ZscwQZLcmY=; b=ESmYO6amTnQkGiIyRqWxQQzoUWBo2Mj1xDSkHpqosip9z816UH9rWE7mNlYFZPrVH1 53MiUL7QYaUV/venV514rFEWb6ouFQICQJNbZJILFqM4Zl5jAOTEUBkiJwCN7AS6LyrI IFYhcXyul/IBtQgdRtwfSbcyK9SQ/Dmsn1VVklHDpRzIVOuvYoTgUts6fWCe4mXmUpVu c84Li1veXIwZb6+xcv1rwnukL1sRCw3LPcXjcY8zzT7ZofIxWDQjMLPcaZsTFy0FVT6T 0ZOvJlWjMQALAuhoRabQRJcMHZgjaO5SzJwNOg3OSQsGAracwKqKqBC2lIZXIhw/3wZ8 IKlA== X-Gm-Message-State: AHPjjUgzx+QD2SLI3XGpXc/vjswrVcsmwqbV86jQypVkJfStCltEc40F nTZPU4BM9jGU6X6kqTw= X-Google-Smtp-Source: AOwi7QAFRNOFjdgXltM678dWxVZH8BBgY7mZQE9Zxo+OhWbPmVeeO/NtKC+rb1voZ1gnI6sH+nL/vw== X-Received: by 10.237.35.35 with SMTP id h32mr26656612qtc.47.1505340378153; Wed, 13 Sep 2017 15:06:18 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id w46sm4597135qta.84.2017.09.13.15.06.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:17 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:32 -0400 Message-Id: <20170913220546.19560-10-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 09/21] efi_loader: use proper device-paths for net 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Signed-off-by: Rob Clark --- lib/efi_loader/efi_net.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 0b949d86e8..aa0618fd3a 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -26,9 +26,6 @@ struct efi_net_obj { /* EFI Interface callback struct for network */ struct efi_simple_network net; struct efi_simple_network_mode net_mode; - /* Device path to the network adapter */ - struct efi_device_path_mac_addr dp_mac; - struct efi_device_path_file_path dp_end; /* PXE struct to transmit dhcp data */ struct efi_pxe pxe; struct efi_pxe_mode pxe_mode; @@ -213,16 +210,6 @@ void efi_net_set_dhcp_ack(void *pkt, int len) int efi_net_register(void **handle) { struct efi_net_obj *netobj; - struct efi_device_path_mac_addr dp_net = { - .dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR, - .dp.length = sizeof(dp_net), - }; - struct efi_device_path_file_path dp_end = { - .dp.type = DEVICE_PATH_TYPE_END, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, - .dp.length = sizeof(dp_end), - }; if (!eth_get_dev()) { /* No eth device active, don't expose any */ @@ -236,7 +223,8 @@ int efi_net_register(void **handle) netobj->parent.protocols[0].guid = &efi_net_guid; netobj->parent.protocols[0].protocol_interface = &netobj->net; netobj->parent.protocols[1].guid = &efi_guid_device_path; - netobj->parent.protocols[1].protocol_interface = &netobj->dp_mac; + netobj->parent.protocols[1].protocol_interface = + efi_dp_from_eth(); netobj->parent.protocols[2].guid = &efi_pxe_guid; netobj->parent.protocols[2].protocol_interface = &netobj->pxe; netobj->parent.handle = &netobj->net; @@ -255,9 +243,6 @@ int efi_net_register(void **handle) netobj->net.receive = efi_net_receive; netobj->net.mode = &netobj->net_mode; netobj->net_mode.state = EFI_NETWORK_STARTED; - netobj->dp_mac = dp_net; - netobj->dp_end = dp_end; - memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6); memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6); netobj->net_mode.max_packet_size = PKTSIZE; From patchwork Wed Sep 13 22:05:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813642 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LXhBqpXt"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswqK5lXYz9sRg for ; Thu, 14 Sep 2017 08:11:25 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 40EC8C22518; Wed, 13 Sep 2017 22:09:50 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 EEED5C22606; Wed, 13 Sep 2017 22:07:57 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 15BDDC2260D; Wed, 13 Sep 2017 22:06:26 +0000 (UTC) Received: from mail-qt0-f194.google.com (mail-qt0-f194.google.com [209.85.216.194]) by lists.denx.de (Postfix) with ESMTPS id A4802C2259B for ; Wed, 13 Sep 2017 22:06:22 +0000 (UTC) Received: by mail-qt0-f194.google.com with SMTP id t46so941799qtj.3 for ; Wed, 13 Sep 2017 15:06:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GKVPX3C6Z1ZPcvHI1fm+8gyMoefAOck5Gls/3FNNXDk=; b=LXhBqpXtrflTJY4rSdA112oZVV28jptOX+KCKQgEvxWC6Gu1Tlv3plMkVXmXoyvqhd O4YXgxZOCwc8uqslWHu7agktxPW8IOTSYj06H7rhFmQ4/nGQGgt2zhLocSiKhG9FWDIa bATSrpGWjTXWthDFW+5c13twvkqHXdNLcSNVYB8xJjkG/IvAY0REMYgkAiob/1sw2M9m 3vXtUPUipgPVPUsqEfotqMyubNVMCPI1QHYP7X3cvrSbXhcwReDR8eJw1nNMeEsXjCt3 Q5aJr8KxxRFN3oQYtNmhyuCPtNv7RgzYbpZRIXt/o1PzkaAVwCyA7RNUgWDOQ66wkDXo ZGJg== 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; bh=GKVPX3C6Z1ZPcvHI1fm+8gyMoefAOck5Gls/3FNNXDk=; b=PmQl++7aMlDn23RTQDUaaiuDSdRZjNLo5y5PPs6DnPzdz3g+LV3y5flfGU/2xmULYp VClanJgaoHc6sw2C54MBJ9GM13ddBuZxnTXK+U6wZNoxFrK506THPEdALuqJ4zuhU8J9 bSReBeHFGq4BlnVcVCdLMtS3ZBDnMwGU+X8UlwMF3H5d766tlzHqnrOl6d3dwGWi2VVD c2a0QyyEwGJY4+RpeJ3ZDQ4HRlVEYpXW6QmBFdnwf8mkaaAdv/2mxQVLL4KeFxNiDkaE qiiApgEsQmje+p5w8DF0UwSMRYpBkHfpOM4JzDZmoD6pyssPCFZPZddTspduThXVrqz0 6+tA== X-Gm-Message-State: AHPjjUiN/VmMslwsAGgP0UTvesCUgpDZE80tm6pl1Tdu5IyCqVuNJx5G 4jebCARBvkE9yrCmxbQ= X-Google-Smtp-Source: AOwi7QBT0REo7sK5jTQbFygFo9Fy8eHQERxjmKKGkOFBP9dsnd2yl0WQtGfYBlltGDzrexiD7MkazQ== X-Received: by 10.200.47.16 with SMTP id j16mr28042756qta.161.1505340381256; Wed, 13 Sep 2017 15:06:21 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id h67sm10012443qkf.6.2017.09.13.15.06.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:20 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:33 -0400 Message-Id: <20170913220546.19560-11-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 10/21] efi_loader: refactor boot device and loaded_image handling 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Get rid of the hacky fake boot-device and duplicate device-path constructing (which needs to match what efi_disk and efi_net do). Instead convert over to use efi_device_path helpers to construct device-paths, and use that to look up the actual boot device. Also, extract out a helper to plug things in properly to the loaded_image. In a following patch we'll want to re-use this in efi_load_image() to handle the case of loading an image from a file_path. Signed-off-by: Rob Clark --- cmd/bootefi.c | 201 +++++++++++++----------------------------- include/efi_loader.h | 5 +- lib/efi_loader/efi_boottime.c | 36 ++++++++ lib/efi_loader/efi_net.c | 5 +- 4 files changed, 100 insertions(+), 147 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 3196d86040..0980088668 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -22,97 +22,14 @@ DECLARE_GLOBAL_DATA_PTR; static uint8_t efi_obj_list_initalized; -/* - * When booting using the "bootefi" command, we don't know which - * physical device the file came from. So we create a pseudo-device - * called "bootefi" with the device path /bootefi. - * - * In addition to the originating device we also declare the file path - * of "bootefi" based loads to be /bootefi. - */ -static struct efi_device_path_file_path bootefi_image_path[] = { - { - .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, - .dp.length = sizeof(bootefi_image_path[0]), - .str = { 'b','o','o','t','e','f','i' }, - }, { - .dp.type = DEVICE_PATH_TYPE_END, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, - .dp.length = sizeof(bootefi_image_path[0]), - } -}; - -static struct efi_device_path_file_path bootefi_device_path[] = { - { - .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, - .dp.length = sizeof(bootefi_image_path[0]), - .str = { 'b','o','o','t','e','f','i' }, - }, { - .dp.type = DEVICE_PATH_TYPE_END, - .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, - .dp.length = sizeof(bootefi_image_path[0]), - } -}; - -/* The EFI loaded_image interface for the image executed via "bootefi" */ -static struct efi_loaded_image loaded_image_info = { - .device_handle = bootefi_device_path, - .file_path = bootefi_image_path, -}; - -/* The EFI object struct for the image executed via "bootefi" */ -static struct efi_object loaded_image_info_obj = { - .handle = &loaded_image_info, - .protocols = { - { - /* - * When asking for the loaded_image interface, just - * return handle which points to loaded_image_info - */ - .guid = &efi_guid_loaded_image, - .protocol_interface = &loaded_image_info, - }, - { - /* - * When asking for the device path interface, return - * bootefi_device_path - */ - .guid = &efi_guid_device_path, - .protocol_interface = bootefi_device_path, - }, - { - .guid = &efi_guid_console_control, - .protocol_interface = (void *) &efi_console_control - }, - { - .guid = &efi_guid_device_path_to_text_protocol, - .protocol_interface = (void *) &efi_device_path_to_text - }, - }, -}; - -/* The EFI object struct for the device the "bootefi" image was loaded from */ -static struct efi_object bootefi_device_obj = { - .handle = bootefi_device_path, - .protocols = { - { - /* When asking for the device path interface, return - * bootefi_device_path */ - .guid = &efi_guid_device_path, - .protocol_interface = bootefi_device_path - } - }, -}; +static struct efi_device_path *bootefi_image_path; +static struct efi_device_path *bootefi_device_path; /* Initialize and populate EFI object list */ static void efi_init_obj_list(void) { efi_obj_list_initalized = 1; - list_add_tail(&loaded_image_info_obj.link, &efi_obj_list); - list_add_tail(&bootefi_device_obj.link, &efi_obj_list); efi_console_register(); #ifdef CONFIG_PARTITIONS efi_disk_register(); @@ -121,13 +38,7 @@ static void efi_init_obj_list(void) efi_gop_register(); #endif #ifdef CONFIG_NET - void *nethandle = loaded_image_info.device_handle; - efi_net_register(&nethandle); - - if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6)) - loaded_image_info.device_handle = nethandle; - else - loaded_image_info.device_handle = bootefi_device_path; + efi_net_register(); #endif #ifdef CONFIG_GENERATE_SMBIOS_TABLE efi_smbios_register(); @@ -210,14 +121,27 @@ static unsigned long efi_run_in_el2(asmlinkage ulong (*entry)( * Load an EFI payload into a newly allocated piece of memory, register all * EFI objects it would want to access and jump to it. */ -static unsigned long do_bootefi_exec(void *efi, void *fdt) +static unsigned long do_bootefi_exec(void *efi, void *fdt, + struct efi_device_path *device_path, + struct efi_device_path *image_path) { + struct efi_loaded_image loaded_image_info = {}; + struct efi_object loaded_image_info_obj = {}; + ulong ret; + ulong (*entry)(void *image_handle, struct efi_system_table *st) asmlinkage; ulong fdt_pages, fdt_size, fdt_start, fdt_end; const efi_guid_t fdt_guid = EFI_FDT_GUID; bootm_headers_t img = { 0 }; + /* Initialize and populate EFI object list */ + if (!efi_obj_list_initalized) + efi_init_obj_list(); + + efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj, + device_path, image_path); + /* * gd lives in a fixed register which may get clobbered while we execute * the payload. So save it here and restore it on every callback entry @@ -252,18 +176,18 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) /* Load the EFI payload */ entry = efi_load_pe(efi, &loaded_image_info); - if (!entry) - return -ENOENT; - - /* Initialize and populate EFI object list */ - if (!efi_obj_list_initalized) - efi_init_obj_list(); + if (!entry) { + ret = -ENOENT; + goto exit; + } /* Call our payload! */ debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); if (setjmp(&loaded_image_info.exit_jmp)) { - return loaded_image_info.exit_status; + ret = loaded_image_info.exit_status; + EFI_EXIT(ret); + goto exit; } #ifdef CONFIG_ARM64 @@ -282,7 +206,13 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) } #endif - return efi_do_enter(&loaded_image_info, &systab, entry); + ret = efi_do_enter(&loaded_image_info, &systab, entry); + +exit: + /* image has returned, loaded-image obj goes *poof*: */ + list_del(&loaded_image_info_obj.link); + + return ret; } @@ -315,7 +245,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } printf("## Starting EFI application at %08lx ...\n", addr); - r = do_bootefi_exec((void *)addr, (void*)fdt_addr); + r = do_bootefi_exec((void *)addr, (void *)fdt_addr, + bootefi_device_path, bootefi_image_path); printf("## Application terminated, r = %lu\n", r & ~EFI_ERROR_MASK); @@ -344,58 +275,44 @@ U_BOOT_CMD( bootefi_help_text ); -void efi_set_bootdev(const char *dev, const char *devnr, const char *path) +static int parse_partnum(const char *devnr) { - __maybe_unused struct blk_desc *desc; - char devname[32] = { 0 }; /* dp->str is u16[32] long */ - char *colon, *s; - -#if defined(CONFIG_BLK) || CONFIG_IS_ENABLED(ISO_PARTITION) - desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10)); -#endif - -#ifdef CONFIG_BLK - if (desc) { - snprintf(devname, sizeof(devname), "%s", desc->bdev->name); - } else -#endif - - { - /* Assemble the condensed device name we use in efi_disk.c */ - snprintf(devname, sizeof(devname), "%s%s", dev, devnr); + const char *str = strchr(devnr, ':'); + if (str) { + str++; + return simple_strtoul(str, NULL, 16); } + return 0; +} - colon = strchr(devname, ':'); - -#if CONFIG_IS_ENABLED(ISO_PARTITION) - /* For ISOs we create partition block devices */ - if (desc && (desc->type != DEV_TYPE_UNKNOWN) && - (desc->part_type == PART_TYPE_ISO)) { - if (!colon) - snprintf(devname, sizeof(devname), "%s:1", devname); +void efi_set_bootdev(const char *dev, const char *devnr, const char *path) +{ + char filename[32] = { 0 }; /* dp->str is u16[32] long */ + char *s; - colon = NULL; - } -#endif + if (strcmp(dev, "Net")) { + struct blk_desc *desc; + int part; - if (colon) - *colon = '\0'; + desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10)); + part = parse_partnum(devnr); - /* Patch bootefi_device_path to the target device */ - memset(bootefi_device_path[0].str, 0, sizeof(bootefi_device_path[0].str)); - ascii2unicode(bootefi_device_path[0].str, devname); + bootefi_device_path = efi_dp_from_part(desc, part); + } else { +#ifdef CONFIG_NET + bootefi_device_path = efi_dp_from_eth(); +#endif + } - /* Patch bootefi_image_path to the target file path */ - memset(bootefi_image_path[0].str, 0, sizeof(bootefi_image_path[0].str)); if (strcmp(dev, "Net")) { /* Add leading / to fs paths, because they're absolute */ - snprintf(devname, sizeof(devname), "/%s", path); + snprintf(filename, sizeof(filename), "/%s", path); } else { - snprintf(devname, sizeof(devname), "%s", path); + snprintf(filename, sizeof(filename), "%s", path); } /* DOS style file path: */ - s = devname; + s = filename; while ((s = strchr(s, '/'))) *s++ = '\\'; - ascii2unicode(bootefi_image_path[0].str, devname); + bootefi_image_path = efi_dp_from_file(NULL, 0, filename); } diff --git a/include/efi_loader.h b/include/efi_loader.h index f39c2ee6da..ec8803f588 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -136,7 +136,7 @@ int efi_disk_register(void); /* Called by bootefi to make GOP (graphical) interface available */ int efi_gop_register(void); /* Called by bootefi to make the network interface available */ -int efi_net_register(void **handle); +int efi_net_register(void); /* Called by bootefi to make SMBIOS tables available */ void efi_smbios_register(void); @@ -193,6 +193,9 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, int efi_memory_init(void); /* Adds new or overrides configuration table entry to the system table */ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table); +void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, + struct efi_device_path *device_path, + struct efi_device_path *file_path); #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER extern void *efi_bounce_buffer; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index b962b62a97..837e61d8fe 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -726,6 +726,42 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, return EFI_EXIT(efi_install_configuration_table(guid, table)); } +/* Initialize a loaded_image_info + loaded_image_info object with correct + * protocols, boot-device, etc. + */ +void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, + struct efi_device_path *device_path, + struct efi_device_path *file_path) +{ + obj->handle = info; + + /* + * When asking for the device path interface, return + * bootefi_device_path + */ + obj->protocols[0].guid = &efi_guid_device_path; + obj->protocols[0].protocol_interface = device_path; + + /* + * When asking for the loaded_image interface, just + * return handle which points to loaded_image_info + */ + obj->protocols[1].guid = &efi_guid_loaded_image; + obj->protocols[1].protocol_interface = info; + + obj->protocols[2].guid = &efi_guid_console_control; + obj->protocols[2].protocol_interface = (void *)&efi_console_control; + + obj->protocols[3].guid = &efi_guid_device_path_to_text_protocol; + obj->protocols[3].protocol_interface = + (void *)&efi_device_path_to_text; + + info->file_path = file_path; + info->device_handle = efi_dp_find_obj(device_path, NULL); + + list_add_tail(&obj->link, &efi_obj_list); +} + static efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_handle_t parent_image, struct efi_device_path *file_path, diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index aa0618fd3a..91f1e4a69e 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -207,7 +207,7 @@ void efi_net_set_dhcp_ack(void *pkt, int len) } /* This gets called from do_bootefi_exec(). */ -int efi_net_register(void **handle) +int efi_net_register(void) { struct efi_net_obj *netobj; @@ -253,8 +253,5 @@ int efi_net_register(void **handle) /* Hook net up to the device list */ list_add_tail(&netobj->parent.link, &efi_obj_list); - if (handle) - *handle = &netobj->net; - return 0; } From patchwork Wed Sep 13 22:05:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813652 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="af4CeB2q"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswzM07rsz9s76 for ; Thu, 14 Sep 2017 08:18:22 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 9A0D4C22518; Wed, 13 Sep 2017 22:09:08 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 BCC27C225AB; Wed, 13 Sep 2017 22:07:53 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9A5C4C2258B; Wed, 13 Sep 2017 22:06:30 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 85A55C21EC9 for ; Wed, 13 Sep 2017 22:06:26 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id b1so955815qtc.0 for ; Wed, 13 Sep 2017 15:06:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kFlWhaB4WpUD8hIh5CpzG+89KVM8KE+dsJbeo4M0HNo=; b=af4CeB2qBYj28TobvT5ZCVKJWzQP4GoIPkn6+0gmZWm1zYJ8i43C8s7e2YN7rh3I43 aDkm18S94Ha346nET3f6qUG4NbHWPErTCn5J3g2WLYVXSObJ0nX8sPOi/iGYcEpkRu/p vpi79EfjpNfE8+jl/j/Ym1hwfpiVVdCPDSwodBdwcgXphdZM62CP6X1xlvmFepluR++W qVS6YzX/0IH/saKLrzAcEbFmj3hBZfQuHRMtODhM5A87KU7zwpLTG1Eo4H+AlxRk+85E IWRdWVAd+NnSAAEe0JmS+uaMzAjUb9P+vmmQRor2DN1SvP5DX7GPKwMpaoiDX5Y5lbFS ZNHg== 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; bh=kFlWhaB4WpUD8hIh5CpzG+89KVM8KE+dsJbeo4M0HNo=; b=q7euiNRSJZWEO5bZpZadA22M2rIljtl/Vs2XmWhEBMbcMarNaKMWkavM15N3OUpPYY EquIJY3X5Mley5pYNEwGt+aI7XRGjFi3nT91HAkJoE+XiUPG0MnCQDux2b22Ul1P3gbQ 1ap95J//xirzayvi4OFuc8X94iKJoFUOGnX3jxeGLnPpFKGyn6eqnXA+TPceGZ8+ucqt 0q0UWPQq17byvlCHbuUtx162W9r7YYHgiEvmXlVooAB8gQEYf5nvJ7D8McTdb98d8QAd +gcyvXMmjj7uJ7YNe1odJToBIFrfk7TH3MyrekMHdAB6qLmgruWgkBszMGX9wBImu9k/ 36ug== X-Gm-Message-State: AHPjjUjpRsgcIr442qxj9D57NSUMVmWgLUT39xauko3vJms0z/hpQd0L 52RvCwjlQyKbxZM6wDE= X-Google-Smtp-Source: AOwi7QA3OUjItbZW3c6d6hJNgXXxCOJ2Wj5MtInnVu9F2LOnbSdVzUMQ236s+S+8g7SAfek9TO6lWg== X-Received: by 10.200.3.159 with SMTP id t31mr28166337qtg.338.1505340385023; Wed, 13 Sep 2017 15:06:25 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id f4sm10394310qtg.35.2017.09.13.15.06.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:23 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:34 -0400 Message-Id: <20170913220546.19560-12-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 11/21] efi_loader: add file/filesys support 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" fallback.efi (and probably other things) use UEFI's simple-file-system protocol and file support to search for OS's to boot. Signed-off-by: Rob Clark --- include/efi.h | 2 + include/efi_api.h | 65 +++++ include/efi_loader.h | 13 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_disk.c | 32 +++ lib/efi_loader/efi_file.c | 560 ++++++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_image_loader.c | 3 + 7 files changed, 676 insertions(+) create mode 100644 lib/efi_loader/efi_file.c diff --git a/include/efi.h b/include/efi.h index 87b0b43f20..ddd2b96417 100644 --- a/include/efi.h +++ b/include/efi.h @@ -81,6 +81,8 @@ typedef struct { #define EFI_IP_ADDRESS_CONFLICT (EFI_ERROR_MASK | 34) #define EFI_HTTP_ERROR (EFI_ERROR_MASK | 35) +#define EFI_WARN_DELETE_FAILURE 2 + typedef unsigned long efi_status_t; typedef u64 efi_physical_addr_t; typedef u64 efi_virtual_addr_t; diff --git a/include/efi_api.h b/include/efi_api.h index 0c36122107..1aae96355f 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -666,4 +666,69 @@ struct efi_pxe { struct efi_pxe_mode *mode; }; +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \ + 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) +#define EFI_FILE_PROTOCOL_REVISION 0x00010000 + +struct efi_file_handle { + u64 rev; + efi_status_t (EFIAPI *open)(struct efi_file_handle *file, + struct efi_file_handle **new_handle, + s16 *file_name, u64 open_mode, u64 attributes); + efi_status_t (EFIAPI *close)(struct efi_file_handle *file); + efi_status_t (EFIAPI *delete)(struct efi_file_handle *file); + efi_status_t (EFIAPI *read)(struct efi_file_handle *file, + u64 *buffer_size, void *buffer); + efi_status_t (EFIAPI *write)(struct efi_file_handle *file, + u64 *buffer_size, void *buffer); + efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file, + u64 *pos); + efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file, + u64 pos); + efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file, + efi_guid_t *info_type, u64 *buffer_size, void *buffer); + efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *file, + efi_guid_t *info_type, u64 buffer_size, void *buffer); + efi_status_t (EFIAPI *flush)(struct efi_file_handle *file); +}; + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \ + 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 + +struct efi_simple_file_system_protocol { + u64 rev; + efi_status_t (EFIAPI *open_volume)(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); +}; + +#define EFI_FILE_INFO_GUID \ + EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, \ + 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) + +#define EFI_FILE_MODE_READ 0x0000000000000001 +#define EFI_FILE_MODE_WRITE 0x0000000000000002 +#define EFI_FILE_MODE_CREATE 0x8000000000000000 + +#define EFI_FILE_READ_ONLY 0x0000000000000001 +#define EFI_FILE_HIDDEN 0x0000000000000002 +#define EFI_FILE_SYSTEM 0x0000000000000004 +#define EFI_FILE_RESERVED 0x0000000000000008 +#define EFI_FILE_DIRECTORY 0x0000000000000010 +#define EFI_FILE_ARCHIVE 0x0000000000000020 +#define EFI_FILE_VALID_ATTR 0x0000000000000037 + +struct efi_file_info { + u64 size; + u64 file_size; + u64 physical_size; + struct efi_time create_time; + struct efi_time last_access_time; + struct efi_time modification_time; + u64 attribute; + s16 file_name[0]; +}; + #endif diff --git a/include/efi_loader.h b/include/efi_loader.h index ec8803f588..b0c1e8fb78 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -65,6 +65,8 @@ extern const efi_guid_t efi_guid_console_control; extern const efi_guid_t efi_guid_device_path; extern const efi_guid_t efi_guid_loaded_image; extern const efi_guid_t efi_guid_device_path_to_text_protocol; +extern const efi_guid_t efi_simple_file_system_protocol_guid; +extern const efi_guid_t efi_file_info_guid; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; @@ -140,6 +142,9 @@ int efi_net_register(void); /* Called by bootefi to make SMBIOS tables available */ void efi_smbios_register(void); +struct efi_simple_file_system_protocol * +efi_fs_from_path(struct efi_device_path *fp); + /* Called by networking code to memorize the dhcp ack package */ void efi_net_set_dhcp_ack(void *pkt, int len); @@ -168,6 +173,14 @@ efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type, /* Call this to signal an event */ void efi_signal_event(struct efi_event *event); +/* open file system: */ +struct efi_simple_file_system_protocol *efi_simple_file_system( + struct blk_desc *desc, int part, struct efi_device_path *dp); + +/* open file from device-path: */ +struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp); + + /* Generic EFI memory allocator, call this to get memory */ void *efi_alloc(uint64_t len, int memory_type); /* More specific EFI memory allocator, called by EFI payloads */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index f35e5ce8a8..cce92cfeb5 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -16,6 +16,7 @@ always := $(efiprogs-y) obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o +obj-y += efi_file.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 14f3e020c8..9805585eb1 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -31,6 +31,8 @@ struct efi_disk_obj { struct efi_device_path *dp; /* partition # */ unsigned part; + /* handle to filesys proto (for partition objects) */ + struct efi_simple_file_system_protocol *volume; /* Offset into disk for simple partitions */ lbaint_t offset; /* Internal block device */ @@ -172,6 +174,28 @@ static const struct efi_block_io block_io_disk_template = { .flush_blocks = &efi_disk_flush_blocks, }; +/* + * Find filesystem from a device-path. The passed in path 'p' probably + * contains one or more /File(name) nodes, so the comparison stops at + * the first /File() node, and returns the pointer to that via 'rp'. + * This is mostly intended to be a helper to map a device-path to an + * efi_file_handle object. + */ +struct efi_simple_file_system_protocol * +efi_fs_from_path(struct efi_device_path *fp) +{ + struct efi_object *efiobj; + struct efi_disk_obj *diskobj; + + efiobj = efi_dp_find_obj(fp, NULL); + if (!efiobj) + return NULL; + + diskobj = container_of(efiobj, struct efi_disk_obj, parent); + + return diskobj->volume; +} + static void efi_disk_add_dev(const char *name, const char *if_typename, struct blk_desc *desc, @@ -194,6 +218,14 @@ static void efi_disk_add_dev(const char *name, diskobj->parent.protocols[0].protocol_interface = &diskobj->ops; diskobj->parent.protocols[1].guid = &efi_guid_device_path; diskobj->parent.protocols[1].protocol_interface = diskobj->dp; + if (part >= 1) { + diskobj->volume = efi_simple_file_system(desc, part, + diskobj->dp); + diskobj->parent.protocols[2].guid = + &efi_simple_file_system_protocol_guid; + diskobj->parent.protocols[2].protocol_interface = + diskobj->volume; + } diskobj->parent.handle = diskobj; diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c new file mode 100644 index 0000000000..5e1eee5a20 --- /dev/null +++ b/lib/efi_loader/efi_file.c @@ -0,0 +1,560 @@ +/* + * EFI utils + * + * Copyright (c) 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +struct file_system { + struct efi_simple_file_system_protocol base; + struct efi_device_path *dp; + struct blk_desc *desc; + int part; +}; +#define to_fs(x) container_of(x, struct file_system, base) + +struct file_handle { + struct efi_file_handle base; + struct file_system *fs; + loff_t offset; /* current file position/cursor */ + int isdir; + + /* for reading a directory: */ + struct fs_dir_stream *dirs; + struct fs_dirent *dent; + + char path[0]; +}; +#define to_fh(x) container_of(x, struct file_handle, base) + +static const struct efi_file_handle efi_file_handle_protocol; + +static char *basename(struct file_handle *fh) +{ + char *s = strrchr(fh->path, '/'); + if (s) + return s + 1; + return fh->path; +} + +static int set_blk_dev(struct file_handle *fh) +{ + return fs_set_blk_dev_with_part(fh->fs->desc, fh->fs->part); +} + +static int is_dir(struct file_handle *fh) +{ + struct fs_dir_stream *dirs; + + set_blk_dev(fh); + dirs = fs_opendir(fh->path); + if (!dirs) + return 0; + + fs_closedir(dirs); + + return 1; +} + +/* + * Normalize a path which may include either back or fwd slashes, + * double slashes, . or .. entries in the path, etc. + */ +static int sanitize_path(char *path) +{ + char *p ; + + /* backslash to slash: */ + p = path; + while ((p = strchr(p, '\\'))) + *p++ = '/'; + + /* handle double-slashes: */ + p = path; + while ((p = strstr(p, "//"))) { + char *src = p + 1; + memmove(p, src, strlen(src) + 1); + } + + /* handle extra /.'s */ + p = path; + while ((p = strstr(p, "/."))) { + /* + * You'd be tempted to do this *after* handling ".."s + * below to avoid having to check if "/." is start of + * a "/..", but that won't have the correct results.. + * for example, "/foo/./../bar" would get resolved to + * "/foo/bar" if you did these two passes in the other + * order + */ + if (p[2] == '.') { + p += 2; + continue; + } + char *src = p + 2; + memmove(p, src, strlen(src) + 1); + } + + /* handle extra /..'s: */ + p = path; + while ((p = strstr(p, "/.."))) { + char *src = p + 3; + + p--; + + /* find beginning of previous path entry: */ + while (true) { + if (p < path) + return -1; + if (*p == '/') + break; + p--; + } + + memmove(p, src, strlen(src) + 1); + } + + return 0; +} + +/* NOTE: despite what you would expect, 'file_name' is actually a path. + * With windoze style backlashes, ofc. + */ +static struct efi_file_handle *file_open(struct file_system *fs, + struct file_handle *parent, s16 *file_name, u64 mode) +{ + struct file_handle *fh; + char f0[MAX_UTF8_PER_UTF16] = {0}; + int plen = 0; + int flen = 0; + + if (file_name) { + utf16_to_utf8((u8 *)f0, (u16 *)file_name, 1); + flen = utf16_strlen((u16 *)file_name); + } + + /* we could have a parent, but also an absolute path: */ + if (f0[0] == '\\') { + plen = 0; + } else if (parent) { + plen = strlen(parent->path) + 1; + } + + /* +2 is for null and '/' */ + fh = calloc(1, sizeof(*fh) + plen + (flen * MAX_UTF8_PER_UTF16) + 2); + + fh->base = efi_file_handle_protocol; + fh->fs = fs; + + if (parent) { + char *p = fh->path; + + if (plen > 0) { + strcpy(p, parent->path); + p += plen - 1; + *p++ = '/'; + } + + utf16_to_utf8((u8 *)p, (u16 *)file_name, flen); + + if (sanitize_path(fh->path)) + goto error; + + /* check if file exists: */ + if (set_blk_dev(fh)) + goto error; + + if (!((mode & EFI_FILE_MODE_CREATE) || fs_exists(fh->path))) + goto error; + + /* figure out if file is a directory: */ + fh->isdir = is_dir(fh); + } else { + fh->isdir = 1; + strcpy(fh->path, ""); + } + + return &fh->base; + +error: + free(fh); + return NULL; +} + +static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, + struct efi_file_handle **new_handle, + s16 *file_name, u64 open_mode, u64 attributes) +{ + struct file_handle *fh = to_fh(file); + + EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name, + open_mode, attributes); + + *new_handle = file_open(fh->fs, fh, file_name, open_mode); + if (!*new_handle) + return EFI_EXIT(EFI_NOT_FOUND); + + return EFI_EXIT(EFI_SUCCESS); +} + +static efi_status_t file_close(struct file_handle *fh) +{ + fs_closedir(fh->dirs); + free(fh); + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +{ + struct file_handle *fh = to_fh(file); + EFI_ENTRY("%p", file); + return EFI_EXIT(file_close(fh)); +} + +static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) +{ + struct file_handle *fh = to_fh(file); + EFI_ENTRY("%p", file); + file_close(fh); + return EFI_EXIT(EFI_WARN_DELETE_FAILURE); +} + +static efi_status_t file_read(struct file_handle *fh, u64 *buffer_size, + void *buffer) +{ + loff_t actread; + + if (fs_read(fh->path, (ulong)buffer, fh->offset, + *buffer_size, &actread)) + return EFI_DEVICE_ERROR; + + *buffer_size = actread; + fh->offset += actread; + + return EFI_SUCCESS; +} + +static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, + void *buffer) +{ + struct efi_file_info *info = buffer; + struct fs_dirent *dent; + unsigned required_size; + + if (!fh->dirs) { + assert(fh->offset == 0); + fh->dirs = fs_opendir(fh->path); + if (!fh->dirs) + return EFI_DEVICE_ERROR; + } + + /* + * So this is a bit awkward. Since fs layer is stateful and we + * can't rewind an entry, in the EFI_BUFFER_TOO_SMALL case below + * we might have to return without consuming the dent.. so we + * have to stash it for next call. + */ + if (fh->dent) { + dent = fh->dent; + fh->dent = NULL; + } else { + dent = fs_readdir(fh->dirs); + } + + + if (!dent) { + /* no more files in directory: */ + /* workaround shim.efi bug/quirk.. as find_boot_csv() + * loops through directory contents, it initially calls + * read w/ zero length buffer to find out how much mem + * to allocate for the EFI_FILE_INFO, then allocates, + * and then calls a 2nd time. If we return size of + * zero the first time, it happily passes that to + * AllocateZeroPool(), and when that returns NULL it + * thinks it is EFI_OUT_OF_RESOURCES. So on first + * call return a non-zero size: + */ + if (*buffer_size == 0) + *buffer_size = sizeof(*info); + else + *buffer_size = 0; + return EFI_SUCCESS; + } + + /* check buffer size: */ + required_size = sizeof(*info) + 2 * (strlen(dent->name) + 1); + if (*buffer_size < required_size) { + *buffer_size = required_size; + fh->dent = dent; + return EFI_BUFFER_TOO_SMALL; + } + + *buffer_size = required_size; + memset(info, 0, required_size); + + info->size = required_size; + info->file_size = dent->size; + info->physical_size = dent->size; + + if (dent->type == FS_DT_DIR) + info->attribute |= EFI_FILE_DIRECTORY; + + ascii2unicode((u16 *)info->file_name, dent->name); + + fh->offset++; + + return EFI_SUCCESS; +} + +static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file, + u64 *buffer_size, void *buffer) +{ + struct file_handle *fh = to_fh(file); + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); + + if (set_blk_dev(fh)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + if (fh->isdir) + ret = dir_read(fh, buffer_size, buffer); + else + ret = file_read(fh, buffer_size, buffer); + +error: + return EFI_EXIT(ret); +} + +static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file, + u64 *buffer_size, void *buffer) +{ + struct file_handle *fh = to_fh(file); + efi_status_t ret = EFI_SUCCESS; + loff_t actwrite; + + EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); + + if (set_blk_dev(fh)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + if (fs_write(fh->path, (ulong)buffer, fh->offset, *buffer_size, + &actwrite)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + *buffer_size = actwrite; + fh->offset += actwrite; + +error: + return EFI_EXIT(ret); +} + +static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file, + u64 *pos) +{ + struct file_handle *fh = to_fh(file); + EFI_ENTRY("%p, %p", file, pos); + *pos = fh->offset; + return EFI_EXIT(EFI_SUCCESS); +} + +static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, + u64 pos) +{ + struct file_handle *fh = to_fh(file); + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %llu", file, pos); + + if (fh->isdir) { + if (pos != 0) { + ret = EFI_UNSUPPORTED; + goto error; + } + fs_closedir(fh->dirs); + fh->dirs = NULL; + } + + if (pos == ~0ULL) { + loff_t file_size; + + if (set_blk_dev(fh)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + if (fs_size(fh->path, &file_size)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + pos = file_size; + } + + fh->offset = pos; + +error: + return EFI_EXIT(ret); +} + +static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file, + efi_guid_t *info_type, u64 *buffer_size, void *buffer) +{ + struct file_handle *fh = to_fh(file); + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %p, %p, %p", file, info_type, buffer_size, buffer); + + if (!guidcmp(info_type, &efi_file_info_guid)) { + struct efi_file_info *info = buffer; + char *filename = basename(fh); + unsigned required_size; + loff_t file_size; + + /* check buffer size: */ + required_size = sizeof(*info) + 2 * (strlen(filename) + 1); + if (*buffer_size < required_size) { + *buffer_size = required_size; + ret = EFI_BUFFER_TOO_SMALL; + goto error; + } + + if (set_blk_dev(fh)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + if (fs_size(fh->path, &file_size)) { + ret = EFI_DEVICE_ERROR; + goto error; + } + + memset(info, 0, required_size); + + info->size = required_size; + info->file_size = file_size; + info->physical_size = file_size; + + if (fh->isdir) + info->attribute |= EFI_FILE_DIRECTORY; + + ascii2unicode((u16 *)info->file_name, filename); + } else { + ret = EFI_UNSUPPORTED; + } + +error: + return EFI_EXIT(ret); +} + +static efi_status_t EFIAPI efi_file_setinfo(struct efi_file_handle *file, + efi_guid_t *info_type, u64 buffer_size, void *buffer) +{ + EFI_ENTRY("%p, %p, %llu, %p", file, info_type, buffer_size, buffer); + return EFI_EXIT(EFI_UNSUPPORTED); +} + +static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *file) +{ + EFI_ENTRY("%p", file); + return EFI_EXIT(EFI_SUCCESS); +} + +static const struct efi_file_handle efi_file_handle_protocol = { + .rev = EFI_FILE_PROTOCOL_REVISION, + .open = efi_file_open, + .close = efi_file_close, + .delete = efi_file_delete, + .read = efi_file_read, + .write = efi_file_write, + .getpos = efi_file_getpos, + .setpos = efi_file_setpos, + .getinfo = efi_file_getinfo, + .setinfo = efi_file_setinfo, + .flush = efi_file_flush, +}; + +struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) +{ + struct efi_simple_file_system_protocol *v; + struct efi_file_handle *f; + efi_status_t ret; + + v = efi_fs_from_path(fp); + if (!v) + return NULL; + + EFI_CALL(ret = v->open_volume(v, &f)); + if (ret != EFI_SUCCESS) + return NULL; + + /* skip over device-path nodes before the file path: */ + while (fp && !EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) + fp = efi_dp_next(fp); + + while (fp) { + struct efi_device_path_file_path *fdp = + container_of(fp, struct efi_device_path_file_path, dp); + struct efi_file_handle *f2; + + if (!EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) { + printf("bad file path!\n"); + f->close(f); + return NULL; + } + + EFI_CALL(ret = f->open(f, &f2, (s16 *)fdp->str, + EFI_FILE_MODE_READ, 0)); + if (ret != EFI_SUCCESS) + return NULL; + + fp = efi_dp_next(fp); + + EFI_CALL(f->close(f)); + f = f2; + } + + return f; +} + +static efi_status_t EFIAPI +efi_open_volume(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + struct file_system *fs = to_fs(this); + + EFI_ENTRY("%p, %p", this, root); + + *root = file_open(fs, NULL, NULL, 0); + + return EFI_EXIT(EFI_SUCCESS); +} + +struct efi_simple_file_system_protocol * +efi_simple_file_system(struct blk_desc *desc, int part, + struct efi_device_path *dp) +{ + struct file_system *fs; + + fs = calloc(1, sizeof(*fs)); + fs->base.rev = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + fs->base.open_volume = efi_open_volume; + fs->desc = desc; + fs->part = part; + fs->dp = dp; + + return &fs->base; +} diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index f961407f50..469acae082 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -17,6 +17,9 @@ DECLARE_GLOBAL_DATA_PTR; const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID; const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID; +const efi_guid_t efi_simple_file_system_protocol_guid = + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, unsigned long rel_size, void *efi_reloc) From patchwork Wed Sep 13 22:05:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813656 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hK8snWTQ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx114Q97z9sxR for ; Thu, 14 Sep 2017 08:19:49 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 5CC2AC226F5; Wed, 13 Sep 2017 22:10:17 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 1F01AC225FA; Wed, 13 Sep 2017 22:08:09 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id ED6FBC2260B; Wed, 13 Sep 2017 22:06:33 +0000 (UTC) Received: from mail-qk0-f194.google.com (mail-qk0-f194.google.com [209.85.220.194]) by lists.denx.de (Postfix) with ESMTPS id D13F4C2249C for ; Wed, 13 Sep 2017 22:06:29 +0000 (UTC) Received: by mail-qk0-f194.google.com with SMTP id g128so957177qke.0 for ; Wed, 13 Sep 2017 15:06:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DKsVzCsw32z5Rh0dgOU0MOQ8zk25bcDzhP7cBWZSGfE=; b=hK8snWTQ6Oq22BXpaDq1Rb8Qa54S6PkYPwJQngcJh0HNCuqEbXbV5uk2ixJXY2D466 JeD9Jk8wM33oPPEw+Aci8/a+gMG8bDAE8hfJbhEXv8wJNB82Zwy9qrofQXtWc6mLsvuB +Fjl/DczCysZgAamaZMsvpKIlE2AMjqWiFYvP3PhUvAkGuRG0x4XRzzahH4fIOXDwgBO diZNEi+iaglcRUn8RQymKxOkKVhZC2EOnKfywLk1oln+O9q1ny/9DQwOhOhJqUl9rV2U cwJgW/Vs2Ks0QC3aWXrXB8Xe7+7ci7ydAZ344e70GLXzmXFsm1YixasCBLLQCbG1UKsL BGhg== 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; bh=DKsVzCsw32z5Rh0dgOU0MOQ8zk25bcDzhP7cBWZSGfE=; b=XeqrwZRPbfFurrq3AquDq4yvbOv9Nr9+z04lk50e/K7glV0qM8uXKzy4aR8syDyPt2 D1daQna/IAfxvKAYPDHcfwbMwBk2G/0AdiYMI0qem6+gvt12JiNfmj7TX+josQjZMTWB XwufRoky9Y5P4QtDdnpAyVgWtDM86coX05NGuw2WzRJzfPAzfjl/9f1ZYUO7XzzHJ7y7 c/psiXMSfdP43v31y3HsMt3HbKMcHRTZJJRqmaG4PYBPr8/LDWNUZLlCUgS/k799jkn+ QX+IuHnvSVbNefqKQA/lNBFNnYvejVMsQTry5cM2u/aiVkATMnMGqetCo1/kmGx7HIai Lt0Q== X-Gm-Message-State: AHPjjUhXSYqhNH22h0HmW7kEfjymxBNxsEqKqbaKVbcfXh6pXgAOTgSm f9fFpXWrX2kZSWqn3Kc= X-Google-Smtp-Source: AOwi7QAXyA9uFecgFbXq8WmQ3UV0RcGPf/h3dCPI4OS+vmVHsIEjZ3IWYy4f9SCmSTcpI9n6PiOcMw== X-Received: by 10.55.12.16 with SMTP id 16mr25384238qkm.213.1505340388536; Wed, 13 Sep 2017 15:06:28 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id e18sm10524005qtc.59.2017.09.13.15.06.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:27 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:35 -0400 Message-Id: <20170913220546.19560-13-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 12/21] efi_loader: support load_image() from a file-path 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Previously we only supported the case when the EFI application loaded the image into memory for us. But fallback.efi does not do this. Signed-off-by: Rob Clark --- lib/efi_loader/efi_boottime.c | 85 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 837e61d8fe..ec40f41bcb 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -762,6 +762,47 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob list_add_tail(&obj->link, &efi_obj_list); } +static efi_status_t load_image_from_path(struct efi_device_path *file_path, + void **buffer) +{ + struct efi_file_info *info = NULL; + struct efi_file_handle *f; + static efi_status_t ret; + uint64_t bs; + + f = efi_file_from_path(file_path); + if (!f) + return EFI_DEVICE_ERROR; + + bs = 0; + EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, + &bs, info)); + if (ret == EFI_BUFFER_TOO_SMALL) { + info = malloc(bs); + EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, + &bs, info)); + } + if (ret != EFI_SUCCESS) + goto error; + + ret = efi_allocate_pool(EFI_LOADER_DATA, info->file_size, buffer); + if (ret) + goto error; + + EFI_CALL(ret = f->read(f, &info->file_size, *buffer)); + +error: + free(info); + EFI_CALL(f->close(f)); + + if (ret != EFI_SUCCESS) { + efi_free_pool(*buffer); + *buffer = NULL; + } + + return ret; +} + static efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_handle_t parent_image, struct efi_device_path *file_path, @@ -769,25 +810,40 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, unsigned long source_size, efi_handle_t *image_handle) { - static struct efi_object loaded_image_info_obj = { - .protocols = { - { - .guid = &efi_guid_loaded_image, - }, - }, - }; struct efi_loaded_image *info; struct efi_object *obj; EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image, file_path, source_buffer, source_size, image_handle); - info = malloc(sizeof(*info)); - loaded_image_info_obj.protocols[0].protocol_interface = info; - obj = malloc(sizeof(loaded_image_info_obj)); - memset(info, 0, sizeof(*info)); - memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj)); - obj->handle = info; - info->file_path = file_path; + + info = calloc(1, sizeof(*info)); + obj = calloc(1, sizeof(*obj)); + + if (!source_buffer) { + struct efi_device_path *dp, *fp; + efi_status_t ret; + + ret = load_image_from_path(file_path, &source_buffer); + if (ret != EFI_SUCCESS) { + free(info); + free(obj); + return EFI_EXIT(ret); + } + + /* + * split file_path which contains both the device and + * file parts: + */ + efi_dp_split_file_path(file_path, &dp, &fp); + + efi_setup_loaded_image(info, obj, dp, fp); + } else { + /* In this case, file_path is the "device" path, ie. + * something like a HARDWARE_DEVICE:MEMORY_MAPPED + */ + efi_setup_loaded_image(info, obj, file_path, NULL); + } + info->reserved = efi_load_pe(source_buffer, info); if (!info->reserved) { free(info); @@ -796,7 +852,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, } *image_handle = info; - list_add_tail(&obj->link, &efi_obj_list); return EFI_EXIT(EFI_SUCCESS); } From patchwork Wed Sep 13 22:05:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813657 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hxw4xxlj"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx1X3zRXz9sxR for ; Thu, 14 Sep 2017 08:20:16 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 458B8C22743; Wed, 13 Sep 2017 22:10:56 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 A2880C22615; Wed, 13 Sep 2017 22:08:22 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 3E512C2259E; Wed, 13 Sep 2017 22:06:36 +0000 (UTC) Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by lists.denx.de (Postfix) with ESMTPS id 9DD22C224BA for ; Wed, 13 Sep 2017 22:06:32 +0000 (UTC) Received: by mail-qk0-f195.google.com with SMTP id o77so945925qke.2 for ; Wed, 13 Sep 2017 15:06:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rRpS4m7+k9Kgg68zb96oaEj5ZZmnh1UimVhSWh7Vh34=; b=hxw4xxljTkg940TVv2ZZ3+y6wt1DaUfzgDWTXj220EU8mTgT3F0OSDi8s6pOcpLGCf X38pzjVVXLWL/vyVN3oaOQmMva08u4ONR1VdpLKJm8deHEwLsw9UhMPK2vHDiFrhP1IS MdXrvLZ+fWjYJHoQHt59tqLGpRiRGmfqTn+X5CnQl4RDwt5a1/c4u28KFwvESPOMI4hB VlryONh9tN/tmPelDQ6CElYorR4AR2ysoeb21eFbqOmR8CqDzJtE5qxlqmvdVRPFgr3R C1xC0UFuHDPY8m+belEFqlqXX8m7HC/44OxAzQJepjdZJX1zSxhkX5wPqJOFnlyG0Rgv 8HZg== 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; bh=rRpS4m7+k9Kgg68zb96oaEj5ZZmnh1UimVhSWh7Vh34=; b=Sl+aLImgiVPIlutbwpBriMFL6vtk7bRUSYhn2E0h919aUselYZtOXvGM1ISwoJpZI4 qZeT6nTvtTTgdvTVsgzrCpnsX/MJod8sBGf98Ns36bQji0GhAdAareG4Es4dNJrEGHNq Xj9+nPDQc3wY8EM1wboGGVHkc0ZuwexycdcYUIkWIzuJwOxrW14Oz30WRABjMKcwqnBL I1f7M/8+qw5vDMq+RcNALl3xy6EoqJHcfb2mfGb3Z2tfkQAPkgegaKR3rRx3ocJieBct 8Gsh1GEerg22or4BgrMneNOXc50haWt0SBQ/0yFfzj6jW2zt6dsYEBDWBaligz8vm35p IuEg== X-Gm-Message-State: AHPjjUizqGnClUma2qRdQKR89YtD95OJhETNtMz350iBlBCUCWgStiFY EJH3x8zVpIjJ9TQV//A= X-Google-Smtp-Source: AOwi7QDMwpDESRcxWivvO7MTRHpaeS6YLTDiFHq97PeC0/yVEex9CCKlIMNwCyhOznGF500SGyqBLA== X-Received: by 10.55.209.16 with SMTP id s16mr32586qki.46.1505340391356; Wed, 13 Sep 2017 15:06:31 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id d42sm10355596qta.17.2017.09.13.15.06.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:30 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:36 -0400 Message-Id: <20170913220546.19560-14-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 13/21] efi_loader: make pool allocations cacheline aligned 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This avoids printf() spam about file reads (such as loading an image) into unaligned buffers (and the associated memcpy()). And generally seems like a good idea. Signed-off-by: Rob Clark --- lib/efi_loader/efi_memory.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 9e079f1fa3..1f0b9d0449 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -43,7 +43,7 @@ void *efi_bounce_buffer; */ struct efi_pool_allocation { u64 num_pages; - char data[]; + char data[] __attribute__((aligned(ARCH_DMA_MINALIGN))); }; /* @@ -356,7 +356,8 @@ efi_status_t efi_allocate_pool(int pool_type, unsigned long size, { efi_status_t r; efi_physical_addr_t t; - u64 num_pages = (size + sizeof(u64) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; + u64 num_pages = (size + sizeof(struct efi_pool_allocation) + + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; if (size == 0) { *buffer = NULL; From patchwork Wed Sep 13 22:05:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813643 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="IQuriuDk"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswr02Xyjz9sNw for ; Thu, 14 Sep 2017 08:12:00 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CBE45C22545; Wed, 13 Sep 2017 22:08: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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 BC9E7C22556; Wed, 13 Sep 2017 22:07:28 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 01962C22534; Wed, 13 Sep 2017 22:06:40 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 1D865C2222A for ; Wed, 13 Sep 2017 22:06:36 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id l25so951928qtf.2 for ; Wed, 13 Sep 2017 15:06:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TcXSVnkuzNuuhq/qGicmO35MPEloXzfvi9hiWlZsjUI=; b=IQuriuDkLIklGXrXQ/zGYoJ+ZUrBhVUDsJs14ON1UulfQ4AHvQ+rJ8S/k83sIFg++r +gxgChrJpYWr1FsYtOxO0BEmmSZ2DoQcdUm/hffXGQD0792PXO470wJP9eQ2AVISkqrT yBcZcmGb9ktmJmfEWluj8M36e0/tMG5nrTIZILhZ+rf+ypUFxXs6tyj1ykC7OZMoaFfm Ob/U7oYGviPS1N5+Mq14bNC/pwDp0tXejgGiklohJZ2J4Az2Q9dKGqoZF7wW6oVzKcix u4hIglnsFqnFu63+wUbjsRTpxO8b/1m/eh9vMm1W5ozbicRZ49at/3cWXD8Mw4ZcGr1U 9ZnA== 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; bh=TcXSVnkuzNuuhq/qGicmO35MPEloXzfvi9hiWlZsjUI=; b=YGmAongq3jST0qGaHV/dg1ow+IPVeJIh2Z4krXeq6yPQxZVnoAQ7l3R5XNFpPDnpHc gbRDLLhXgMvwUilpI3K0osUzA9ZKcdxY0G304BV8RPwc4hAvfR4gbg1NhYBoh4fhcvlz qBNtcxQqOIKh4RVy3sI3HkOlP5D2WdBX422xptAs8QBNhafQcErCZpPwBRoTH4eAiCNo aMB4DAFTNqsgkBhZTDkYDkKqwko2cdk+rJfFsPxMOBXTRDwgr0J5u+ECBjUSgChEhmuB 2uX3E561D9CYi+bZKLM0TG+HffZANIv1PfAXA/ciFZZw48zkkzhyX0ojdo9/5OAswUk3 wwMQ== X-Gm-Message-State: AHPjjUi/kdoSD8SyIjoD80X4WOpN8FuRRD6qaI7HQkNE3iUbvjQQuCW5 RxA78IHR47+lrIc6J4s= X-Google-Smtp-Source: AOwi7QCrKO9JEfKXrTEddGQ5YE1nEBGa3glJ7FjItwa0eHDU4wLBVm5VdkQGBtOHsNd783xrehMWvQ== X-Received: by 10.200.58.67 with SMTP id w61mr15220804qte.151.1505340394592; Wed, 13 Sep 2017 15:06:34 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id d140sm4591220qkc.41.2017.09.13.15.06.33 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:33 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:37 -0400 Message-Id: <20170913220546.19560-15-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 14/21] efi_loader: efi variable support 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add EFI variable support, mapping to u-boot environment variables. Variables are pretty important for setting up boot order, among other things. If the board supports saveenv, then it will be called in ExitBootServices() to persist variables set by the efi payload. (For example, fallback.efi configuring BootOrder and BootXXXX load-option variables.) Variables are *not* currently exposed at runtime, post ExitBootServices. On boards without a dedicated device for storage, which the loaded OS is not trying to also use, this is rather tricky. One idea, at least for boards that can persist RAM across reboot, is to keep a "journal" of modified variables in RAM, and then turn halt into a reboot into u-boot, plus store variables, plus halt. Whatever the solution, it likely involves some per-board support. Mapping between EFI variables and u-boot variables: efi_$guid_$varname = {attributes}(type)value For example: efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported= "{ro,boot,run}(blob)0000000000000000" efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder= "(blob)00010000" The attributes are a comma separated list of these possible attributes: + ro - read-only + boot - boot-services access + run - runtime access NOTE: with current implementation, no variables are available after ExitBootServices, and all are persisted (if possible). If not specified, the attributes default to "{boot}". The required type is one of: + utf8 - raw utf8 string + blob - arbitrary length hex string Signed-off-by: Rob Clark --- cmd/bootefi.c | 4 + include/efi.h | 19 +++ include/efi_loader.h | 10 ++ lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_boottime.c | 6 + lib/efi_loader/efi_runtime.c | 17 ++- lib/efi_loader/efi_variable.c | 335 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 388 insertions(+), 5 deletions(-) create mode 100644 lib/efi_loader/efi_variable.c diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 0980088668..d3ae33e25b 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -181,6 +181,10 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt, goto exit; } + /* we don't support much: */ + env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported", + "{ro,boot}(blob)0000000000000000"); + /* Call our payload! */ debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); diff --git a/include/efi.h b/include/efi.h index ddd2b96417..04e83220b4 100644 --- a/include/efi.h +++ b/include/efi.h @@ -324,6 +324,25 @@ extern char image_base[]; /* Start and end of U-Boot image (for payload) */ extern char _binary_u_boot_bin_start[], _binary_u_boot_bin_end[]; +/* + * Variable Attributes + */ +#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 +#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 + +#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS | \ + EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_APPEND_WRITE) + /** * efi_get_sys_table() - Get access to the main EFI system table * diff --git a/include/efi_loader.h b/include/efi_loader.h index b0c1e8fb78..9eee62dc9c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -277,6 +277,16 @@ efi_status_t __efi_runtime EFIAPI efi_get_time( struct efi_time_cap *capabilities); void efi_get_time_init(void); +efi_status_t EFIAPI efi_get_variable(s16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + unsigned long *data_size, void *data); +efi_status_t EFIAPI efi_get_next_variable( + unsigned long *variable_name_size, + s16 *variable_name, efi_guid_t *vendor); +efi_status_t EFIAPI efi_set_variable(s16 *variable_name, + efi_guid_t *vendor, u32 attributes, + unsigned long data_size, void *data); + #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */ /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index cce92cfeb5..f58cb13337 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -16,7 +16,7 @@ always := $(efiprogs-y) obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -obj-y += efi_file.o +obj-y += efi_file.o efi_variable.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index ec40f41bcb..c406ff82ff 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -942,6 +943,11 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, { EFI_ENTRY("%p, %ld", image_handle, map_key); +#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) + /* save any EFI variables that have been written: */ + env_save(); +#endif + board_quiesce_devices(); /* Fix up caches for EFI payloads if necessary */ diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index ad7f3754bd..2f95c766ac 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -184,7 +184,16 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { /* Clean up system table */ .ptr = &systab.boottime, .patchto = NULL, - }, + }, { + .ptr = &efi_runtime_services.get_variable, + .patchto = &efi_device_error, + }, { + .ptr = &efi_runtime_services.get_next_variable, + .patchto = &efi_device_error, + }, { + .ptr = &efi_runtime_services.set_variable, + .patchto = &efi_device_error, + } }; static bool efi_runtime_tobedetached(void *p) @@ -382,9 +391,9 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .set_wakeup_time = (void *)&efi_unimplemented, .set_virtual_address_map = &efi_set_virtual_address_map, .convert_pointer = (void *)&efi_invalid_parameter, - .get_variable = (void *)&efi_device_error, - .get_next_variable = (void *)&efi_device_error, - .set_variable = (void *)&efi_device_error, + .get_variable = efi_get_variable, + .get_next_variable = efi_get_next_variable, + .set_variable = efi_set_variable, .get_next_high_mono_count = (void *)&efi_device_error, .reset_system = &efi_reset_system_boottime, }; diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c new file mode 100644 index 0000000000..5569b3d3f0 --- /dev/null +++ b/lib/efi_loader/efi_variable.c @@ -0,0 +1,335 @@ +/* + * EFI utils + * + * Copyright (c) 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define READ_ONLY BIT(31) + +/* + * Mapping between EFI variables and u-boot variables: + * + * efi_$guid_$varname = {attributes}(type)value + * + * For example: + * + * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported= + * "{ro,boot,run}(blob)0000000000000000" + * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder= + * "(blob)00010000" + * + * The attributes are a comma separated list of these possible + * attributes: + * + * + ro - read-only + * + boot - boot-services access + * + run - runtime access + * + * NOTE: with current implementation, no variables are available after + * ExitBootServices, and all are persisted (if possible). + * + * If not specified, the attributes default to "{boot}". + * + * The required type is one of: + * + * + utf8 - raw utf8 string + * + blob - arbitrary length hex string + * + * Maybe a utf16 type would be useful to for a string value to be auto + * converted to utf16? + */ + +#define MAX_VAR_NAME 31 +#define MAX_NATIVE_VAR_NAME \ + (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ + (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) + +static int hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +static const char *hex2mem(u8 *mem, const char *hexstr, int count) +{ + memset(mem, 0, count/2); + + do { + int nibble; + + *mem = 0; + + if (!count || !*hexstr) + break; + + nibble = hex(*hexstr); + if (nibble < 0) + break; + + *mem = nibble; + count--; + hexstr++; + + if (!count || !*hexstr) + break; + + nibble = hex(*hexstr); + if (nibble < 0) + break; + + *mem = (*mem << 4) | nibble; + count--; + hexstr++; + mem++; + + } while (1); + + if (*hexstr) + return hexstr; + + return NULL; +} + +static char *mem2hex(char *hexstr, const u8 *mem, int count) +{ + static const char hexchars[] = "0123456789abcdef"; + + while (count-- > 0) { + u8 ch = *mem++; + *hexstr++ = hexchars[ch >> 4]; + *hexstr++ = hexchars[ch & 0xf]; + } + + return hexstr; +} + +static efi_status_t efi_to_native(char *native, s16 *variable_name, + efi_guid_t *vendor) +{ + size_t len; + + len = utf16_strlen((u16 *)variable_name); + if (len >= MAX_VAR_NAME) + return EFI_DEVICE_ERROR; + + native += sprintf(native, "efi_%pUl_", vendor); + native = (char *)utf16_to_utf8((u8 *)native, (u16 *)variable_name, len); + *native = '\0'; + + return EFI_SUCCESS; +} + +static const char *prefix(const char *str, const char *prefix) +{ + size_t n = strlen(prefix); + if (!strncmp(prefix, str, n)) + return str + n; + return NULL; +} + +/* parse attributes part of variable value, if present: */ +static const char *parse_attr(const char *str, u32 *attrp) +{ + u32 attr = 0; + char sep = '{'; + + if (*str != '{') { + *attrp = EFI_VARIABLE_BOOTSERVICE_ACCESS; + return str; + } + + while (*str == sep) { + const char *s; + + str++; + + if ((s = prefix(str, "ro"))) { + attr |= READ_ONLY; + } else if ((s = prefix(str, "boot"))) { + attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS; + } else if ((s = prefix(str, "run"))) { + attr |= EFI_VARIABLE_RUNTIME_ACCESS; + } else { + printf("invalid attribute: %s\n", str); + break; + } + + str = s; + sep = ','; + } + + str++; + + *attrp = attr; + + return str; +} + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.29 */ +efi_status_t EFIAPI efi_get_variable(s16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + unsigned long *data_size, void *data) +{ + char native_name[MAX_NATIVE_VAR_NAME + 1]; + efi_status_t ret; + unsigned long in_size; + const char *val, *s; + u32 attr; + + EFI_ENTRY("%p %p %p %p %p", variable_name, vendor, attributes, + data_size, data); + + if (!variable_name || !vendor || !data_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + ret = efi_to_native(native_name, variable_name, vendor); + if (ret) + return EFI_EXIT(ret); + + debug("%s: get '%s'\n", __func__, native_name); + + val = env_get(native_name); + if (!val) + return EFI_EXIT(EFI_NOT_FOUND); + + val = parse_attr(val, &attr); + + in_size = *data_size; + + if ((s = prefix(val, "(blob)"))) { + unsigned len = strlen(s); + + /* two characters per byte: */ + len = DIV_ROUND_UP(len, 2); + *data_size = len; + + if (in_size < len) + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + + if (!data) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (hex2mem(data, s, len * 2)) + return EFI_EXIT(EFI_DEVICE_ERROR); + + debug("%s: got value: \"%s\"\n", __func__, s); + } else if ((s = prefix(val, "(utf8)"))) { + unsigned len = strlen(s) + 1; + + *data_size = len; + + if (in_size < len) + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + + if (!data) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + memcpy(data, s, len); + ((char *)data)[len] = '\0'; + + debug("%s: got value: \"%s\"\n", __func__, (char *)data); + } else { + debug("%s: invalid value: '%s'\n", __func__, val); + return EFI_EXIT(EFI_DEVICE_ERROR); + } + + if (attributes) + *attributes = attr & EFI_VARIABLE_MASK; + + return EFI_EXIT(EFI_SUCCESS); +} + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 */ +efi_status_t EFIAPI efi_get_next_variable( + unsigned long *variable_name_size, + s16 *variable_name, efi_guid_t *vendor) +{ + EFI_ENTRY("%p %p %p", variable_name_size, variable_name, vendor); + + return EFI_EXIT(EFI_DEVICE_ERROR); +} + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.29 */ +efi_status_t EFIAPI efi_set_variable(s16 *variable_name, + efi_guid_t *vendor, u32 attributes, + unsigned long data_size, void *data) +{ + char native_name[MAX_NATIVE_VAR_NAME + 1]; + efi_status_t ret = EFI_SUCCESS; + char *val, *s; + u32 attr; + + EFI_ENTRY("%p %p %x %lu %p", variable_name, vendor, attributes, + data_size, data); + + if (!variable_name || !vendor) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + ret = efi_to_native(native_name, variable_name, vendor); + if (ret) + return EFI_EXIT(ret); + +#define ACCESS_ATTR (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS) + + if ((data_size == 0) || !(attributes & ACCESS_ATTR)) { + /* delete the variable: */ + env_set(native_name, NULL); + return EFI_EXIT(EFI_SUCCESS); + } + + val = env_get(native_name); + if (val) { + parse_attr(val, &attr); + + if (attr & READ_ONLY) + return EFI_EXIT(EFI_WRITE_PROTECTED); + } + + val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1); + if (!val) + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + + s = val; + + /* store attributes: */ + attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); + s += sprintf(s, "{"); + while (attributes) { + u32 attr = 1 << (ffs(attributes) - 1); + + if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) + s += sprintf(s, "boot"); + else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) + s += sprintf(s, "run"); + + attributes &= ~attr; + if (attributes) + s += sprintf(s, ","); + } + s += sprintf(s, "}"); + + /* store payload: */ + s += sprintf(s, "(blob)"); + s = mem2hex(s, data, data_size); + *s = '\0'; + + debug("%s: setting: %s=%s\n", __func__, native_name, val); + + if (env_set(native_name, val)) + ret = EFI_DEVICE_ERROR; + + free(val); + + return EFI_EXIT(ret); +} From patchwork Wed Sep 13 22:05:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813660 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="AuoeOp3V"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx3v3W41z9t0F for ; Thu, 14 Sep 2017 08:22:19 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 34A5CC22225; Wed, 13 Sep 2017 22:12:29 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 3ADB0C2260B; Wed, 13 Sep 2017 22:10:52 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 10941C2258B; Wed, 13 Sep 2017 22:06:43 +0000 (UTC) Received: from mail-qk0-f170.google.com (mail-qk0-f170.google.com [209.85.220.170]) by lists.denx.de (Postfix) with ESMTPS id 6BDBDC21F60 for ; Wed, 13 Sep 2017 22:06:39 +0000 (UTC) Received: by mail-qk0-f170.google.com with SMTP id b23so3828005qkg.1 for ; Wed, 13 Sep 2017 15:06:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rY8MEr4JeuCx8ZpzzWQio3wE30vawbb/Y8pwm0b89rE=; b=AuoeOp3VTtnRvmY1gVz7Kw84k7sDVGxoKSfQaTkqJatjyPx/LazFztxgIht39JGzpC Z15cLyMaow9kunWJ2lctz+36vrXMbDMQOKRtob5VGHYB/aamFUtyPrbGGHB5bInVEWWi E9efqrsHlu7umKj8YKDTxbtC/G7us+yRqYWxktFDtK6jlomVkQK/Dcy1M1kVliNSTBqu Ehgdu4tpQvN0lgIaMrUNo4+BIUckEHqPe5mz2WoAO1Zjxm5RBwMhhDWzfqeeH1adZJu/ 7VEIrbRwZ2gd1RPbEIceCd95oHvvuYNkvY6WmcxxpguQIjWu1AoAQajY49Oht5l4+s9U TXjg== 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; bh=rY8MEr4JeuCx8ZpzzWQio3wE30vawbb/Y8pwm0b89rE=; b=jWffagam3u5ZnNyz3Bmx88IOt4N6zqBa+3CuXbUM4aUTTKQUn8XRr6fwBYCLC9VZ1K kF2IngKdl8SSoi3LHQ0QVu0fybD2w11M0/SPp1JaxQLghIIFUzuWKrZLK1VeOd5bKPEi yKBE77JGLZ/XKkEmWeyh15jpI92OA2RpYoxhz4S9bHvUJgU/1uf6NsJJXFy3g/hfIAEk dpgF6MD/hgRWcmiCxbVDG0Lw90bvf6E9gwD42F4p3ukX4NaLUhVj4n9RtUOiFwr4QnJA 8CMUtviu21YD/IKsEmfgWYO3hBX3DhgmaRql+0uOK3u8klmzQDvIerBIWLl+WqqGX67t dTUQ== X-Gm-Message-State: AHPjjUjLgg9NuINEzHQdksaxkx9Kt9GwuQn7QF2FfwelOtaQBwy8gTVr XReGChlLWvnWTwsNUXk= X-Google-Smtp-Source: AOwi7QBbla5X2VSg0tuF5f4z3Mm+5qMOinkRBNOWRiNv2WwM2NtoDz7AvoJF2khwFdjSOac6/SiaiQ== X-Received: by 10.55.155.203 with SMTP id d194mr1638qke.288.1505340397955; Wed, 13 Sep 2017 15:06:37 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id v17sm10391279qtv.62.2017.09.13.15.06.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:37 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:38 -0400 Message-Id: <20170913220546.19560-16-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 15/21] efi_loader: add bootmgr 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Similar to a "real" UEFI implementation, the bootmgr looks at the BootOrder and BootXXXX variables to try to find an EFI payload to load and boot. This is added as a sub-command of bootefi. The idea is that the distro bootcmd would first try loading a payload via the bootmgr, and then if that fails (ie. first boot or corrupted EFI variables) it would fallback to loading bootaa64.efi. (Which would then load fallback.efi which would look for \EFI\*\boot.csv and populate BootOrder and BootXXXX based on what it found.) Signed-off-by: Rob Clark --- cmd/bootefi.c | 48 +++++++++- include/config_distro_bootcmd.h | 5 ++ include/efi_api.h | 4 + include/efi_loader.h | 6 ++ lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_bootmgr.c | 180 ++++++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_boottime.c | 6 +- lib/efi_loader/efi_image_loader.c | 1 + 8 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 lib/efi_loader/efi_bootmgr.c diff --git a/cmd/bootefi.c b/cmd/bootefi.c index d3ae33e25b..fcd8dbafc1 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -219,6 +219,36 @@ exit: return ret; } +static int do_bootefi_bootmgr_exec(unsigned long fdt_addr) +{ + struct efi_device_path *device_path, *file_path; + void *addr; + efi_status_t r; + + /* Initialize and populate EFI object list */ + if (!efi_obj_list_initalized) + efi_init_obj_list(); + + /* + * gd lives in a fixed register which may get clobbered while we execute + * the payload. So save it here and restore it on every callback entry + */ + efi_save_gd(); + + addr = efi_bootmgr_load(&device_path, &file_path); + if (!addr) + return 1; + + printf("## Starting EFI application at %p ...\n", addr); + r = do_bootefi_exec(addr, (void *)fdt_addr, device_path, file_path); + printf("## Application terminated, r = %lu\n", + r & ~EFI_ERROR_MASK); + + if (r != EFI_SUCCESS) + return 1; + + return 0; +} /* Interpreter command to boot an arbitrary EFI image from memory */ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -237,7 +267,14 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) memcpy((char *)addr, __efi_hello_world_begin, size); } else #endif - { + if (!strcmp(argv[1], "bootmgr")) { + unsigned long fdt_addr = 0; + + if (argc > 2) + fdt_addr = simple_strtoul(argv[2], NULL, 16); + + return do_bootefi_bootmgr_exec(fdt_addr); + } else { saddr = argv[1]; addr = simple_strtoul(saddr, NULL, 16); @@ -270,7 +307,11 @@ static char bootefi_help_text[] = "hello\n" " - boot a sample Hello World application stored within U-Boot" #endif - ; + "bootmgr [fdt addr]\n" + " - load and boot EFI payload based on BootOrder/BootXXXX variables.\n" + "\n" + " If specified, the device tree located at gets\n" + " exposed as EFI configuration table.\n"; #endif U_BOOT_CMD( @@ -308,6 +349,9 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path) #endif } + if (!path) + return; + if (strcmp(dev, "Net")) { /* Add leading / to fs paths, because they're absolute */ snprintf(filename, sizeof(filename), "/%s", path); diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 9ed6b9892c..e0d0034ed3 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -112,6 +112,11 @@ #define BOOTENV_SHARED_EFI \ "boot_efi_binary=" \ + "if fdt addr ${fdt_addr_r}; then " \ + "bootefi bootmgr ${fdt_addr_r};" \ + "else " \ + "bootefi bootmgr ${fdtcontroladdr};" \ + "fi;" \ "load ${devtype} ${devnum}:${distro_bootpart} " \ "${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \ "if fdt addr ${fdt_addr_r}; then " \ diff --git a/include/efi_api.h b/include/efi_api.h index 1aae96355f..d0aefa8221 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -211,6 +211,10 @@ struct efi_runtime_services { EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) +#define EFI_GLOBAL_VARIABLE_GUID \ + EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, \ + 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c) + #define LOADED_IMAGE_PROTOCOL_GUID \ EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, \ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) diff --git a/include/efi_loader.h b/include/efi_loader.h index 9eee62dc9c..adc0bcf609 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -61,6 +61,7 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; uint16_t *efi_dp_str(struct efi_device_path *dp); +extern const efi_guid_t efi_global_variable_guid; extern const efi_guid_t efi_guid_console_control; extern const efi_guid_t efi_guid_device_path; extern const efi_guid_t efi_guid_loaded_image; @@ -209,6 +210,8 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, struct efi_device_path *device_path, struct efi_device_path *file_path); +efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, + void **buffer); #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER extern void *efi_bounce_buffer; @@ -287,6 +290,9 @@ efi_status_t EFIAPI efi_set_variable(s16 *variable_name, efi_guid_t *vendor, u32 attributes, unsigned long data_size, void *data); +void *efi_bootmgr_load(struct efi_device_path **device_path, + struct efi_device_path **file_path); + #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */ /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index f58cb13337..930c0e218e 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -16,7 +16,7 @@ always := $(efiprogs-y) obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -obj-y += efi_file.o efi_variable.o +obj-y += efi_file.o efi_variable.o efi_bootmgr.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c new file mode 100644 index 0000000000..857d88a879 --- /dev/null +++ b/lib/efi_loader/efi_bootmgr.c @@ -0,0 +1,180 @@ +/* + * EFI utils + * + * Copyright (c) 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static const struct efi_boot_services *bs; +static const struct efi_runtime_services *rs; + +#define LOAD_OPTION_ACTIVE 0x00000001 +#define LOAD_OPTION_FORCE_RECONNECT 0x00000002 +#define LOAD_OPTION_HIDDEN 0x00000008 + +/* + * bootmgr implements the logic of trying to find a payload to boot + * based on the BootOrder + BootXXXX variables, and then loading it. + * + * TODO detecting a special key held (f9?) and displaying a boot menu + * like you would get on a PC would be clever. + * + * TODO if we had a way to write and persist variables after the OS + * has started, we'd also want to check OsIndications to see if we + * should do normal or recovery boot. + */ + + +/* + * 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) +{ + lo->attributes = *(u32 *)ptr; + ptr += sizeof(u32); + + lo->file_path_length = *(u16 *)ptr; + ptr += sizeof(u16); + + lo->label = ptr; + ptr += (utf16_strlen(lo->label) + 1) * 2; + + lo->file_path = ptr; + ptr += lo->file_path_length; + + lo->optional_data = ptr; +} + +/* free() the result */ +static void *get_var(u16 *name, const efi_guid_t *vendor, + unsigned long *size) +{ + efi_guid_t *v = (efi_guid_t *)vendor; + efi_status_t ret; + void *buf = NULL; + + *size = 0; + EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); + if (ret == EFI_BUFFER_TOO_SMALL) { + buf = malloc(*size); + EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); + } + + if (ret != EFI_SUCCESS) { + free(buf); + *size = 0; + return NULL; + } + + return buf; +} + +/* + * Attempt to load load-option number 'n', returning device_path and file_path + * if successful. This checks that the EFI_LOAD_OPTION is active (enabled) + * and that the specified file to boot exists. + */ +static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, + struct efi_device_path **file_path) +{ + struct load_option lo; + u16 varname[] = L"Boot0000"; + u16 hexmap[] = L"0123456789ABCDEF"; + void *load_option, *image = NULL; + unsigned long size; + + varname[4] = hexmap[(n & 0xf000) >> 12]; + varname[5] = hexmap[(n & 0x0f00) >> 8]; + varname[6] = hexmap[(n & 0x00f0) >> 4]; + varname[7] = hexmap[(n & 0x000f) >> 0]; + + load_option = get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + return NULL; + + parse_load_option(&lo, load_option); + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + efi_status_t ret; + u16 *str = NULL; + + debug("%s: trying to load \"%ls\" from: %ls\n", __func__, + lo.label, (str = efi_dp_str(lo.file_path))); + efi_free_pool(str); + + ret = efi_load_image_from_path(lo.file_path, &image); + + if (ret != EFI_SUCCESS) + goto error; + + printf("Booting: %ls\n", lo.label); + efi_dp_split_file_path(lo.file_path, device_path, file_path); + } + +error: + free(load_option); + + return image; +} + +/* + * Attempt to load, in the order specified by BootOrder EFI variable, the + * available load-options, finding and returning the first one that can + * be loaded successfully. + */ +void *efi_bootmgr_load(struct efi_device_path **device_path, + struct efi_device_path **file_path) +{ + uint16_t *bootorder; + unsigned long size; + void *image = NULL; + int i, num; + + __efi_entry_check(); + + bs = systab.boottime; + rs = systab.runtime; + + bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + goto error; + + num = size / sizeof(uint16_t); + for (i = 0; i < num; i++) { + debug("%s: trying to load Boot%04X\n", __func__, bootorder[i]); + image = try_load_entry(bootorder[i], device_path, file_path); + if (image) + break; + } + + free(bootorder); + +error: + __efi_exit_check(); + + return image; +} diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index c406ff82ff..cea242cd49 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -763,8 +763,8 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob list_add_tail(&obj->link, &efi_obj_list); } -static efi_status_t load_image_from_path(struct efi_device_path *file_path, - void **buffer) +efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, + void **buffer) { struct efi_file_info *info = NULL; struct efi_file_handle *f; @@ -824,7 +824,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, struct efi_device_path *dp, *fp; efi_status_t ret; - ret = load_image_from_path(file_path, &source_buffer); + ret = efi_load_image_from_path(file_path, &source_buffer); if (ret != EFI_SUCCESS) { free(info); free(obj); diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 469acae082..242e6a504b 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; +const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID; const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID; const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID; const efi_guid_t efi_simple_file_system_protocol_guid = From patchwork Wed Sep 13 22:05:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813647 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LtYZJ9VQ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswvX0YXqz9sNw for ; Thu, 14 Sep 2017 08:15:03 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id A0CCBC22616; Wed, 13 Sep 2017 22:12: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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 F0AD6C223DA; Wed, 13 Sep 2017 22:10:05 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id BA007C22606; Wed, 13 Sep 2017 22:06:46 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 40201C225E2 for ; Wed, 13 Sep 2017 22:06:42 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id l25so952021qtf.2 for ; Wed, 13 Sep 2017 15:06:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eKNEbTNPwYyc9cSmY1v6hSuh8K6+67XhrvgdWfpB7Es=; b=LtYZJ9VQkBmzj2ndMs6gUrbexO1i7GphKm3O3cgxVYetqrF+EZHmrbS5PAAnCEwzua Pz5KsKFydVHaCP5921uPShbXmpsJ13mPW76PX2nVFXTcLUh60q5H5XYYo31oU+lGubfO xCx6ZYgmRZgYZXBp79dTFNeR1kwaYvjDrIEOuE/t0aX7S6Ji1iiH0PnhKlI+NBynUr/9 +bbTAOssl4/tPtFgJP06j99/1UP/b02PKkC1kEzde3ceZZpAUvAVOwOuG4Dm5XphDJT5 uMVVZzX7gnNrJlvXaY7wJ0g0Tlf4mavxO/ICxe2W5AVAs23Tz62UEUZwcYm1skVin97W 8g3A== 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; bh=eKNEbTNPwYyc9cSmY1v6hSuh8K6+67XhrvgdWfpB7Es=; b=NCZjmfHDkAWB1hsZfpilTvxQbGvou3RGYrPSTf0L4VVBFlD2JslTm9oOHMw33v73tQ mgL0OECdVHdrTZS92Ml0e6+kg8kN3EMi3Kijk4tfK3YC6YqCUTJEM0Z4Mv0q46iNpl88 l2B5helsdIPuKWz9ILDxufOFg8S/8DcuNylKEVk3VoNatwp3FjTLFPH2j/nFBqjiNgg7 IsEg6xN/uKVHiwr2isDF71P/unOpTBNsWECmmTXUF9Di5na3rfFzmh5u32iWrEwrPmZj WHhl5NGXvQhutPM2a2Zft5koJ3ijpVrq1M7Lr9nYqaVMMXvUWZTqmzbKTCKnGv6Sp25F LELA== X-Gm-Message-State: AHPjjUhFlPx303oHoIw6XbOjiH5OdT0pm8l7Y0NFoKJR3eDeLC4S9yjz 7H8yRRasRKa83eeImBM= X-Google-Smtp-Source: AOwi7QAiXjsJlZXQ0XedvgCdA3t5emQUEkmAuSOPWluC3AXThWsF0G+uxhjnPC4XEm1MLSg1jln4Hg== X-Received: by 10.200.53.216 with SMTP id l24mr27761892qtb.7.1505340401000; Wed, 13 Sep 2017 15:06:41 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id u17sm10638363qtc.15.2017.09.13.15.06.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:40 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:39 -0400 Message-Id: <20170913220546.19560-17-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 16/21] efi_loader: file_path should be variable length 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Signed-off-by: Rob Clark --- include/efi_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/efi_api.h b/include/efi_api.h index d0aefa8221..604c5b7ec4 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -373,7 +373,7 @@ struct efi_device_path_cdrom_path { struct efi_device_path_file_path { struct efi_device_path dp; - u16 str[32]; + u16 str[]; } __packed; #define BLOCK_IO_GUID \ From patchwork Wed Sep 13 22:05:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813655 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="foB516/u"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx0y1h4nz9sxR for ; Thu, 14 Sep 2017 08:19:46 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E4589C226F5; Wed, 13 Sep 2017 22:12:57 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 40E09C225FD; Wed, 13 Sep 2017 22:11:57 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 17966C2257F; Wed, 13 Sep 2017 22:06:49 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id 63472C2257F for ; Wed, 13 Sep 2017 22:06:45 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id t46so942220qtj.3 for ; Wed, 13 Sep 2017 15:06:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=agLKFCHofSoXSGDDqTTx4I8hvrEJSirlG3r1W1vdczo=; b=foB516/ulBHjib94ZrsVYqhzw3uZcuLZcZlSTWH6WP5fuzhMeTAFA3Q2EUpskGE40x bQ7PogzK5WQbF8L7omsf4Ocd62CJLHZbXaFIRvJaZcz7K+3Q3Iz8pDQmi40uxcfDJqhR OClMkakuH51TESRRd8L2aO39l8zVSH33+zVOQKQD5MIRilHEEFHrYOTN+E4kuqHy31Di NWNkzMvmFTCy3fNif2lv22nD0kgQk3omU9ljkHr5TjXIQD0Tsy49qxawYt09ZpYeTHT/ myOPwlaXCA7rJuZi8DoTpDKP5kEhzCUwn3GwaD0FP+RsmKlbpSA/Ctteilz1c2rdmOls Ioxg== 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; bh=agLKFCHofSoXSGDDqTTx4I8hvrEJSirlG3r1W1vdczo=; b=LhZ+g8eszlbJ5eCbwlMwbWCgAilNWUoVn/oDJUGWg/5mV1ROc4JOo751xrCwvl1BU6 bm+Qz+8PzaS8XWdmsNxfsVAnzZ3yDN1P5/6CULIkTQ+jxUFv6qcEEeLSKy1B3z/1PaZL fw1MnocisExnUICNOer+sZy43xnmpnIBPT8sbo9DYKYTsyGHx7kutCUtUdXEmDVujq9C bnpg5jaOm/8zhuT041KyisHSE4mUhrbhhQkO2HMTcupgb0ueb0140/jCyHnt8WTIoG+s NJwhh2s2zOyqnsxGtfkpsAY1vQiKXegW7uXI+CCjBAiDV0BfYDZn5SLSUVEdoXkrhnET 76HA== X-Gm-Message-State: AHPjjUgfsofeHKCTucPczz5gHZax6d9TqlnKsttQbNx5ofdTJMwjL+8G V+CPjtHUVatKqdxDPYU= X-Google-Smtp-Source: AOwi7QDc56FegPvAG5DvC/nWPH3eye95MZJcR6fa7RishxT/BSiwdBqaTmQy8wRQ9/S2IKSKg4ftDw== X-Received: by 10.200.35.204 with SMTP id r12mr18317907qtr.95.1505340404103; Wed, 13 Sep 2017 15:06:44 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id r22sm10509933qtj.94.2017.09.13.15.06.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:43 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:40 -0400 Message-Id: <20170913220546.19560-18-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 17/21] efi_loader: set loaded image code/data type properly 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" These should be set according to the image type. Shell.efi and SCT.efi use these fields to determine what sort of image they are loading. Signed-off-by: Rob Clark --- include/pe.h | 6 ++++++ lib/efi_loader/efi_image_loader.c | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/pe.h b/include/pe.h index deb35a0ea4..4ef3e92efa 100644 --- a/include/pe.h +++ b/include/pe.h @@ -62,6 +62,12 @@ typedef struct _IMAGE_DATA_DIRECTORY { #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +/* PE32+ Subsystem type for EFI images */ +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + typedef struct _IMAGE_OPTIONAL_HEADER64 { uint16_t Magic; /* 0x20b */ uint8_t MajorLinkerVersion; diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 242e6a504b..af29cc4f04 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -94,6 +94,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) unsigned long virt_size = 0; bool can_run_nt64 = true; bool can_run_nt32 = true; + uint16_t image_type; #if defined(CONFIG_ARM64) can_run_nt32 = false; @@ -139,6 +140,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; + image_type = opt->Subsystem; } else if (can_run_nt32 && (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) { IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader; @@ -152,12 +154,32 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) entry = efi_reloc + opt->AddressOfEntryPoint; rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; + image_type = opt->Subsystem; } else { printf("%s: Invalid optional header magic %x\n", __func__, nt->OptionalHeader.Magic); return NULL; } + switch (image_type) { + case IMAGE_SUBSYSTEM_EFI_APPLICATION: + loaded_image_info->image_code_type = EFI_LOADER_CODE; + loaded_image_info->image_data_type = EFI_LOADER_DATA; + break; + case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: + loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE; + loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA; + break; + case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: + case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER: + loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE; + loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA; + break; + default: + printf("%s: invalid image type: %u\n", __func__, image_type); + break; + } + /* Load sections into RAM */ for (i = num_sections - 1; i >= 0; i--) { IMAGE_SECTION_HEADER *sec = §ions[i]; From patchwork Wed Sep 13 22:05:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813646 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="CDNZTxMt"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswsw0YZRz9sNw for ; Thu, 14 Sep 2017 08:13:40 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id DFA06C225FD; Wed, 13 Sep 2017 22:11: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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 ACEF1C22649; Wed, 13 Sep 2017 22:09:21 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id EB488C22611; Wed, 13 Sep 2017 22:06:52 +0000 (UTC) Received: from mail-qk0-f196.google.com (mail-qk0-f196.google.com [209.85.220.196]) by lists.denx.de (Postfix) with ESMTPS id 70474C22518 for ; Wed, 13 Sep 2017 22:06:48 +0000 (UTC) Received: by mail-qk0-f196.google.com with SMTP id r66so943103qke.4 for ; Wed, 13 Sep 2017 15:06:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JxCT757wgQICSsbBlPdYYntd3CmqgUV/Om6Fv6OmC04=; b=CDNZTxMtJ4LhtX5BQ2l1Avr0bGbBboNtLs4VjolP/OjHt4r4WMia0WwygmPCZKDfD+ 6iGbJptIM6PQQYMSALpE/abUTvB1/SackDOBkD3hryrGND9qvULFamE3RvxamRHclyia Y/u2VFB2Bb5bOzh41MLvMBX+GfEGcl//A7WhWA0184zt9S2DFzumBf/hETg25rcJewnu t6LdactgCb/2T6VMUXwIamEamr9JqyTt82+dbex5fJq0Ubmldj+2ZEKuzriQUMEcf/LC FqkwyQcgfR55fdUlymuu88TyiMUfwlL6RhbxyIdb8OU1LwETrZ5scvTkPO+9IUyid+jE chOw== 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; bh=JxCT757wgQICSsbBlPdYYntd3CmqgUV/Om6Fv6OmC04=; b=K2cITJSAqCFhg13UWJ3eQBXwPxU29tBa6M3g+lTS0a2uQoiJ8EZPP4xlU33lIH5FzA 7iRhUi4ShoNi6GJnbFJPD8dvFWqO0LTLPZx/Bi/9LTB1Osxr0L9yaUVfIgF/jGPo4KNp 4S6g3Hn6EKreTg1fwgl9gKbT0vrQFLPqvot7PbrLYPogtiP3c+i2cW9GsWvsJFUEjkxv jvJwX2hgSaiIHlEx6IwDKduRr2G1S4uJa4+ChpjAXvCSyv4HMYZGDxI5IyogZMNrAmnR x0C6Ks/fvaU9nq1HVL1ehbSFqglND9nbUnOs6hAsDC842DCcbDtN/+7Znghjp0VAoH6N ZELg== X-Gm-Message-State: AHPjjUi0wcNewludLKFdl5hLDJ1aBEGCqRrRSb0ZJBuW+TzICkp+BEvW 2ADTkMrQagBJDdvEywo= X-Google-Smtp-Source: AOwi7QCnDge1PPln2ob9A+okboO7Pvaw/jZ/QbTzIst+auJckUdnoKnhqZ1biK2oXJDbqXb5+d+zKg== X-Received: by 10.55.110.3 with SMTP id j3mr25600830qkc.195.1505340407149; Wed, 13 Sep 2017 15:06:47 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id e126sm9851950qkd.86.2017.09.13.15.06.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:46 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:41 -0400 Message-Id: <20170913220546.19560-19-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 18/21] efi_loader: print GUIDs 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Utilize printf GUID support to print GUIDs. Signed-off-by: Rob Clark --- lib/efi_loader/efi_boottime.c | 22 +++++++++++----------- lib/efi_loader/efi_variable.c | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index cea242cd49..b6f32c98d9 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -514,7 +514,7 @@ static efi_status_t EFIAPI efi_install_protocol_interface_ext(void **handle, efi_guid_t *protocol, int protocol_interface_type, void *protocol_interface) { - EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type, + EFI_ENTRY("%p, %pUl, %d, %p", handle, protocol, protocol_interface_type, protocol_interface); return EFI_EXIT(efi_install_protocol_interface(handle, protocol, @@ -526,7 +526,7 @@ static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle, efi_guid_t *protocol, void *old_interface, void *new_interface) { - EFI_ENTRY("%p, %p, %p, %p", handle, protocol, old_interface, + EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface, new_interface); return EFI_EXIT(EFI_ACCESS_DENIED); } @@ -575,7 +575,7 @@ out: static efi_status_t EFIAPI efi_uninstall_protocol_interface_ext(void *handle, efi_guid_t *protocol, void *protocol_interface) { - EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface); + EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface); return EFI_EXIT(efi_uninstall_protocol_interface(handle, protocol, protocol_interface)); @@ -585,7 +585,7 @@ static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol, struct efi_event *event, void **registration) { - EFI_ENTRY("%p, %p, %p", protocol, event, registration); + EFI_ENTRY("%pUl, %p, %p", protocol, event, registration); return EFI_EXIT(EFI_OUT_OF_RESOURCES); } @@ -655,7 +655,7 @@ static efi_status_t EFIAPI efi_locate_handle_ext( efi_guid_t *protocol, void *search_key, unsigned long *buffer_size, efi_handle_t *buffer) { - EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, + EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key, buffer_size, buffer); return EFI_EXIT(efi_locate_handle(search_type, protocol, search_key, @@ -723,7 +723,7 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, void *table) { - EFI_ENTRY("%p, %p", guid, table); + EFI_ENTRY("%pUl, %p", guid, table); return EFI_EXIT(efi_install_configuration_table(guid, table)); } @@ -1012,7 +1012,7 @@ static efi_status_t EFIAPI efi_close_protocol(void *handle, void *agent_handle, void *controller_handle) { - EFI_ENTRY("%p, %p, %p, %p", handle, protocol, agent_handle, + EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, agent_handle, controller_handle); return EFI_EXIT(EFI_NOT_FOUND); } @@ -1022,7 +1022,7 @@ static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle, struct efi_open_protocol_info_entry **entry_buffer, unsigned long *entry_count) { - EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer, + EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer, entry_count); return EFI_EXIT(EFI_NOT_FOUND); } @@ -1088,7 +1088,7 @@ static efi_status_t EFIAPI efi_locate_handle_buffer( efi_status_t r; unsigned long buffer_size = 0; - EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, + EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key, no_handles, buffer); if (!no_handles || !buffer) { @@ -1120,7 +1120,7 @@ static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol, struct list_head *lhandle; int i; - EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface); + EFI_ENTRY("%pUl, %p, %p", protocol, registration, protocol_interface); if (!protocol || !protocol_interface) return EFI_EXIT(EFI_INVALID_PARAMETER); @@ -1228,7 +1228,7 @@ static efi_status_t EFIAPI efi_open_protocol( int i; efi_status_t r = EFI_INVALID_PARAMETER; - EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol, + EFI_ENTRY("%p, %pUl, %p, %p, %p, 0x%x", handle, protocol, protocol_interface, agent_handle, controller_handle, attributes); diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 5569b3d3f0..6c177da3a6 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -187,7 +187,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name, const char *val, *s; u32 attr; - EFI_ENTRY("%p %p %p %p %p", variable_name, vendor, attributes, + EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes, data_size, data); if (!variable_name || !vendor || !data_size) @@ -255,7 +255,7 @@ efi_status_t EFIAPI efi_get_next_variable( unsigned long *variable_name_size, s16 *variable_name, efi_guid_t *vendor) { - EFI_ENTRY("%p %p %p", variable_name_size, variable_name, vendor); + EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); return EFI_EXIT(EFI_DEVICE_ERROR); } @@ -270,7 +270,7 @@ efi_status_t EFIAPI efi_set_variable(s16 *variable_name, char *val, *s; u32 attr; - EFI_ENTRY("%p %p %x %lu %p", variable_name, vendor, attributes, + EFI_ENTRY("\"%ls\" %pUl %x %lu %p", variable_name, vendor, attributes, data_size, data); if (!variable_name || !vendor) From patchwork Wed Sep 13 22:05:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813654 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kFuTe9iF"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswzp0HkGz9s76 for ; Thu, 14 Sep 2017 08:18:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CDD4AC22721; Wed, 13 Sep 2017 22:13:46 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 70DDDC2259B; Wed, 13 Sep 2017 22:13:43 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 901DFC225AC; Wed, 13 Sep 2017 22:06:54 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id 43DA3C21F60 for ; Wed, 13 Sep 2017 22:06:51 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id t46so942300qtj.3 for ; Wed, 13 Sep 2017 15:06:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zmASFMSzYWSBSdugC77vjUNtmmQgCCSF2tHQAtczTpw=; b=kFuTe9iFoM7alWc7OE//IW/e/FV9tGgl3TmgTr+eO3FfQ5DSYjJ3wT1R+OBdYJWUVN To7NgcPgMSHiv5B14sFvJDUyyW2pHFwR+nHM5oseqzbSkpFyU5RTsSrlkVitTl4wv5tc tFGsnkT6p+oYOAFKeZPsjaSMMnIa6iFGdjotOiTrZgJqQ4gae8yjEkiD7cbmQf52O6y5 s5U9Nk4lady+7rLd2ColCYfLnLAtwpdWRG1oKNgYD7wdEWYeNCZ0zwwuIgO4LhhFmMPl Gu3gQPQNdU9ulemvIpyrbZNAthwia5M3aQT4026flN4VrIYRYs6CRT3VNNtbwLPglINq z93A== 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; bh=zmASFMSzYWSBSdugC77vjUNtmmQgCCSF2tHQAtczTpw=; b=ncHBabtQIREf3nzqcTcD04pqNTPlQN5QL7RDlbcKAytx6hXn1aRaOMYHGeoEbWGliV tUcX+ecirmHWPEHxo7hJgFMjmtITcQzoc1HtCPvlIbXzAvznq0a9fHO8U4kCtNhPhZ/J A3kZOys/IRpEcpssDZlSyd2Q1LJWC7Y8p//mu1vhbNmqpyvcrWJR3jp6BKTo1OXwwrMm bK5Z2fi1XAQbgmHViPZ0rpk4Eoi9FRjLRpYgAvlJk4/k6ukDu20o0rZvmYDI9ZpFz6aD /UiPP+oYCRIFpAnimZlu/ys4wH07stj51rKpEOkKR1AO0srq1IZ/ldaictIdeAKV/KFM S9zg== X-Gm-Message-State: AHPjjUg5QvLZoY1nms5ryxt2wF/1uP1JwuYqW2xIrPZYJfoobrIv8I0e I0sbse8QSPC9/n3y6s8= X-Google-Smtp-Source: AOwi7QB5D3vB68JYN/LWdw+ga3IalxQ5ZmDXLtqToxqIs0x6Gbcpxt1klz1ZA41gXUW3fSuafiNl1w== X-Received: by 10.200.3.111 with SMTP id w47mr18698830qtg.144.1505340409985; Wed, 13 Sep 2017 15:06:49 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id v11sm10398324qkl.45.2017.09.13.15.06.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:49 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:42 -0400 Message-Id: <20170913220546.19560-20-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 19/21] efi_loader: split out escape sequence based size query 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" We need to do something different for vidconsole, since it cannot respond to the query on stdin. Prep work for next patch. Signed-off-by: Rob Clark --- lib/efi_loader/efi_console.c | 53 +++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 3fc82b8726..e8c02870eb 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -186,6 +186,34 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols) return (mode->rows == rows) && (mode->columns == cols); } +static int query_console_serial(int *rows, int *cols) +{ + /* Ask the terminal about its size */ + int n[3]; + u64 timeout; + + /* Empty input buffer */ + while (tstc()) + getc(); + + printf(ESC"[18t"); + + /* Check if we have a terminal that understands */ + timeout = timer_get_us() + 1000000; + while (!tstc()) + if (timer_get_us() > timeout) + return -1; + + /* Read {depth,rows,cols} */ + if (term_read_reply(n, 3, 't')) + return -1; + + *cols = n[2]; + *rows = n[1]; + + return 0; +} + static efi_status_t EFIAPI efi_cout_query_mode( struct efi_simple_text_output_protocol *this, unsigned long mode_number, unsigned long *columns, @@ -194,33 +222,12 @@ static efi_status_t EFIAPI efi_cout_query_mode( EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows); if (!console_size_queried) { - /* Ask the terminal about its size */ - int n[3]; - int cols; - int rows; - u64 timeout; + int rows, cols; console_size_queried = true; - /* Empty input buffer */ - while (tstc()) - getc(); - - printf(ESC"[18t"); - - /* Check if we have a terminal that understands */ - timeout = timer_get_us() + 1000000; - while (!tstc()) - if (timer_get_us() > timeout) - goto out; - - /* Read {depth,rows,cols} */ - if (term_read_reply(n, 3, 't')) { + if (query_console_serial(&rows, &cols)) goto out; - } - - cols = n[2]; - rows = n[1]; /* Test if we can have Mode 1 */ if (cols >= 80 && rows >= 50) { From patchwork Wed Sep 13 22:05:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813659 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="CZZWr+aZ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xsx3N2lxfz9sxR for ; Thu, 14 Sep 2017 08:21:52 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1106FC2217C; Wed, 13 Sep 2017 22:11:26 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 4BC2CC22616; Wed, 13 Sep 2017 22:08:44 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B3D90C22625; Wed, 13 Sep 2017 22:06:57 +0000 (UTC) Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by lists.denx.de (Postfix) with ESMTPS id 07AFFC2257F for ; Wed, 13 Sep 2017 22:06:54 +0000 (UTC) Received: by mail-qt0-f195.google.com with SMTP id t46so942351qtj.3 for ; Wed, 13 Sep 2017 15:06:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vtK1zZTLszv9J+4U8WH5KLG+0f5uZYnvDQoIBqpAXI4=; b=CZZWr+aZ+0bGwQsRMyVu6H21zKVUsJPeebt7qc74hiVLuY5OWehTnzCi1q738YNDpb D/nk2SLrDVR2vNq0ODXuTHly8tQhLmuz1zJ3M61ZqCOxjJBI+g/CQFIjJP3N7NGjGE9W 5wBQdsRHMWE8zZN5Hlud2xSGWrXMWJiSza2GHudDa284+HmY6YqHf5wOC/KA/bs4xdm0 vkDNz4NCDj0TyLwODRvonlY3Zl8UWZgeb7Xbq4h8MmjQj1pn2a1TAXCIYPKV+Y6GgUWh CbIh/9HGMYJHS1d4mIkqHy2p1jgjop/7Ike0xv50uhTk2kzF29+MsPyimmrLuEFgX7tt eiLg== 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; bh=vtK1zZTLszv9J+4U8WH5KLG+0f5uZYnvDQoIBqpAXI4=; b=DCK122Yq3bFBns+mXFHRUJwFuCAWL/HakWE1+8XgNoQ1X5ZwDEl4yHbeGENSy1xmqu 1y9K1ZSW+s9TlXjBqmWy8KL3JuObKRTCXaMQG8/1dv20UmyjNW9k6coVljcQvWPbJvAm G1KFHfHFT309A/dk8Q8l1ArJwqYEWXYFhdOPj7UhM6JAM8NczX6dz/uHCval1ui8/N1L oxV/Bwb+OgnrRrGV+Uvltx9vK22o3vR+PGejN4UXcEWjAa5MzuiRxa23KIC4OcNErfuD dejj6zd5sn4axOTlfy/6RPRxdzmwtFeg8/o9F7xx2rpZoXEQkA1QANO60EUOArl5zkHb EV7Q== X-Gm-Message-State: AHPjjUiZ4JEdnNrqRKHvaYJIxX/9oVu6UL0a+MzGvFbGx6au8c5ueniq 8yyqJTxw6WHUDTbkxoc= X-Google-Smtp-Source: AOwi7QAbI5G8EwB2WJ12nhpBCu0rm90R59bF58pP8CqaokOva4luSAsMYpKWwI9U4zzQETJ1nc4obw== X-Received: by 10.200.15.210 with SMTP id f18mr29063129qtk.226.1505340412749; Wed, 13 Sep 2017 15:06:52 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id s7sm9872594qkf.4.2017.09.13.15.06.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:51 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:43 -0400 Message-Id: <20170913220546.19560-21-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 20/21] efi_loader: Correctly figure out size for vidconsole 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" If stdout is vidconsole, we cannot rely on ANSI escape sequences to query the size, as vidconsole cannot reply on stdin. Instead special- case this if stdout is vidconsole. Signed-off-by: Rob Clark --- lib/efi_loader/efi_console.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index e8c02870eb..9048a8d32c 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -8,7 +8,10 @@ #include #include +#include #include +#include +#include static bool console_size_queried; @@ -222,12 +225,23 @@ static efi_status_t EFIAPI efi_cout_query_mode( EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows); if (!console_size_queried) { + const char *stdout_name = env_get("stdout"); int rows, cols; console_size_queried = true; - if (query_console_serial(&rows, &cols)) + if (stdout_name && !strcmp(stdout_name, "vidconsole") && + IS_ENABLED(CONFIG_DM_VIDEO)) { + struct stdio_dev *stdout_dev = + stdio_get_by_name("vidconsole"); + struct udevice *dev = stdout_dev->priv; + struct vidconsole_priv *priv = + dev_get_uclass_priv(dev); + rows = priv->rows; + cols = priv->cols; + } else if (query_console_serial(&rows, &cols)) { goto out; + } /* Test if we can have Mode 1 */ if (cols >= 80 && rows >= 50) { From patchwork Wed Sep 13 22:05:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 813651 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; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="p19Gjsn9"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xswzG1kg8z9s76 for ; Thu, 14 Sep 2017 08:18:18 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 021A5C22739; Wed, 13 Sep 2017 22:11:40 +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=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, 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 8353BC22440; Wed, 13 Sep 2017 22:09:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 293F4C22649; Wed, 13 Sep 2017 22:07:00 +0000 (UTC) Received: from mail-qk0-f193.google.com (mail-qk0-f193.google.com [209.85.220.193]) by lists.denx.de (Postfix) with ESMTPS id 23125C222F6 for ; Wed, 13 Sep 2017 22:06:57 +0000 (UTC) Received: by mail-qk0-f193.google.com with SMTP id g128so957656qke.0 for ; Wed, 13 Sep 2017 15:06:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tTjJNgm+knfE2IVXbgcSZPd7Q9s0s6Q4yiWNU5LVgTo=; b=p19Gjsn94q8hJs1Xa1e60A1TEdRggJDYW4/tjg5KNI+WXmBIDg69dJHSv5vg9qVqyk 1swG+00Mm1XRKUrayK7c+dhRH1w+uQAI8iTGsybpDDEwOI34BggMaO13Xg7PHSjX1G0R 24kED1+O/e/7IvWW8UAmBiGqGws6BpZg4CNEzwIWhfaDxysFr26DISc1gR+sWnDGizbC ZYL7w8/wDhNWlMd8OAvkbb93PccezIDl0MBhuwWsBkZqnq+11Zp8zsd3PNVFPovQMvp2 5pENu/Y8WbWLKmJJavNtOR4z05ltwErLhVhkk6dMWd1Ph8jDcQnFWmPQHB3rBCVVY1Qb jo3Q== 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; bh=tTjJNgm+knfE2IVXbgcSZPd7Q9s0s6Q4yiWNU5LVgTo=; b=c8HcUQiVDfqnG0BpVi1cdALXvBcSAPVrVXTr9qyo5vtDcIx5Hwd4BpzDPx8483kEFD 2tcirt8ES1bGcpBB48Hwzrk7TDHJQ05HtOwwPIfE7BQtlRRGk1c27mOeWf3fASeDhhVG a6OT7w0gATPNqgX1mSwD0+h9Lz3bPt3l0Gab26u/0KocZMVoWiNo1iilybUBpjY/reKK cp797hnlW70DHEJd/KgIbe2YYhXe6uQNnRPeKrhX+SfmTJburQzA1Sr9J4xZGwHDYkUr 9WRzv0zJUNyi8aViEbP8c8Ij30Ohh0DMU+Krio7yF3EC3Wgkedzhw13id7AQP7nPGIQG 75dg== X-Gm-Message-State: AHPjjUiP2byD/mAlDDZ2e5Mjh/b0IgblXojyxgjLq8i2aeagseYl6VtI upIz6p1yFt2av6I79DU= X-Google-Smtp-Source: AOwi7QAgQ2WMpVM6BL8QwKJkWqUvVnw/9ycqdDqC95Qin0teqklmoO7YOnQn2VRsqP8FvBxYjj+XEA== X-Received: by 10.55.98.18 with SMTP id w18mr27728572qkb.163.1505340415863; Wed, 13 Sep 2017 15:06:55 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id c7sm6554168qtg.30.2017.09.13.15.06.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Sep 2017 15:06:54 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Wed, 13 Sep 2017 18:05:44 -0400 Message-Id: <20170913220546.19560-22-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913220546.19560-1-robdclark@gmail.com> References: <20170913220546.19560-1-robdclark@gmail.com> Cc: Heinrich Schuchardt , Peter Jones Subject: [U-Boot] [PATCH v3 21/21] efi_loader: Some console improvements for vidconsole 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 1) use fputs() to reduce cache flushes from once-per-char to once-per-string 2) handle \r, \t, and \b in addition to just \n for tracking cursor position 3) cursor row/col are zero based, not one based Signed-off-by: Rob Clark --- include/efi_api.h | 6 +++-- lib/efi_loader/efi_console.c | 58 ++++++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 604c5b7ec4..c3b9032a48 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -29,6 +29,8 @@ enum efi_timer_delay { }; #define UINTN size_t +typedef long INTN; +typedef uint16_t *efi_string_t; #define EVT_TIMER 0x80000000 #define EVT_RUNTIME 0x40000000 @@ -427,10 +429,10 @@ struct efi_simple_text_output_protocol { void *reset; efi_status_t (EFIAPI *output_string)( struct efi_simple_text_output_protocol *this, - const unsigned short *str); + const efi_string_t str); efi_status_t (EFIAPI *test_string)( struct efi_simple_text_output_protocol *this, - const unsigned short *str); + const efi_string_t str); efi_status_t(EFIAPI *query_mode)( struct efi_simple_text_output_protocol *this, unsigned long mode_number, unsigned long *columns, diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 9048a8d32c..afc725a2c7 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -140,34 +140,46 @@ static efi_status_t EFIAPI efi_cout_reset( return EFI_EXIT(EFI_UNSUPPORTED); } -static void print_unicode_in_utf8(u16 c) -{ - char utf8[MAX_UTF8_PER_UTF16] = { 0 }; - utf16_to_utf8((u8 *)utf8, &c, 1); - puts(utf8); -} - static efi_status_t EFIAPI efi_cout_output_string( struct efi_simple_text_output_protocol *this, - const unsigned short *string) + const efi_string_t string) { - struct cout_mode *mode; - u16 ch; + struct simple_text_output_mode *con = &efi_con_mode; + struct cout_mode *mode = &efi_cout_modes[con->mode]; - mode = &efi_cout_modes[efi_con_mode.mode]; EFI_ENTRY("%p, %p", this, string); - for (;(ch = *string); string++) { - print_unicode_in_utf8(ch); - efi_con_mode.cursor_column++; - if (ch == '\n') { - efi_con_mode.cursor_column = 1; - efi_con_mode.cursor_row++; - } else if (efi_con_mode.cursor_column > mode->columns) { - efi_con_mode.cursor_column = 1; - efi_con_mode.cursor_row++; + + unsigned n16 = utf16_strlen(string); + char buf[MAX_UTF8_PER_UTF16 * n16 + 1]; + char *p; + + *utf16_to_utf8((u8 *)buf, string, n16) = '\0'; + + fputs(stdout, buf); + + for (p = buf; *p; p++) { + switch (*p) { + case '\r': /* carriage-return */ + con->cursor_column = 0; + break; + case '\n': /* newline */ + con->cursor_column = 0; + con->cursor_row++; + break; + case '\t': /* tab, assume 8 char align */ + break; + case '\b': /* backspace */ + con->cursor_column = max(0, con->cursor_column - 1); + break; + default: + con->cursor_column++; + break; + } + if (con->cursor_column >= mode->columns) { + con->cursor_column = 0; + con->cursor_row++; } - if (efi_con_mode.cursor_row > mode->rows) - efi_con_mode.cursor_row = mode->rows; + con->cursor_row = min(con->cursor_row, (s32)mode->rows - 1); } return EFI_EXIT(EFI_SUCCESS); @@ -175,7 +187,7 @@ static efi_status_t EFIAPI efi_cout_output_string( static efi_status_t EFIAPI efi_cout_test_string( struct efi_simple_text_output_protocol *this, - const unsigned short *string) + const efi_string_t string) { EFI_ENTRY("%p, %p", this, string); return EFI_EXIT(EFI_SUCCESS);