From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107720+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901418587175.4736147512525; Sat, 12 Aug 2023 21:36:58 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=caKGFmdPQJTg9U4TY1E4P2YU9UkzUzokUOzuInORCZs=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901418; v=1; b=NpLqjxcbWSf9L1hQdvgQBiuYtBDy6FXNXyVaEmQmg7aflVJZeDfUfV7GqwMg4gQVRmV5Js2x NgF+oIvlroIWZY3Cx1iPweM2NDa/prmKFtFv2JZIpuFNQq2d2phzkFG+V8mIGLbMK0EBzVmYkN/ lya0YbTRGJ74DM0zsn2YaL80= X-Received: by 127.0.0.2 with SMTP id j950YY1788612xIjwJdbDysH; Sat, 12 Aug 2023 21:36:58 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.72]) by mx.groups.io with SMTP id smtpd.web10.80501.1691901417180048655 for ; Sat, 12 Aug 2023 21:36:57 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nslI5IT8yrVFvPgPho047wMfaZB/EhKFUD6uVVrh/2NyXiyzVxdXZGrUbXcNy/cRvK1XqFlpatCNYWhzd2BbiUyCAm0dx4xWi13eEoqTuWoYQk7aVE1TxwHcPv4GRDgEMBtd8kzMIL0TB1NOE8BweQGCZqeMjwX84TjhDE6Z/nnSx5UzLVR0ebf+Q5UnMWxA/kWdXUSD/K3k/yhJRg+Eiw9ARN+t0rN+sZtZ/57I1nNpZ+YEtwB/0hKE619zsKbsffPdEkJ7UGB6XZrYM1KKWV7tsDdeKChcVAuxwERn7cwGGZlgjWVNwer+vMzLmaid2i2gLh6AG1HGTxxVZBgZIA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xx+lZ5TUJyKzkpZTwj6Oo3FOx1RedYkhlY3VmvzbjPw=; b=QbtrsGwApAqUtfERosyodP1bCkMj/tBhbqOWS3JzxUXBQuxiAzGE3G/hBQHyswfAbn3At/naBZutvE+edN2AGYnPHGhz/Sg7iwonKu+Bkw+Aa0M77D0nbbbbXOzeWnD5h0FWgazG+LSif4ITilRZxqMc0nxtqFQDQ4tK7fUgimFJVBoBPshoj5QtDHVw5OyDyzAO5wDtsC7qXSboHIB2ik3ndBbgx0xnxoRta+v/Gzd3qm3ihGZwnB1dJp9v1S1Nnxsrpfy64/9hwGvsrOJT0rhy76KJZraZ/PqsojWQviqhWJfMdYGzDqVsHY5J0yEm9T2MyL+8E/MWAxWr8FH2CA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CYZPR02CA0021.namprd02.prod.outlook.com (2603:10b6:930:a1::18) by MN2PR12MB4095.namprd12.prod.outlook.com (2603:10b6:208:1d1::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.24; Sun, 13 Aug 2023 04:36:53 +0000 X-Received: from CY4PEPF0000EDD1.namprd03.prod.outlook.com (2603:10b6:930:a1:cafe::14) by CYZPR02CA0021.outlook.office365.com (2603:10b6:930:a1::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:36:53 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107720+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD1.mail.protection.outlook.com (10.167.241.205) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:36:53 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:36:51 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V3 1/6] MdePkg/Include: Update definitions of SPI related header files Date: Sun, 13 Aug 2023 12:36:25 +0800 Message-ID: <20230813043630.1123-2-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD1:EE_|MN2PR12MB4095:EE_ X-MS-Office365-Filtering-Correlation-Id: a05daef6-1002-4240-8a8f-08db9bb6eb37 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: dL3quXiFK4xzSGTf9TU04Z5hsdSRvT2IGk5ZIkvAAUFfLv3QdwXtpvRy42w9n7Nj3aMGP7bkKiGGjriihUIJRn0I8KCu+ff8dzL14lO6xwAf/havEdMgm/R6LJJQtsWevXQ1IwVgXgXQ0ZUji5GUQ30WHSmuJXEpiSmJsFgMNfXpyZ0HZLM/L8k3Y/KK3AF4//BJ6kkmP7kLMAHui3mp3uw8Zl1nxIrhZhqie0aV9L7QlfDYcP8ac6KxA3HwyOL/iYKNgkI5pnq9vzLmk7RQONTk+HCuDpL81wFhxvtypt3rgimK54zD7dSEnU2vWNMsOdANu9D3sKqf3Mb7na8Bd8AnPpwYuDmYWFrO+W3psrrlOZkBn+uk9DQtyfQZQZdzChqkgIh8v1CM385GILUnj8Ygno/1AlfVDgVJ6xCW62zswB8UOYk1HmX6zOt8DRTTWeb59A4SsQ655j/2OU4ow6qoMGRM2gnTnP24YB5h/oA/KaHklvT1Tbr69r5EspOyWG4RvNW2Br1uI1EayraIQdXAQpHfUNOr4O8QC0X+jjxcsGTT8QR0nj1XUTLiZi1m6vuV/xNS1FTyQIH6Ks1UgGXSSGio+SCe6PB4bFmG5gQ48wxo26zvXXvETk0I58sZPQnFnIfyhUGUTrkyDMfMPAJUrVxVm3FeWqbniRXqB/V7HRSbjsbvVCi1zb6zDZ3IvvbWhTHwI4oDJ9R+gjsto6YgoJfO97guJ8SoXyKSGJHS1BcVgBmVWTLP2LdBLaP/f7PvxP8yjuIfpLsTEH+6zA== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:36:53.4446 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a05daef6-1002-4240-8a8f-08db9bb6eb37 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4095 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: lkgcIXgU1k3CX484aPH2DUxwx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901419192100001 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4471 Update definitions according to PI spec v1.8 Errata as it is approved in PIWG (Ticket #2394). Signed-off-by: Abner Chang Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Abdul Lateef Attar --- MdePkg/Include/Protocol/SpiConfiguration.h | 8 ++++++++ MdePkg/Include/Protocol/SpiHc.h | 14 ++++++++++++++ MdePkg/Include/Protocol/SpiIo.h | 10 ++++++++++ 3 files changed, 32 insertions(+) diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h b/MdePkg/Include/Pr= otocol/SpiConfiguration.h index 3f8fb9ff62c..cffdc8e232d 100644 --- a/MdePkg/Include/Protocol/SpiConfiguration.h +++ b/MdePkg/Include/Protocol/SpiConfiguration.h @@ -2,6 +2,7 @@ This file defines the SPI Configuration Protocol. =20 Copyright (c) 2017, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Revision Reference: @@ -168,6 +169,13 @@ typedef struct _EFI_SPI_BUS { VOID *ClockParameter; } EFI_SPI_BUS; =20 +/// +/// Definitions of SPI Part Attributes. +/// +#define SPI_PART_SUPPORTS_2_BIT_DATA_BUS_WIDTH BIT0 +#define SPl_PART_SUPPORTS_4_B1T_DATA_BUS_WIDTH BIT1 +#define SPl_PART_SUPPORTS_8_B1T_DATA_BUS_WIDTH BIT2 + /// /// The EFI_SPI_PERIPHERAL data structure describes how a specific block of /// logic which is connected to the SPI bus. This data structure also sele= cts diff --git a/MdePkg/Include/Protocol/SpiHc.h b/MdePkg/Include/Protocol/SpiH= c.h index 30128dd5c4d..645bfdefe9b 100644 --- a/MdePkg/Include/Protocol/SpiHc.h +++ b/MdePkg/Include/Protocol/SpiHc.h @@ -2,6 +2,7 @@ This file defines the SPI Host Controller Protocol. =20 Copyright (c) 2017, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Revision Reference: @@ -121,6 +122,19 @@ typedef EFI_STATUS IN EFI_SPI_BUS_TRANSACTION *BusTransaction ); =20 +/// +/// Definitions of SPI Host Controller Attributes. +/// +#define HC_SUPPORTS_WRITE_ONLY_OPERATIONS BIT0 +#define HC_SUPPORTS_READ_ONLY_OPERATIONS BIT1 +#define HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS BIT2 +#define HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS BIT3 +#define HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS BIT4 +#define HC_SUPPORTS_2_BIT_DATA_BUS_WIDTH BIT5 +#define HC_SUPPORTS_4_BIT_DATA_BUS_WIDTH BIT6 +#define HC_SUPPORTS_8_BIT_DATA_BUS_WIDTH BIT7 +#define HC_TRANSFER_SIZE_INCLUDES_OPCODE BIT8 +#define HC_TRANSFER_SIZE_INCLUDES_ADDRESS BIT9 /// /// Support a SPI data transaction between the SPI controller and a SPI ch= ip. /// diff --git a/MdePkg/Include/Protocol/SpiIo.h b/MdePkg/Include/Protocol/SpiI= o.h index b4fc5e03b88..0ea881fd115 100644 --- a/MdePkg/Include/Protocol/SpiIo.h +++ b/MdePkg/Include/Protocol/SpiIo.h @@ -2,6 +2,7 @@ This file defines the SPI I/O Protocol. =20 Copyright (c) 2017, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Revision Reference: @@ -223,6 +224,15 @@ typedef struct _EFI_SPI_BUS_TRANSACTION { UINT8 *ReadBuffer; } EFI_SPI_BUS_TRANSACTION; =20 +/// +/// Definitions of SPI I/O Attributes. +/// +#define SPI_IO_SUPPORTS_2_BIT_DATA_BUS_WIDTH BIT0 +#define SPI_IO_SUPPORTS_4_BIT_DATA_BUS_WIDTH BIT1 +#define SPI_IO_SUPPORTS_8_BIT_DATA_BUS_WIDTH BIT2 +#define SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE BIT3 +#define SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS BIT4 + /// /// Support managed SPI data transactions between the SPI controller and a= SPI /// chip. --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107720): https://edk2.groups.io/g/devel/message/107720 Mute This Topic: https://groups.io/mt/100713985/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107721+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901420539626.1095838713856; Sat, 12 Aug 2023 21:37:00 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=dDZHanHPxJKP7IK7ybsVOi2pXQpd6ZhlwLIIiutxUdQ=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901420; v=1; b=UvC2YkSRtjiTSEen/RvJZoCgentit1oFRK3nfo8GaHMv4LPTZBDQFqJ0LmSEjkrWg8T6fSXz AcWVGAAUUxRQu3TqliBm50rPPaXrZwpFiBALG/B+0eaiRmRlfBBX2rb8QblFJHbmxA5tns0Obuh 7RLmCyurW9RnI7NPvb7GPXNs= X-Received: by 127.0.0.2 with SMTP id GthQYY1788612xAoTeLhXTTu; Sat, 12 Aug 2023 21:37:00 -0700 X-Received: from NAM02-SN1-obe.outbound.protection.outlook.com (NAM02-SN1-obe.outbound.protection.outlook.com [40.107.96.73]) by mx.groups.io with SMTP id smtpd.web10.80502.1691901419540736243 for ; Sat, 12 Aug 2023 21:36:59 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LnuF2U5j61vT6QcqzU6KLp1WBfWVjwhXMfpNxk3O5VGMzr2SLFcdDiD/9sUSWJDlhaYBglKPDukDTUsHtpJ+pi17OUYfrZnHJv9jq05bAgva2xWDWMJ8KwZgBGX1DXO7EudP2Env6iOUzr1SOvxUgtBrYnGJCW9xAUX2MqrcTxWPC99iH5RgVDpwrrWljmI2rwiwvsCHMac2fw1JAzQ3eFP2eSN3SVDCybCtWJYpy79VxOwiZhhHpKQiateJKUKRWmApTcBJvLQHsxvyvbzArDibDuS3jG7QcvJdGonBx/nyJij8c8ocxDNnqmXVjvPbdGfh/kWRSKU1g6/wOwSDiw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ouwCLXZ8pxdLygzHttd3EHw1QEPJtNkEjDoUL63g/D8=; b=j9g/xjb+UHJomqJ83RKlNPkso7giu74PQAtH252a3c2OzMVVTKJO9Ad/niFg7WxZXxdCZhPd7Vx3hMXuuix+9NvUImW7soMR7LV7DTeywmZ+nfBnPGIZg2bSJJzW71uNki6Waw0C0k7p5R8aRilHox4qbMAO3+lW4/zTT1XobtDbKC5HVrtxpmFLhDuxpIhsshShOXhBQaQ5h7zczBb0nCaBxXyZgmHU1veMsbu/akZ2kstNGh85doAOlc2dssIE7JRzlhrh4wp/mKOrYWp8zrArxqZexv+inJH+fItti41Ae131v0LbqFi+BzB1DXAwr0AS7Mn1hEOI/+++dWZCNg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CYZPR02CA0013.namprd02.prod.outlook.com (2603:10b6:930:a1::11) by PH8PR12MB7134.namprd12.prod.outlook.com (2603:10b6:510:22d::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.23; Sun, 13 Aug 2023 04:36:56 +0000 X-Received: from CY4PEPF0000EDD1.namprd03.prod.outlook.com (2603:10b6:930:a1:cafe::fa) by CYZPR02CA0013.outlook.office365.com (2603:10b6:930:a1::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:36:55 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107721+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD1.mail.protection.outlook.com (10.167.241.205) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:36:55 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:36:53 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V3 2/6] MdePkg/Include: Add SPI NOR Flash JEDEC SFDP header file Date: Sun, 13 Aug 2023 12:36:26 +0800 Message-ID: <20230813043630.1123-3-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD1:EE_|PH8PR12MB7134:EE_ X-MS-Office365-Filtering-Correlation-Id: db666247-86b9-45a0-6896-08db9bb6ec79 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 8D0VmauB5pi6pU7sMedCXP3eXs78uS8m1mAywlgyPgU8eA67Fc/azJZlHXFFrt0ijmLZnQpWomsp4ufLbK/wFDfXOMjgiNtfwWHxcViCGKUrg4m2H2K+hhv9cQLWqTJhjg9lVuLQ3hxn68QazeeHyaY1BVfTpHMT9UIlcZJGWUievO4m2y2CPvjBeEBGKhNgshEBDKIQeE53rn96cz3JZek75Pw/3Wg9sc1btFRezkn5LOxjsHnwkqCiU2YnACxHt7iTeiX3WFvSxmWjoFs2ktf6wVvMLSrJBtdqa8lSxatBBdZyHbmsPDoM9kFwWdQp2VGLYr1kqU+8Iwg1yZUecmvzWtxVUQ6EHSCVzafPCnXJEXWucMfK78keGxB8AnUtN5nnctEOTnLMVcKCBtkBZWGM1wYNLdwCaWGoJ3Y2WtEsC6GJuTjUMaKSprWiNMzCysqlMvi8Cq+HaH0J+XKv6hBivwskwagIqODQzKJwtSIA7RnJaaUscG+8gZ9yaquOJe0FjfeTGmiVBQscoYWHEdZzR0tfUDuMeBdvwRgy+Y5epznDzfJeViJPdC/e1U1LXR/yppjJoYjQ+vb603KGzpxCLICycP2KZ6PT0WQFexhBoOzJWIhlfXmmH+OEvW4RdgpgZBwI2u80kZj1Q4Co0Vn6J9XYltZIoie5eXolgpt2QxTX25DIm0aIqt9gX6/hCKgRw5p9ZSnQVqiOuqDI4+z5m5BcjanVCknPBX/fvnKPvJflvKCSjxH3NUX2ZpJp5jjJjfwR0+czhJT45tEwdA== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:36:55.5696 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: db666247-86b9-45a0-6896-08db9bb6ec79 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB7134 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 7ielzBP1DH44KhmQTFdEtZaWx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901421130100009 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4472 Add definition of JEDEC Serial Flash Discoverable Parameters (SFDP) specification. https://www.jedec.org/standards-documents/docs/jesd216b Signed-off-by: Abner Chang Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Abdul Lateef Attar --- .../IndustryStandard/SpiNorFlashJedecSfdp.h | 324 ++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 MdePkg/Include/IndustryStandard/SpiNorFlashJedecSfdp.h diff --git a/MdePkg/Include/IndustryStandard/SpiNorFlashJedecSfdp.h b/MdePk= g/Include/IndustryStandard/SpiNorFlashJedecSfdp.h new file mode 100644 index 00000000000..44ab5a12633 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/SpiNorFlashJedecSfdp.h @@ -0,0 +1,324 @@ +/** @file + SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) + header file. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - JEDEC Standard, JESD216F.02 + https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 + + @par Glossary: + - SFDP - Serial Flash Discoverable Parameters + - PTP - Parameter Table Pointer +**/ + +#ifndef SPI_NOR_FLASH_JEDEC_H_ +#define SPI_NOR_FLASH_JEDEC_H_ + +#include + +#define SFDP_HEADER_SIGNATURE 0x50444653 +#define SFDP_SUPPORTED_MAJOR_REVISION 0x1ul + +/// JEDEC Basic Flash Parameter Header +#define SFDP_BASIC_PARAMETER_ID_LSB 0x00 +#define SFDP_BASIC_PARAMETER_ID_MSB 0xFF + +/// +/// JDEC Sector Map Parameter Header and Table +/// +#define SFDP_SECTOR_MAP_PARAMETER_ID_LSB 0x81 +#define SFDP_FOUR_BYTE_ADDRESS_INSTRUCTION_LSB 0x84 +#define SFDP_SECTOR_MAP_PARAMETER_ID_MSB 0xFF + +#define SFDP_FLASH_MEMORY_DENSITY_4GBIT 0x80000000 + +#pragma pack (1) +typedef struct _SFDP_HEADER { + UINT32 Signature; + UINT32 MinorRev : 8; + UINT32 MajorRev : 8; + UINT32 NumParameterHeaders : 8; + UINT32 AccessProtocol : 8; +} SFDP_HEADER; + +typedef struct _SFDP_PARAMETER_HEADER { + UINT32 IdLsb : 8; + UINT32 MinorRev : 8; + UINT32 MajorRev : 8; + UINT32 Length : 8; + UINT32 TablePointer : 24; + UINT32 IdMsb : 8; +} SFDP_PARAMETER_HEADER; + +typedef struct _SFDP_BASIC_FLASH_PARAMETER { + // DWORD 1 + UINT32 EraseSizes : 2; + UINT32 WriteGranularity : 1; + UINT32 VolatileStatusBlockProtect : 1; + UINT32 WriteEnableVolatileStatus : 1; + UINT32 Unused1Dw1 : 3; + UINT32 FourKEraseInstr : 8; + UINT32 FastRead112 : 1; + UINT32 AddressBytes : 2; + UINT32 DtrClocking : 1; + UINT32 FastRead122 : 1; + UINT32 FastRead144 : 1; + UINT32 FastRead114 : 1; + UINT32 Unused2Dw1 : 9; + // DWORD 2 + UINT32 Density; + // DWORD 3 + // Fast Read 144 + UINT32 FastRead144Dummy : 5; + UINT32 FastRead144ModeClk : 3; + UINT32 FastRead144Instr : 8; + // Fast Read 114 + UINT32 FastRead114Dummy : 5; + UINT32 FastRead114ModeClk : 3; + UINT32 FastRead114Instr : 8; + // DWORD 4 + // Fast Read 112 + UINT32 FastRead112Dummy : 5; + UINT32 FastRead112ModeClk : 3; + UINT32 FastRead112Instr : 8; + // Fast Read 122 + UINT32 FastRead122Dummy : 5; + UINT32 FastRead122ModeClk : 3; + UINT32 FastRead122Instr : 8; + // DWORD 5 + UINT32 FastRead222 : 1; + UINT32 Unused1Dw5 : 3; + UINT32 FastRead444 : 1; + UINT32 Unused2Dw5 : 27; + // DWORD 6 + UINT32 UnusedDw6 : 16; + // Fast Read 222 + UINT32 FastRead222Dummy : 5; + UINT32 FastRead222ModeClk : 3; + UINT32 FastRead222Instr : 8; + // DWORD 7 + UINT32 UnusedDw7 : 16; + // Fast Read 444 + UINT32 FastRead444Dummy : 5; + UINT32 FastRead444ModeClk : 3; + UINT32 FastRead444Instr : 8; + // DWORD 8 + UINT32 Erase1Size : 8; + UINT32 Erase1Instr : 8; + UINT32 Erase2Size : 8; + UINT32 Erase2Instr : 8; + // DWORD 9 + UINT32 Erase3Size : 8; + UINT32 Erase3Instr : 8; + UINT32 Erase4Size : 8; + UINT32 Erase4Instr : 8; + // DWORD 10 + UINT32 EraseMultiplier : 4; + UINT32 Erase1Time : 7; + UINT32 Erase2Time : 7; + UINT32 Erase3Time : 7; + UINT32 Erase4Time : 7; + // DWORD 11 + UINT32 ProgramMultiplier : 4; + UINT32 PageSize : 4; + UINT32 PPTime : 6; + UINT32 BPFirstTime : 5; + UINT32 BPAdditionalTime : 5; + UINT32 ChipEraseTime : 7; + UINT32 Unused1Dw11 : 1; + // DWORD 12 + UINT32 ProgSuspendProhibit : 4; + UINT32 EraseSuspendProhibit : 4; + UINT32 Unused1Dw13 : 1; + UINT32 ProgResumeToSuspend : 4; + UINT32 ProgSuspendInProgressTime : 7; + UINT32 EraseResumeToSuspend : 4; + UINT32 EraseSuspendInProgressTime : 7; + UINT32 SuspendResumeSupported : 1; + // DWORD 13 + UINT32 Unused13; + // DWORD 14 + UINT32 Unused14; + // DWORD 15 + UINT32 Unused15; + // DWORD 16 + UINT32 Unused16; + // DWORD 17 + UINT32 FastRead188Dummy : 5; + UINT32 FastRead188ModeClk : 3; + UINT32 FastRead188Instr : 8; + UINT32 FastRead118Dummy : 5; + UINT32 FastRead118ModeClk : 3; + UINT32 FastRead118Instr : 8; + // + // Don't care about remaining DWORDs + // DWORD 18 to DWORD 23 + // + UINT32 Unused18; + UINT32 Unused19; + UINT32 Unused20; + UINT32 Unused21; + UINT32 Unused22; + UINT32 Unused23; +} SFDP_BASIC_FLASH_PARAMETER; +#pragma pack () + +#define SPI_UNIFORM_4K_ERASE_SUPPORTED 0x01 +#define SPI_UNIFORM_4K_ERASE_UNSUPPORTED 0x03 + +/// +/// Number of address bytes opcode can support +/// +#define SPI_ADDR_3BYTE_ONLY 0x00 +#define SPI_ADDR_3OR4BYTE 0x01 +#define SPI_ADDR_4BYTE_ONLY 0x02 + +#define SFDP_ERASE_TYPES_NUMBER 4 +#define SFDP_ERASE_TYPE_1 0x0001 +#define SFDP_ERASE_TYPE_2 0x0002 +#define SFDP_ERASE_TYPE_3 0x0003 +#define SFDP_ERASE_TYPE_4 0x0004 + +/// +/// Read/Write Array Commands +/// +#define SPI_FLASH_READ 0x03 +#define SPI_FLASH_READ_DUMMY 0x00 +#define SPI_FLASH_READ_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_FAST_READ 0x0B +#define SPI_FLASH_FAST_READ_DUMMY 0x01 +#define SPI_FLASH_FAST_READ_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_PP 0x02 +#define SPI_FLASH_PP_DUMMY 0x00 +#define SPI_FLASH_PP_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_PAGE_SIZE 256 +#define SPI_FLASH_SE 0x20 +#define SPI_FLASH_SE_DUMMY 0x00 +#define SPI_FLASH_SE_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_BE32K 0x52 +#define SPI_FLASH_BE32K_DUMMY 0x00 +#define SPI_FLASH_BE32K_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_BE 0xD8 +#define SPI_FLASH_BE_DUMMY 0x00 +#define SPI_FLASH_BE_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_CE 0x60 +#define SPI_FLASH_CE_DUMMY 0x00 +#define SPI_FLASH_CE_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_RDID 0x9F +#define SPI_FLASH_RDID_DUMMY 0x00 +#define SPI_FLASH_RDID_ADDR_BYTES SPI_ADDR_3OR4BYTE + +/// +/// Register Setting Commands +/// +#define SPI_FLASH_WREN 0x06 +#define SPI_FLASH_WREN_DUMMY 0x00 +#define SPI_FLASH_WREN_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_WRDI 0x04 +#define SPI_FLASH_WRDI_DUMMY 0x00 +#define SPI_FLASH_WRDI_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_RDSR 0x05 +#define SPI_FLASH_RDSR_DUMMY 0x00 +#define SPI_FLASH_RDSR_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_SR_NOT_WIP 0x0 +#define SPI_FLASH_SR_WIP BIT0 +#define SPI_FLASH_SR_WEL BIT1 +#define SPI_FLASH_WRSR 0x01 +#define SPI_FLASH_WRSR_DUMMY 0x00 +#define SPI_FLASH_WRSR_ADDR_BYTES SPI_ADDR_3OR4BYTE +#define SPI_FLASH_WREN_50H 0x50 +#define SPI_FLASH_RDSFDP 0x5A +#define SPI_FLASH_RDSFDP_DUMMY 0x01 +#define SPI_FLASH_RDSFDP_ADDR_BYTES SPI_ADDR_3BYTE_ONLY +#define ERASE_TYPICAL_TIME_UNITS_MASK 0x60 +#define ERASE_TYPICAL_TIME_BIT_POSITION 5 +#define ERASE_TYPICAL_TIME_UNIT_1_MS_BITMAP 0x00 +#define ERASE_TYPICAL_TIME_UNIT_1_MS 1 +#define ERASE_TYPICAL_TIME_UNIT_16_MS_BITMAP 0x01 +#define ERASE_TYPICAL_TIME_UNIT_16_MS 16 +#define ERASE_TYPICAL_TIME_UNIT_128_MS_BITMAP 0x10 +#define ERASE_TYPICAL_TIME_UNIT_128_MS 128 +#define ERASE_TYPICAL_TIME_UNIT_1000_MS_BITMAP 0x11 +#define ERASE_TYPICAL_TIME_UNIT_1000_MS 1000 +#define ERASE_TYPICAL_TIME_COUNT_MASK 0x1f + +/// +/// Flash Device Configuration Detection Command descriptor. +/// +typedef struct { + // DWORD 1 + UINT32 DescriptorEnd : 1; ///< Descriptor Sequence End I= ndicator. + UINT32 DescriptorType : 1; ///< Descriptor Type. + UINT32 Reserve1 : 6; ///< Bit [7:2] is reserved. + UINT32 DetectionInstruction : 8; ///< Sector map configuration = detection command. + UINT32 DetectionLatency : 4; ///< Configuration detection c= ommand read latency. + UINT32 Reserve2 : 2; ///< Bit [21:20] is reserved. + UINT32 DetectionCommandAddressLen : 2; ///< Configuration detection c= ommand address length. + UINT32 ReadDataMask : 8; ///< Bit mask of the interst b= it of the returned + ///< byte read from the detect= ion command. + // DWORD 2 + UINT32 CommandAddress : 32; ///< Sector map configuration= detection command address. +} SFDP_SECTOR_CONFIGURATION_COMMAND; + +#define SFDP_SECTOR_MAP_TABLE_ENTRY_TYPE_COMMAND 0 +#define SFDP_SECTOR_MAP_TABLE_ENTRY_TYPE_MAP 1 +#define SFDP_SECTOR_MAP_TABLE_ENTRY_LAST 1 + +/// +/// Definition of Configuration detection command address length. +/// +typedef enum { + SpdfConfigurationCommandAddressNone =3D 0, + SpdfConfigurationCommandAddress3Byte =3D 1, + SpdfConfigurationCommandAddress4Byte =3D 2, + SpdfConfigurationCommandAddressVariable =3D 3 +} SPDF_CONFIGURATION_COMMAND_ADDR_LENGTH; + +/// +/// Flash Device Configuration Map descriptor. +/// +typedef struct { + // DWORD 1 + UINT32 DescriptorEnd : 1; ///< Descriptor Sequence End Ind= icator. + UINT32 DescriptorType : 1; ///< Descriptor Type. + UINT32 Reserve1 : 6; ///< Bit [7:2] is reserved. + UINT32 ConfigurationID : 8; ///< ID of this configuration. + UINT32 RegionCount : 8; ///< The region count of this co= nfiguration. + UINT32 Reserve2 : 8; ///< [31:24] is reserved. +} SFDP_SECTOR_CONFIGURATION_MAP; + +typedef struct { + UINT32 DescriptorEnd : 1; ///< Descriptor Sequence End Ind= icator. + UINT32 DescriptorType : 1; ///< Descriptor Type. +} SFDP_SECTOR_CONFIGURATION_GENERIC_HEADER; + +/// +/// Flash Device Region Definition. +/// +typedef struct _SFDP_SECTOR_REGION { + // DWORD 1 + UINT32 EraseType1 : 1; ///< Earse type 1 is supported. + UINT32 EraseType2 : 1; ///< Earse type 2 is supported. + UINT32 EraseType3 : 1; ///< Earse type 3 is supported. + UINT32 EraseType4 : 1; ///< Earse type 4 is supported. + UINT32 Reserve1 : 4; ///< Bit [7:4] is reserved. + UINT32 RegionSize : 24; ///< Region size in 256 Byte uni= t. +} SFDP_SECTOR_REGION; +#define SFDP_SECTOR_REGION_SIZE_UNIT 256 + +/// +/// Sector Map Table structure, the entry could be +/// either Configuration Detection Command descriptor, +/// or Configuration Map descriptor. +/// +typedef union _SFDP_SECTOR_MAP_TABLE { + SFDP_SECTOR_CONFIGURATION_GENERIC_HEADER GenericHeader; + SFDP_SECTOR_CONFIGURATION_COMMAND ConfigurationCommand; ///< F= ash configuration detection command. + SFDP_SECTOR_CONFIGURATION_MAP ConfigurationMap; ///< F= lash map descriptor. +} SFDP_SECTOR_MAP_TABLE; + +#endif // SPI_NOR_FLASH_JEDEC_H_ --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107721): https://edk2.groups.io/g/devel/message/107721 Mute This Topic: https://groups.io/mt/100713986/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107722+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901421642468.05497257092077; Sat, 12 Aug 2023 21:37:01 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=I+O73iDbiM8uPeW8aNAS+5BhlOeS5kYBHdFLBXSMp+k=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901421; v=1; b=NEz6xSfbXCC3oSL8moX/3NRj6x/Wry7A8UHibH7Ub0Y/NG1LaYjC6m3jLbYzU/+2gSrwDdjA p+r/rGQn42yZ2km5Ot2eJuqDxVvhQo3FQpI/uDlbsbDbjbmqfqNbwsItn0Rz/M3TCeJXq7WGcbN +rcbCD5zgyLV1k0dryDaDt3c= X-Received: by 127.0.0.2 with SMTP id 7IF1YY1788612xoxKbvQhHtp; Sat, 12 Aug 2023 21:37:01 -0700 X-Received: from NAM02-SN1-obe.outbound.protection.outlook.com (NAM02-SN1-obe.outbound.protection.outlook.com [40.107.96.83]) by mx.groups.io with SMTP id smtpd.web11.80328.1691901420602969106 for ; Sat, 12 Aug 2023 21:37:00 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NwwkIDVhj/uds72Gh9UfG8PRI6TlwUn40GS7+On6zqzilNHmqQFCIzWMpwkmmJsgk74XucNntA1emcP3ltovTQ81f39hCSnRU9PohTkypg+XzENVrSn53TKoncYm/f7CR8vtNMQSwmajlWhmSHgAK1Gc47WbLhbdoneZ/1gZsDl8GXIWN84VSbwP//N5Gu2aL1e3dok8pUJrxwS2Cj5S82nMoraAzU0XijroIanNp6vncFWOBy62dPWzKrCe/Iyf6RArEBbvhOJ0+49xMe1RKzwo4Ss8+gY/4LrZ7Plx2RiUjyR0zgN1k6IWZd+VSQ0As9B8mL6F8Ry81WQn2jFCKw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gU5SmXGTzK6j83AkDCF0WgBYVQEh9lJUmq35GRTa8Fc=; b=GH9yLY3dFFjxg9SkOK4EXQsvaRL58JsmbznU0n7nweEMozF8Ilfr3qmPMUspjQE+x/9z48N4gN1uQKb7QejV5heATVLGuTE/8hsDtYwpcsi2QGCk477CvcYLYPm+gDDVQAvYmROzsYqrfP25l0yaZJP6VoUmzyuC6w3jEseOrXifi/akzepqkCjDk11hp5xDsrWUJ+QpWKRxuewkDrxk+vJSpmOVbIzZxjfxiEdGHlWJi6gWn7HPT9w8w7qTrNbce5/TbVWiCJc4zgF2wUOztqzQ0R5l64PdceX3m5fRkZiZdon6MoKuuS/642Q+mDL6hlc8eXN/OwB4uMs4tVfNKg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CYZPR02CA0013.namprd02.prod.outlook.com (2603:10b6:930:a1::11) by DS7PR12MB6094.namprd12.prod.outlook.com (2603:10b6:8:9d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.22; Sun, 13 Aug 2023 04:36:57 +0000 X-Received: from CY4PEPF0000EDD1.namprd03.prod.outlook.com (2603:10b6:930:a1:cafe::40) by CYZPR02CA0013.outlook.office365.com (2603:10b6:930:a1::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:36:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107722+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD1.mail.protection.outlook.com (10.167.241.205) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:36:57 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:36:55 -0500 From: "Chang, Abner via groups.io" To: CC: Liming Gao , Jian J Wang , Abdul Lateef Attar Subject: [edk2-devel] [PATCH V3 3/6] MdeModulePkg: Add definitions in DEC for SPI NOR Flash SFDP driver Date: Sun, 13 Aug 2023 12:36:27 +0800 Message-ID: <20230813043630.1123-4-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD1:EE_|DS7PR12MB6094:EE_ X-MS-Office365-Filtering-Correlation-Id: fa47e214-04b8-4e43-8592-08db9bb6ed78 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: RoR8FVJTkyKtcgUiYvY3EyHVGDy72h7AhiYjFH5j9t0FxthnqoSs+dPhFSU5ZeGSvQBPZFDWRjSJdJ2A05f7kwB2Q5pZqYZT67F5uzuP4c2B+7pYyjGPlRGmfkGFdLEIVv1M2/a939RU+BhphHeV4/nteWGJtNu+SUXxCj8nSMWAy23iGcdTJvykco1pTNr2v2BJnhhNCrRskKo5wBwugWn5rRlMgDQAzt9fll2AMLxO30VWD0bq5Un2oNH8slOa8wbDd8Rl76ADlOGWwKCMVHAVshv4tYZA6F3yRFgf52xNyYR9sJkOQ7CwrqYUMEL3O12PhO8OaPFAEBbBwjd6SmqtiaMOsrxT/VvFwowm7ZVFGAW5i9HZ/3FJcOs2ncDh93NdgPunZyk4VYsyqfqvkyXJN5sLPfByJTzO6eLtb08bCwy3BCQ4c3mPYTzBxsRK4UrUn6BRogrCZsz6ofDg7UAIP+pwsV+OHLezVxJ3yJf8wbcPEMOafLFUP3/og1lKaJOtRCoLk+rX38JCaOyFQPjGDviBvN0dqI7N1UiX9qvhfuzFHTDIAlIUbdzVTownLCKoc1Ci4K237u/ZFLSm5XMvpTE2UjEBi326TVE8EdmfJVNxpGutuOT6IySCeoG1dQX69TfPcnqwvNio4mgkdJ9j7CLbRVWOubzdesu1sMr0NTx6YpNZz/2PA9UPEPld+OFgzTQ0a6ZRJ/76J7LG30v0ewN2VWuLdjmHCd2r2RJq3VWy3pa9xXWQsyWPeaW9IqwQMTMaDyN/ZKjiF2Gk6A== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:36:57.2571 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fa47e214-04b8-4e43-8592-08db9bb6ed78 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR12MB6094 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 7hTMTwZvcuqfl255NKR14MNix1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901423288100013 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4473 Signed-off-by: Abner Chang Cc: Liming Gao Cc: Jian J Wang Cc: Abdul Lateef Attar --- MdeModulePkg/MdeModulePkg.dec | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 0ff058b0a9d..8f1f9b9c951 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -445,6 +445,12 @@ ## GUID used for Boot Discovery Policy FormSet guid and related variable= s. gBootDiscoveryPolicyMgrFormsetGuid =3D { 0x5b6f7107, 0xbb3c, 0x4660, { 0= x92, 0xcd, 0x54, 0x26, 0x90, 0x28, 0x0b, 0xbd } } =20 + # + # SPI NOR flash JEDEC Serial Flash Discoverable Parameters (SFDP) driver= GUID + # + gEdk2JedecSfdpSpiDxeDriverGuid =3D { 0xBE71701E, 0xB63C, 0x4574, { 0x9C= , 0x5C, 0x36, 0x29, 0xE8, 0xEA, 0xC4, 0x14 }} + gEdk2JedecSfdpSpiSmmDriverGuid =3D { 0x95A1E915, 0x195C, 0x477C, { 0x92= , 0x6F, 0x7E, 0x24, 0x67, 0xC1, 0xB3, 0x1F }} + [Ppis] ## Include/Ppi/FirmwareVolumeShadowPpi.h gEdkiiPeiFirmwareVolumeShadowPpiGuid =3D { 0x7dfe756c, 0xed8d, 0x4d77, {= 0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } } @@ -1612,6 +1618,19 @@ # @Prompt The value of Retry Count, Default value is 5. gEfiMdeModulePkgTokenSpaceGuid.PcdAhciCommandRetryCount|5|UINT32|0x00000= 032 =20 + ## SPI NOR Flash operation retry counts + # 0x00000000: No retry + # 0xFFFFFFFF: Maximum retry value + # + # @Prompt SPI NOR Flash Operation Retry Value + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount|0xFFFFF= FFF|UINT32|0x00000033 + + ## SPI NOR Flash operation delay in microseconds + # Deafult is set to 0x0000000f microseconds + # + # @Prompt SPI NOR Flash Operation Delay in Microseconds + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds|= 0x0000000F|UINT32|0x00000034 + [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] ## This PCD defines the Console output row. The default value is 25 acco= rding to UEFI spec. # This PCD could be set to 0 then console output would be at max column= and max row. --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107722): https://edk2.groups.io/g/devel/message/107722 Mute This Topic: https://groups.io/mt/100713987/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107724+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901428807822.6586478291405; Sat, 12 Aug 2023 21:37:08 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=E6eeBLYTNgzGHu/7z+BpJru/HU5AvkKg3snOKk9ke6Y=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901428; v=1; b=Nivj2mBLnNSrmJ+iGIh4KcDHw/XBShfVlLkVb03c0eSF4N3LbQSLZh/nK5i52ZRliUJs705+ ktGCBbuBW/bbKV6Fd1JwMSnwGWMncNVknIZUscxH8PJ+cYmXM5MxmqYuI5wSa547OPja2AoguPn C24QkMoDyg6EVwfGUFZprhlA= X-Received: by 127.0.0.2 with SMTP id iC4YYY1788612xtiumlsfLqo; Sat, 12 Aug 2023 21:37:08 -0700 X-Received: from NAM12-MW2-obe.outbound.protection.outlook.com (NAM12-MW2-obe.outbound.protection.outlook.com [40.107.244.80]) by mx.groups.io with SMTP id smtpd.web10.80506.1691901427601311935 for ; Sat, 12 Aug 2023 21:37:07 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DEoiCH6LhdvI4fVCfgBYyTcfqL9/5g867aPYaOShfYU7ZMlQTIWXXC+oOs4z5ixZiC2IgdVCyzh454Q2jBa9V/wPOS3N2WeT95fAJJLr7lgRKUtr5Lq1MLnCLgrCzSf3B+FYp6BfYq3ZwG5SLBducmLz8FsdEMCOKmIF2B8ipyxd9nNz9DQUEgO68XKdFFgKUoB404HsB4bSfDmpUcxBSlgep+tqgngr7K0ZV8vxVGSadyFpUdpIRV2/jrR9njzj2HB41Iaiao2KWvmbBgu9XwDHitmpmMqecVxIYTd5J04aycTBvmOMNyhqye6kJM1V8fUxkV+3BBskr688PrnV/g== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=sjvjLLIuibnuWP+/+6/GHtnty7MMA7v5+1XTt0nBp1w=; b=erlEYFgaWwaMURiITCez9VUjUbZUsi3+gMZchxRgQnwdt/KnHaBBPhm2AXpKO/ULEfl6wfAJV/zpWxCSAdDcSN5ZA2XuKzCy0T+FL//XDnLhYPqyhXnG+mwL197d2dKAL9ylGnzhP3KZ0EBSwuHC0fvqUicHwYAD6aKIVIf07lD5M1B50mvrAZxkkUjWgDehigBnj++NMogBuZ5xTaIFytqbuxGPFyvXK0CSGTkua8gschqqjS4AwRbauPp5hSAcWS0eCyWqODQkj1PVeUgBqRtvA2b4Ue5b4lYcaQFPlVW1Gn+QzNLEfl+GJ2pV67Tsf3hNSuyOS5d+4GIcUuUOJg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CYZPR02CA0023.namprd02.prod.outlook.com (2603:10b6:930:a1::21) by SA1PR12MB8741.namprd12.prod.outlook.com (2603:10b6:806:378::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.20; Sun, 13 Aug 2023 04:37:00 +0000 X-Received: from CY4PEPF0000EDD1.namprd03.prod.outlook.com (2603:10b6:930:a1:cafe::84) by CYZPR02CA0023.outlook.office365.com (2603:10b6:930:a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:36:59 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107724+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD1.mail.protection.outlook.com (10.167.241.205) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:36:59 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:36:57 -0500 From: "Chang, Abner via groups.io" To: CC: Hao A Wu , Ray Ni , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V3 4/6] MdeModulePkg/SpiNorFlashJedecSfdp: SPI NOR Flash JEDEC SFDP Date: Sun, 13 Aug 2023 12:36:28 +0800 Message-ID: <20230813043630.1123-5-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD1:EE_|SA1PR12MB8741:EE_ X-MS-Office365-Filtering-Correlation-Id: b8a95245-ec79-4c89-1095-08db9bb6ef09 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: Eo+F6aC8UhW5KpDo7gs5+q/H315K2IItX9YFcC/DJ47CwS41Rnh79WE/8bqQQFWJkoAcy0yTC08G/yDJfq0MOujUKGDB8gotgJdnTba6DhUh0j3jleOdEIhC9P6g/qgiRRJQrInh3XPldyjYDoXWm2YXKf/v7VkYMsyZzDogDdIOc1oxxA19FyabLj3t4lIuKdmFqOFB8RBwtTcLZ2OrVR9cqVsATyfLD2LRqp93Skb5WDkQIXGJxzN0lXNxf+qaemtS2CERL0PWAVYUVCQ0VnjqxT0Eb9igMNl8b6sCD0zhv0PSsA2mwveI43eeBHL6cnmYoKOzb2mHokAd06YCJYTsvmw8CrRA/XRNnjS+TPvvHlljV5jfQSHSHHXwjhC4xF2LLh0NMvEZsiS7RSQLjP+mNz4SNQAbdf6g8UORpxAs1kCj45t0X5Z9HTStjLAkRC0XOcVqUum1fCKY8Crx/Sw5dGO9SE6KWa0H089eCZzhTeDkNDhgpLHYlrKFIsRRMprCoumYXKrYoYMHx2vbboiCCv/sYAqkJPoWAzOzYIJB9or6J6JnhGehY9KNd7jFlo1hNDnLj0LcE6uar8wJFmqYJgjd7ogYVn/O4S7/RJHHWJ9e1uu9o5cM26oidWw9a3XM572nLzGa83fVfVlL79enIP3QtfzmRB1VuHnSaj9PFLcKnWFfySM/eB3PVJ6QSjdzgeJBCwKz5Mz1s4F0PmwjT/BZzYfQ+bHAzz4akn7A0nbpxuJI2laDNphdqdhGPMYoFOQOCL3rR/nl8ckPWbArymaA80PeHIs7y1oEroY= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:36:59.8665 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b8a95245-ec79-4c89-1095-08db9bb6ef09 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB8741 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: uel5SBfXlqItGqXdl10oMok6x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901430885100001 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4473 SPI NOR Flash JEDEC Serial Flash Discoverable Driver implementation. Signed-off-by: Abner Chang Cc: Hao A Wu Cc: Ray Ni Cc: Abdul Lateef Attar --- .../SpiNorFlashJedecSfdpDxe.inf | 63 + .../SpiNorFlashJedecSfdpSmm.inf | 63 + .../Spi/SpiNorFlashJedecSfdp/SpiNorFlash.h | 274 +++ .../SpiNorFlashJedecSfdpInternal.h | 294 +++ .../Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c | 1114 +++++++++++ .../SpiNorFlashJedecSfdp.c | 1772 +++++++++++++++++ .../SpiNorFlashJedecSfdpDxe.c | 261 +++ .../SpiNorFlashJedecSfdpSmm.c | 234 +++ .../SpiNorFlashJedecSfdpDxe.uni | 13 + .../SpiNorFlashJedecSfdpExtra.uni | 11 + .../SpiNorFlashJedecSfdpSmm.uni | 13 + 11 files changed, 4112 insertions(+) create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpDxe.inf create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpSmm.inf create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.h create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpInternal.h create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdp.c create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpDxe.c create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpSmm.c create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpDxe.uni create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpExtra.uni create mode 100644 MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJe= decSfdpSmm.uni diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Dxe.inf b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe= .inf new file mode 100644 index 00000000000..6bd6b53ef0d --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe.inf @@ -0,0 +1,63 @@ +## @file +# The SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) +# DXE driver INF file. +# +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Revision Reference: +# - JEDEC Standard, JESD216F.02 +# https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 +# +# @par Glossary: +# - SFDP - Serial Flash Discoverable Parameters +# - PTP - Parameter Table Pointer +## + +[Defines] + INF_VERSION =3D 1.25 + BASE_NAME =3D SpiNorFlashJedecSfdpDxe + FILE_GUID =3D 0DC9C2C7-D450-41BA-9CF7-D2090C35A797 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 0.1 + PI_SPECIFICATION_VERSION =3D 1.10 + ENTRY_POINT =3D SpiNorFlashJedecSfdpDxeEntry + MODULE_UNI_FILE =3D SpiNorFlashJedecSfdpDxe.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + TimerLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[Sources] + SpiNorFlashJedecSfdpDxe.c + SpiNorFlash.c + SpiNorFlashJedecSfdp.c + SpiNorFlashJedecSfdpInternal.h + SpiNorFlash.h + +[Protocols] + gEfiSpiNorFlashProtocolGuid ## PROCUDES + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds + +[Guids] + gEdk2JedecSfdpSpiDxeDriverGuid + +[Depex] + gEdk2JedecSfdpSpiDxeDriverGuid + +[UserExtensions.TianoCore."ExtraFiles"] + SpiNorFlashJedecSfdpExtra.uni diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Smm.inf b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm= .inf new file mode 100644 index 00000000000..72d3ace886a --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm.inf @@ -0,0 +1,63 @@ +## @file +# The SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) +# SMM driver INF file. +# +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Revision Reference: +# - JEDEC Standard, JESD216F.02 +# https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 +# +# @par Glossary: +# - SFDP - Serial Flash Discoverable Parameters +# - PTP - Parameter Table Pointer +## + +[Defines] + INF_VERSION =3D 1.25 + BASE_NAME =3D SpiNorFlashJedecSfdpSmm + FILE_GUID =3D AC7884C7-35A2-40AC-B9E0-AD67298E3BBA + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 0.1 + PI_SPECIFICATION_VERSION =3D 1.10 + ENTRY_POINT =3D SpiNorFlashJedecSfdpSmmEntry + MODULE_UNI_FILE =3D SpiNorFlashJedecSfdpSmm.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + SmmServicesTableLib + TimerLib + UefiDriverEntryPoint + +[Sources] + SpiNorFlashJedecSfdpSmm.c + SpiNorFlash.c + SpiNorFlashJedecSfdp.c + SpiNorFlashJedecSfdpInternal.h + SpiNorFlash.h + +[Protocols] + gEfiSpiSmmNorFlashProtocolGuid ## PROCUDES + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount + gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds + +[Guids] + gEdk2JedecSfdpSpiSmmDriverGuid + +[Depex] + gEdk2JedecSfdpSpiSmmDriverGuid + +[UserExtensions.TianoCore."ExtraFiles"] + SpiNorFlashJedecSfdpExtra.uni diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.h b/MdeM= odulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.h new file mode 100644 index 00000000000..ca85ab103ab --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.h @@ -0,0 +1,274 @@ +/** @file + Definitions of SPI NOR flash operation functions. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_NOR_FLASH_H_ +#define SPI_NOR_FLASH_H_ + +#include +#include +#include +#include "SpiNorFlashJedecSfdpInternal.h" + +/** + Fill Write Buffer with Opcode, Address, Dummy Bytes, and Data + + @param[in] Opcode - Opcode for transaction + @param[in] Address - SPI Offset Start Address + @param[in] WriteBytes - Number of bytes to write to SPI device + @param[in] WriteBuffer - Buffer containing bytes to write to SPI devi= ce + + @retval Size of Data in Buffer +**/ +UINT32 +FillWriteBuffer ( + IN SPI_NOR_FLASH_INSTANCE *SpiNorFlashInstance, + IN UINT8 Opcode, + IN UINT32 DummyBytes, + IN UINT8 AddressBytesSupported, + IN BOOLEAN UseAddress, + IN UINT32 Address, + IN UINT32 WriteBytes, + IN UINT8 *WriteBuffer + ); + +/** + Set Write Enable Latch + + @param[in] Instance SPI NOR instance with all protocols= , etc. + + @retval EFI_SUCCESS SPI Write Enable succeeded + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +SetWel ( + IN SPI_NOR_FLASH_INSTANCE *SpiNorFlashInstance + ); + +/** + Check for not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitNotWip ( + IN SPI_NOR_FLASH_INSTANCE *SpiNorFlashInstance + ); + +/** + Check for write enable latch set and not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress a= nd + write enable latch is set + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitWelNotWip ( + IN SPI_NOR_FLASH_INSTANCE *SpiNorFlashInstance + ); + +/** + Check for not write enable latch set and not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress a= nd + write enable latch is not set + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitNotWelNotWip ( + IN SPI_NOR_FLASH_INSTANCE *SpiNorFlashInstance + ); + +/** + Read the 3 byte manufacture and device ID from the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine reads the 3 byte manufacture and device ID from the flash p= art + filling the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data struct= ure. + @param[out] Buffer Pointer to a 3 byte buffer to receive the manufactur= e and + device ID. + + + + @retval EFI_SUCCESS The manufacture and device ID was read + successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +EFIAPI +GetFlashId ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + OUT UINT8 *Buffer + ); + +/** + Read data from the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine reads data from the SPI part in the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start reading + @param[in] LengthInBytes Read length in bytes + @param[out] Buffer Address of a buffer to receive the data + + @retval EFI_SUCCESS The data was read successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + +**/ +EFI_STATUS +EFIAPI +ReadData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + OUT UINT8 *Buffer + ); + +/** + Read data from the SPI flash at not fast speed + + This routine must be called at or below TPL_NOTIFY. + This routine reads data from the SPI part in the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start reading + @param[in] LengthInBytes Read length in bytes + @param[out] Buffer Address of a buffer to receive the data + + @retval EFI_SUCCESS The data was read successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + +**/ +EFI_STATUS +EFIAPI +LfReadData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + OUT UINT8 *Buffer + ); + +/** + Read the flash status register. + + This routine must be called at or below TPL_NOTIFY. + This routine reads the flash part status register. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] LengthInBytes Number of status bytes to read. + @param[out] FlashStatus Pointer to a buffer to receive the flash stat= us. + + @retval EFI_SUCCESS The status register was read successfully. + +**/ +EFI_STATUS +EFIAPI +ReadStatus ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 LengthInBytes, + OUT UINT8 *FlashStatus + ); + +/** + Write the flash status register. + + This routine must be called at or below TPL_N OTIFY. + This routine writes the flash part status register. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] LengthInBytes Number of status bytes to write. + @param[in] FlashStatus Pointer to a buffer containing the new status. + + @retval EFI_SUCCESS The status write was successful. + @retval EFI_OUT_OF_RESOURCES Failed to allocate the write buffer. + +**/ +EFI_STATUS +EFIAPI +WriteStatus ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 LengthInBytes, + IN UINT8 *FlashStatus + ); + +/** + Write data to the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine breaks up the write operation as necessary to write the dat= a to + the SPI part. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start writing + @param[in] LengthInBytes Write length in bytes + @param[in] Buffer Address of a buffer containing the data + + @retval EFI_SUCCESS The data was written successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + @retval EFI_OUT_OF_RESOURCES Insufficient memory to copy buffer. + +**/ +EFI_STATUS +EFIAPI +WriteData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + IN UINT8 *Buffer + ); + +/** + Efficiently erases one or more 4KiB regions in the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine uses a combination of 4 KiB and larger blocks to erase the + specified area. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address within a 4 KiB block to start erasing + @param[in] BlockCount Number of 4 KiB blocks to erase + + @retval EFI_SUCCESS The erase was completed successfully. + @retval EFI_INVALID_PARAMETER FlashAddress >=3D This->FlashSize, or + BlockCount * 4 KiB + > This->FlashSize - FlashAddress + +**/ +EFI_STATUS +EFIAPI +Erase ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 BlockCount + ); + +#endif // SPI_NOR_FLASH_H_ diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Internal.h b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Internal.h new file mode 100644 index 00000000000..6812559b880 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpInterna= l.h @@ -0,0 +1,294 @@ +/** @file + SPI NOR flash driver internal definitions. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_NOR_FLASH_INSTANCE_H_ +#define SPI_NOR_FLASH_INSTANCE_H_ + +#include +#include +#include +#include + +#define SPI_NOR_FLASH_SIGNATURE SIGNATURE_32 ('s', 'n', 'f', 'm') + +#define SPI_NOR_FLASH_FROM_THIS(a) CR (a, SPI_NOR_FLASH_INSTANCE, Protocol= , SPI_NOR_FLASH_SIGNATURE) + +typedef struct { + LIST_ENTRY NextFastReadCap; ///< Link list to next Fast read capa= bility + UINT8 FastReadInstruction; ///< Fast read instruction. + UINT8 ModeClocks; ///< Fast read clock. + UINT8 WaitStates; ///< Fast read wait dummy clocks +} SFPD_FAST_READ_CAPBILITY_RECORD; + +typedef struct { + LIST_ENTRY NextEraseType; ///< Link list to next erase type. + UINT16 EraseType; ///< Erase type this flash device supp= orts. + UINT8 EraseInstruction; ///< Erase instruction + UINT32 EraseSizeInByte; ///< The size of byte in 2^EraseSize t= he erase type command + ///< can erase. + UINT32 EraseTypicalTime; ///< Time the device typically takes t= o erase this type + ///< size. + UINT64 EraseTimeout; ///< Maximum typical erase timeout. +} SFDP_SUPPORTED_ERASE_TYPE_RECORD; + +typedef enum { + SearchEraseTypeByType =3D 1, + SearchEraseTypeByCommand, + SearchEraseTypeBySize, + SearchEraseTypeBySmallestSize, + SearchEraseTypeByBiggestSize +} SFDP_SEARCH_ERASE_TYPE; + +typedef struct { + LIST_ENTRY NextCommand; ///< Lin= k list to next detection command. + UINT32 CommandAddress; ///< Add= ress to issue the command. + UINT8 CommandInstruction; ///< Det= ection command instruction. + UINT8 LatencyInClock; ///< Com= mand latency in clocks. + SPDF_CONFIGURATION_COMMAND_ADDR_LENGTH CommandAddressLength; ///< Add= dress length of detection command. + UINT8 ConfigurationBitMask; ///< The= interest bit of the byte data retunred + ///< aft= er sending the detection command. +} SFDP_SECTOR_MAP_DETECTION_RECORD; + +typedef struct { + LIST_ENTRY NextRegion; ///< Link= list to the next region. + UINT32 RegionAddress; ///< Regi= on starting address. + UINT32 RegionTotalSize; ///< Regi= on total size in bytes. + UINT32 RegionSectors; ///< Sect= ors in this region. + UINT32 SectorSize; ///< Sect= or size in byte (Minimum blcok erase size) + UINT8 SupportedEraseTypeNum; ///< Numb= er of erase type supported. + UINT8 SupportedEraseType[SFDP_ERASE_TYPES_NUMBER]; ///< Eras= e types supported. + UINT32 EraseTypeBySizeBitmap; ///< The = bitmap of supoprted srase block sizes. + ///< from= big to small. +} SFDP_SECTOR_REGION_RECORD; + +typedef struct { + LIST_ENTRY NextDescriptor; ///< Link= list to next flash map descriptor. + UINT8 ConfigurationId; ///< The = ID of this configuration. + UINT8 RegionCount; ///< The = regions of this sector map configuration. + LIST_ENTRY RegionList; ///< The = linked list of the regions. +} SFDP_SECTOR_MAP_RECORD; + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_SPI_NOR_FLASH_PROTOCOL Protocol; + EFI_SPI_IO_PROTOCOL *SpiIo; + UINT32 SfdpBasicFlashByteCount; + UINT32 SfdpSectorMapByteCount; + SFDP_BASIC_FLASH_PARAMETER *SfdpBasicFlash; + SFDP_SECTOR_MAP_TABLE *SfdpFlashSectorMap; + UINT8 *SpiTransactionWriteBuffer; + UINT32 SpiTransactionWriteBufferIndex; + // + // SFDP information. + // + SFDP_HEADER SfdpHeader; ///< SFDP header. + UINT32 FlashDeviceSize; ///< The total si= ze of this flash device. + UINT8 CurrentAddressBytes; ///< The current = address bytes. + + // + // This is a linked list in which the Fast Read capability tables + // are linked from the low performance transfer to higher performance + // transfer. The SPI read would use the first Fast Read entry for + // SPI read operation. + // + LIST_ENTRY FastReadTableList; + + LIST_ENTRY SupportedEraseTypes; ///< The linked = list of supported erase types. + BOOLEAN Uniform4KEraseSupported; ///< The flash d= evice supoprts uniform 4K erase. + BOOLEAN WriteEnableLatchRequired; ///< Wether Writ= e Enable Latch is supported. + UINT8 WriteEnableLatchCommand; ///< Write Enabl= e Latch command. + // + // Below is the linked list of flash device sector + // map configuration detection command and map descriptors. + // + BOOLEAN ConfigurationCommandsNeeded; ///< Indicate= s whether sector map + ///< configur= ation detection is + ///< required. + LIST_ENTRY ConfigurationCommandList; ///< The link= ed list of configuration + ///< detectio= n command sequence. + LIST_ENTRY ConfigurationMapList; ///< The link= ed list of configuration + ///< map desc= riptors. + SFDP_SECTOR_MAP_RECORD *CurrentSectorMap; ///< The curr= ent activated flash device + ///< sector m= ap. +} SPI_NOR_FLASH_INSTANCE; + +/** + This routine returns the desired Fast Read mode. + + @param[in] Instance Spi Nor Flash Instance dat= a with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL= and EFI_SPI_IO_PROTOCOL + @param[in,out] FastReadInstruction Fast Read instruction, the= input is + the default value. + @param[in,out] FastReadOperationClock Fast Read operation clock,= the input is + the default value. + @param[in,out] FastReadDummyClocks Fast Read wait state (Dumm= y clocks), the + input is the default value. + @retval EFI_SUCCESS The parameters are updated. + @retval EFI_NOT_FOUND No desired Fas Read mode found. + +**/ +EFI_STATUS +GetFastReadParameter ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN OUT UINT8 *FastReadInstruction, + IN OUT UINT8 *FastReadOperationClock, + IN OUT UINT8 *FastReadDummyClocks + ); + +/** + Read SFDP parameters into buffer + + This routine reads the JEDEC SPI Flash Discoverable Parameters from the = SPI + chip. + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL + + @retval EFI_SUCCESS The SPI part size is filled. + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +ReadSfdpBasicParameterTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +/** + Read SFDP Sector Map Parameter into buffer + + This routine reads the JEDEC SPI Flash Discoverable Parameters from the = SPI + chip. + + @param[in] Instance Spi Nor Flash Instance data with pointer = to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO= _PROTOCOL + + @retval EFI_SUCCESS The SPI part size is filled. + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +ReadSfdpSectorMapParameterTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +/** + Return flash device size from SFDP Basic Flash Parameter Table DWORD 2 + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + +* @retval UINT32 Flash device size in byte, zero indicates error. + +**/ +UINT32 +SfdpGetFlashSize ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +/** + Read SFDP + This routine reads the JEDEC SPI Flash Discoverable Parameters. We just + read the necessary tables in this routine. + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOC= OL + + @retval EFI_SUCCESS Header is filled in + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +ReadSfdp ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +/** + Set EraseBlockBytes in SPI NOR Flash Protocol + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOC= OL + + @retval EFI_SUCCESS The erase block size is returned. + @retval Otherwise Failed to get erase block size. + +**/ +EFI_STATUS +SetSectorEraseBlockSize ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +/** + Get the erase block attribute for the target address. + + @param[in] Instance Spi Nor Flash Instance data with p= ointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI= _SPI_IO_PROTOCOL + @param[in] FlashRegion The region the flash address belon= g. + @param[in] FlashAddress The target flash address. + @param[in] RemainingSize Remaining size to erase. + @param[in, out] BlockSizeToErase Input - The block erase size for = this continious blocks. + Output - The determined block size= for erasing. + @param[in, out] BlockCountToErase Input - The expected blocks to er= ase. + Output - The determined number of = blocks to erase. + @param[out] BlockEraseCommand The erase command used for this co= ntinious blocks. + + @retval EFI_SUCCESS The erase block attribute is returned. + @retval EFI_DEVICE_ERROR No valid SFDP discovered. + @retval EFI_NOT_FOUND No valud erase block attribute found. + +**/ +EFI_STATUS +GetEraseBlockAttribute ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_SECTOR_REGION_RECORD *FlashRegion, + IN UINT32 FlashAddress, + IN UINT32 RemainingSize, + IN OUT UINT32 *BlockSizeToErase, + IN OUT UINT32 *BlockCountToErase, + OUT UINT8 *BlockEraseCommand + ); + +/** + Get the erase block attribute for the target address. + + @param[in] Instance Spi Nor Flash Instance data with po= inter to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_= SPI_IO_PROTOCOL + @param[in] FlashAddress The target flash address. + @param[out] FlashRegion The target flash address. + + @retval EFI_SUCCESS The region is returned. + @retval EFI_INVALID_PARAMETER FlashAddress is not belong to any region. + @retval EFI_INVALID_PARAMETER Other errors. + +**/ +EFI_STATUS +GetRegionByFlashAddress ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT32 FlashAddress, + OUT SFDP_SECTOR_REGION_RECORD **FlashRegion + ); + +/** + Initial SPI_NOR_FLASH_INSTANCE structure. + + @param[in] Instance Pointer to SPI_NOR_FLASH_INSTANCE. + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_= SPI_IO_PROTOCOL + + @retval EFI_SUCCESS SPI_NOR_FLASH_INSTANCE is initializ= ed according to + SPI NOR Flash SFDP specification. + @retval Otherwisw Failed to initial SPI_NOR_FLASH_INS= TANCE structure. + +**/ +EFI_STATUS +InitialSpiNorFlashSfdpInstance ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ); + +#endif // SPI_NOR_FLASH_INSTANCE_H_ diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c b/MdeM= odulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c new file mode 100644 index 00000000000..5f6724a9324 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c @@ -0,0 +1,1114 @@ +/** @file + SPI NOR Flash operation functions. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "SpiNorFlash.h" + +/** + Fill Write Buffer with Opcode, Address, Dummy Bytes, and Data + + @param[in] Opcode - Opcode for transaction + @param[in] Address - SPI Offset Start Address + @param[in] WriteBytes - Number of bytes to write to SPI device + @param[in] WriteBuffer - Buffer containing bytes to write to SPI devi= ce + + @retval Size of Data in Buffer +**/ +UINT32 +FillWriteBuffer ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT8 Opcode, + IN UINT32 DummyBytes, + IN UINT8 AddressBytesSupported, + IN BOOLEAN UseAddress, + IN UINT32 Address, + IN UINT32 WriteBytes, + IN UINT8 *WriteBuffer + ) +{ + UINT32 AddressSize; + UINT32 BigEndianAddress; + UINT32 Index; + UINT8 SfdpAddressBytes; + + SfdpAddressBytes =3D (UINT8)Instance->SfdpBasicFlash->AddressBytes; + + // Copy Opcode into Write Buffer + Instance->SpiTransactionWriteBuffer[0] =3D Opcode; + Index =3D 1; + if (UseAddress =3D=3D TRUE) { + if (AddressBytesSupported =3D=3D SPI_ADDR_3BYTE_ONLY) { + if (SfdpAddressBytes !=3D 0) { + // Check if the supported address length is already initiated. + if ((SfdpAddressBytes !=3D SPI_ADDR_3BYTE_ONLY) && (SfdpAddressByt= es !=3D SPI_ADDR_3OR4BYTE)) { + DEBUG ((DEBUG_ERROR, "%a: Unsupported Address Bytes: 0x%x, SFDP = is: 0x%x\n", __func__, AddressBytesSupported, SfdpAddressBytes)); + ASSERT (FALSE); + } + } + + AddressSize =3D 3; + } else if (AddressBytesSupported =3D=3D SPI_ADDR_4BYTE_ONLY) { + if (SfdpAddressBytes !=3D 0) { + // Check if the supported address length is already initiated. + if ((SfdpAddressBytes !=3D SPI_ADDR_4BYTE_ONLY) && (SfdpAddressByt= es !=3D SPI_ADDR_3OR4BYTE)) { + DEBUG ((DEBUG_ERROR, "%a: Unsupported Address Bytes: 0x%x, SFDP = is: 0x%x\n", __func__, AddressBytesSupported, SfdpAddressBytes)); + ASSERT (FALSE); + } + } + + AddressSize =3D 4; + } else if (AddressBytesSupported =3D=3D SPI_ADDR_3OR4BYTE) { + if (SfdpAddressBytes !=3D 0) { + // Check if the supported address length is already initiated. + if (SfdpAddressBytes !=3D SPI_ADDR_3OR4BYTE) { + DEBUG ((DEBUG_ERROR, "%a: Unsupported Address Bytes: 0x%x, SFDP = is: 0x%x\n", __func__, AddressBytesSupported, SfdpAddressBytes)); + ASSERT (FALSE); + } + } + + if (Instance->Protocol.FlashSize <=3D SIZE_16MB) { + AddressSize =3D 3; + } else { + // SPI part is > 16MB use 4-byte addressing. + AddressSize =3D 4; + } + } else { + DEBUG ((DEBUG_ERROR, "%a: Invalid Address Bytes\n", __func__)); + ASSERT (FALSE); + } + + BigEndianAddress =3D SwapBytes32 ((UINT32)Address); + BigEndianAddress >>=3D ((sizeof (UINT32) - AddressSize) * 8); + CopyMem ( + &Instance->SpiTransactionWriteBuffer[Index], + &BigEndianAddress, + AddressSize + ); + Index +=3D AddressSize; + } + + if (SfdpAddressBytes =3D=3D SPI_ADDR_3OR4BYTE) { + // + // TODO: + // We may need to enter/exit 4-Byte mode if SPI flash + // device is currently operated in 3-Bytes mode. + // + } + + // Fill DummyBytes + if (DummyBytes !=3D 0) { + SetMem ( + &Instance->SpiTransactionWriteBuffer[Index], + DummyBytes, + 0 + ); + Index +=3D DummyBytes; + } + + // Fill Data + if (WriteBytes > 0) { + CopyMem ( + &Instance->SpiTransactionWriteBuffer[Index], + WriteBuffer, + WriteBytes + ); + Index +=3D WriteBytes; + } + + return Index; +} + +/** + Internal Read the flash status register. + + This routine reads the flash part status register. + + @param[in] Instance SPI_NOR_FLASH_INSTANCE + structure. + @param[in] LengthInBytes Number of status bytes to read. + @param[out] FlashStatus Pointer to a buffer to receive the flash stat= us. + + @retval EFI_SUCCESS The status register was read successfully. + +**/ +EFI_STATUS +EFIAPI +InternalReadStatus ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT32 LengthInBytes, + OUT UINT8 *FlashStatus + ) +{ + EFI_STATUS Status; + UINT32 TransactionBufferLength; + + // Read Status register + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_RDSR, + SPI_FLASH_RDSR_DUMMY, + SPI_FLASH_RDSR_ADDR_BYTES, + FALSE, + 0, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 1, + FlashStatus + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Set Write Enable Latch + + @param[in] Instance SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS SPI Write Enable succeeded + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +SetWel ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT32 TransactionBufferLength; + + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + Instance->WriteEnableLatchCommand, + SPI_FLASH_WREN_DUMMY, + SPI_FLASH_WREN_ADDR_BYTES, + FALSE, + 0, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_ONLY, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 0, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Set WEL fail.\n", __func__)); + ASSERT (FALSE); + } + + return Status; +} + +/** + Check for not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitNotWip ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT8 DeviceStatus; + UINTN RetryCount; + UINTN DelayMicroseconds; + + DelayMicroseconds =3D FixedPcdGet32 (PcdSpiNorFlashOperationDelayMicrose= conds); + RetryCount =3D FixedPcdGet32 (PcdSpiNorFlashOperationRetryCount); + if (RetryCount =3D=3D 0) { + RetryCount =3D 1; + } + + do { + Status =3D InternalReadStatus (Instance, 1, &DeviceStatus); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Read status error\n", __func__)); + ASSERT (FALSE); + break; + } + + if ( EFI_ERROR (Status) + || ((DeviceStatus & SPI_FLASH_SR_WIP) =3D=3D SPI_FLASH_SR_NOT_WIP)) + { + break; + } + + MicroSecondDelay (DelayMicroseconds); + RetryCount--; + } while (RetryCount > 0); + + if (RetryCount =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "%a: Timeout error\n", __func__)); + Status =3D EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Check for write enable latch set and not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress a= nd + write enable latch is set + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitWelNotWip ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT8 DeviceStatus; + UINTN RetryCount; + UINTN DelayMicroseconds; + + DelayMicroseconds =3D FixedPcdGet32 (PcdSpiNorFlashOperationDelayMicrose= conds); + RetryCount =3D FixedPcdGet32 (PcdSpiNorFlashOperationRetryCount); + if (RetryCount =3D=3D 0) { + RetryCount =3D 1; + } + + do { + Status =3D InternalReadStatus (Instance, 1, &DeviceStatus); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to read WEL.\n", __func__)); + ASSERT_EFI_ERROR (Status); + } + + if ( EFI_ERROR (Status) + || ((DeviceStatus & (SPI_FLASH_SR_WIP | SPI_FLASH_SR_WEL)) + =3D=3D SPI_FLASH_SR_WEL)) + { + break; + } + + MicroSecondDelay (DelayMicroseconds); + RetryCount--; + } while (RetryCount > 0); + + if (RetryCount =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "%a: Timeout error\n", __func__)); + Status =3D EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Check for not write enable latch set and not device write in progress + + @param[in] Instance - SPI NOR instance with all protocols, etc. + + @retval EFI_SUCCESS Device does not have a write in progress a= nd + write enable latch is not set + @retval EFI_DEVICE_ERROR SPI Flash part did not respond properly +**/ +EFI_STATUS +WaitNotWelNotWip ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT8 DeviceStatus; + UINTN RetryCount; + UINTN DelayMicroseconds; + + DelayMicroseconds =3D FixedPcdGet32 (PcdSpiNorFlashOperationDelayMicrose= conds); + RetryCount =3D FixedPcdGet32 (PcdSpiNorFlashOperationRetryCount); + if (RetryCount =3D=3D 0) { + RetryCount =3D 1; + } + + do { + Status =3D InternalReadStatus (Instance, 1, &DeviceStatus); + ASSERT_EFI_ERROR (Status); + if ( EFI_ERROR (Status) + || ((DeviceStatus & (SPI_FLASH_SR_WIP | SPI_FLASH_SR_WEL)) + =3D=3D SPI_FLASH_SR_NOT_WIP)) + { + break; + } + + MicroSecondDelay (DelayMicroseconds); + RetryCount--; + } while (RetryCount > 0); + + if (RetryCount =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "SpiNorFlash:%a: Timeout error\n", __func__)); + Status =3D EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Read the 3 byte manufacture and device ID from the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine reads the 3 byte manufacture and device ID from the flash p= art + filling the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data struct= ure. + @param[out] Buffer Pointer to a 3 byte buffer to receive the manufactur= e and + device ID. + + @retval EFI_SUCCESS The manufacture and device ID was read + successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +EFIAPI +GetFlashId ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT32 TransactionBufferLength; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__)); + + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + + // Check not WIP + Status =3D WaitNotWip (Instance); + + if (!EFI_ERROR (Status)) { + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_RDID, + SPI_FLASH_RDID_DUMMY, + SPI_FLASH_RDID_ADDR_BYTES, + FALSE, + 0, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 3, + Buffer + ); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + +/** + Read data from the SPI flash at not fast speed + + This routine must be called at or below TPL_NOTIFY. + This routine reads data from the SPI part in the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start reading + @param[in] LengthInBytes Read length in bytes + @param[out] Buffer Address of a buffer to receive the data + + @retval EFI_SUCCESS The data was read successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + +**/ +EFI_STATUS +EFIAPI +LfReadData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT32 ByteCounter; + UINT32 CurrentAddress; + UINT8 *CurrentBuffer; + UINT32 Length; + UINT32 TransactionBufferLength; + UINT32 MaximumTransferBytes; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__)); + + Status =3D EFI_DEVICE_ERROR; + if ((Buffer =3D=3D NULL) || + (FlashAddress >=3D This->FlashSize) || + (LengthInBytes > This->FlashSize - FlashAddress)) + { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + MaximumTransferBytes =3D Instance->SpiIo->MaximumTransferBytes; + + CurrentBuffer =3D Buffer; + Length =3D 0; + for (ByteCounter =3D 0; ByteCounter < LengthInBytes;) { + CurrentAddress =3D FlashAddress + ByteCounter; + CurrentBuffer =3D Buffer + ByteCounter; + Length =3D LengthInBytes - ByteCounter; + // Length must be MaximumTransferBytes or less + if (Length > MaximumTransferBytes) { + Length =3D MaximumTransferBytes; + } + + // Check not WIP + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_READ, + SPI_FLASH_READ_DUMMY, + SPI_FLASH_READ_ADDR_BYTES, + TRUE, + CurrentAddress, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + Length, + CurrentBuffer + ); + ASSERT_EFI_ERROR (Status); + ByteCounter +=3D Length; + } + + return Status; +} + +/** + Read data from the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine reads data from the SPI part in the buffer provided. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start reading + @param[in] LengthInBytes Read length in bytes + @param[out] Buffer Address of a buffer to receive the data + + @retval EFI_SUCCESS The data was read successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + +**/ +EFI_STATUS +EFIAPI +ReadData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT32 ByteCounter; + UINT32 CurrentAddress; + UINT8 *CurrentBuffer; + UINT32 Length; + UINT32 TransactionBufferLength; + UINT32 MaximumTransferBytes; + UINT8 FastReadInstruction; + UINT8 FastReadWaitStateDummyClocks; + UINT8 FastReadModeClock; + + DEBUG ((DEBUG_INFO, "%a: Entry, Read address =3D 0x%08x, Length =3D 0x%0= 8x\n", __func__, FlashAddress, LengthInBytes)); + + Status =3D EFI_DEVICE_ERROR; + if ((Buffer =3D=3D NULL) || + (FlashAddress >=3D This->FlashSize) || + (LengthInBytes > This->FlashSize - FlashAddress)) + { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + MaximumTransferBytes =3D Instance->SpiIo->MaximumTransferBytes; + + // + // Initial the default read operation parameters. + // + FastReadInstruction =3D SPI_FLASH_FAST_READ; + FastReadWaitStateDummyClocks =3D SPI_FLASH_FAST_READ_DUMMY * 8; + FastReadModeClock =3D 0; + // + // Override by the Fast Read capabiity table. + // + // Get the first supported fast read comamnd. + // This will be the standard fast read command (0x0b), + // which is the first fast read command added to the + // supported list. + // TODO: The mechanism to choose the advanced fast read + // is not determined yet in this version of + // SpiNorFlash driver. + Status =3D GetFastReadParameter ( + Instance, + &FastReadInstruction, + &FastReadModeClock, + &FastReadWaitStateDummyClocks + ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_VERBOSE, " Use below Fast Read mode:\n")); + } else { + DEBUG ((DEBUG_VERBOSE, " Use the default Fast Read mode:\n")); + } + + DEBUG ((DEBUG_VERBOSE, " Instruction : 0x%x\n"= , FastReadInstruction)); + DEBUG ((DEBUG_VERBOSE, " Mode Clock : 0x%x\n"= , FastReadModeClock)); + DEBUG ((DEBUG_VERBOSE, " Wait States (Dummy Clocks) in clock: 0x%x\n"= , FastReadWaitStateDummyClocks)); + DEBUG ((DEBUG_VERBOSE, " Supported erase address bytes by device: 0x= %02x.\n", Instance->SfdpBasicFlash->AddressBytes)); + DEBUG ((DEBUG_VERBOSE, " (00: 3-Byte, 01: 3 or 4-Byte. 10: 4-Byte= )\n")); + + CurrentBuffer =3D Buffer; + Length =3D 0; + for (ByteCounter =3D 0; ByteCounter < LengthInBytes;) { + CurrentAddress =3D FlashAddress + ByteCounter; + CurrentBuffer =3D Buffer + ByteCounter; + Length =3D LengthInBytes - ByteCounter; + // Length must be MaximumTransferBytes or less + if (Length > MaximumTransferBytes) { + Length =3D MaximumTransferBytes; + } + + // Check not WIP + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + FastReadInstruction, + FastReadWaitStateDummyClocks / 8, + (UINT8)Instance->SfdpBasicFlash->AddressBy= tes, + TRUE, + CurrentAddress, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + Length, + CurrentBuffer + ); + ASSERT_EFI_ERROR (Status); + ByteCounter +=3D Length; + } + + return Status; +} + +/** + Read the flash status register. + + This routine must be called at or below TPL_NOTIFY. + This routine reads the flash part status register. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] LengthInBytes Number of status bytes to read. + @param[out] FlashStatus Pointer to a buffer to receive the flash stat= us. + + @retval EFI_SUCCESS The status register was read successfully. + +**/ +EFI_STATUS +EFIAPI +ReadStatus ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 LengthInBytes, + OUT UINT8 *FlashStatus + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + + if (LengthInBytes !=3D 1) { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + + Status =3D InternalReadStatus (Instance, LengthInBytes, FlashStatus); + + return Status; +} + +/** + Write the flash status register. + + This routine must be called at or below TPL_N OTIFY. + This routine writes the flash part status register. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] LengthInBytes Number of status bytes to write. + @param[in] FlashStatus Pointer to a buffer containing the new status. + + @retval EFI_SUCCESS The status write was successful. + @retval EFI_OUT_OF_RESOURCES Failed to allocate the write buffer. + +**/ +EFI_STATUS +EFIAPI +WriteStatus ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 LengthInBytes, + IN UINT8 *FlashStatus + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT32 TransactionBufferLength; + + if (LengthInBytes !=3D 1) { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + + // Check not WIP + Status =3D WaitNotWip (Instance); + + // Set Write Enable + if (!EFI_ERROR (Status)) { + if (Instance->WriteEnableLatchRequired) { + Status =3D SetWel (Instance); + DEBUG ((DEBUG_ERROR, "%a: set Write Enable Error.\n", __func__)); + ASSERT_EFI_ERROR (Status); + // Check not WIP & WEL enabled + Status =3D WaitWelNotWip (Instance); + } + + // Write the Status Register + if (!EFI_ERROR (Status)) { + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_WRSR, + SPI_FLASH_WRSR_DUMMY, + SPI_FLASH_WRSR_ADDR_BYTES, + FALSE, + 0, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_ONLY, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + } + + return Status; +} + +/** + Write data to the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine breaks up the write operation as necessary to write the dat= a to + the SPI part. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address in the flash to start writing + @param[in] LengthInBytes Write length in bytes + @param[in] Buffer Address of a buffer containing the data + + @retval EFI_SUCCESS The data was written successfully. + @retval EFI_INVALID_PARAMETER Buffer is NULL, or + FlashAddress >=3D This->FlashSize, or + LengthInBytes > This->FlashSize - FlashAd= dress + @retval EFI_OUT_OF_RESOURCES Insufficient memory to copy buffer. + +**/ +EFI_STATUS +EFIAPI +WriteData ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 LengthInBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT32 ByteCounter; + UINT32 CurrentAddress; + UINT32 Length; + UINT32 BytesUntilBoundary; + UINT8 *CurrentBuffer; + UINT32 TransactionBufferLength; + UINT32 MaximumTransferBytes; + UINT32 SpiFlashPageSize; + + DEBUG ((DEBUG_INFO, "%a: Entry: Write address =3D 0x%08x, Length =3D 0x%= 08x\n", __func__, FlashAddress, LengthInBytes)); + + Status =3D EFI_DEVICE_ERROR; + if ((Buffer =3D=3D NULL) || + (LengthInBytes =3D=3D 0) || + (FlashAddress >=3D This->FlashSize) || + (LengthInBytes > This->FlashSize - FlashAddress)) + { + return EFI_INVALID_PARAMETER; + } + + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + MaximumTransferBytes =3D Instance->SpiIo->MaximumTransferBytes; + if (Instance->SfdpBasicFlashByteCount >=3D 11 * 4) { + // JESD216C spec DWORD 11 + SpiFlashPageSize =3D 1 << Instance->SfdpBasicFlash->PageSize; + } else { + SpiFlashPageSize =3D 256; + } + + CurrentBuffer =3D Buffer; + Length =3D 0; + for (ByteCounter =3D 0; ByteCounter < LengthInBytes;) { + CurrentAddress =3D FlashAddress + ByteCounter; + CurrentBuffer =3D Buffer + ByteCounter; + Length =3D LengthInBytes - ByteCounter; + // Length must be MaximumTransferBytes or less + if (Length > MaximumTransferBytes) { + Length =3D MaximumTransferBytes; + } + + // Cannot cross SpiFlashPageSize boundary + BytesUntilBoundary =3D SpiFlashPageSize + - (CurrentAddress % SpiFlashPageSize); + if ((BytesUntilBoundary !=3D 0) && (Length > BytesUntilBoundary)) { + Length =3D BytesUntilBoundary; + } + + // Check not WIP + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + + if (Instance->WriteEnableLatchRequired) { + // Set Write Enable + Status =3D SetWel (Instance); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + break; + } + + // Check not WIP & WEL enabled + Status =3D WaitWelNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } + + // Write Data + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_PP, + SPI_FLASH_PP_DUMMY, + SPI_FLASH_PP_ADDR_BYTES, + TRUE, + CurrentAddress, + Length, + CurrentBuffer + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_ONLY, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + break; + } + + if (Instance->WriteEnableLatchRequired) { + // Check not WIP & not WEL + Status =3D WaitNotWelNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } else { + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } + + ByteCounter +=3D Length; + } + + return Status; +} + +/** + Efficiently erases blocks in the SPI flash. + + This routine must be called at or below TPL_NOTIFY. + This routine may use the combination of variable earse sizes to erase the + specified area accroding to the flash region. + + @param[in] This Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data + structure. + @param[in] FlashAddress Address to start erasing + @param[in] BlockCount Number of blocks to erase. The block size is in= dicated + in EraseBlockBytes in EFI_SPI_NOR_FLASH_PROTOCO= L. + + @retval EFI_SUCCESS The erase was completed successfully. + @retval EFI_DEVICE_ERROR The flash devices has problems. + @retval EFI_INVALID_PARAMETER The given FlashAddress and/or BlockCount + is invalid. + +**/ +EFI_STATUS +EFIAPI +Erase ( + IN CONST EFI_SPI_NOR_FLASH_PROTOCOL *This, + IN UINT32 FlashAddress, + IN UINT32 BlockCount + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + UINT8 Opcode; + UINT32 Dummy; + UINT32 ByteCounter; + UINT32 EraseLength; + UINT32 TotalEraseLength; + UINT32 CurrentAddress; + UINT32 TransactionBufferLength; + UINT32 BlockCountToErase; + UINT32 BlockSizeToErase; + UINT8 BlockEraseCommand; + SFDP_SECTOR_REGION_RECORD *FlashRegion; + + DEBUG ((DEBUG_INFO, "%a: Entry: Erase address =3D 0x%08x, Block count = =3D 0x%x\n", __func__, FlashAddress, BlockCount)); + + Status =3D EFI_DEVICE_ERROR; + Instance =3D SPI_NOR_FLASH_FROM_THIS (This); + + // Get the region of this flash address. + Status =3D GetRegionByFlashAddress (Instance, FlashAddress, &FlashRegion= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, " Failed to get the flash region of this flash a= ddress.\n")); + ASSERT (FALSE); + return Status; + } + + CurrentAddress =3D FlashAddress; + BlockCountToErase =3D BlockCount; + BlockSizeToErase =3D FlashRegion->SectorSize; // This is also the minim= um block erase size. + TotalEraseLength =3D BlockCountToErase * FlashRegion->SectorSize; + if ((FlashAddress + TotalEraseLength) > (FlashRegion->RegionAddress + Fl= ashRegion->RegionTotalSize)) { + DEBUG ((DEBUG_ERROR, " The blocks to erase exceeds the region boundar= y.\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_VERBOSE, " Region starting address: 0x%08x.\n", FlashRegi= on->RegionAddress)); + DEBUG ((DEBUG_VERBOSE, " Region size : 0x%08x.\n", FlashRegi= on->RegionTotalSize)); + DEBUG ((DEBUG_VERBOSE, " Region sector size : 0x%08x.\n", FlashRegi= on->SectorSize)); + DEBUG ((DEBUG_VERBOSE, " Supported erase address bytes by device: 0x%02= x.\n", Instance->SfdpBasicFlash->AddressBytes)); + DEBUG ((DEBUG_VERBOSE, " (00: 3-Byte, 01: 3 or 4-Byte. 10: 4-Byte)\n"= )); + + // Loop until all blocks are erased. + ByteCounter =3D 0; + while (ByteCounter < TotalEraseLength) { + CurrentAddress =3D FlashAddress + ByteCounter; + + // Is this the whole device erase. + if (TotalEraseLength =3D=3D This->FlashSize) { + Opcode =3D SPI_FLASH_CE; + Dummy =3D SPI_FLASH_CE_DUMMY; + EraseLength =3D TotalEraseLength; + DEBUG ((DEBUG_VERBOSE, " This is the chip erase.\n")); + } else { + // + // Get the erase block attributes. + // + Status =3D GetEraseBlockAttribute ( + Instance, + FlashRegion, + CurrentAddress, + TotalEraseLength - ByteCounter, + &BlockSizeToErase, + &BlockCountToErase, + &BlockEraseCommand + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, " Failed to get erase block attribute.\n")); + ASSERT (FALSE); + } + + Opcode =3D BlockEraseCommand; + Dummy =3D SPI_FLASH_BE_DUMMY; + EraseLength =3D BlockCountToErase * BlockSizeToErase; + DEBUG (( + DEBUG_VERBOSE, + " Erase command 0x%02x at adddress 0x%08x for length 0x%08x.\n", + BlockEraseCommand, + CurrentAddress, + EraseLength + )); + } + + // + // Process the erase command. + // + + // Check not WIP + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + + if (Instance->WriteEnableLatchRequired) { + // Set Write Enable + Status =3D SetWel (Instance); + if (EFI_ERROR (Status)) { + break; + } + + // Check not WIP & WEL enabled + Status =3D WaitWelNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } + + // Erase Block + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + Opcode, + Dummy, + (UINT8)Instance->SfdpBasicFlash->AddressBy= tes, + TRUE, + CurrentAddress, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_ONLY, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + break; + } else { + DEBUG ((DEBUG_VERBOSE, "Erase command sucessfully.\n")); + } + + if (Instance->WriteEnableLatchRequired) { + // Check not WIP & not WEL + Status =3D WaitNotWelNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } else { + Status =3D WaitNotWip (Instance); + if (EFI_ERROR (Status)) { + break; + } + } + + ByteCounter +=3D EraseLength; + } + + return Status; +} diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= .c b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp.c new file mode 100644 index 00000000000..00ba0a62a51 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp.c @@ -0,0 +1,1772 @@ +/** @file + SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) + common functions. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - JEDEC Standard, JESD216F.02 + https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 + + @par Glossary: + - SFDP - Serial Flash Discoverable Parameters + - PTP - Parameter Table Pointer +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SpiNorFlash.h" +#include "SpiNorFlashJedecSfdpInternal.h" + +/** + Build up the Fast Read capability entry and link it to + the linked list. + + @param[in] Instance SPI Nor Flash Instance data with point= er to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + @param[in] FastReadInstruction The string of fast read instruction. + @param[in] FastReadModeClk The string of fast read mode clock. + @param[in] FastReadDummyClk The string of fast read dummy clock. + +**/ +VOID +CreateSpiFastReadTableEntry ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT32 FastReadInstruction, + IN UINT32 FastReadModeClk, + IN UINT32 FastReadDummyClk + ) +{ + SFPD_FAST_READ_CAPBILITY_RECORD *CapabilityEntry; + + CapabilityEntry =3D AllocateZeroPool (sizeof (SFPD_FAST_READ_CAPBILITY_R= ECORD)); + if (CapabilityEntry =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Failed to create fast read table\n", __func_= _)); + ASSERT (FALSE); + return; + } + + InitializeListHead (&CapabilityEntry->NextFastReadCap); + CapabilityEntry->FastReadInstruction =3D (UINT8)FastReadInstruction; + CapabilityEntry->ModeClocks =3D (UINT8)FastReadModeClk; + CapabilityEntry->WaitStates =3D (UINT8)FastReadDummyClk; + InsertTailList (&Instance->FastReadTableList, &CapabilityEntry->NextFast= ReadCap); + DEBUG ((DEBUG_VERBOSE, "%a: Create and link table.\n", __func__)); + DEBUG ((DEBUG_VERBOSE, " Instruction : 0x%x\n", FastReadI= nstruction)); + DEBUG ((DEBUG_VERBOSE, " Mode bits : 0x%x\n", FastReadM= odeClk)); + DEBUG ((DEBUG_VERBOSE, " Wait States (Dummy Clocks): 0x%x\n", FastReadD= ummyClk)); +} + +/** + Calculate erase type typical time. + + @param[in] SfdpEraseTypicalTime Erase type typical time indicated = in + Basic Flash Parameter Table. + EraseTypicalTime [0:4] - Count + EraseTypicalTime [5:6] - Unit + 00b: 1ms + 01b: 16ms + 10b: 128= ms + 11b: 1s + @param[in] SfdpEraseTimeMultiplier Multiplier from erase typical time. + @param[out] EraseTypicalTime Pointer to receive Erase typical t= ime in milliseconds. + @param[out] EraseTimeout Pointer to receive Erase timeout i= n milliseconds. + + @retval Erase time in milliseconds. +**/ +VOID +CalculateEraseTiming ( + IN UINT32 SfdpEraseTypicalTime, + IN UINT32 SfdpEraseTimeMultiplier, + OUT UINT32 *EraseTypicalTime, + OUT UINT64 *EraseTimeout + ) +{ + UINT32 UnitInMs; + + UnitInMs =3D (SfdpEraseTypicalTime & ERASE_TYPICAL_TIME_UNITS_MASK) >> E= RASE_TYPICAL_TIME_BIT_POSITION; + switch (UnitInMs) { + case ERASE_TYPICAL_TIME_UNIT_1_MS_BITMAP: + UnitInMs =3D ERASE_TYPICAL_TIME_UNIT_1_MS; + break; + + case ERASE_TYPICAL_TIME_UNIT_16_MS_BITMAP: + UnitInMs =3D ERASE_TYPICAL_TIME_UNIT_16_MS; + break; + + case ERASE_TYPICAL_TIME_UNIT_128_MS_BITMAP: + UnitInMs =3D ERASE_TYPICAL_TIME_UNIT_128_MS; + break; + + case ERASE_TYPICAL_TIME_UNIT_1000_MS_BITMAP: + UnitInMs =3D ERASE_TYPICAL_TIME_UNIT_1000_MS; + break; + default: + DEBUG ((DEBUG_ERROR, "%a: Unsupported Erase Typical time.\n", __func= __)); + ASSERT (FALSE); + } + + *EraseTypicalTime =3D UnitInMs * ((SfdpEraseTypicalTime & ERASE_TYPICAL_= TIME_COUNT_MASK) + 1); + *EraseTimeout =3D 2 * (SfdpEraseTimeMultiplier + 1) * *EraseTypicalT= ime; + return; +} + +/** + Print out the erase type information. + + @param[in] SupportedEraseType Pointer to SFDP_SUPPORTED_ERASE_TYPE_R= ECORD. +**/ +VOID +DebugPrintEraseType ( + IN SFDP_SUPPORTED_ERASE_TYPE_RECORD *SupportedEraseType + ) +{ + DEBUG ((DEBUG_VERBOSE, " Erase Type %d\n", SupportedEraseType->EraseTyp= e)); + DEBUG ((DEBUG_VERBOSE, " Erase Type instruction: 0x%x\n", SupportedEras= eType->EraseInstruction)); + DEBUG ((DEBUG_VERBOSE, " Erase size: 0x%x bytes\n", SupportedEraseType-= >EraseSizeInByte)); + DEBUG ((DEBUG_VERBOSE, " Erase time: %d Milliseconds\n", SupportedErase= Type->EraseTypicalTime)); + DEBUG ((DEBUG_VERBOSE, " Erase timeout: %d Milliseconds:\n", Supported= EraseType->EraseTimeout)); +} + +/** + Insert supported erase type entry. + + @param[in] Instance SPI Nor Flash Instance data with point= er to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + @param[in] SupportedEraseType Pointer to SFDP_SUPPORTED_ERASE_TYPE_R= ECORD. +**/ +VOID +CreateEraseTypeEntry ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_SUPPORTED_ERASE_TYPE_RECORD *SupportedEraseType + ) +{ + InitializeListHead (&SupportedEraseType->NextEraseType); + InsertTailList (&Instance->SupportedEraseTypes, &SupportedEraseType->Nex= tEraseType); + + DEBUG ((DEBUG_VERBOSE, "%a: Erase Type 0x%x is supported:\n", __func__, = SupportedEraseType->EraseType)); + DebugPrintEraseType (SupportedEraseType); +} + +/** + Build up the erase type tables. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + +**/ +VOID +BuildUpEraseTypeTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + SFDP_SUPPORTED_ERASE_TYPE_RECORD *SupportedEraseType; + + // Build up erase type 1 entry. + if (Instance->SfdpBasicFlash->Erase1Size !=3D 0) { + SupportedEraseType =3D AllocateZeroPool (sizeof (SFDP_SUPPORTED_ERASE_= TYPE_RECORD)); + if (SupportedEraseType !=3D NULL) { + SupportedEraseType->EraseType =3D SFDP_ERASE_TYPE_1; + SupportedEraseType->EraseInstruction =3D (UINT8)Instance->SfdpBasicF= lash->Erase1Instr; + SupportedEraseType->EraseSizeInByte =3D (UINT32)1 << Instance->Sfdp= BasicFlash->Erase1Size; + CalculateEraseTiming ( + Instance->SfdpBasicFlash->Erase1Time, + Instance->SfdpBasicFlash->EraseMultiplier, + &SupportedEraseType->EraseTypicalTime, + &SupportedEraseType->EraseTimeout + ); + CreateEraseTypeEntry (Instance, SupportedEraseType); + } else { + DEBUG ((DEBUG_ERROR, "%a: Memory allocated failed for SFDP_SUPPORTED= _ERASE_TYPE_RECORD (Type 1).\n", __func__)); + ASSERT (FALSE); + } + } + + // Build up erase type 2 entry. + if (Instance->SfdpBasicFlash->Erase2Size !=3D 0) { + SupportedEraseType =3D AllocateZeroPool (sizeof (SFDP_SUPPORTED_ERASE_= TYPE_RECORD)); + if (SupportedEraseType !=3D NULL) { + SupportedEraseType->EraseType =3D SFDP_ERASE_TYPE_2; + SupportedEraseType->EraseInstruction =3D (UINT8)Instance->SfdpBasicF= lash->Erase2Instr; + SupportedEraseType->EraseSizeInByte =3D (UINT32)1 << Instance->Sfdp= BasicFlash->Erase2Size; + CalculateEraseTiming ( + Instance->SfdpBasicFlash->Erase2Time, + Instance->SfdpBasicFlash->EraseMultiplier, + &SupportedEraseType->EraseTypicalTime, + &SupportedEraseType->EraseTimeout + ); + CreateEraseTypeEntry (Instance, SupportedEraseType); + } else { + DEBUG ((DEBUG_ERROR, "%a: Memory allocated failed for SFDP_SUPPORTED= _ERASE_TYPE_RECORD (Type 2).\n", __func__)); + ASSERT (FALSE); + } + } + + // Build up erase type 3 entry. + if (Instance->SfdpBasicFlash->Erase3Size !=3D 0) { + SupportedEraseType =3D AllocateZeroPool (sizeof (SFDP_SUPPORTED_ERASE_= TYPE_RECORD)); + if (SupportedEraseType !=3D NULL) { + SupportedEraseType->EraseType =3D SFDP_ERASE_TYPE_3; + SupportedEraseType->EraseInstruction =3D (UINT8)Instance->SfdpBasicF= lash->Erase3Instr; + SupportedEraseType->EraseSizeInByte =3D (UINT32)1 << Instance->Sfdp= BasicFlash->Erase3Size; + CalculateEraseTiming ( + Instance->SfdpBasicFlash->Erase3Time, + Instance->SfdpBasicFlash->EraseMultiplier, + &SupportedEraseType->EraseTypicalTime, + &SupportedEraseType->EraseTimeout + ); + CreateEraseTypeEntry (Instance, SupportedEraseType); + } else { + DEBUG ((DEBUG_ERROR, "%a: Memory allocated failed for SFDP_SUPPORTED= _ERASE_TYPE_RECORD (Type 3).\n", __func__)); + ASSERT (FALSE); + } + } + + // Build up erase type 4 entry. + if (Instance->SfdpBasicFlash->Erase4Size !=3D 0) { + SupportedEraseType =3D AllocateZeroPool (sizeof (SFDP_SUPPORTED_ERASE_= TYPE_RECORD)); + if (SupportedEraseType !=3D NULL) { + SupportedEraseType->EraseType =3D SFDP_ERASE_TYPE_4; + SupportedEraseType->EraseInstruction =3D (UINT8)Instance->SfdpBasicF= lash->Erase4Instr; + SupportedEraseType->EraseSizeInByte =3D (UINT32)1 << Instance->Sfdp= BasicFlash->Erase4Size; + CalculateEraseTiming ( + Instance->SfdpBasicFlash->Erase4Time, + Instance->SfdpBasicFlash->EraseMultiplier, + &SupportedEraseType->EraseTypicalTime, + &SupportedEraseType->EraseTimeout + ); + CreateEraseTypeEntry (Instance, SupportedEraseType); + } else { + DEBUG ((DEBUG_ERROR, "%a: Memory allocated failed for SFDP_SUPPORTED= _ERASE_TYPE_RECORD (Type 4).\n", __func__)); + ASSERT (FALSE); + } + } +} + +/** + This function check if the erase type is one of the target erase types. + + @param[in] EraseType The erase type. + @param[in] TargetTypeNum Number of target search types. + @param[in] TargetTypes Target types. + + + @retval TRUE Yes, this is the target erase type. + @retval FALSE No, this is not the target erase type. + +**/ +BOOLEAN +IsTargetEraseType ( + IN UINT16 EraseType, + IN UINT8 TargetTypeNum, + IN UINT8 *TargetTypes + ) +{ + UINT8 Index; + + for (Index =3D 0; Index < TargetTypeNum; Index++) { + if (EraseType =3D=3D *(TargetTypes + Index)) { + return TRUE; + } + } + + return FALSE; +} + +/** + Search the erase type record according to the given search type and valu= e. + + @param[in] Instance SPI Nor Flash Instance data with po= inter to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + @param[in] SearchType Search type. + @param[in] SearchValue The value of according to search ty= pe. + - For SearchEraseTypeByCommand: + SearchValue is the erase instruct= ion. + - For SearchEraseTypeBySize: + SearchValue is the erase block s= ize. + - For SearchEraseTypeBySmallestSize: + SearchValue is not used. + - For SearchEraseTypeByBiggestSize: + SearchValue is not used. + @param[in] SupportedTypeTargetNum Only search the specific erase type= s. + @param[in] SupportedTypeTarget Pointer to SupportedTypeTargetNum of + supported erase types. + @param[out] EraseTypeRecord Pointer to receive the erase type r= ecord. + + @retval EFI_SUCCESS Pointer to erase type record is ret= urned. + EFI_INVALID_PARAMETER Invalid SearchType. + EFI_NOT_FOUND Erase type not found. +**/ +EFI_STATUS +GetEraseTypeRecord ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_SEARCH_ERASE_TYPE SearchType, + IN UINT32 SearchValue, + IN UINT8 SupportedTypeTargetNum, + IN UINT8 *SupportedTypeTarget OPTIONAL, + OUT SFDP_SUPPORTED_ERASE_TYPE_RECORD **EraseTypeRecord + ) +{ + SFDP_SUPPORTED_ERASE_TYPE_RECORD *EraseType; + UINT32 ValueToCompare; + BOOLEAN ExitSearching; + + if (IsListEmpty (&Instance->SupportedEraseTypes)) { + return EFI_NOT_FOUND; + } + + *EraseTypeRecord =3D NULL; + + // + // Initial the comapre value. + // + switch (SearchType) { + case SearchEraseTypeByType: + case SearchEraseTypeByCommand: + case SearchEraseTypeBySize: + break; + case SearchEraseTypeBySmallestSize: + ValueToCompare =3D (UINT32)-1; + break; + case SearchEraseTypeByBiggestSize: + ValueToCompare =3D 0; + break; + default: + return EFI_INVALID_PARAMETER; + } + + ExitSearching =3D FALSE; + EraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetFirstNode (&Ins= tance->SupportedEraseTypes); + while (TRUE) { + if ((SupportedTypeTarget =3D=3D NULL) || IsTargetEraseType (EraseType-= >EraseType, SupportedTypeTargetNum, SupportedTypeTarget)) { + switch (SearchType) { + case SearchEraseTypeByType: + if (EraseType->EraseType =3D=3D SearchValue) { + *EraseTypeRecord =3D EraseType; + ExitSearching =3D TRUE; + } + + break; + + case SearchEraseTypeBySize: + if (EraseType->EraseSizeInByte =3D=3D SearchValue) { + *EraseTypeRecord =3D EraseType; + ExitSearching =3D TRUE; + } + + break; + + case SearchEraseTypeByCommand: + if (EraseType->EraseInstruction =3D=3D (UINT8)SearchValue) { + *EraseTypeRecord =3D EraseType; + ExitSearching =3D TRUE; + } + + break; + + case SearchEraseTypeBySmallestSize: + if (EraseType->EraseSizeInByte < ValueToCompare) { + ValueToCompare =3D EraseType->EraseSizeInByte; + *EraseTypeRecord =3D EraseType; + } + + break; + + case SearchEraseTypeByBiggestSize: + if (EraseType->EraseSizeInByte > ValueToCompare) { + ValueToCompare =3D EraseType->EraseSizeInByte; + *EraseTypeRecord =3D EraseType; + } + + break; + + default: + return EFI_INVALID_PARAMETER; + } + } + + if (IsNodeAtEnd (&Instance->SupportedEraseTypes, &EraseType->NextErase= Type) || ExitSearching) { + break; + } + + EraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetNextNode (&Instan= ce->SupportedEraseTypes, &EraseType->NextEraseType); + } + + if (*EraseTypeRecord =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Get the erase block attribute for the target address. + + @param[in] Instance Spi Nor Flash Instance data with p= ointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI= _SPI_IO_PROTOCOL + @param[in] FlashRegion The region the flash address belon= g. + @param[in] FlashAddress The target flash address. + @param[in] RemainingSize Remaining size to erase. + @param[in, out] BlockSizeToErase Input - The block erase size for = this continious blocks. + Output - The determined block size= for erasing. + @param[in, out] BlockCountToErase Input - The expected blocks to er= ase. + Output - The determined number of = blocks to erase. + @param[out] BlockEraseCommand The erase command used for this co= ntinious blocks. + + @retval EFI_SUCCESS The erase block attribute is returned. + @retval EFI_DEVICE_ERROR No valid SFDP discovered. + @retval EFI_NOT_FOUND No valud erase block attribute found. + +**/ +EFI_STATUS +GetEraseBlockAttribute ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_SECTOR_REGION_RECORD *FlashRegion, + IN UINT32 FlashAddress, + IN UINT32 RemainingSize, + IN OUT UINT32 *BlockSizeToErase, + IN OUT UINT32 *BlockCountToErase, + OUT UINT8 *BlockEraseCommand + ) +{ + EFI_STATUS Status; + SFDP_SUPPORTED_ERASE_TYPE_RECORD *EraseType; + UINT32 EraseSize; + + DEBUG ((DEBUG_VERBOSE, "%a: Entry\n", __func__)); + + for (EraseSize =3D SIZE_2GB; EraseSize !=3D 0; EraseSize =3D EraseSize >= > 1) { + Status =3D GetEraseTypeRecord (Instance, SearchEraseTypeBySize, EraseS= ize, 0, NULL, &EraseType); + if (!EFI_ERROR (Status)) { + // Validate this erase type. + if (((FlashAddress & (EraseType->EraseSizeInByte - 1)) =3D=3D 0) && + (RemainingSize >=3D EraseType->EraseSizeInByte)) + { + *BlockSizeToErase =3D EraseType->EraseSizeInByte; + *BlockCountToErase =3D 1; + *BlockEraseCommand =3D EraseType->EraseInstruction; + Status =3D EFI_SUCCESS; + break; + } + } + } + + if (EraseType =3D=3D NULL) { + return EFI_DEVICE_ERROR; + } + + DEBUG ((DEBUG_VERBOSE, " Erase address at 0x%08x.\n", FlashAddress)); + DEBUG ((DEBUG_VERBOSE, " - Erase block size : 0x%08x.\n", *BlockSiz= eToErase)); + DEBUG ((DEBUG_VERBOSE, " - Erase block count : 0x%08x.\n", *BlockCou= ntToErase)); + DEBUG ((DEBUG_VERBOSE, " - Erase block command: 0x%02x.\n", *BlockEra= seCommand)); + DEBUG ((DEBUG_VERBOSE, " - Remaining size to erase: 0x%08x.\n", Remai= ningSize)); + return EFI_SUCCESS; +} + +/** + Get the erase block attribute for the target address. + + @param[in] Instance Spi Nor Flash Instance data with po= inter to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_= SPI_IO_PROTOCOL + @param[in] FlashAddress The target flash address. + @param[out] FlashRegion The target flash address. + + @retval EFI_SUCCESS The region is returned. + @retval EFI_INVALID_PARAMETER FlashAddress is not belong to any region. + @retval Otherwise Other errors. + +**/ +EFI_STATUS +GetRegionByFlashAddress ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT32 FlashAddress, + OUT SFDP_SECTOR_REGION_RECORD **FlashRegion + ) +{ + SFDP_SECTOR_MAP_RECORD *SectorMapRecord; + SFDP_SECTOR_REGION_RECORD *RegionRecord; + + DEBUG ((DEBUG_VERBOSE, "%a: Entry\n", __func__)); + + SectorMapRecord =3D Instance->CurrentSectorMap; + if (SectorMapRecord =3D=3D NULL) { + return EFI_DEVICE_ERROR; + } + + RegionRecord =3D (SFDP_SECTOR_REGION_RECORD *)GetFirstNode (&SectorMapRe= cord->RegionList); + while (TRUE) { + if ((FlashAddress >=3D RegionRecord->RegionAddress) && + (FlashAddress < RegionRecord->RegionAddress + RegionRecord->Region= TotalSize)) + { + *FlashRegion =3D RegionRecord; + return EFI_SUCCESS; + } + + if (IsNodeAtEnd (&SectorMapRecord->RegionList, &RegionRecord->NextRegi= on)) { + break; + } + + RegionRecord =3D (SFDP_SECTOR_REGION_RECORD *)GetNextNode (&SectorMapR= ecord->RegionList, &RegionRecord->NextRegion); + } + + return EFI_INVALID_PARAMETER; +} + +/** + Build up the Fast Read capability tables. The earlier linked table + in the linked list has the faster transfer. + NOTE: 1. The Quad input instructions mentioned in 21th DWOWRD + are not considered yet. + 2. Maximum speed options for certain Fast Read modes are + not considered yet. (e.g., 8D-8D-8D or 4S-4D-4D) + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + +**/ +VOID +BuildUpFastReadTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + // Build up the standard Fast Read + // This will be first picked for the ReadData. + // TODO: The mechanism to choose the advance fast read + // is not determined yet in this version of + // SpiNorFlash driver. + CreateSpiFastReadTableEntry ( + Instance, + SPI_FLASH_FAST_READ, + 0, + SPI_FLASH_FAST_READ_DUMMY * 8 + ); + + // Build up Fast Read table 1S-1S-4S + if (Instance->SfdpBasicFlash->FastRead114 !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead114Instr, + Instance->SfdpBasicFlash->FastRead114ModeClk, + Instance->SfdpBasicFlash->FastRead114Dummy + ); + } + + // Build up Fast Read table 1S-2S-2S + if (Instance->SfdpBasicFlash->FastRead122 !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead122Instr, + Instance->SfdpBasicFlash->FastRead122ModeClk, + Instance->SfdpBasicFlash->FastRead122Dummy + ); + } + + // Build up Fast Read table 2S-2S-2S + if (Instance->SfdpBasicFlash->FastRead222 !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead222Instr, + Instance->SfdpBasicFlash->FastRead222ModeClk, + Instance->SfdpBasicFlash->FastRead222Dummy + ); + } + + // Build up Fast Read table 1S-4S-4S + if (Instance->SfdpBasicFlash->FastRead144 !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead144Instr, + Instance->SfdpBasicFlash->FastRead144ModeClk, + Instance->SfdpBasicFlash->FastRead144Dummy + ); + } + + // Build up Fast Read table 4S-4S-4S + if (Instance->SfdpBasicFlash->FastRead444 !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead444Instr, + Instance->SfdpBasicFlash->FastRead444ModeClk, + Instance->SfdpBasicFlash->FastRead444Dummy + ); + } + + // Build up Fast Read table 1S-1S-8S + if (Instance->SfdpBasicFlash->FastRead118Instr !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead118Instr, + Instance->SfdpBasicFlash->FastRead118ModeClk, + Instance->SfdpBasicFlash->FastRead118Dummy + ); + } + + // Build up Fast Read table 1S-8S-8S + if (Instance->SfdpBasicFlash->FastRead188Instr !=3D 0) { + CreateSpiFastReadTableEntry ( + Instance, + Instance->SfdpBasicFlash->FastRead188Instr, + Instance->SfdpBasicFlash->FastRead188ModeClk, + Instance->SfdpBasicFlash->FastRead188Dummy + ); + } +} + +/** + This function sets up the erase types supported + by this region. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + @param[in] RegionRecord Pointer to SFDP_SECTOR_REGION_RECORD of th= is + regions. + @retval EFI_SUCCESS Current sector map configuration is determ= ined. + EFI_DEVICE_ERROR Current sector map configuration is not fo= und. + +**/ +EFI_STATUS +SetupRegionEraseInfo ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_SECTOR_REGION_RECORD *RegionRecord + ) +{ + SFDP_SUPPORTED_ERASE_TYPE_RECORD *SupportedEraseType; + UINT32 MinimumEraseSize; + + if (IsListEmpty (&Instance->SupportedEraseTypes)) { + DEBUG ((DEBUG_ERROR, "%a: No erase type suppoted on the flash device.\= n", __func__)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + MinimumEraseSize =3D (UINT32)-1; + SupportedEraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetFirstNode = (&Instance->SupportedEraseTypes); + while (TRUE) { + RegionRecord->SupportedEraseType[RegionRecord->SupportedEraseTypeNum] = =3D (UINT8)SupportedEraseType->EraseType; + RegionRecord->SupportedEraseTypeNum++; + RegionRecord->EraseTypeBySizeBitmap |=3D SupportedEraseType->EraseSize= InByte; + if (MinimumEraseSize > SupportedEraseType->EraseSizeInByte) { + MinimumEraseSize =3D SupportedEraseType->EraseSizeInByte; + } + + if (IsNodeAtEnd (&Instance->SupportedEraseTypes, &SupportedEraseType->= NextEraseType)) { + break; + } + + SupportedEraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetNextNode= (&Instance->SupportedEraseTypes, &SupportedEraseType->NextEraseType); + } + + RegionRecord->SectorSize =3D MinimumEraseSize; + RegionRecord->RegionTotalSize =3D Instance->FlashDeviceSize; + RegionRecord->RegionSectors =3D RegionRecord->RegionTotalSize / Region= Record->SectorSize; + return EFI_SUCCESS; +} + +/** + Create a single flash sector map. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + @retval EFI_SUCCESS Current sector map configuration is dete= rmined. + EFI_DEVICE_ERROR Current sector map configuration is not = found. + +**/ +EFI_STATUS +CreateSingleFlashSectorMap ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + SFDP_SECTOR_MAP_RECORD *SectorMapRecord; + SFDP_SECTOR_REGION_RECORD *RegionRecord; + UINTN EraseIndex; + + DEBUG ((DEBUG_VERBOSE, "%a: Entry:\n", __func__)); + SectorMapRecord =3D (SFDP_SECTOR_MAP_RECORD *)AllocateZeroPool (sizeof (= SFDP_SECTOR_MAP_RECORD)); + if (SectorMapRecord =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for SFDP_SECTOR_MAP_DETEC= TION_RECORD.\n", __func__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + // Create SFDP_SECTOR_MAP_RECORD. + InitializeListHead (&SectorMapRecord->NextDescriptor); + InitializeListHead (&SectorMapRecord->RegionList); + SectorMapRecord->ConfigurationId =3D 0; + SectorMapRecord->RegionCount =3D 1; + InsertTailList (&Instance->ConfigurationMapList, &SectorMapRecord->NextD= escriptor); + DEBUG ((DEBUG_VERBOSE, " Sector map configurations ID : 0x%x\n", = SectorMapRecord->ConfigurationId)); + DEBUG ((DEBUG_VERBOSE, " Sector map configurations regions: %d\n", Se= ctorMapRecord->RegionCount)); + + // Create SFDP_SECTOR_MAP_RECORD region record. + RegionRecord =3D (SFDP_SECTOR_REGION_RECORD *)AllocateZeroPool (sizeof (= SFDP_SECTOR_REGION_RECORD)); + if (RegionRecord =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for SFDP_SECTOR_REGION_RE= CORD.\n", __func__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&RegionRecord->NextRegion); + + RegionRecord->RegionAddress =3D 0; + // + // Setup erase information in the region record. + // + SetupRegionEraseInfo (Instance, RegionRecord); + + InsertTailList (&SectorMapRecord->RegionList, &RegionRecord->NextRegion); + + Instance->CurrentSectorMap =3D SectorMapRecord; + + DEBUG ((DEBUG_VERBOSE, " Region totoal size : 0x%x\n", Region= Record->RegionTotalSize)); + DEBUG ((DEBUG_VERBOSE, " Region sector size : 0x%x\n", Region= Record->SectorSize)); + DEBUG ((DEBUG_VERBOSE, " Region sectors : 0x%x\n", Region= Record->RegionSectors)); + + for (EraseIndex =3D 0; EraseIndex < RegionRecord->SupportedEraseTypeNum;= EraseIndex++) { + DEBUG ((DEBUG_VERBOSE, " Region erase type supported: 0x%x\n", Regi= onRecord->SupportedEraseType[EraseIndex])); + } + + return EFI_SUCCESS; +} + +/** + Set EraseBlockBytes in SPI NOR Flash Protocol + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOC= OL + + @retval EFI_SUCCESS The erase block size is returned. + @retval Otherwise Failed to get erase block size. + +**/ +EFI_STATUS +SetSectorEraseBlockSize ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + SFDP_SUPPORTED_ERASE_TYPE_RECORD *EraseTypeRecord; + + // Use the smallest size for the sector erase. + Status =3D GetEraseTypeRecord (Instance, SearchEraseTypeBySmallestSize, = 0, 0, NULL, &EraseTypeRecord); + if (!EFI_ERROR (Status)) { + Instance->Protocol.EraseBlockBytes =3D EraseTypeRecord->EraseSizeInByt= e; + DEBUG ((DEBUG_VERBOSE, " Erase block size =3D 0x%08x\n", EraseTypeRec= ord->EraseSizeInByte)); + } + + return Status; +} + +/** + Get the current sector map configuration. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + + @retval EFI_SUCCESS Current sector map configuration is dete= rmined. + EFI_DEVICE_ERROR Current sector map configuration is not = found. + +**/ +EFI_STATUS +GetCurrentSectorMapConfiguration ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT32 TransactionBufferLength; + UINT8 AddressLength; + BOOLEAN UseAddress; + UINT32 DummyBytes; + UINT8 ReturnByte; + UINT8 ConfigurationId; + SFDP_SECTOR_MAP_RECORD *SectorMap; + SFDP_SECTOR_MAP_DETECTION_RECORD *CommandEntry; + + Instance->CurrentSectorMap =3D NULL; + if (!Instance->ConfigurationCommandsNeeded) { + // No command needed measn only one configuration for the flash device= sector map. + Instance->CurrentSectorMap =3D (SFDP_SECTOR_MAP_RECORD *)GetFirstNode = (&Instance->ConfigurationMapList); + return EFI_SUCCESS; + } + + // + // Send the command to collect interest bit. + // + ConfigurationId =3D 0; + CommandEntry =3D (SFDP_SECTOR_MAP_DETECTION_RECORD *)GetFirstNode (&I= nstance->ConfigurationCommandList); + while (TRUE) { + // Check not WIP + Status =3D WaitNotWip (Instance); + + // Read configuration byte. + AddressLength =3D SPI_ADDR_3BYTE_ONLY; + DummyBytes =3D 1; + if (CommandEntry->CommandAddressLength =3D=3D SpdfConfigurationCommand= Address4Byte) { + AddressLength =3D SPI_ADDR_4BYTE_ONLY; + DummyBytes =3D 0; + } + + UseAddress =3D TRUE; + if (CommandEntry->CommandAddress =3D=3D SpdfConfigurationCommandAddres= sNone) { + UseAddress =3D FALSE; + } + + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + CommandEntry->CommandInstruction, + DummyBytes, + AddressLength, + UseAddress, + CommandEntry->CommandAddress, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + 1, + &ReturnByte + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to read the configuration byte.\n", = __func__)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + // + // Retrieve the interest bit. + // + if ((ReturnByte & CommandEntry->ConfigurationBitMask) !=3D 0) { + ConfigurationId |=3D 0x01; + } + + if (IsNodeAtEnd (&Instance->ConfigurationCommandList, &CommandEntry->N= extCommand)) { + break; + } + + CommandEntry =3D (SFDP_SECTOR_MAP_DETECTION_RECORD *)GetNextNode (&= Instance->ConfigurationCommandList, &CommandEntry->NextCommand); + ConfigurationId =3D ConfigurationId << 1; + } + + // + // Now we have current activated configuration ID in ConfigurationId. + // Walk through ConfigurationMapList to record the activated flash sector + // map configuration. + // + SectorMap =3D (SFDP_SECTOR_MAP_RECORD *)GetFirstNode (&Instance->Configu= rationMapList); + while (TRUE) { + if (SectorMap->ConfigurationId =3D=3D ConfigurationId) { + Instance->CurrentSectorMap =3D SectorMap; + break; + } + + if (IsNodeAtEnd (&Instance->ConfigurationMapList, &SectorMap->NextDesc= riptor)) { + break; + } + + SectorMap =3D (SFDP_SECTOR_MAP_RECORD *)GetNextNode (&Instance->Config= urationMapList, &SectorMap->NextDescriptor); + } + + if (Instance->CurrentSectorMap =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Activated flash sector map is not found!\n",= __func__)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Build sector map configurations. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + + @retval EFI_SUCCESS Records of sector map configuration co= mmand and map + descriptor are built up successfully. + EFI_OUT_OF_RESOURCES Not enough memory resource. + EFI_DEVICE_ERROR SFDP Sector Map Parameter is not + constructed correctly. + +**/ +EFI_STATUS +BuildSectorMapCommandAndMap ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + SFDP_SECTOR_MAP_TABLE *SfdpSectorMapTable; + SFDP_SECTOR_CONFIGURATION_COMMAND *SfdpDetectionCommand; + SFDP_SECTOR_MAP_DETECTION_RECORD *CommandEntry; + SFDP_SECTOR_CONFIGURATION_MAP *SfdpConfigurationMap; + SFDP_SECTOR_MAP_RECORD *SectorMapRecord; + SFDP_SECTOR_REGION *SpdfSectorRegion; + SFDP_SECTOR_REGION_RECORD *RegionRecord; + SFDP_SUPPORTED_ERASE_TYPE_RECORD *SupportedEraseType; + UINT8 RegionCount; + UINT8 EraseTypeCount; + UINT32 MinimumEraseSize; + UINT32 RegionAddress; + + SfdpSectorMapTable =3D Instance->SfdpFlashSectorMap; + SfdpConfigurationMap =3D &SfdpSectorMapTable->ConfigurationMap; + SfdpDetectionCommand =3D &SfdpSectorMapTable->ConfigurationCommand; + + if (SfdpSectorMapTable->GenericHeader.DescriptorType =3D=3D SFDP_SECTOR_= MAP_TABLE_ENTRY_TYPE_MAP) { + // No configuration detection commands are needs. + Instance->ConfigurationCommandsNeeded =3D FALSE; + } else { + DEBUG ((DEBUG_VERBOSE, "%a: Sector map configuration detection command= is needed\n", __func__)); + Instance->ConfigurationCommandsNeeded =3D TRUE; + + // Go through the section map detection commands. + while (TRUE) { + CommandEntry =3D (SFDP_SECTOR_MAP_DETECTION_RECORD *)AllocateZeroPoo= l (sizeof (SFDP_SECTOR_MAP_DETECTION_RECORD)); + if (CommandEntry =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for SFDP_SECTOR_MAP_D= ETECTION_RECORD.\n", __func__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&CommandEntry->NextCommand); + CommandEntry->CommandAddress =3D SfdpDetectionCommand->Command= Address; + CommandEntry->CommandAddressLength =3D (SPDF_CONFIGURATION_COMMAND_A= DDR_LENGTH)SfdpDetectionCommand->DetectionCommandAddressLen; + CommandEntry->CommandInstruction =3D (UINT8)SfdpDetectionCommand->= DetectionInstruction; + CommandEntry->ConfigurationBitMask =3D (UINT8)SfdpDetectionCommand->= ReadDataMask; + CommandEntry->LatencyInClock =3D (UINT8)SfdpDetectionCommand->= DetectionLatency; + InsertTailList (&Instance->ConfigurationCommandList, &CommandEntry->= NextCommand); + DEBUG ((DEBUG_VERBOSE, " Command instruction : 0x%x\n", CommandEn= try->CommandInstruction)); + DEBUG ((DEBUG_VERBOSE, " Bit selection : 0x%x\n", CommandEn= try->ConfigurationBitMask)); + DEBUG ((DEBUG_VERBOSE, " Command address : 0x%x\n", CommandEn= try->CommandAddress)); + DEBUG ((DEBUG_VERBOSE, " Command address length: %d\n", CommandEntr= y->CommandAddressLength)); + DEBUG ((DEBUG_VERBOSE, " Command latency clocks: %d\n\n", CommandEn= try->LatencyInClock)); + if (SfdpDetectionCommand->DescriptorEnd =3D=3D SFDP_SECTOR_MAP_TABLE= _ENTRY_LAST) { + break; + } + + SfdpDetectionCommand++; + } + + SfdpConfigurationMap =3D (SFDP_SECTOR_CONFIGURATION_MAP *)SfdpDetectio= nCommand++; + } + + // + // Go through the region table pointed in SfdpConfigurationMap. + // + if (SfdpConfigurationMap->DescriptorType !=3D SFDP_SECTOR_MAP_TABLE_ENTR= Y_TYPE_MAP) { + DEBUG ((DEBUG_ERROR, "%a: Incorrect format of Sector Map Parameter.\n"= , __func__)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + while (TRUE) { + DEBUG ((DEBUG_VERBOSE, "%a: Sector map configurations:\n", __func__)); + SectorMapRecord =3D (SFDP_SECTOR_MAP_RECORD *)AllocateZeroPool (sizeof= (SFDP_SECTOR_MAP_RECORD)); + if (SectorMapRecord =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for SFDP_SECTOR_MAP_DET= ECTION_RECORD.\n", __func__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&SectorMapRecord->NextDescriptor); + InitializeListHead (&SectorMapRecord->RegionList); + SectorMapRecord->ConfigurationId =3D (UINT8)SfdpConfigurationMap->Conf= igurationID; + SectorMapRecord->RegionCount =3D (UINT8)SfdpConfigurationMap->Regi= onCount; + InsertTailList (&Instance->ConfigurationMapList, &SectorMapRecord->Nex= tDescriptor); + DEBUG ((DEBUG_VERBOSE, " Sector map configurations ID : 0x%x\n"= , SectorMapRecord->ConfigurationId)); + DEBUG ((DEBUG_VERBOSE, " Sector map configurations regions: %d\n", = SectorMapRecord->RegionCount)); + SpdfSectorRegion =3D (SFDP_SECTOR_REGION *)SfdpConfigurationMap + 1; + RegionAddress =3D 0; + for (RegionCount =3D 0; RegionCount < SectorMapRecord->RegionCount; Re= gionCount++) { + RegionRecord =3D (SFDP_SECTOR_REGION_RECORD *)AllocateZeroPool (size= of (SFDP_SECTOR_REGION_RECORD)); + if (RegionRecord =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for SFDP_SECTOR_MAP_D= ETECTION_RECORD.\n", __func__)); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&RegionRecord->NextRegion); + RegionRecord->RegionTotalSize =3D (SpdfSectorRegion->RegionSize + 1)= * SFDP_SECTOR_REGION_SIZE_UNIT; + // + // Construct erase type supported for this region. + // + if (SpdfSectorRegion->EraseType1 !=3D 0) { + RegionRecord->SupportedEraseType[RegionRecord->SupportedEraseTypeN= um] =3D SFDP_ERASE_TYPE_1; + RegionRecord->SupportedEraseTypeNum++; + } + + if (SpdfSectorRegion->EraseType2 !=3D 0) { + RegionRecord->SupportedEraseType[RegionRecord->SupportedEraseTypeN= um] =3D SFDP_ERASE_TYPE_2; + RegionRecord->SupportedEraseTypeNum++; + } + + if (SpdfSectorRegion->EraseType3 !=3D 0) { + RegionRecord->SupportedEraseType[RegionRecord->SupportedEraseTypeN= um] =3D SFDP_ERASE_TYPE_3; + RegionRecord->SupportedEraseTypeNum++; + } + + if (SpdfSectorRegion->EraseType4 !=3D 0) { + RegionRecord->SupportedEraseType[RegionRecord->SupportedEraseTypeN= um] =3D SFDP_ERASE_TYPE_4; + RegionRecord->SupportedEraseTypeNum++; + } + + // + // Calculate the sector size and total sectors. + // + if (IsListEmpty (&Instance->SupportedEraseTypes)) { + DEBUG ((DEBUG_ERROR, "%a: No erase type suppoted on the flash devi= ce.\n", __func__)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + MinimumEraseSize =3D (UINT32)-1; + for (EraseTypeCount =3D 0; EraseTypeCount < RegionRecord->SupportedE= raseTypeNum++; EraseTypeCount++) { + // + // Walk through Instance->SupportedEraseTypes to find the matching= erase type and + // Use the minimum erase size as the sector size; + // + SupportedEraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetFirs= tNode (&Instance->SupportedEraseTypes); + while (TRUE) { + if (RegionRecord->SupportedEraseType[EraseTypeCount] =3D=3D Supp= ortedEraseType->EraseType) { + // Set erase size bitmap. + RegionRecord->EraseTypeBySizeBitmap |=3D SupportedEraseType->E= raseSizeInByte; + + if (MinimumEraseSize > SupportedEraseType->EraseSizeInByte) { + MinimumEraseSize =3D SupportedEraseType->EraseSizeInByte; + break; + } + } + + if (IsNodeAtEnd (&Instance->SupportedEraseTypes, &SupportedErase= Type->NextEraseType)) { + break; + } + + SupportedEraseType =3D (SFDP_SUPPORTED_ERASE_TYPE_RECORD *)GetNe= xtNode (&Instance->SupportedEraseTypes, &SupportedEraseType->NextEraseType); + } + } + + RegionRecord->SectorSize =3D MinimumEraseSize; + RegionRecord->RegionSectors =3D RegionRecord->RegionTotalSize / Regi= onRecord->SectorSize; + RegionRecord->RegionAddress =3D RegionAddress; + + // Insert to link. + InsertTailList (&SectorMapRecord->RegionList, &RegionRecord->NextReg= ion); + DEBUG ((DEBUG_VERBOSE, " Region: %d\n", RegionCount)); + DEBUG ((DEBUG_VERBOSE, " Region totoal size: 0x%x\n", Regio= nRecord->RegionTotalSize)); + DEBUG ((DEBUG_VERBOSE, " Region sector size: 0x%x\n", Regio= nRecord->SectorSize)); + DEBUG ((DEBUG_VERBOSE, " Region sectors : 0x%x\n", Regio= nRecord->RegionSectors)); + DEBUG ((DEBUG_VERBOSE, " Region erase supported bitmap: 0x%= x\n", RegionRecord->EraseTypeBySizeBitmap)); + + SpdfSectorRegion++; + RegionAddress +=3D RegionRecord->RegionTotalSize; + } + + if (SfdpConfigurationMap->DescriptorEnd =3D=3D SFDP_SECTOR_MAP_TABLE_E= NTRY_LAST) { + break; + } + + SfdpConfigurationMap =3D (SFDP_SECTOR_CONFIGURATION_MAP *)SpdfSectorRe= gion; + } + + return EFI_SUCCESS; +} + +/** + This routine get Write Enable latch command. + + @param[in] Instance SPI Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + +**/ +VOID +GetWriteEnableCommand ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + // + // Set Wrtie Enable command. + // + Instance->WriteEnableLatchRequired =3D TRUE; + Instance->WriteEnableLatchCommand =3D SPI_FLASH_WREN; + if (Instance->SfdpBasicFlash->VolatileStatusBlockProtect =3D=3D 1) { + if (Instance->SfdpBasicFlash->WriteEnableVolatileStatus =3D=3D 0) { + Instance->WriteEnableLatchCommand =3D SPI_FLASH_WREN_50H; + } + } + + DEBUG ((DEBUG_ERROR, "%a: Use Write Enable Command 0x%x.\n", __func__, I= nstance->WriteEnableLatchCommand)); +} + +/** + This routine returns the desired Fast Read mode. + + @param[in] Instance Spi Nor Flash Instance dat= a with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL= and EFI_SPI_IO_PROTOCOL + @param[in,out] FastReadInstruction Fast Read instruction, the= input is + the default value. + @param[in,out] FastReadModeBits The operational mode bits. + @param[in,out] FastReadDummyClocks Fast Read wait state (Dumm= y clocks), the + input is the default value. + @param[out] FastReadStr Pointer to retrieve the hu= man readable string + of fast read mode. + @retval EFI_SUCCESS The parameters are updated. + @retval EFI_NOT_FOUND No desired Fas Read mode found. + +**/ +EFI_STATUS +GetFastReadParameter ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN OUT UINT8 *FastReadInstruction, + IN OUT UINT8 *FastReadModeBits, + IN OUT UINT8 *FastReadDummyClocks + ) +{ + SFPD_FAST_READ_CAPBILITY_RECORD *FastReadEntry; + + if (IsListEmpty (&Instance->FastReadTableList)) { + return EFI_NOT_FOUND; + } + + FastReadEntry =3D (SFPD_FAST_READ_CAPBILITY_RECORD *)GetFirstNode= (&Instance->FastReadTableList); + *FastReadInstruction =3D FastReadEntry->FastReadInstruction; + *FastReadDummyClocks =3D FastReadEntry->WaitStates; + *FastReadModeBits =3D FastReadEntry->ModeClocks; + + // + // *FastReadOperationClock may be replaced by 8D-8D-8D or 4S-4D-4D Fast = Read + // mode clock operation mode. Which is not cosidered in the implementati= on yet. + // + return EFI_SUCCESS; +} + +/** + Return the flash device size from SFDP Basic Flash Parameter Table DWORD= 2 + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and + EFI_SPI_IO_PROTOCOL. + + @retval UINT32 Flash device size in byte, zero indicates error. + +**/ +UINT32 +SfdpGetFlashSize ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + if (Instance =3D=3D NULL) { + return 0; + } + + if ((Instance->SfdpBasicFlash->Density & SFDP_FLASH_MEMORY_DENSITY_4GBIT= ) =3D=3D 0) { + // + // The flash device size is <=3D 256MB. + // + return (Instance->SfdpBasicFlash->Density + 1) / 8; + } + + // + // The flash deivce size is >=3D 512MB. + // Bit [0:30] defines 'N' where the density is computed as 2^N bits. + // N must be >=3D32 according to the SFDP specification. + // + if ((Instance->SfdpBasicFlash->Density & ~SFDP_FLASH_MEMORY_DENSITY_4GBI= T) < 32) { + return 0; + } + + return (UINT32)RShiftU64 (LShiftU64 (1, Instance->SfdpBasicFlash->Densit= y & ~SFDP_FLASH_MEMORY_DENSITY_4GBIT), 3); +} + +/** + Read SFDP Header + + This routine reads the JEDEC SPI Flash Discoverable Parameter header fro= m the + SPI chip. Fails if Major Revision is not =3D 1 + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOC= OL + + @retval EFI_SUCCESS Header is filled in + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +EFIAPI +ReadSfdpHeader ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT32 TransactionBufferLength; + + // Check not WIP + Status =3D WaitNotWip (Instance); + + // Read SFDP Header + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_RDSFDP, + SPI_FLASH_RDSFDP_DUMMY, + SPI_FLASH_RDSFDP_ADDR_BYTES, + TRUE, + 0, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + sizeof (SFDP_HEADER), + (UINT8 *)&Instance->SfdpHeader + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + // Read Basic Flash Parameter Header + if ((Instance->SfdpHeader.Signature !=3D SFDP_HEADER_SIGNATURE) || + (Instance->SfdpHeader.MajorRev !=3D SFDP_SUPPORTED_MAJOR_REVISION)) + { + Status =3D EFI_DEVICE_ERROR; + } else { + DEBUG ((DEBUG_VERBOSE, "Total %d parameter headers\n", Instance->Sfd= pHeader.NumParameterHeaders + 1)); + } + } + + return Status; +} + +/** + Read SFDP + This routine reads the JEDEC SPI Flash Discoverable Parameters. We just + read the necessary tables in this routine. + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOC= OL + + @retval EFI_SUCCESS Header is filled in + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +ReadSfdp ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + SFDP_SUPPORTED_ERASE_TYPE_RECORD *EraseTypeRecord; + + InitializeListHead (&Instance->FastReadTableList); + InitializeListHead (&Instance->SupportedEraseTypes); + InitializeListHead (&Instance->ConfigurationCommandList); + InitializeListHead (&Instance->ConfigurationMapList); + + DEBUG ((DEBUG_VERBOSE, "%a: Entry\n", __func__)); + + Status =3D ReadSfdpHeader (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to read SFDP header\n", __func__)); + ASSERT (FALSE); + return Status; + } + + Status =3D ReadSfdpBasicParameterTable (Instance); + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to read SFDP Basic Parameter Table\n"= , __func__)); + ASSERT (FALSE); + return Status; + } + + Instance->FlashDeviceSize =3D SfdpGetFlashSize (Instance); + DEBUG ((DEBUG_VERBOSE, "%a: Flash Size=3D0x%X\n", __func__, Instance->Fl= ashDeviceSize)); + if (Instance->FlashDeviceSize =3D=3D 0) { + ASSERT (FALSE); + return Status; + } + + Status =3D ReadSfdpSectorMapParameterTable (Instance); + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to read SFDP Sector Map Parameter Tab= le\n", __func__)); + ASSERT (FALSE); + } else if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG ((DEBUG_VERBOSE, "%a: The SPI NOR flash device doesn't have SFDP= Sector Map Parameter Table implemented:\n", __func__)); + + // + // No SFDP Sector Map Parameter Table exist. + // Check if device support the uniform 4K erase size. + // + Instance->Uniform4KEraseSupported =3D FALSE; + if (Instance->SfdpBasicFlash->EraseSizes =3D=3D SPI_UNIFORM_4K_ERASE_S= UPPORTED) { + DEBUG ((DEBUG_VERBOSE, "%a: The SPI NOR flash device supports unifor= m 4K erase.\n", __func__)); + + // Check if 4K erase type supported? + Status =3D GetEraseTypeRecord (Instance, SearchEraseTypeBySize, SIZE= _4KB, 0, NULL, &EraseTypeRecord); + if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, "However, no corresponding 4K size erase type= found.\n", __func__)); + ASSERT (FALSE); + } + + Instance->Uniform4KEraseSupported =3D TRUE; + } else { + // Uniform 4K erase unsupported, get the smallest erase block size. + DEBUG ((DEBUG_VERBOSE, "%a: The SPI NOR flash device doesn't support= uniform 4K erase.\n", __func__)); + } + + // + // Build flash map + // Instance->ConfigurationMapList is an empty list because no FDP Sect= or Map Parameter Table. + // + CreateSingleFlashSectorMap (Instance); + Status =3D EFI_SUCCESS; + } + + return Status; +} + +/** + Read SFDP Specific Parameter Header + + This routine reads the JEDEC SPI Flash Discoverable Parameter header fro= m the + SPI chip. Fails if Major Revision is not =3D SFDP_SUPPORTED_MAJOR_REVIS= ION. + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PR= OTOCOL + @param[in] SfdpHeader SFDP Header Buffer Pointer + @param[in] ParameterIdMsb Most significant byte of parameter ID. + @param[in] ParameterIdLsb Lowest significant byte of parameter ID. + + @retval EFI_SUCCESS Header is filled in + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + @retval EFI_NOT_FOUND Unsupported Parameter Header. + +**/ +EFI_STATUS +EFIAPI +ReadSfdpParameterHeader ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN SFDP_PARAMETER_HEADER *SfdpParameterHeader, + IN UINT8 ParameterIdMsb, + IN UINT8 ParameterIdLsb + ) +{ + EFI_STATUS Status; + UINT32 Index; + SFDP_PARAMETER_HEADER LocalSfdpParameterHeader; + UINT32 TransactionBufferLength; + + DEBUG ((DEBUG_VERBOSE, "%a: Entry\n", __func__)); + DEBUG ((DEBUG_VERBOSE, " Looking for Parameter Header %02x:%02x\n", Par= ameterIdMsb, ParameterIdLsb)); + + // + // Parse Parameter Headers Starting at size eof SFDP_HEADER. + // SfdpHeader.NumParameterHeaders is zero based, 0 means 1 parameter hea= der. + // + ZeroMem (SfdpParameterHeader, sizeof (SFDP_PARAMETER_HEADER)); + for (Index =3D 0; Index < Instance->SfdpHeader.NumParameterHeaders + 1; = Index++) { + // Check not WIP + Status =3D WaitNotWip (Instance); + if (!EFI_ERROR (Status)) { + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_RDSFDP, + SPI_FLASH_RDSFDP_DUMMY, + SPI_FLASH_RDSFDP_ADDR_BYTES, + TRUE, + sizeof (SFDP_HEADER) + Index * 8, // Par= ameter Header Index + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + sizeof (LocalSfdpParameterHeader), + (UINT8 *)&LocalSfdpParameterHeader + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + // Break if SfdParamHeader is Type 0, Basic SPI Protocol Parameters + DEBUG (( + DEBUG_VERBOSE, + " #%d Parameter Header: %02x:%02x, revision: %d.%d\n", + Index, + LocalSfdpParameterHeader.IdMsb, + LocalSfdpParameterHeader.IdLsb, + LocalSfdpParameterHeader.MajorRev, + LocalSfdpParameterHeader.MinorRev >=3D SfdpParameterHeader->Mino= rRev + )); + if ((LocalSfdpParameterHeader.IdLsb =3D=3D ParameterIdLsb) && + (LocalSfdpParameterHeader.IdMsb =3D=3D ParameterIdMsb) && + (LocalSfdpParameterHeader.MajorRev =3D=3D (UINT32)SFDP_SUPPORT= ED_MAJOR_REVISION) && + (LocalSfdpParameterHeader.MinorRev >=3D SfdpParameterHeader->M= inorRev)) + { + CopyMem ( + (VOID **)SfdpParameterHeader, + (VOID **)&LocalSfdpParameterHeader, + sizeof (SFDP_PARAMETER_HEADER) + ); + } + } else { + break; + } + } else { + break; + } + } + + if (Status !=3D EFI_DEVICE_ERROR) { + if ((SfdpParameterHeader->IdLsb !=3D ParameterIdLsb) || + (SfdpParameterHeader->IdMsb !=3D ParameterIdMsb)) + { + DEBUG ((DEBUG_ERROR, " Parameter Header: %02x:%02x is not found.\n"= , ParameterIdMsb, ParameterIdLsb)); + Status =3D EFI_NOT_FOUND; + } + } + + return Status; +} + +/** + Read from SFDP table pointer + + This routine sends SPI_FLASH_RDSFDP command and reads parameter from the + given TablePointer. + + @param[in] Instance Spi Nor Flash Instance data with pointer = to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO= _PROTOCOL + @param[in] TablePointer Pointer to read data from SFDP. + @param[in] DestBuffer Destination buffer. + @param[in] LengthInBytes Length to read. + + @retval EFI_SUCCESS The SPI part size is filled. + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + @retval Other errors + +**/ +EFI_STATUS +EFIAPI +SpiReadSfdpPtp ( + IN SPI_NOR_FLASH_INSTANCE *Instance, + IN UINT32 TablePointer, + IN VOID *DestBuffer, + IN UINT32 LengthInBytes + ) +{ + EFI_STATUS Status; + UINT32 Length; + UINT8 *CurrentBuffer; + UINT32 ByteCounter; + UINT32 CurrentAddress; + UINT32 MaximumTransferBytes; + UINT32 TransactionBufferLength; + + Length =3D 0; + MaximumTransferBytes =3D Instance->SpiIo->MaximumTransferBytes; + CurrentBuffer =3D (UINT8 *)DestBuffer; + for (ByteCounter =3D 0; ByteCounter < LengthInBytes; ByteCounter +=3D Le= ngth) { + CurrentAddress =3D TablePointer + ByteCounter; + Length =3D LengthInBytes - ByteCounter; + + // Length must be MaximumTransferBytes or less + if (Length > MaximumTransferBytes) { + Length =3D MaximumTransferBytes; + } + + // Check not WIP + Status =3D WaitNotWip (Instance); + + // Read Data + if (!EFI_ERROR (Status)) { + TransactionBufferLength =3D FillWriteBuffer ( + Instance, + SPI_FLASH_RDSFDP, + SPI_FLASH_RDSFDP_DUMMY, + SPI_FLASH_RDSFDP_ADDR_BYTES, + TRUE, + CurrentAddress, + 0, + NULL + ); + Status =3D Instance->SpiIo->Transaction ( + Instance->SpiIo, + SPI_TRANSACTION_WRITE_THEN_READ, + FALSE, + 0, + 1, + 8, + TransactionBufferLength, + Instance->SpiTransactionWriteBuffer, + Length, + CurrentBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to read SFDP parameter.\n", __func= __)); + ASSERT_EFI_ERROR (Status); + } + + CurrentBuffer +=3D Length; + } else { + break; + } + } + + return Status; +} + +/** + Read SFDP Sector Map Parameter into buffer + + This routine reads the JEDEC SPI Flash Discoverable Parameters from the = SPI + chip. + + @param[in] Instance Spi Nor Flash Instance data with pointer = to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO= _PROTOCOL + + @retval EFI_SUCCESS The SPI part size is filled. + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + +**/ +EFI_STATUS +ReadSfdpSectorMapParameterTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + SFDP_PARAMETER_HEADER SfdpParamHeader; + + Status =3D ReadSfdpParameterHeader ( + Instance, + &SfdpParamHeader, + SFDP_SECTOR_MAP_PARAMETER_ID_MSB, + SFDP_SECTOR_MAP_PARAMETER_ID_LSB + ); + if (!EFI_ERROR (Status)) { + // Read Sector Map Parameters. Already know it is MajorRev =3D SFDP_S= UPPORTED_MAJOR_REVISION + Instance->SfdpSectorMapByteCount =3D SfdpParamHeader.Length * sizeof (= UINT32); + Instance->SfdpFlashSectorMap =3D AllocateZeroPool (Instance->SfdpS= ectorMapByteCount); + if (Instance->SfdpFlashSectorMap !=3D NULL) { + // Read from SFDP Parameter Table Pointer (PTP). + Status =3D SpiReadSfdpPtp ( + Instance, + SfdpParamHeader.TablePointer, + (VOID *)Instance->SfdpFlashSectorMap, + Instance->SfdpSectorMapByteCount + ); + if (!EFI_ERROR (Status)) { + Status =3D BuildSectorMapCommandAndMap (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to build sector map command and = descriptor.\n", __func__)); + ASSERT (FALSE); + Status =3D GetCurrentSectorMapConfiguration (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to get current sector map conf= iguration.\n", __func__)); + ASSERT (FALSE); + } + } + } else { + FreePool (Instance->SfdpFlashSectorMap); + Instance->SfdpFlashSectorMap =3D NULL; + DEBUG ((DEBUG_ERROR, "%a: Fails to read SFDP Sector Map Parameter.= \n", __func__)); + ASSERT (FALSE); + } + } else { + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to allocate memory for reading SFD= P Sector Map Parameter.\n", __func__)); + ASSERT (FALSE); + } + } + } + + return Status; +} + +/** + Read SFDP Basic Parameters into buffer + + This routine reads the JEDEC SPI Flash Discoverable Parameters from the = SPI + chip. + + @param[in] Instance Spi Nor Flash Instance data with pointer to + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL + + @retval EFI_SUCCESS The SPI part size is filled. + @retval EFI_DEVICE_ERROR Invalid data received from SPI flash part. + @retval EFI_NOT_FOUND Parameter header is not found. + +**/ +EFI_STATUS +ReadSfdpBasicParameterTable ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + SFDP_PARAMETER_HEADER SfdpBasicFlashParamHeader; + + Status =3D ReadSfdpParameterHeader ( + Instance, + &SfdpBasicFlashParamHeader, + SFDP_BASIC_PARAMETER_ID_MSB, + SFDP_BASIC_PARAMETER_ID_LSB + ); + if (!EFI_ERROR (Status)) { + // Read Basic Flash Parameters. Already know it is MajorRev =3D SFDP_= SUPPORTED_MAJOR_REVISION + Instance->SfdpBasicFlashByteCount =3D SfdpBasicFlashParamHeader.Length= * sizeof (UINT32); + Instance->SfdpBasicFlash =3D AllocateZeroPool (Instance->Sfdp= BasicFlashByteCount); + if (Instance->SfdpBasicFlash !=3D NULL) { + // Read from SFDP Parameter Table Pointer (PTP). + Status =3D SpiReadSfdpPtp ( + Instance, + SfdpBasicFlashParamHeader.TablePointer, + (VOID *)Instance->SfdpBasicFlash, + Instance->SfdpBasicFlashByteCount + ); + if (!EFI_ERROR (Status)) { + GetWriteEnableCommand (Instance); + // + // Build the Fast Read capability table according to + // the Basic Flash Parameter Table. + // + BuildUpFastReadTable (Instance); + BuildUpEraseTypeTable (Instance); // Build up erase type and size. + + // Set current address bytes to 3-Bytes. + Instance->CurrentAddressBytes =3D 3; + } else { + FreePool (Instance->SfdpBasicFlash); + Instance->SfdpBasicFlash =3D NULL; + DEBUG ((DEBUG_ERROR, "%a: Fails to read SFDP Basic Parameter.\n", = __func__)); + ASSERT (FALSE); + } + } else { + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to allocate memory for reading SFD= P Basic Parameter.\n", __func__)); + ASSERT (FALSE); + } + } + } + + return Status; +} + +/** + Initial SPI_NOR_FLASH_INSTANCE structure. + + @param[in] Instance Pointer to SPI_NOR_FLASH_INSTANCE. + EFI_SPI_NOR_FLASH_PROTOCOL and EFI_= SPI_IO_PROTOCOL + + @retval EFI_SUCCESS SPI_NOR_FLASH_INSTANCE is initializ= ed according to + SPI NOR Flash SFDP specification. + @retval EFI_INVALID_PARAMETER Instance =3D NULL or + Instance->SpiIo =3D=3D NULL or + Instance->SpiIo->SpiPeripheral =3D= =3D NULL or + Instance->SpiIo->SpiPeripheral->Spi= Bus =3D=3D NULL or + Instance->SpiIo->SpiPeripheral->Spi= Bus->ControllerPath. + @retval Otherwise Failed to initial SPI_NOR_FLASH_INS= TANCE structure. + +**/ +EFI_STATUS +InitialSpiNorFlashSfdpInstance ( + IN SPI_NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + EFI_SPI_NOR_FLASH_PROTOCOL *Protocol; + + if (Instance =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Instance is NULL.\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + if ((Instance->SpiIo =3D=3D NULL) || + (Instance->SpiIo->SpiPeripheral =3D=3D NULL) || + (Instance->SpiIo->SpiPeripheral->SpiBus =3D=3D NULL) + ) + { + DEBUG ((DEBUG_ERROR, "%a: One of SpiIo, SpiPeripheral and SpiBus is NU= LL.\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + Instance->Signature =3D SPI_NOR_FLASH_SIGNATURE; + + // Allocate write buffer for SPI IO transactions with extra room for Opc= ode + // and Address with 10 bytes extra room. + Instance->SpiTransactionWriteBuffer =3D + AllocatePool (Instance->SpiIo->MaximumTransferBytes + 10); + + Protocol =3D &Instance->Protocol; + Protocol->SpiPeripheral =3D Instance->SpiIo->SpiPeripheral; + Protocol->GetFlashid =3D GetFlashId; + Protocol->ReadData =3D ReadData; // Fast Read transfer + Protocol->LfReadData =3D LfReadData; // Normal Read transfer + Protocol->ReadStatus =3D ReadStatus; + Protocol->WriteStatus =3D WriteStatus; + Protocol->WriteData =3D WriteData; + Protocol->Erase =3D Erase; + Status =3D Protocol->GetFlashid (Protocol, (UINT8 *)&Pr= otocol->Deviceid); + ASSERT_EFI_ERROR (Status); + DEBUG (( + DEBUG_VERBOSE, + "%a: Flash ID: Manufacturer=3D0x%02X, Device=3D0x%02X%02X\n", + __func__, + Protocol->Deviceid[0], + Protocol->Deviceid[1], + Protocol->Deviceid[2] + ) + ); + + Status =3D ReadSfdp (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to Read SFDP\n", __func__)); + ASSERT (FALSE); + } + + // Get flash deivce size from SFDP. + Protocol->FlashSize =3D SfdpGetFlashSize (Instance); + DEBUG ((DEBUG_VERBOSE, "%a: Flash Size=3D0x%X\n", __func__, Protocol->Fl= ashSize)); + if (Protocol->FlashSize =3D=3D 0) { + ASSERT_EFI_ERROR (Status); + } + + // Set flash erase block size. + Status =3D SetSectorEraseBlockSize (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fails to get the smallest erase block size.\= n", __func__)); + ASSERT (FALSE); + } + + return Status; +} diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Dxe.c b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe.c new file mode 100644 index 00000000000..88d5c2ac96a --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe.c @@ -0,0 +1,261 @@ +/** @file + SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) + DXE driver. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - JEDEC Standard, JESD216F.02 + https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 + + @par Glossary: + - SFDP - Serial Flash Discoverable Parameters + - PTP - Parameter Table Pointer +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "SpiNorFlash.h" +#include "SpiNorFlashJedecSfdpInternal.h" + +/** + Function to create SPI_NOR_FLASH_INSTANCE for this SPI part. + + @param[in] SpiIoHandle The handle with SPI I/O protocol installed. + + @retval EFI_SUCCESS Succeed. + @retval EFI_OUT_OF_RESOURCES Not enough resource to create SPI_NOR_FLAS= H_INSTANCE. + @retval otherwise Fail to create SPI NOR Flash SFDP Instance +**/ +EFI_STATUS +CreateSpiNorFlashSfdpInstance ( + IN EFI_HANDLE SpiIoHandle + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + + // Allocate SPI_NOR_FLASH_INSTANCE Instance. + Instance =3D AllocateZeroPool (sizeof (SPI_NOR_FLASH_INSTANCE)); + ASSERT (Instance !=3D NULL); + if (Instance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Locate the SPI IO Protocol + Status =3D gBS->HandleProtocol ( + SpiIoHandle, + &gEdk2JedecSfdpSpiDxeDriverGuid, + (VOID **)&Instance->SpiIo + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to locate SPI I/O protocol\n", __func__= )); + FreePool (Instance); + } else { + Status =3D InitialSpiNorFlashSfdpInstance (Instance); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to initial SPI_NOR_FLASH_INSTANCE.\n"= , __func__)); + FreePool (Instance); + } else { + // Install SPI NOR Flash Protocol. + Status =3D gBS->InstallProtocolInterface ( + &Instance->Handle, + &gEfiSpiNorFlashProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->Protocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to Install gEfiSpiNorFlashProtocolG= uid protocol.\n", __func__)); + FreePool (Instance); + } + } + } + + return Status; +} + +/** + Callback function executed when the EFI_SPI_IO_PROTOCOL + protocol interface is installed. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to SPI I/O protocol GUID. + +**/ +VOID +EFIAPI +SpiIoProtocolInstalledCallback ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_STATUS Status; + UINTN InstanceBufferSize; + EFI_HANDLE InstanceBuffer; + + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__)); + InstanceBufferSize =3D sizeof (EFI_HANDLE); + Status =3D gBS->LocateHandle ( + ByRegisterNotify, + (EFI_GUID *)Context, + NULL, + &InstanceBufferSize, + &InstanceBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Can't locate SPI I/O protocol.\n", __func__)); + DEBUG ((DEBUG_INFO, "%a: Exit.\n", __func__)); + return; + } + + CreateSpiNorFlashSfdpInstance (InstanceBuffer); + DEBUG ((DEBUG_INFO, "%a: Exit.\n", __func__)); + return; +} + +/** + Register for the later installed SPI I/O protocol notification. + + @retval EFI_SUCCESS Succeed. + @retval otherwise Fail to register SPI I/O protocol installed + notification. +**/ +EFI_STATUS +RegisterSpioProtocolNotification ( + VOID + ) +{ + EFI_EVENT Event; + EFI_STATUS Status; + VOID *Registration; + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + SpiIoProtocolInstalledCallback, + NULL, + &Event + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the SPI I/O Protoco= l installation.", __func__)); + return Status; + } + + Status =3D gBS->RegisterProtocolNotify ( + &gEdk2JedecSfdpSpiDxeDriverGuid, + Event, + &Registration + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the SPI I/O Proto= col installation.", __func__)); + } else { + DEBUG ((DEBUG_INFO, "%a: Notification for SPI I/O Protocol installatio= n was registered.", __func__)); + } + + return Status; +} + +/** + Entry point of the Macronix SPI NOR Flash driver. + + @param ImageHandle Image handle of this driver. + @param SystemTable Pointer to standard EFI system table. + + @retval EFI_SUCCESS Succeed. + @retval EFI_NOT_FOUND No gEdk2JedecSfdpSpiSmmDriverGuid installe= d on + system yet. + @retval EFI_OUT_OF_RESOURCES Not enough resource for SPI NOR Flash JEDE= C SFDP + initialization. + @retval Otherwise Other errors. +**/ +EFI_STATUS +EFIAPI +SpiNorFlashJedecSfdpDxeEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE *InstanceBuffer; + UINTN InstanceIndex; + UINTN InstanceBufferSize; + + DEBUG ((DEBUG_INFO, "%a - ENTRY\n", __func__)); + + // + // Register notification for the later SPI I/O protocol installation. + // + RegisterSpioProtocolNotification (); + DEBUG ((DEBUG_INFO, "Check if there were already some gEdk2JedecSfdpSpiD= xeDriverGuid handles installed.\n")); + + // + // Check if there were already some gEdk2JedecSfdpSpiDxeDriverGuid + // handles installed. + // + // Locate the SPI I/O Protocol for the SPI flash part + // that supports JEDEC SFDP specification. + // + InstanceBufferSize =3D 0; + InstanceBuffer =3D NULL; + Status =3D gBS->LocateHandle ( + ByProtocol, + &gEdk2JedecSfdpSpiDxeDriverGuid, + NULL, + &InstanceBufferSize, + InstanceBuffer + ); + if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "No gEdk2JedecSfdpSpiSmmDriverGuid handles found at the moment, wait= for the notification of SPI I/O protocol installation.\n" + )); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return EFI_SUCCESS; + } else if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + InstanceBuffer =3D (EFI_HANDLE *)AllocateZeroPool (InstanceBufferSize); + ASSERT (InstanceBuffer !=3D NULL); + if (InstanceBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Not enough resource for gEdk2JedecSfdpSpiDxeDr= iverGuid handles.\n")); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return EFI_OUT_OF_RESOURCES; + } + } else if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Error to locate gEdk2JedecSfdpSpiDxeDriverGuid -= Status =3D %r.\n", Status)); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; + } + + Status =3D gBS->LocateHandle ( + ByProtocol, + &gEdk2JedecSfdpSpiDxeDriverGuid, + NULL, + &InstanceBufferSize, + InstanceBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to locate all gEdk2JedecSfdpSpiDxeDriverGui= d handles.\n")); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; + } + + DEBUG ((DEBUG_INFO, "%d of gEdk2JedecSfdpSpiDxeDriverGuid are found.\n",= InstanceBufferSize / sizeof (EFI_HANDLE))); + for (InstanceIndex =3D 0; InstanceIndex < InstanceBufferSize / sizeof (E= FI_HANDLE); InstanceIndex++) { + Status =3D CreateSpiNorFlashSfdpInstance (*(InstanceBuffer + InstanceI= ndex)); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to create SPI NOR Flash SFDP instance #%d= .\n", InstanceIndex)); + } + } + + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; +} diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Smm.c b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm.c new file mode 100644 index 00000000000..18b69dcfb16 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm.c @@ -0,0 +1,234 @@ +/** @file + SPI NOR Flash JEDEC Serial Flash Discoverable Parameters (SFDP) + SMM driver. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + - JEDEC Standard, JESD216F.02 + https://www.jedec.org/document_search?search_api_views_fulltext=3DJE= SD216 + + @par Glossary: + - SFDP - Serial Flash Discoverable Parameters + - PTP - Parameter Table Pointer +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "SpiNorFlash.h" +#include "SpiNorFlashJedecSfdpInternal.h" + +/** + Function to create SPI_NOR_FLASH_INSTANCE for this SPI part. + + @param[in] SpiIoHandle The handle with SPI I/O protocol installed. + + @retval EFI_SUCCESS Succeed. + @retval EFI_OUT_OF_RESOURCES Not enough resource to create SPI_NOR_FLAS= H_INSTANCE. + @retval otherwise Fail to create SPI NOR Flash SFDP Instance +**/ +EFI_STATUS +CreateSpiNorFlashSfdpInstance ( + IN EFI_HANDLE SpiIoHandle + ) +{ + EFI_STATUS Status; + SPI_NOR_FLASH_INSTANCE *Instance; + + // Allocate SPI_NOR_FLASH_INSTANCE Instance. + Instance =3D AllocateZeroPool (sizeof (SPI_NOR_FLASH_INSTANCE)); + ASSERT (Instance !=3D NULL); + if (Instance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Locate the SPI IO Protocol. + Status =3D gSmst->SmmHandleProtocol ( + SpiIoHandle, + &gEdk2JedecSfdpSpiSmmDriverGuid, + (VOID **)&Instance->SpiIo + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to locate SPI I/O protocol.\n", __func_= _)); + FreePool (Instance); + } else { + Status =3D InitialSpiNorFlashSfdpInstance (Instance); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to initial SPI_NOR_FLASH_INSTANCE.\n"= , __func__)); + FreePool (Instance); + } else { + // Install SPI NOR Flash Protocol. + Status =3D gSmst->SmmInstallProtocolInterface ( + &Instance->Handle, + &gEfiSpiSmmNorFlashProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->Protocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to Install gEfiSpiSmmNorFlashProtoc= olGuid protocol.\n", __func__)); + FreePool (Instance); + } + } + } + + return Status; +} + +/** + Callback function executed when the EFI_SPI_IO_PROTOCOL + protocol interface is installed. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +SpiIoProtocolInstalledCallback ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__)); + Status =3D CreateSpiNorFlashSfdpInstance (Handle); + return Status; +} + +/** + Register notification for the later installed SPI I/O protocol. + + @retval EFI_SUCCESS Succeed. + @retval otherwise Fail to register the notification of + SPI I/O protocol installation. + +**/ +EFI_STATUS +RegisterSpioProtocolNotification ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Registration; + + Status =3D gSmst->SmmRegisterProtocolNotify ( + &gEdk2JedecSfdpSpiSmmDriverGuid, + SpiIoProtocolInstalledCallback, + &Registration + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the SPI I/O Proto= col installation.", __func__)); + } else { + DEBUG ((DEBUG_INFO, "%a: Notification for SPI I/O Protocol installatio= n was registered.", __func__)); + } + + return Status; +} + +/** + Entry point of the SPI NOR Flash SFDP SMM driver. + + @param ImageHandle Image handle of this driver. + @param SystemTable Pointer to standard EFI system table. + + @retval EFI_SUCCESS Succeed. + @retval EFI_NOT_FOUND No gEdk2JedecSfdpSpiSmmDriverGuid installe= d on + system yet. + @retval EFI_OUT_OF_RESOURCES Not enough resource for SPI NOR Flash JEDE= C SFDP + initialization. + @retval Otherwise Other errors. +**/ +EFI_STATUS +EFIAPI +SpiNorFlashJedecSfdpSmmEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE *InstanceBuffer; + UINTN InstanceIndex; + UINTN InstanceBufferSize; + + DEBUG ((DEBUG_INFO, "%a - ENTRY.\n", __func__)); + + // + // Register notification for the later SPI I/O protocol installation. + // + RegisterSpioProtocolNotification (); + DEBUG ((DEBUG_INFO, "Check if there were already some gEdk2JedecSfdpSpiS= mmDriverGuid handles installed.\n")); + // + // Check if there were already some gEdk2JedecSfdpSpiSmmDriverGuid + // handles installed. + // + // Locate the SPI I/O Protocol for the SPI flash part + // that supports JEDEC SFDP specification. + // + InstanceBufferSize =3D 0; + InstanceBuffer =3D NULL; + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEdk2JedecSfdpSpiSmmDriverGuid, + NULL, + &InstanceBufferSize, + InstanceBuffer + ); + if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG (( + DEBUG_INFO, + "No gEdk2JedecSfdpSpiSmmDriverGuid handles found at the moment, wait= for the notification of SPI I/O protocol installation.\n" + )); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return EFI_SUCCESS; + } else if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + InstanceBuffer =3D (EFI_HANDLE *)AllocateZeroPool (InstanceBufferSize); + ASSERT (InstanceBuffer !=3D NULL); + if (InstanceBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Not enough resource for gEdk2JedecSfdpSpiSmmDr= iverGuid handles.\n")); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return EFI_OUT_OF_RESOURCES; + } + } else if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Error to locate gEdk2JedecSfdpSpiSmmDriverGuid -= Status =3D %r.\n", Status)); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; + } + + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gEdk2JedecSfdpSpiSmmDriverGuid, + NULL, + &InstanceBufferSize, + InstanceBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to locate all gEdk2JedecSfdpSpiSmmDriverGui= d handles.\n")); + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; + } + + DEBUG ((DEBUG_INFO, "%d of gEdk2JedecSfdpSpiSmmDriverGuid handles are fo= und.\n", InstanceBufferSize / sizeof (EFI_HANDLE))); + for (InstanceIndex =3D 0; InstanceIndex < InstanceBufferSize / sizeof (E= FI_HANDLE); InstanceIndex++) { + Status =3D CreateSpiNorFlashSfdpInstance (*(InstanceBuffer + InstanceI= ndex)); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to create SPI NOR Flash SFDP instance #%d= .\n", InstanceIndex)); + } + } + + DEBUG ((DEBUG_INFO, "%a: EXIT - Status=3D%r\n", __func__, Status)); + return Status; +} diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Dxe.uni b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe= .uni new file mode 100644 index 00000000000..4e091f6850d --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe.uni @@ -0,0 +1,13 @@ +// /** @file +// SPI NOR Flash SFDP Localized Strings and Content. +// +// Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "EDK2 SPI NOR FLAS= H SFDP DXE driver" + +#string STR_MODULE_DESCRIPTION #language en-US "This driver provi= des SPI NOR FLASH Serial Flash Discoverable Parameter (SFDP) compatible fla= sh device capability discovery." + diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Extra.uni b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpE= xtra.uni new file mode 100644 index 00000000000..0efea67b9e4 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpExtra.u= ni @@ -0,0 +1,11 @@ +// /** @file +// SPI NOR Flash SFDP Localized Strings and Content. +// +// Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US "SPI NOR Flash driver for JEDEC Serial Flash Discoverabl= e Parameters (SFDP) compliant SPI Flash Memory" diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdp= Smm.uni b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm= .uni new file mode 100644 index 00000000000..b487ec71a12 --- /dev/null +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm.uni @@ -0,0 +1,13 @@ +// /** @file +// SPI NOR Flash SFDP Localized Strings and Content. +// +// Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "EDK2 SPI NOR FLAS= H SFDP SMM driver" + +#string STR_MODULE_DESCRIPTION #language en-US "This driver provi= des SPI NOR FLASH Serial Flash Discoverable Parameter (SFDP) compatible fla= sh device capability discovery." + --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107724): https://edk2.groups.io/g/devel/message/107724 Mute This Topic: https://groups.io/mt/100713990/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107723+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901425993876.0158756528396; Sat, 12 Aug 2023 21:37:05 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=1DS3bdRov2eEF/R4mJgtC4Z7T5OBBO6J+A/LMArcr7A=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901425; v=1; b=MKL5Esacy3E623cOswjgN+rkUTQG3lDQE5VIIceTG8NVT+Oh5XqFGMkNxx2dZY7lKBah0Z58 sWDGcktF5MRFfHNyNwq/+xA2nSJDuGt+BtAC4xFpD444aGfmt0SW7cD8KM4gdtC8Vq/Ctx9kWll CHKb/PzXX9+hQUInzTtZBOh8= X-Received: by 127.0.0.2 with SMTP id 1sblYY1788612xHolH6Rbuwz; Sat, 12 Aug 2023 21:37:05 -0700 X-Received: from NAM04-MW2-obe.outbound.protection.outlook.com (NAM04-MW2-obe.outbound.protection.outlook.com [40.107.101.81]) by mx.groups.io with SMTP id smtpd.web10.80505.1691901425065778632 for ; Sat, 12 Aug 2023 21:37:05 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M3z3hx1czB83FeGyVqF+enoYDE2/1uF9JoaW1UcaDTTUhaUWvyGtxVmxlYoRXT9GhQGXg2DDuX8EC4C4g/EgPzwhpduiDAYxCzKwMgI/KL4JUFdDAnFDY4BQT2XSaQnFWDeIEZAn30iWw/hsAbx8Tp3hzUp+FH99EwfLtd/88CUNsafrBiIwNbnxxkdPxRGwXwOHqWO3t0u0padieycZej6A0lyFnKoMTHBzohB3+0JDDY8oUbMivHoSmTxQM1G1dr8WhZjto5lgdUpFI11B8cQPm5oQUYkiCiU+wF0dd8NW7zb+zHFS0SmqPyYsGmwF1eeoNxTPrqDYQJtCyjgHcA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=LMtHctNk/nWrzzcZFYMi4CLFhCD6gYPl5TvTpwj04/Q=; b=TrYZniAE/Gk6+Ie1SdyZJIG8j4GRV3woc0Bt29B9idd/e3x1drDa82kWouCrQS0nUEBPiOcy4eeU4vVhs3LG9MTgSGhEgaDB80nv+nsi7vjtC7ZS4XmG+ZU5F8iCX0rxbLZPYFYwJIg41lB60UM9wgwt4ETdz4LJQI4gZ9HqWURWE3Md5qQwTJ/okvaKRgVVMu82+6gEwza6StLswPYd3mVP2GruP0tD99ymQzK7Q7iCD6IKEHJYavDQKwmtZjkvoS3RaE73Tpx3EilX/Ipq5YuA40rLysm5G0StOquushiuk6tzYCvPLvvZYWYC0WdK1unN0FM7Ky/hl2Z9xmR8cg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CYZPR02CA0023.namprd02.prod.outlook.com (2603:10b6:930:a1::21) by SA3PR12MB9092.namprd12.prod.outlook.com (2603:10b6:806:37f::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.23; Sun, 13 Aug 2023 04:37:01 +0000 X-Received: from CY4PEPF0000EDD1.namprd03.prod.outlook.com (2603:10b6:930:a1:cafe::41) by CYZPR02CA0023.outlook.office365.com (2603:10b6:930:a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:37:01 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107723+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD1.mail.protection.outlook.com (10.167.241.205) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:37:01 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:36:59 -0500 From: "Chang, Abner via groups.io" To: CC: Jian J Wang , Liming Gao , Abdul Lateef Attar Subject: [edk2-devel] [PATCH V3 5/6] MdeModulePkg: Add SPI NOR FLash SFDP drivers to DSC Date: Sun, 13 Aug 2023 12:36:29 +0800 Message-ID: <20230813043630.1123-6-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD1:EE_|SA3PR12MB9092:EE_ X-MS-Office365-Filtering-Correlation-Id: fee75f5f-4ab6-470f-19b4-08db9bb6eff5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: cvtGpoD1YYKSaGNT97a/POtfBGf+jOGHzs0A51Ru0uOyVvrubUnydlV0MMOIOYQmQnbVv+fqY0dOyxFwxuaENIclg0mQNSC9rDDksA2J5vpRRINxDLtvikPobo+EnvaXJ1RDBPWw+RHgTl37VR/M8R5h1TkMRYCdxR8Qd2/A4ItitCKR3uI86zxPYpWMRFAvY3/Qmk2+bUrSPI2RoBBHEwZT2yxklr7dU8Z+7kphC3pAge//VeUy+9r8jW+oyZSZOJRsny+eND61SNZZkdKqZtwOSWdopG6E6lzaZh1rAmhc7y21QXLHvUq5MEll3BaBoVrq+P+t6ZFku9kjeShk6C7HdtfhsCKp4EnCayL4NBV5+Tg8CS6s3TbGw2jukfLF/Ex6XvNZpz2VBQqGUhJDC4mG08hUcxRGME5CE5zePdoSWkOd2CxH9gkhg5hZ4dh3g4PRtMFNXsPzDEiCWy1iaF9VpL10/Ezyin8aQwj7N310B7OLke5zAB3n3Zv+rTZqD/d7sVLlO4zCF9P8+GxCVph1yxu7r3ajCAxPbQNhjwvSE+Izpe+P5NtukBKLb/6Q2QG68KOppWaxB+FT4rjEz97e4Kt0FgtqeQ8Rf+dH1mh4bbBVpeTczjtrvP2bvnR+bLOgYxN+pTx6uumzA3+lWScqQEhhQ27hBfBRnWloZHMRn93KGnLKHTQ5dmSGHUvv5023qimt3/c2Or4QCBCcfwuGx5eip+hzP0NQMXh75vNE+HL0sFZE/LcRmlW9AOklvc5ynZQ9JQX5v0t95jVfBA== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:37:01.4290 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fee75f5f-4ab6-470f-19b4-08db9bb6eff5 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR12MB9092 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: Oyi94e73iqILyTp86RZOwhSSx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901427206100001 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4473 SPI NOR Flash JEDEC Serial Flash Discoverable Driver implementation. Signed-off-by: Abner Chang Cc: Jian J Wang Cc: Liming Gao Cc: Abdul Lateef Attar --- MdeModulePkg/MdeModulePkg.dsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index db3b5af5379..137e88aa7ed 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -285,6 +285,8 @@ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDevic= eDxe.inf + MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpDxe.inf + MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpSmm.inf =20 MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf MdeModulePkg/Core/Pei/PeiMain.inf --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107723): https://edk2.groups.io/g/devel/message/107723 Mute This Topic: https://groups.io/mt/100713988/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 08:57:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107725+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1691901430630670.2977800652328; Sat, 12 Aug 2023 21:37:10 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=ZK57HHHy7zzsn09pY9GHiQHbL5dnyEQSFQG/74nFROY=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1691901430; v=1; b=B3Q+3QW/9HEEWVkt02NUTkuwKKSRPR7GzzvAGXEsl/BIArSIRt4L07Vhu6535E8Ljy0MAoZA XGlw1HEQ8k1bDm3v4724cH6q4F6ptW6Vaz5QullemGzqVHLr7JH00vMgtR76FVBY5wYldvU4vSh LVgn7JLvTjoQvDcVZY0GBw8w= X-Received: by 127.0.0.2 with SMTP id pUOiYY1788612xsmrNme7WkT; Sat, 12 Aug 2023 21:37:10 -0700 X-Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.61]) by mx.groups.io with SMTP id smtpd.web10.80507.1691901429643418843 for ; Sat, 12 Aug 2023 21:37:09 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IcelI00P1S5ZNQiQ3M7+3XMrNehyDzgv4Rc8LZiPKR0bm437PcPmd69r9ZigIhY7jY6kqNh6vbUF/SUBRoyNF97BdnMAO2cI4TNoOT5KzId4BOceghN/sVFitktyZIqBW1lsMPZHXB8cY/xGnlOkw3RkKCkpk4/ZMTqSGMbvFWH5Im5RvZF3yRTrf6NmpW5lSlCDzObV7oTt6HU9RXIlKrujRnf1ifBIeb4xWkY+becnd/ik9jrMN+tezNm5wEbcDPq71raQMRVsVHDCGlABOQMNr6SmV9EACO1vHcwd5vzPwf8SLYBf++C3miYXMdbcAETEBsF+dEvkPEiTNVbAfQ== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=czTMA5bm0zj5mwNB1cVF1N36LhHuUGwCysdyfhb+4HY=; b=fd3n8rRlWWTKywbwAWa/Q2A4fGdWLVB+LHldeNnApF2/Ac6jnhqcebHHEcLpKroqxgcWVL4oNWJWY4nsb2cqOQ1hLLaWeQ7uXYbD38p00kgAlbPgg0yJsewChOdXeC2QiWIJL2RdkiCv0TMDE5S6faPLr9/5qwPIIuVufU4Kdrtt8TfXnO++rGSdsUZfFhIOBlcJBxUTTYsbkZLgxkGHFiBPl9i+gESB3xvMzGHmUNTZluAPX/XUyYQnavkhf44uTOTChNnbMZqT4+tpFITM8qnCgGhDGLSFdlZ/oTbuX7rbR/GDNpavBH4YfII9KPim+zNl5zR6AtNOL9atIeVYVA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none X-Received: from CH2PR19CA0001.namprd19.prod.outlook.com (2603:10b6:610:4d::11) by MW6PR12MB8757.namprd12.prod.outlook.com (2603:10b6:303:239::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.24; Sun, 13 Aug 2023 04:37:05 +0000 X-Received: from CY4PEPF0000EDD6.namprd03.prod.outlook.com (2603:10b6:610:4d:cafe::b9) by CH2PR19CA0001.outlook.office365.com (2603:10b6:610:4d::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend Transport; Sun, 13 Aug 2023 04:37:05 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+107725+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000EDD6.mail.protection.outlook.com (10.167.241.210) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6699.12 via Frontend Transport; Sun, 13 Aug 2023 04:37:04 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Sat, 12 Aug 2023 23:37:01 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Andrew Fish , Leif Lindholm , "Abdul Lateef Attar" , Brit Chesley , Jian J Wang , Liming Gao , Hao A Wu , Ray Ni , Zhiguang Liu Subject: [edk2-devel] [PATCH V3 6/6] Maintainers.txt: Update maintainer for SPI modules Date: Sun, 13 Aug 2023 12:36:30 +0800 Message-ID: <20230813043630.1123-7-abner.chang@amd.com> In-Reply-To: <20230813043630.1123-1-abner.chang@amd.com> References: <20230813043630.1123-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000EDD6:EE_|MW6PR12MB8757:EE_ X-MS-Office365-Filtering-Correlation-Id: 779c4c8a-f2b0-4ffe-34f3-08db9bb6f204 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 2P4yET32CXVNgJkBqZu3w8X0QfEZH17YNhfuXx8LYcopOQwjmOJq0CqlayGu5/YOTAKAW+VA887g4pbf9uZ2nNt57kEF/4f5rQq1fxizatcuYe8pigY2fFgH+/nYDUpWNBxhVFMRMaZ+iotBxjg7mFm75Ij+22xKsfosaBcLu0eMTJn+h9WbJzpdjr5cmGOkrFhbk7wr0cdSgt2+EFeN/iittQqcHcAr2GpF+3yv3Cu8CRT4KyyevJvNppZSb7VJN9e3OuPIExET1pT4ybEyiQ7TRkYAiX09ySNIuaB++8vIYeGxw36lXE3IAMhP9KZ07p7GS5H07eO+T0HBpsKCbd/kdNQU4ngu8KnVnzmk3JZQ4o73zRnqPvALdO/sUw5GiV6ILjIDtPjkUg1cP5HtO0ovqVKg4fmVnM/QgHt1dZGECRwWkbdBhTbhLfjvfmZsIGblYG7hIs77JVJ+W1SdkwYtviz38vlVgetHA90BW4Y2/su+T22n8nfJpYQ1aKP1CW2jqhdA4UF0jyixl7h66QmW9+89LQSWMcUvfRciaBsOOeu3Q3JZjRJOdcW5PlAwwy1G5hQzehYs7wAl3ekaxd/RZw0gHvNCyeeMgfDtpX06HW6bHGvkvReo0B5JBApJSzHH1jQIcunPCG5rTGfoVEVaYHP62JE6Nnu6Vtf4ttEpSHuuHHo6inxojOXszf+K3FuZ6aoJA/r4ykAFat/YhW6a8KHt9Vlq3th8E0oqquYkATCV44ZqZ+gvcEsHS77vkkDdx0sT4rMSOVSPl7EnzQ== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Aug 2023 04:37:04.8678 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 779c4c8a-f2b0-4ffe-34f3-08db9bb6f204 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000EDD6.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW6PR12MB8757 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: ahUbC5Jb6RJCF80FhuJUeovTx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1691901431355100005 Content-Type: text/plain; charset="utf-8" From: Abner Chang Add maintainer entry of MdeModulePkg/Bus/Spi. Cc: Michael D Kinney Cc: Andrew Fish Cc: Leif Lindholm Cc: Abdul Lateef Attar Cc: Brit Chesley Cc: Jian J Wang Cc: Liming Gao Cc: Hao A Wu Cc: Ray Ni Cc: Zhiguang Liu Signed-off-by: Abner Chang --- Maintainers.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Maintainers.txt b/Maintainers.txt index 5a95929a14b..a6a5a9b4e03 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -443,6 +443,11 @@ F: MdeModulePkg/Include/Protocol/UsbEthernetProtocol.h M: Richard Ho [richardho] R: Rebecca Cran [bcran] =20 +MdeModulePkg: SPI Bus modules +F: MdeModulePkg/Bus/Spi +M: Abner Chang [changab] +R: Brit Chesley [BritChesley] + MdePkg F: MdePkg/ W: https://github.com/tianocore/tianocore.github.io/wiki/MdePkg --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107725): https://edk2.groups.io/g/devel/message/107725 Mute This Topic: https://groups.io/mt/100713991/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-