From patchwork Mon Mar 8 11:29:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jose Marinho X-Patchwork-Id: 1448991 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-armh-onmicrosoft-com header.b=I1sWrMxJ; dkim=pass (1024-bit key) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-armh-onmicrosoft-com header.b=I1sWrMxJ; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DvGRJ6Cpvz9sVv for ; Mon, 8 Mar 2021 22:32:44 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A50BE82A15; Mon, 8 Mar 2021 12:32:39 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.b="I1sWrMxJ"; dkim=pass (1024-bit key) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.b="I1sWrMxJ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B042082A5C; Mon, 8 Mar 2021 12:32:14 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FORGED_SPF_HELO,MSGID_FROM_MTA_HEADER,SPF_HELO_PASS, UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.2 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on0606.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe0e::606]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id F26F582A23 for ; Mon, 8 Mar 2021 12:31:47 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=Jose.Marinho@arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=v7MZ6RCCmDDb05wRsYJsrrSNw0/36qHNntetk5h8a1Y=; b=I1sWrMxJy2nRslqlVSGAY5PnnTKqb9uIxf6HYO1+2s9mPFehx2UbNEQeoij3hb9HrSpyXuTMknsbW77mGFnqn2RXGyNQYW0UUK1/Z5/X6GrohFQacn2fJFDNeVN09e9IZpiAEliR20Zv/Q5guIAKGTVRKSD84KWjOL10Igo5YY0= Received: from DB7PR02CA0005.eurprd02.prod.outlook.com (2603:10a6:10:52::18) by AS8PR08MB6376.eurprd08.prod.outlook.com (2603:10a6:20b:33e::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.19; Mon, 8 Mar 2021 11:31:41 +0000 Received: from DB5EUR03FT012.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:52:cafe::25) by DB7PR02CA0005.outlook.office365.com (2603:10a6:10:52::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.17 via Frontend Transport; Mon, 8 Mar 2021 11:31:41 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; lists.denx.de; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;lists.denx.de; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DB5EUR03FT012.mail.protection.outlook.com (10.152.20.161) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.17 via Frontend Transport; Mon, 8 Mar 2021 11:31:41 +0000 Received: ("Tessian outbound 72bd4bdd1f59:v71"); Mon, 08 Mar 2021 11:31:41 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: fb35049fd83a324a X-CR-MTA-TID: 64aa7808 Received: from 1e8f70002c3d.2 by 64aa7808-outbound-1.mta.getcheckrecipient.com id C4363DEF-CAE2-4EBF-BDB4-0553BE68EDF8.1; Mon, 08 Mar 2021 11:31:35 +0000 Received: from EUR02-AM5-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 1e8f70002c3d.2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 08 Mar 2021 11:31:35 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=loc2OiR6IXm6WVdlniF6k6qW7nbeqY4z7Ekj0mAG+qPGUptTZP+WjplRafDSn5izizGKRdZnhu36SOvsYiLWERG4OMKsWwgKJox7yIqXifazuLIPmwFbaF9QecCJRinqDjdHkvBUh4HUMRwoSjBjE/sUgmm3DRIvdEPprydLI5vjYsqIIokee1UUhJ4Oa8te66INyWfI3vTbVkRQXuDrVCCtmQZns8LSJa6+Nto25q0O1lnxVYdWhH/eTmwFKswNkvdAoD1xoEk/KZVT2XcrMdVuGv04xBNcWUVaiAk1WqJBngZbssrm8QxnhOU58ijgwPd9fMqKewoE0BaSHqsiXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=v7MZ6RCCmDDb05wRsYJsrrSNw0/36qHNntetk5h8a1Y=; b=ZObk73LiqY8Rq+lHM8oDFREhYbyruWTfgmxbX/P1X255YuFwOFFaW8tzQV9gXEwjfJvu1UjKoqCyEncDnoi7N7wt+By4eDapy2ETgY432MumTMJjxi+8rApAO5nzTI8q/REG9fDg2UpHjgiMr4MASZt/MyACKR4RJbc/qDApo4EMtgh1fTH+FeBcz0T52YBnRg3IWpwcoP0ulFfyI1ysV/1rPsuNhI3Y1q6QVT1wLQLtZ+bpZr8PsuR7FRd0WVl1+SPjOrBNOmA7sxOFiK19EdEHLS4R5EzWq/rJ0dEfagvxorpvoqNUgcRX3d+LmWGX6Zl+7dvUNvkCyM9M9J5W7w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=v7MZ6RCCmDDb05wRsYJsrrSNw0/36qHNntetk5h8a1Y=; b=I1sWrMxJy2nRslqlVSGAY5PnnTKqb9uIxf6HYO1+2s9mPFehx2UbNEQeoij3hb9HrSpyXuTMknsbW77mGFnqn2RXGyNQYW0UUK1/Z5/X6GrohFQacn2fJFDNeVN09e9IZpiAEliR20Zv/Q5guIAKGTVRKSD84KWjOL10Igo5YY0= Authentication-Results-Original: lists.denx.de; dkim=none (message not signed) header.d=none; lists.denx.de; dmarc=none action=none header.from=arm.com; Received: from DBBPR08MB6012.eurprd08.prod.outlook.com (2603:10a6:10:205::9) by DB7PR08MB3500.eurprd08.prod.outlook.com (2603:10a6:10:49::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.17; Mon, 8 Mar 2021 11:31:33 +0000 Received: from DBBPR08MB6012.eurprd08.prod.outlook.com ([fe80::5d51:f66c:7554:6920]) by DBBPR08MB6012.eurprd08.prod.outlook.com ([fe80::5d51:f66c:7554:6920%4]) with mapi id 15.20.3912.027; Mon, 8 Mar 2021 11:31:33 +0000 From: Jose Marinho To: u-boot@lists.denx.de Cc: Jose Marinho , Heinrich Schuchardt , Sughosh Ganu , AKASHI Takahiro , Ilias Apalodimas , Andre Przywara , Alexander Graf , nd@arm.com Subject: [PATCH 1/4 v6] efi: Add ESRT to the EFI system table Date: Mon, 8 Mar 2021 11:29:32 +0000 Message-Id: <20210308112935.5782-2-jose.marinho@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210308112935.5782-1-jose.marinho@arm.com> References: <20210308112935.5782-1-jose.marinho@arm.com> X-Originating-IP: [217.140.106.50] X-ClientProxiedBy: LO2P265CA0158.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:9::26) To DBBPR08MB6012.eurprd08.prod.outlook.com (2603:10a6:10:205::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from josmar02Desktop.cambridge.arm.com (217.140.106.50) by LO2P265CA0158.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:9::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3912.26 via Frontend Transport; Mon, 8 Mar 2021 11:31:33 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 8c916ca2-b5e9-4d59-436b-08d8e225beaa X-MS-TrafficTypeDiagnostic: DB7PR08MB3500:|AS8PR08MB6376: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:8882;OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: f+Al3jaR2MpMigwaRsi0EXB00xmqQZI51BFzqgPBF2Tq5/d6UNQqa0vpTe+2uxwZzxy0HJx7hWrDMAF9lhaOJOptd6MPWIFp5Ht1dsc90I+YAwnMmjDgb/bb9X+b7SO+1U7SHW2R6w/g9Dt/01/V3DG9qz7Zd1vReXgMOMfGNW9tHl0gRAAibeSUDkBGQtvJfJLtRPqIKDECwZNtRCB00JreN8O2A8RAun+3bpngkaUZdgVmW5Kvmgmfhf9syvB9Xmmx97ccAfis3JbIwFfJtyB88s4NWNcEBFbTj806VSfpyGdyoGLP15EH+JKx0yzKK1o545Q7thrlpWWKeSJIcmSwVHsY90tzZ8PKfdyo+pYo/PPLoLKa+aBfuwSZ51ndYTnM0//TFfLxyeBoTSfOoIdoctutTy9GvV1UEvZU94Z+Q+UK3jiXbGbl8V06XGST9pjUDX95tgt5eVkwNp20OBqCtvdIGQUJRkEPT7+s3ijt286CtVRnrC8Ee1TnlVt4QY/U2sb2jO7AI0nigatU7g== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DBBPR08MB6012.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(376002)(346002)(366004)(39850400004)(136003)(396003)(66476007)(1076003)(16526019)(5660300002)(26005)(66946007)(66556008)(8936002)(44832011)(4326008)(7696005)(30864003)(6916009)(52116002)(186003)(478600001)(54906003)(2906002)(83380400001)(316002)(2616005)(956004)(8676002)(6486002)(86362001)(36756003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: /XtxcWDR081a2uLmrs8XRbyUDYiC6tEnuH6E9EtJZPK9wvxh/Ayt12xh7r35cvgVRv759JfCt7wbi8nK7fUgm2cl6gRAGn4kLBSaFoDGRhRonslJINrwkgetYDDCcWPkWQWn7D2P/EsJspFL2Xl1TGWBhxhYJf5WmyX7zuu/BHEpelO8t9FVAQQtCaizFQ84MFJHCfUthAmGbp9+83hzi94Gabbh7m1R7Dh8nNbaQMxxtBipvapfkLUrlT7A7mrIu3dCMsoeCQbSYuDS5EKUVN3DTWn1fnUBOzDGWpgJI6apmB7VUaSus/GGI/KnuydREym/85GUsAoVM7scfK7lFCgrqEzS9iE12fcnGvh1YjXWjMbB1iePKdvM5W6GcikD3YLoYKFtV/bp3IyWewp5xpQo75ZWQoDfHQuJ1q3FK5ML86uUeT8OS1tIvEb7dhGE5tvViCWwn0XJgHA/5pITfwIPMHfgAkr0rfFK9hlDVKcrNeL02XcgUV4VAEqJzDd13Qb7EqV5tG0agonUupUTI5I3yhxa4W/WBmZY1lZorcP6ZTgzlvB+5/R/XyUuIHu7A/BMzsZjfSkYQBLN1mUH3Za1xQ4swHVnMKGO4kA9joj3t2dCP8vbuG9v055kzKvnAxFsPnWtHANo+nut4VFOkDpxPzxVvvAxDW1vt4bm9CcCnobCg+MYki/2mvZSJOt93hUkMkvj/UcMM9u/cicoTz/fBYrS/oSZ90N1akFLs7ftC974rlzzEZmCwa1Uzrb2efx/TdpHbFk3xTFliWri8ulzcuzUsj1LMXEwtLpbNKYaba9VVzhs2BsprEUWxbuBHGmIh2TR3nnVTPfQlGnyDP7mKKGeQ/yqliIX1sVwt6badNfEoergxi3mDeSU+xtru4XfmsjWoiKGi5sqbvJ3UvN9ouJHqFimVbyEVYYtYO9wkVYANk37HRva67P0oIlAY8Vnk2kQ9juPa8D8PPrJ5r2YG0CitHYigu0wsOxwkgTG+vzU5+7t+EZGrXXJPk/Rb0+EhZtQQw5WpmCUnFrTUsnIQRfB/NqpE7SFEGn/3c4ekho/WMUvEHWjo71xX8JJ6xmi/3iAItKRzFtwF42XoYYWH1mEKSJmcCPkntPaFR7xeQYyQ2ipZ+nIsl00UzGbQdP5gTpejU0Mq8sn1qwdq/1RkYA0j9Yx7sE87CoFwJUv2AYTSeBewYbMdwDz6QYDO1fDv+13JMsH6eOGgHpPVXrsqPOgQtSshJex4MrcrL03arB9WbGxMSyXHT6B6yzngbWVqzlNQrEWSI87XkXelvX3bu+oVZSwluTQYlUtgPsSJ/9U/t+6dk5l94O9dkTF X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB7PR08MB3500 Original-Authentication-Results: lists.denx.de; dkim=none (message not signed) header.d=none; lists.denx.de; dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT012.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: d46d85ed-8a43-4ed4-c7fa-08d8e225b9c9 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Vj7mLrOheHSa5BM0A2Dw2MmOtT4jlf867FNAbQHcl2kvCeW6+l9r8HjNClkYQ8+Wnvkwwbif8gwcIvAfmeS3jqCipIQy4FnfBApuhpsSkBu73pXMpuDLhCdVwN1e7+AVGoqL1VGOTHlYKD83B0SMFgdcuUc7FUYrz+goiBjk2L7KljR52R/4cSIhDGbQSYfUQ7SLsqwmdUQ/7+gqSsyrd60p2cdfsuGpaj6Mii4F3WVx8I8JagFmO6ffzkZ4gJajvNL4g3ACBrDUlyx1bVMWyckDUYpmDa6a1ihGzhzS/snu6W5viD7OuU4giKUEKNDsFLapMdobi0IlZJJSffxzGP5+zKmnQDAEyPAdu69auyJA8V6jbe/uYKdQLgZOO4B1hmXOcqcVp7RDpYEHHPc+Ez4UUE2R7Sxu/zU/e1/WxKehk0nBtXCgBM8/c4AQ86PmoMRIrsiaLjpLUDUK9i4GbVZgrGeJDKitgFiFgLKfecO/ucqbXCJ8Eam7MQoww/B4JfOiFO6lPiM/vml9IeHzWKwvg0uFXdPMb8EOqvQFaArW+gXtNOAiNIFYNxndn3G833/KvFLaU0My+Vh26lDH5ltlLA8LW6+/mgoViWzl9WKg+cQHjnEtIpBVwYkdwNuUgqpohm0qCDT6NlIEGJDmgqE6YynMxV7iZ9xniZOi6jY= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(4636009)(396003)(39850400004)(136003)(346002)(376002)(46966006)(36840700001)(4326008)(2906002)(6486002)(81166007)(70206006)(5660300002)(956004)(70586007)(44832011)(336012)(26005)(36860700001)(2616005)(82310400003)(186003)(83380400001)(7696005)(82740400003)(356005)(8936002)(1076003)(316002)(54906003)(16526019)(30864003)(8676002)(36756003)(6916009)(478600001)(86362001)(47076005); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Mar 2021 11:31:41.3341 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8c916ca2-b5e9-4d59-436b-08d8e225beaa X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: DB5EUR03FT012.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB6376 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean The ESRT is initialised during efi_init_objlist after efi_initialize_system_table(). The ESRT is recreated from scratch at the following events: - successful UpdateCapsule; - FMP instance install. The code ensures that every ESRT entry has a unique fw_class value. Limitations: - The ESRT is not updated if an FMP instance is uninstalled; - the fields image_type and flags are in the current implementation left undefined. Setting these values will require a per-platform function that returns the image_type/flags as a function of the image fw_class. CC: Heinrich Schuchardt CC: Sughosh Ganu CC: AKASHI Takahiro CC: Ilias Apalodimas CC: Andre Przywara CC: Alexander Graf CC: nd@arm.com Signed-off-by: Jose Marinho Remove two EFI_CALL() indirections. Move ESRT GUID in efidebug's list of GUIDs. Reviewed-by: Heinrich Schuchardt --- cmd/efidebug.c | 4 + include/efi_api.h | 21 ++ include/efi_loader.h | 24 ++ lib/efi_loader/Kconfig | 7 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_boottime.c | 7 +- lib/efi_loader/efi_capsule.c | 8 + lib/efi_loader/efi_esrt.c | 510 ++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_setup.c | 6 + 9 files changed, 584 insertions(+), 4 deletions(-) create mode 100644 lib/efi_loader/efi_esrt.c diff --git a/cmd/efidebug.c b/cmd/efidebug.c index e4030f514a..b3d7bd8897 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -516,6 +516,10 @@ static const struct { "ACPI table", EFI_ACPI_TABLE_GUID, }, + { + "EFI System Resource Table", + EFI_SYSTEM_RESOURCE_TABLE_GUID, + }, { "device tree", EFI_FDT_GUID, diff --git a/include/efi_api.h b/include/efi_api.h index 48e48a6263..fb53637419 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1722,6 +1722,23 @@ struct efi_load_file_protocol { void *buffer); }; +struct efi_system_resource_entry { + efi_guid_t fw_class; + u32 fw_type; + u32 fw_version; + u32 lowest_supported_fw_version; + u32 capsule_flags; + u32 last_attempt_version; + u32 last_attempt_status; +} __packed; + +struct efi_system_resource_table { + u32 fw_resource_count; + u32 fw_resource_count_max; + u64 fw_resource_version; + struct efi_system_resource_entry entries[]; +} __packed; + /* Boot manager load options */ #define LOAD_OPTION_ACTIVE 0x00000001 #define LOAD_OPTION_FORCE_RECONNECT 0x00000002 @@ -1740,6 +1757,10 @@ struct efi_load_file_protocol { #define ESRT_FW_TYPE_DEVICEFIRMWARE 0x00000002 #define ESRT_FW_TYPE_UEFIDRIVER 0x00000003 +#define EFI_SYSTEM_RESOURCE_TABLE_GUID\ + EFI_GUID(0xb122a263, 0x3661, 0x4f68,\ + 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80) + /* Last Attempt Status Values */ #define LAST_ATTEMPT_STATUS_SUCCESS 0x00000000 #define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x00000001 diff --git a/include/efi_loader.h b/include/efi_loader.h index 68daa1a4a9..719aa90490 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -214,6 +214,8 @@ extern const efi_guid_t efi_guid_rng_protocol; extern const efi_guid_t efi_guid_capsule_report; /* GUID of firmware management protocol */ extern const efi_guid_t efi_guid_firmware_management_protocol; +/* GUID for the ESRT */ +extern const efi_guid_t efi_esrt_guid; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; @@ -558,6 +560,10 @@ struct efi_simple_file_system_protocol *efi_simple_file_system( /* open file from device-path: */ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp); +/* Registers a callback function for a notification event. */ +efi_status_t EFIAPI efi_register_protocol_notify(const efi_guid_t *protocol, + struct efi_event *event, + void **registration); /** * efi_size_in_pages() - convert size in bytes to size in pages * @@ -890,4 +896,22 @@ static inline efi_status_t efi_launch_capsules(void) #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ +/** + * Install the ESRT system table. + * + * @return status code + */ +efi_status_t efi_esrt_register(void); + +/** + * efi_esrt_populate() - Populates the ESRT entries from the FMP instances + * present in the system. + * If an ESRT already exists, the old ESRT is replaced in the system table. + * The memory of the old ESRT is deallocated. + * + * Return: + * - EFI_SUCCESS if the ESRT is correctly created + * - error code otherwise. + */ +efi_status_t efi_esrt_populate(void); #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e729f727df..a96014ce18 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -347,4 +347,11 @@ config EFI_SECURE_BOOT it is signed with a trusted key. To do that, you need to install, at least, PK, KEK and db. +config EFI_ESRT + bool "Enable the UEFI ESRT generation" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + default y + help + Enabling this option creates the ESRT UEFI system table. + endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 10b42e8847..9a8127846f 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -52,6 +52,7 @@ obj-y += efi_variable.o obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o endif obj-y += efi_watchdog.o +obj-$(CONFIG_EFI_ESRT) += efi_esrt.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 41b8949b04..8e8b0a9bc6 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1406,10 +1406,9 @@ out: * * Return: status code */ -static efi_status_t EFIAPI efi_register_protocol_notify( - const efi_guid_t *protocol, - struct efi_event *event, - void **registration) +efi_status_t EFIAPI efi_register_protocol_notify(const efi_guid_t *protocol, + struct efi_event *event, + void **registration) { struct efi_register_notify_event *item; efi_status_t ret = EFI_SUCCESS; diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index b57f0302c5..547e8582bf 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -482,6 +482,14 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } out: + + if (IS_ENABLED(CONFIG_EFI_ESRT)) { + /* Rebuild the ESRT to reflect any updated FW images. */ + ret = efi_esrt_populate(); + if (ret != EFI_SUCCESS) + log_warning("EFI Capsule: failed to update ESRT\n"); + } + return EFI_EXIT(ret); } diff --git a/lib/efi_loader/efi_esrt.c b/lib/efi_loader/efi_esrt.c new file mode 100644 index 0000000000..947bdb5e95 --- /dev/null +++ b/lib/efi_loader/efi_esrt.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * EFI application ESRT tables support + * + * Copyright (C) 2021 Arm Ltd. + */ + +#include +#include +#include +#include +#include + +const efi_guid_t efi_esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID; + +static struct efi_system_resource_table *esrt; + +#define EFI_ESRT_VERSION 1 + +/** + * efi_esrt_image_info_to_entry() - copy the information present in a fw image + * descriptor to a ESRT entry. + * The function ensures the ESRT entry matches the image_type_id in @img_info. + * In case of a mismatch we leave the entry unchanged. + * + * @img_info: the source image info descriptor + * @entry: pointer to the ESRT entry to be filled + * @desc_version: the version of the elements in img_info + * @image_type: the image type value to be set in the ESRT entry + * @flags: the capsule flags value to be set in the ESRT entry + * + * Return: + * - EFI_SUCCESS if the entry is correctly updated + * - EFI_INVALID_PARAMETER if entry does not match image_type_id in @img_info. + */ +static efi_status_t +efi_esrt_image_info_to_entry(struct efi_firmware_image_descriptor *img_info, + struct efi_system_resource_entry *entry, + u32 desc_version, u32 image_type, u32 flags) +{ + if (guidcmp(&entry->fw_class, &img_info->image_type_id)) { + EFI_PRINT("ESRT entry %pUL mismatches img_type_id %pUL\n", + &entry->fw_class, &img_info->image_type_id); + return EFI_INVALID_PARAMETER; + } + + entry->fw_version = img_info->version; + + entry->fw_type = image_type; + entry->capsule_flags = flags; + + /* + * The field lowest_supported_image_version is only present + * on image info structure of version 2 or greater. + * See the EFI_FIRMWARE_IMAGE_DESCRIPTOR definition in UEFI. + */ + if (desc_version >= 2) + entry->lowest_supported_fw_version = + img_info->lowest_supported_image_version; + else + entry->lowest_supported_fw_version = 0; + + /* + * The fields last_attempt_version and last_attempt_status + * are only present on image info structure of version 3 or + * greater. + * See the EFI_FIRMWARE_IMAGE_DESCRIPTOR definition in UEFI. + */ + if (desc_version >= 3) { + entry->last_attempt_version = + img_info->last_attempt_version; + + entry->last_attempt_status = + img_info->last_attempt_status; + } else { + entry->last_attempt_version = 0; + entry->last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; + } + + return EFI_SUCCESS; +} + +/** + * efi_esrt_entries_to_size() - Obtain the bytes used by an ESRT + * datastructure with @num_entries. + * + * @num_entries: the number of entries in the ESRT. + * + * Return: the number of bytes an ESRT with @num_entries occupies in memory. + */ +static +inline u32 efi_esrt_entries_to_size(u32 num_entries) +{ + u32 esrt_size = sizeof(struct efi_system_resource_table) + + num_entries * sizeof(struct efi_system_resource_entry); + + return esrt_size; +} + +/** + * efi_esrt_allocate_install() - Allocates @num_entries for the ESRT and + * performs basic ESRT initialization. + * + * @num_entries: the number of entries that the ESRT will hold. + * + * Return: + * - pointer to the ESRT if successful. + * - NULL otherwise. + */ +static +efi_status_t efi_esrt_allocate_install(u32 num_entries) +{ + efi_status_t ret; + struct efi_system_resource_table *new_esrt; + u32 size = efi_esrt_entries_to_size(num_entries); + efi_guid_t esrt_guid = efi_esrt_guid; + + /* Reserve num_pages for ESRT */ + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, size, + (void **)&new_esrt); + + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT cannot allocate memory for %d entries (%d bytes)\n", + num_entries, efi_esrt_entries_to_size(num_entries)); + + return ret; + } + + new_esrt->fw_resource_count_max = num_entries; + new_esrt->fw_resource_count = 0; + new_esrt->fw_resource_version = EFI_ESRT_VERSION; + + /* Install the ESRT in the system configuration table. */ + ret = efi_install_configuration_table(&esrt_guid, (void *)new_esrt); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to install the ESRT in the system table\n"); + return ret; + } + + /* If there was a previous ESRT, deallocate its memory now. */ + if (esrt) + ret = EFI_CALL(efi_free_pool(esrt)); + + esrt = new_esrt; + + return EFI_SUCCESS; +} + +/** + * esrt_find_entry() - Obtain the ESRT entry for the image with GUID + * @img_fw_class. + * + * If the img_fw_class is not yet present in the ESRT, this function + * reserves the tail element of the current ESRT as the entry for that fw_class. + * The number of elements in the ESRT is updated in that case. + * + * @img_fw_class: the GUID of the FW image which ESRT entry we want to obtain. + * + * Return: + * - A pointer to the ESRT entry for the image with GUID img_fw_class, + * - NULL if: + * - there is no more space in the ESRT, + * - ESRT is not initialized, + */ +static +struct efi_system_resource_entry *esrt_find_entry(efi_guid_t *img_fw_class) +{ + u32 filled_entries; + u32 max_entries; + struct efi_system_resource_entry *entry; + + if (!esrt) { + EFI_PRINT("ESRT access before initialized\n"); + return NULL; + } + + filled_entries = esrt->fw_resource_count; + entry = esrt->entries; + + /* Check if the image with img_fw_class is already in the ESRT. */ + for (u32 idx = 0; idx < filled_entries; idx++) { + if (!guidcmp(&entry[idx].fw_class, img_fw_class)) { + EFI_PRINT("ESRT found entry for image %pUl at index %d\n", + img_fw_class, idx); + return &entry[idx]; + } + } + + max_entries = esrt->fw_resource_count_max; + /* + * Since the image with img_fw_class is not present in the ESRT, check + * if ESRT is full before appending the new entry to it. + */ + if (filled_entries == max_entries) { + EFI_PRINT("ESRT full, this should not happen\n"); + return NULL; + } + + /* + * This is a new entry for a fw image, increment the element + * number in the table and set the fw_class field. + */ + esrt->fw_resource_count++; + entry[filled_entries].fw_class = *img_fw_class; + EFI_PRINT("ESRT allocated new entry for image %pUl at index %d\n", + img_fw_class, filled_entries); + + return &entry[filled_entries]; +} + +/** + * efi_esrt_add_from_fmp() - Populates a sequence of ESRT entries from the FW + * images in the FMP. + * + * @fmp: the FMP instance from which FW images are added to the ESRT + * + * Return: + * - EFI_SUCCESS if all the FW images in the FMP are added to the ESRT + * - Error status otherwise + */ +static +efi_status_t efi_esrt_add_from_fmp(struct efi_firmware_management_protocol *fmp) +{ + struct efi_system_resource_entry *entry = NULL; + size_t info_size = 0; + struct efi_firmware_image_descriptor *img_info = NULL; + u32 desc_version; + u8 desc_count; + size_t desc_size; + u32 package_version; + u16 *package_version_name; + efi_status_t ret = EFI_SUCCESS; + + /* + * TODO: set the field image_type depending on the FW image type + * defined in a platform basis. + */ + u32 image_type = ESRT_FW_TYPE_UNKNOWN; + + /* TODO: set the capsule flags as a function of the FW image type. */ + u32 flags = 0; + + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info, + &desc_version, &desc_count, + &desc_size, NULL, NULL)); + + if (ret != EFI_BUFFER_TOO_SMALL) { + /* + * An input of info_size=0 should always lead + * fmp->get_image_info to return BUFFER_TO_SMALL. + */ + EFI_PRINT("Erroneous FMP implementation\n"); + return EFI_INVALID_PARAMETER; + } + + ret = EFI_CALL(efi_allocate_pool(EFI_BOOT_SERVICES_DATA, info_size, + (void **)&img_info)); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to allocate memory for image info.\n"); + return ret; + } + + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info, + &desc_version, &desc_count, + &desc_size, &package_version, + &package_version_name)); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to obtain the FMP image info\n"); + goto out; + } + + /* + * Iterate over all the FW images in the FMP. + */ + for (u32 desc_idx = 0; desc_idx < desc_count; desc_idx++) { + struct efi_firmware_image_descriptor *cur_img_info = + (struct efi_firmware_image_descriptor *) + ((uintptr_t)img_info + desc_idx * desc_size); + + /* + * Obtain the ESRT entry for the FW image with fw_class + * equal to cur_img_info->image_type_id. + */ + entry = esrt_find_entry(&cur_img_info->image_type_id); + + if (entry) { + ret = efi_esrt_image_info_to_entry(cur_img_info, entry, + desc_version, + image_type, flags); + if (ret != EFI_SUCCESS) + EFI_PRINT("ESRT entry mismatches image_type\n"); + + } else { + EFI_PRINT("ESRT failed to add entry for %pUl\n", + &cur_img_info->image_type_id); + continue; + } + } + +out: + EFI_CALL(efi_free_pool(img_info)); + return EFI_SUCCESS; +} + +/** + * efi_esrt_populate() - Populates the ESRT entries from the FMP instances + * present in the system. + * If an ESRT already exists, the old ESRT is replaced in the system table. + * The memory of the old ESRT is deallocated. + * + * Return: + * - EFI_SUCCESS if the ESRT is correctly created + * - error code otherwise. + */ +efi_status_t efi_esrt_populate(void) +{ + efi_handle_t *base_handle = NULL; + efi_handle_t *it_handle; + size_t no_handles = 0; + struct efi_firmware_management_protocol *fmp; + efi_status_t ret; + u32 num_entries = 0; + struct efi_handler *handler; + + /* + * Obtain the number of registered FMP handles. + */ + ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL, + &efi_guid_firmware_management_protocol, + NULL, &no_handles, + (efi_handle_t **)&base_handle)); + + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT There are no FMP instances\n"); + + ret = efi_esrt_allocate_install(0); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to create table with 0 entries\n"); + return ret; + } + return EFI_SUCCESS; + } + + EFI_PRINT("ESRT populate esrt from (%ld) available FMP handles\n", + no_handles); + + /* + * Iterate over all FMPs to determine an upper bound on the number of + * ESRT entries. + */ + it_handle = base_handle; + for (u32 idx = 0; idx < no_handles; idx++, it_handle++) { + struct efi_firmware_image_descriptor *img_info = NULL; + size_t info_size = 0; + u32 desc_version = 0; + u8 desc_count = 0; + size_t desc_size = 0; + u32 package_version; + u16 *package_version_name; + + ret = efi_search_protocol(*it_handle, + &efi_guid_firmware_management_protocol, + &handler); + + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT Unable to find FMP handle (%d)\n", + idx); + goto out; + } + fmp = handler->protocol_interface; + + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, NULL, + &desc_version, &desc_count, + &desc_size, &package_version, + &package_version_name)); + + if (ret != EFI_BUFFER_TOO_SMALL) { + /* + * An input of info_size=0 should always lead + * fmp->get_image_info to return BUFFER_TO_SMALL. + */ + EFI_PRINT("ESRT erroneous FMP implementation\n"); + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = EFI_CALL(efi_allocate_pool(EFI_BOOT_SERVICES_DATA, info_size, + (void **)&img_info)); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to allocate memory for image info\n"); + goto out; + } + + /* + * Calls to a FMP get_image_info method do not return the + * desc_count value if the return status differs from EFI_SUCCESS. + * We need to repeat the call to get_image_info with a properly + * sized buffer in order to obtain the real number of images + * handled by the FMP. + */ + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, img_info, + &desc_version, &desc_count, + &desc_size, &package_version, + &package_version_name)); + + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to obtain image info from FMP\n"); + EFI_CALL(efi_free_pool(img_info)); + goto out; + } + + num_entries += desc_count; + + EFI_CALL(efi_free_pool(img_info)); + } + + EFI_PRINT("ESRT create table with %d entries\n", num_entries); + /* + * Allocate an ESRT with the sufficient number of entries to accommodate + * all the FMPs in the system. + */ + ret = efi_esrt_allocate_install(num_entries); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to initialize table\n"); + goto out; + } + + /* + * Populate the ESRT entries with all existing FMP. + */ + it_handle = base_handle; + for (u32 idx = 0; idx < no_handles; idx++, it_handle++) { + ret = EFI_CALL(efi_search_protocol(*it_handle, + &efi_guid_firmware_management_protocol, + &handler)); + + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT unable to find FMP handle (%d)\n", + idx); + break; + } + fmp = handler->protocol_interface; + + ret = efi_esrt_add_from_fmp(fmp); + if (ret != EFI_SUCCESS) + EFI_PRINT("ESRT failed to add FMP to the table\n"); + } + +out: + + EFI_CALL(efi_free_pool(base_handle)); + + return ret; +} + +/** + * efi_esrt_new_fmp_notify() - Callback for the EVT_NOTIFY_SIGNAL event raised + * when a new FMP protocol instance is registered in the system. + */ +static void EFIAPI efi_esrt_new_fmp_notify(struct efi_event *event, + void *context) +{ + efi_status_t ret; + + EFI_ENTRY(); + + ret = efi_esrt_populate(); + if (ret != EFI_SUCCESS) + EFI_PRINT("ESRT failed to populate ESRT entry\n"); + + EFI_EXIT(ret); +} + +/** + * efi_esrt_register() - Install the ESRT system table. + * + * Return: status code + */ +efi_status_t efi_esrt_register(void) +{ + struct efi_event *ev = NULL; + void *registration; + efi_status_t ret; + + EFI_PRINT("ESRT creation start\n"); + + ret = efi_esrt_populate(); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to initiate the table\n"); + return ret; + } + + ret = EFI_CALL(efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, + efi_esrt_new_fmp_notify, NULL, NULL, &ev)); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to create event\n"); + return ret; + } + + ret = EFI_CALL(efi_register_protocol_notify(&efi_guid_firmware_management_protocol, + ev, ®istration)); + if (ret != EFI_SUCCESS) { + EFI_PRINT("ESRT failed to register FMP callback\n"); + return ret; + } + + EFI_PRINT("ESRT table created\n"); + + return ret; +} diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index b1c5125032..3c5cf9a435 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -227,6 +227,12 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + if (IS_ENABLED(CONFIG_EFI_ESRT)) { + ret = efi_esrt_register(); + if (ret != EFI_SUCCESS) + goto out; + } + if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { ret = efi_tcg2_register(); if (ret != EFI_SUCCESS)