From nobody Sun Feb 8 09:33:03 2026 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+107419+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 1690876665928583.0913306625268; Tue, 1 Aug 2023 00:57:45 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=41gxfjgxVdkqJTBVGbfCAXExW13PNufkVNMc7zaSukg=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876665; v=1; b=JerKlOYaVtU+IC9fl2gxacEE2RSyucqXrwZ9khDcPo4fvVb9RRXbLhyMVo3BwZkAP/R1hIA2 MhCFHl0OfQ8lcsGqan5V4h12YUUMyXzxWHV5tySin0IBRddjqAWf0MIeo2I5WtfT0hBbpKSHaZ5 natdIW1zzjXeFKY5umiFt2s4= X-Received: by 127.0.0.2 with SMTP id DyH3YY1788612xifHQyxFmVj; Tue, 01 Aug 2023 00:57:45 -0700 X-Received: from NAM04-DM6-obe.outbound.protection.outlook.com (NAM04-DM6-obe.outbound.protection.outlook.com [40.107.102.51]) by mx.groups.io with SMTP id smtpd.web10.7841.1690876664980215056 for ; Tue, 01 Aug 2023 00:57:45 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BvDfxM2mU2Xx2GWM5tkBKAxwBUwr96Qf3TmmNp+1raJ5idSo03MIFJqfg/gvNekRUFJsvqUosUa2/LvvoPsOGLi5l4a6ETrXV2dNIO/neQV8+ynUaqVOVOZ8PMPlOtGDt/RQqXodsqX/QWSnpFrhh1KycgJdMyL+E6CfjmrGKWPTtPSu36jtwyq56eJyb8v6wBUVREqDu9lI67qzVdt9Se2ykR54YAmAiAXuvvyS5hKoNcvg6xMzzSbxb+uR7UOEmlGTPw10P+/x4couMOClZ+1US04kVuZ/6I8d20foOZzLktNe1g69AZWJF4YoRtDv/k7Bx/6Ut/sdMOxrboF74w== 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=B9U4njaQK/gAgF/aObIRLfSVyl1hh112otgGnT5Rf6WzMDFiUw5p0N3tjnu3ZCjVOerjpR3fArAwGa8BeqZ9UNylTXxauOrqoYbMnrE9xjjXr2N0dcqcG/L8RA8keDhX+adSOhBIEfZ8BoevHkSKM85bvEcod0pb6KRr8RH7MSXwd09k7Pw8IVdlh4N0ZlZ4LwZDz81T2d1mZXs29HZs+RNnolrOqL/5DeENULvzTK8BQHnqbQ96QMosGENVK/jPAOFEVjeV0wa8bH7JlP/YJKjlgVHR/inPDuc//z/rgc6We8clBM65M85voNEU5WSU1yQZI19hYd8AIUUoZ+WsEQ== 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 CY5PR15CA0123.namprd15.prod.outlook.com (2603:10b6:930:68::14) by DM6PR12MB4976.namprd12.prod.outlook.com (2603:10b6:5:1ba::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44; Tue, 1 Aug 2023 07:57:42 +0000 X-Received: from CY4PEPF0000EE31.namprd05.prod.outlook.com (2603:10b6:930:68:cafe::79) by CY5PR15CA0123.outlook.office365.com (2603:10b6:930:68::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Tue, 1 Aug 2023 07:57:42 +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+107419+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 CY4PEPF0000EE31.mail.protection.outlook.com (10.167.242.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:57:42 +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; Tue, 1 Aug 2023 02:57:39 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V2 1/6] MdePkg/Include: Update definitions of SPI related header files Date: Tue, 1 Aug 2023 15:57:20 +0800 Message-ID: <20230801075725.1102-2-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE31:EE_|DM6PR12MB4976:EE_ X-MS-Office365-Filtering-Correlation-Id: 94bc9f9c-4212-46ab-f0de-08db9264fc17 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: rrRfvGsNIoTDDd6YyaQ40HJyfqQvjEwHzwtuj9zQEbdPS3c5YT/N7pTAQMGO0x8uH187jsq3nuOpPsMMjGXBIW0QFp8PWLLRDo+KIFqaZWW53ciCvp2ZdLpffhbLYdpGVOOOL8/o4+a7r8Guta7kXIjIoK/Ve4833XG1rBYnhyMQxxPHMR7eJ7jxciU8OSmwT5iKKmWWG5+V+hhdLPoljmIbCp4kvlZEPaevxlqw0iERecntPkx1yCii2x1686vpGk2MQzp0ydXLLyRQD64bM8h9L39hq7y27t1ZWtcsIW4eVuNLqJPKoXMu7SAUXlMiOsBUgIh9c1/HypxlA2+xbrPsN2Vt2GoRzqZ7qvC4sPiAQAUPaJXjXW+GSSSi62Y+F0Waq7VHjmnAYXWGf0F22hhSB4mt85CPg6sxg7GuoDatPnSLyDu5ZTL9AMfd0SWJW3fnP7p99ClzZI/U/KP0ARgN5pkwBsPSMb44VwgPC6UkOB5Db6M2S+oQehEml4CTMCVWju98UveJFHqKnpqID1eH4wRdAfBoc855jqcXlez3kEM6kr5o9MLTLneqp+bpa0mwHoxw9pnB1wBfNnuRzwpWX46hBsxcU5M5JYfId/0Dps/RXPt50IRmgXGQm1hTWwti1Bvg4xHh4KeZWJ86qIfL7gdWb5adFE5ZGHNK82EdACQWwqFNVlsbI3bkV9he11D/tNc51zaz3LxT0uXIzCc6uY2syfZefbstkp90FTpwYzH3XqMhRTFGfydpeHgzWs8OlYrw6JPWd0LR5RLJAw== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:57:42.5619 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 94bc9f9c-4212-46ab-f0de-08db9264fc17 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: CY4PEPF0000EE31.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4976 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: NyUjB03xevaJmCHFi5shu8Qnx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876667592100007 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 (#107419): https://edk2.groups.io/g/devel/message/107419 Mute This Topic: https://groups.io/mt/100478918/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 Sun Feb 8 09:33:03 2026 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+107420+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 1690876668968704.2405075633668; Tue, 1 Aug 2023 00:57:48 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=ZDSX19fgzhR7fgdN9PwWek0u1herOuLsYyxO3mPVkQU=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876668; v=1; b=NXR8fIEGpLUwgfsIfh+L4UHbJgvj+3f+e0sJb5pozLKkATCCTh8DVZ2VDcv0tikNNnAd8D7V ofDdGFIcLkW0EGd4QpTuRfKG42QBUi9t/KhrcuaNG63MrxhJ1OREerqSqMPrli+i1S6CBPdbu7c QW9+jCiYXWes9H+XDDFg7s/k= X-Received: by 127.0.0.2 with SMTP id 2oqfYY1788612xqyat5wSu7H; Tue, 01 Aug 2023 00:57:48 -0700 X-Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.107.94.66]) by mx.groups.io with SMTP id smtpd.web11.7801.1690876667840816830 for ; Tue, 01 Aug 2023 00:57:48 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R4lTuAoUVcsdY5xUBf9kqHvUksET9p2IwuNEungCx008Zh+pLr3OTvnNskHWu/Ae8ZaiUu6TnjYyrYs7owprVECim+FTifjOikPzou8nNXAvoFAOY8uL+rpljklu0+P7eggPZ5sKZecsBbIhBfAsB5VWCK5oxk0RhD+VLrtg9muHdRHeCiGP601ggb6EotEXaIxeQYn1U0Pu5j/65lkFFV24IMTRdyaA1gceLif6yqU7OUYnaD3DNfqbNCm/dR3XLhAlqJAHsKKMzpazh6GpSBjcbXSHbk5YfCxauo1AI8KghF73+KHst1ElOJfmrBp5NvMEiYumdpEZmE4PSZdhDg== 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=Qg60Yf4HnRXkJVhFgTyXHRR+pMvRp4jayBZiwpoJ6a9X0hjhSu+CA2SUNvzuOMYEbf1q6haKIsukV3HgwMVvwx3ru3sHHdZ/qbsPVnLQfkypwqWKBQ0pQvdS3WLUZGZQaX4lhjQik0hv9pqzIDCl7pNfZIiWSYTeL3iNGO7psJt3sYX5TfuwWrQP4P9r8KUdeviMEMH8Udqk56yL//iGeaRCqIXze/ahXX95XmQR64l0hGtSi3Pbuhrcdl0Ggm1dAPc9E6T/wJ5YWk5J9k5/6WedxZyo3JkR4tvb+guxYiAowJZBxVFUjpft8u+UHOaBMO/q0JTgbcDmAM5fz9hDXg== 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 CYZPR05CA0023.namprd05.prod.outlook.com (2603:10b6:930:89::9) by PH7PR12MB7890.namprd12.prod.outlook.com (2603:10b6:510:268::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.42; Tue, 1 Aug 2023 07:57:44 +0000 X-Received: from CY4PEPF0000EE30.namprd05.prod.outlook.com (2603:10b6:930:89:cafe::5d) by CYZPR05CA0023.outlook.office365.com (2603:10b6:930:89::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.18 via Frontend Transport; Tue, 1 Aug 2023 07:57:44 +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+107420+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 CY4PEPF0000EE30.mail.protection.outlook.com (10.167.242.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:57:44 +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; Tue, 1 Aug 2023 02:57:41 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V2 2/6] MdePkg/Include: Add SPI NOR Flash JEDEC SFDP header file Date: Tue, 1 Aug 2023 15:57:21 +0800 Message-ID: <20230801075725.1102-3-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE30:EE_|PH7PR12MB7890:EE_ X-MS-Office365-Filtering-Correlation-Id: b6c1cd74-fa4d-42f3-6fe1-08db9264fd07 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 8l/6d0DZZC5DcXsM9iD9OAWVqjQCU/h6tJdMifJwrCDikQEvnBb5mx1U5WmpL8zx1F2O6LCYGS72gYlz6+LJPgTN/KY5Prq6CdPbSMkP3/f9KryB22dgZZjNdYfz5OI/rmV6Jj0JyZIMTwgkFsFi55vqRG9UwGhUL76Jc/wFIrA6i0nAVsUj/Ccxso3QUHjNi2jQHjpk1AK2ROjhDYRu6dFTFVJtFigYxobH8Lf+swJ02HDJ2lDITEcTIqoVrGXLPMl7Rmpu/phw/jqeZQpHdU7ddycQHJ3ugP7BGynxPwrn4ihI+hh+Be1/8WS2bDNMqg/Mx3icboOx93vvlpfCqI71NgfFMXaAdpb+bf2EIohixTRPHSi/Ve2Mz0+URXC2pySulTjipN4IAQToMsuITgCeX7nUa5USvspV9XOMVpWHqKdpSf0QHd6nXW67BQ+/I0SKbm0Ymd61CEuchbximG46UlCDYFRYa9X0ww7ZRIByyjXvyJNTWA47b98O0yZR/7MqKYiECF4L1GcfGIFcsS7lL+Wmr8VIKlLPN4WxiOUrzcxmGiiPCA2foBgYBLyHEmyQPQTB/3iFLjesR91lOUtYqSgmcaIqs2Vd02rIsCK6wVbB+x+/PcjCdJYM10GMo/U2XfZAupLs6fo4wisUOIT6L2y7ZqkZ1OEv8srht06nFGLf1FzZicRDjGN2GYZXtzQ/jL2/hjrzTxt0UzA6Cgo5xjDMZAus8tUegbTeuIy+jlBJo223MmaDWtjivNqlpPO0YBtzYF6pjryvZ14R6A== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:57:44.1471 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b6c1cd74-fa4d-42f3-6fe1-08db9264fd07 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: CY4PEPF0000EE30.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7890 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: 5eZc028TXNRjMQrEQOrn55xgx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876670432100011 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 (#107420): https://edk2.groups.io/g/devel/message/107420 Mute This Topic: https://groups.io/mt/100478920/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 Sun Feb 8 09:33:03 2026 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+107421+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 1690876670771375.37074211769914; Tue, 1 Aug 2023 00:57:50 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=3moQ0hS/KM/l6JpYVBlYitnHgh9ONX1I9uHxdRcDSK0=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876670; v=1; b=NlWbBYX20yJbyqcVJ+HRd0WyAh2oPPg3ZxoI1ksq/8p3Y5zXydvvck4dc3izU+bR8fIdbEZk EZdjXsoaSh2dFn/4qvWmAR7HOY+csAL0+H379yAP+NSHWoTkrDqAFuz5td6fAPDJiTV7fU73B+F D6omKMIf78z6wZTA2dvWGVSk= X-Received: by 127.0.0.2 with SMTP id FMMIYY1788612xUNcHxfrNZU; Tue, 01 Aug 2023 00:57:50 -0700 X-Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com [40.107.220.40]) by mx.groups.io with SMTP id smtpd.web11.7802.1690876669890366971 for ; Tue, 01 Aug 2023 00:57:50 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lwpBrXnm2r6lV6zU45uGDKcOqEBt12AIy+wbSe33dE6b/PyQ1ddaaUQHfrRfMozt3mr8Rzd+YAki2xDHaO4A8EWcI43r+xy9e2ekGZy8Ixp6p1EaPz6LY0g0C+XAwvEYh7rtOHy/NVoIPbjlpwSXptJovwFYaOLY45KHCLQ7dpH6eZh9Jkeqo+IN3bAiHB0Y4nGt2dM4bhAvbb0TOBwelG/7lDbwG1H4GeKW96DbjoP96ZP7G0yrxuvdbXNrDWTaQDTWIUDmWT1j4tXcExwbj4Vyyela+v4eivAWBUtXAg04jkaQkd0Jby6fVEekSbgh7hOKy2en1IY4rTmT7gBXpQ== 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=igr9HCEwz4ACEN8JnZXK2+e5VoW4Mk/VEi4fwhF9ASo=; b=ZeI+ZZtseKNWfoWsNyGM6JX12UEL02GM1nvq8Djp7NI2Z2kqaNZ3+wMJ4h+kVXsHIGWGm0HNnZrhiPJ75x1oGOOa6Ot2FcO82YDqiOJmVz7ZhhsNAayyAo8sBASNXjPgRqdIjN9K3Y5jGCKRy4dPgUOoDaAmbuKV6Ve1N9fpqbRaJLu7K37r6XhMkjz/425yn4OzPmvbY45uLSEqX1equEkPy8Y6r2ZHn0xNOCArLDNiGX1oD2u3a2Fkhv1MOoyzWRC+XgtOKAcZfOp2Z5FzyZjrs51F7aY5kMD1GXsS5iYP4A/UvP4Iyuy80aoSQoajes2+9o/3NEezLdTYfWjlMg== 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 CY5PR19CA0028.namprd19.prod.outlook.com (2603:10b6:930:15::24) by IA1PR12MB6603.namprd12.prod.outlook.com (2603:10b6:208:3a1::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44; Tue, 1 Aug 2023 07:57:46 +0000 X-Received: from CY4PEPF0000EE36.namprd05.prod.outlook.com (2603:10b6:930:15:cafe::db) by CY5PR19CA0028.outlook.office365.com (2603:10b6:930:15::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Tue, 1 Aug 2023 07:57:46 +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+107421+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 CY4PEPF0000EE36.mail.protection.outlook.com (10.167.242.42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:57:46 +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; Tue, 1 Aug 2023 02:57:43 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V2 3/6] MdePkg: Add definitions in DEC for SPI NOR Flash SPDF driver Date: Tue, 1 Aug 2023 15:57:22 +0800 Message-ID: <20230801075725.1102-4-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE36:EE_|IA1PR12MB6603:EE_ X-MS-Office365-Filtering-Correlation-Id: bcd7fcb1-df9d-4c7f-142f-08db9264fe22 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 97iYgY7yXPtQSeiIDsENXnrN3RE8OpYIX6hCu3sBtf5UzgkSuYibhpLwhsxU6t1gtPBK5THbDKkt8Baod7b2DYo9Gn0Jr1zLXpw+R+L2Cuj2Rs/I8Tbj3XL91tH3zu8rjaiOYWD5xXmthv42TVYz/I9ir1fKgLUBUnmiXZTOwA5EjuxANtaKmLmiXx2FwrembzfnrRM88DFaZnhvWVi/Y8IC/yIbZrNs1HZ6e8+5UMBOGWiqrtc79tdTUGjcHQjZCpJOXGSKAEwIpphWH0JC9vOUmmYDVVEpLri4yBs1io42ePh2rjAeL+3HeLeaN1NoVVwbjHXzqS4dj0LFZw/ptGSzEkUafX2jWfx+vj5b9TpU7h28dYVGhSPWQtWB3Aw2U1RnkRvR4o5im9l4SpWCNFSO8LD0ifFLTQHEC8T6TvLaqFj1ctwjrjZTDokp2VVGEIP5hVJ5EIGV+6/nityieZSgEBdOYfa/PIFsIkM4RbgcnLj3/FAkfaoCPzu8mjs9lwC3meWodg0rOh5cbZNHCu6LCTmtW6f++5bAHGC09fWKuFhLw57YzFvcGsXdzJZClijjm0SN+5oMcx4zTu6jFhMpOTq5W1fsrKbHUUyWnkUUwXiMhE232DmGg2250mF0fNTawMAP1lLQCL3kpZXDr9F7MRQm/FG/YKyiFDV58taCROnlrjgAZ2qPM6KGx+lo3SmT6fTEBlb1omZEySeOKn5xTbxgcI/y5DLzi7KhIaWQ3cuaJ+Sknwyxp79F9z/nY1cBot2AUeBHLneKku5V1T5rkyYWx+iGFRVUxhYn6QLJNPRkE939dx0Ozn/Xltb6 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:57:46.0150 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bcd7fcb1-df9d-4c7f-142f-08db9264fe22 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: CY4PEPF0000EE36.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6603 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: hwK9qhtPgYOOGNWdWWHxS8eZx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876671552100013 Content-Type: text/plain; charset="utf-8" From: Abner Chang BZ#: 4473 Signed-off-by: Abner Chang Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Abdul Lateef Attar --- MdePkg/MdePkg.dec | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index b85614992b9..47d8daba826 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -875,6 +875,12 @@ ## Include/Protocol/CcMeasurement.h gEfiCcFinalEventsTableGuid =3D { 0xdd4a4648, 0x2de7, 0x4665, { 0x96,= 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46 }} =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 }} + [Guids.IA32, Guids.X64] ## Include/Guid/Cper.h gEfiIa32X64ErrorTypeCacheCheckGuid =3D { 0xA55701F5, 0xE3EF, 0x43de, { 0= xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }} @@ -2232,6 +2238,19 @@ # @Prompt Speculation Barrier Type. gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType|0x01|UINT8|0x30001018 =20 + ## SPI NOR Flash operation retry counts + # 0x00000000: No retry + # 0xFFFFFFFF: Maximum retry value + # + # @Prompt SPI NOR Flash Operation Retry Value + gEfiMdePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount|0xFFFFFFFF|UI= NT32|0x30001019 + + ## SPI NOR Flash operation delay in microseconds + # Deafult is set to 0x0000000f microseconds + # + # @Prompt SPI NOR Flash Operation Delay in Microseconds + gEfiMdePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds|0x0000= 000F|UINT32|0x3000101A + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy()= , StrnCpy()

--=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 (#107421): https://edk2.groups.io/g/devel/message/107421 Mute This Topic: https://groups.io/mt/100478921/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 Sun Feb 8 09:33:03 2026 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+107423+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 1690876677473251.04363478076255; Tue, 1 Aug 2023 00:57:57 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=Cv87lde44VTHOdy6F2JXuXAhuQDILQzUY0r97CLe7Xs=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876677; v=1; b=Uk9iIiTKyicFCN+rwV8geBqMuSR8OZhgsJmPTP4JOE18LXwo0+y/3LZfVx2H2hRfYEad+Q/p VBN1HJfFeSzW4H62pRiLelAnH0V/CjJJuBYiQ18hr/G6X+nxFNQ6Uclr5V1UUn8BswKyuA9/CHK 9gBDNH9c2DQzquHmzZVcbeDk= X-Received: by 127.0.0.2 with SMTP id gSBTYY1788612xTsLV8TkrhK; Tue, 01 Aug 2023 00:57:57 -0700 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.79]) by mx.groups.io with SMTP id smtpd.web11.7804.1690876676061131158 for ; Tue, 01 Aug 2023 00:57:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bBMi2ehUi2cIknwvoFEGFsEw7cYkMXk4X/lI44gwN5TZ48QnRaU44YCJ3uTHtLjdQwsTY6sUEMMPEav19ePXMLfvbpIggIkE6I4i+NEYQjDTpx6gWo/kmJsAzWWowLUH05FdhFu3RBD+IXC/k5phZjSHElBQiR+wmR0bM1ry0wI4/xm/WLAZSmqbzXTj7/A+TTCPvID54u+1ItXr4xa3PLooniiGfwgVVkeWKaG9mZMWJma8IgMDMU0rtVuZ4EG9jpH59xaRmvPkkhDJLiu35hHwPaBpUCzCuukN+2UGjZDqHWRcVLBFx1kDeCjZYZEc7OChmV7aYQHOhJJ8oAkdpQ== 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=fWYjXnE5i680dUxauptzotxXf0bE31IED+3VKjsgLpY=; b=De28AfZHz4YGNydwszCOxIl3byMbph/BWwlmlUf1cQFn97JZdDWauioZajlDESKfdoSSQNcjNYknUJDjIWcjIdWidmZdZK3ieTnhDkm6LqsR20uxgcJ/HhyjOe6Q7kYc3mDdLZnB86abYsIeX1InGDpuMbN8yb081IzY5EMQlveMYcFgRsMETlM3RYZ8uB0dGGU5iPUfj4khyMiQHrVPePMYqXS2oblRm56dzJ8n39ExJbByLH7R64ZNvpzyMcX+rxuljxGhG47y/WZdrLQ6VnM7i8Xxv1dCT6b0Bf4jsOcn2gzY+6X5/txmqwaD18/MbtRUC7Unv4EuQE/6RIlmdA== 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 CY5PR19CA0020.namprd19.prod.outlook.com (2603:10b6:930:15::19) by CH3PR12MB7738.namprd12.prod.outlook.com (2603:10b6:610:14e::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44; Tue, 1 Aug 2023 07:57:50 +0000 X-Received: from CY4PEPF0000EE36.namprd05.prod.outlook.com (2603:10b6:930:15:cafe::62) by CY5PR19CA0020.outlook.office365.com (2603:10b6:930:15::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Tue, 1 Aug 2023 07:57:50 +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+107423+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 CY4PEPF0000EE36.mail.protection.outlook.com (10.167.242.42) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:57:50 +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; Tue, 1 Aug 2023 02:57:45 -0500 From: "Chang, Abner via groups.io" To: CC: Hao A Wu , Ray Ni , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH V2 4/6] MdeModulePkg/SpiNorFlashJedecSfdp: SPI NOR Flash JEDEC SFDP Date: Tue, 1 Aug 2023 15:57:23 +0800 Message-ID: <20230801075725.1102-5-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE36:EE_|CH3PR12MB7738:EE_ X-MS-Office365-Filtering-Correlation-Id: 3d5bc235-4b67-4cb2-581e-08db926500ce X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: wHhtRpTM2H4Gst0Axc/8irb75Kd9XaXKq/7R+R3bvcULOwsfOknGT5MFwInYKIPTrHR+g7ILFB1PjpVcZ6ouPXeg+OMf5EDdjp/qRMAMpQzYPlemTZLIZFCJio/2r0VuKFUBO4CUr3Ww3dou5KOE/iT+vfEBcgMor6XhUcIK4MEu1MlLwEPlXCJn8q5cv8X7UfCQX9xmGBCr9zwcghX6BccbVrQgjpvR3HPAQZ4HSzRak0XdW/r3dFbN44mCQIQlgiu33i6FjMKcClC5niB71NLtEhUySrWsZ/8womoeA0aFCw7/5ZcP4qH8aqKbx2IU8GHD06tmp6cKFTFA4Gmzw4bBKZIGsJqbU9Jj61FTa0eCay5mNA9Lwq65P1ih3jEnrKlouzbmWBYPmd8oksUc2VYBqWVP63tKd+NCddvl3+UDjNNUICJG13SYFJa3VN3fJw++gdwp3fzcjW11nlvOkbkG4rxXbhwdnfIoGU9mbWKUDEtSQbOkhRVSU8O5GhjOUiZPCaaFM8kyEnnVbI4wKWXHWpg0jz+5pJ+o9prksO6VjWvvrpIe9k2wm1PzRlOs04e1Lr+FbNhsSRnZQtraaYWkIidIfYBiY6fQPAmHXwE3066lL6bIGIfdzH28UcVS5H4hBi+fQxy5lVNruc/G8p2aVnZnlMn04bqUaWi4XHJdx3rUfLEDxC0ip1trp5mxM5TbssnUbq2yaskJqwPz+JyIdMFl4iNfs2mjDjPtGly0Bc1/CmlBQP9eeVsJUO6US7oP2Nlm2FmMhcX6YKuRy1TUCQ+nqCF3Lb+Gb8KMQBg= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:57:50.4838 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3d5bc235-4b67-4cb2-581e-08db926500ce 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: CY4PEPF0000EE36.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB7738 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: lbjJ8SqWitXSUARQFoHbhADtx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876679654100007 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..d3c9c5a0641 --- /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] + gEfiMdePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount + gEfiMdePkgTokenSpaceGuid.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..e95dd9f3b56 --- /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] + gEfiMdePkgTokenSpaceGuid.PcdSpiNorFlashOperationRetryCount + gEfiMdePkgTokenSpaceGuid.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 (#107423): https://edk2.groups.io/g/devel/message/107423 Mute This Topic: https://groups.io/mt/100478924/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 Sun Feb 8 09:33:03 2026 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+107422+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 1690876677040500.92683433108357; Tue, 1 Aug 2023 00:57:57 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=/UZ/JndpCFTK6x/VlZEkYlc9Uusb7jaJrq/667Kl+zU=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876676; v=1; b=b2dQowH5+dlxGWqVkzyvXywkuslKr6ZgHJdx0kfRLtmq8TKbEcmT0tQ1ILKpTAIzJOgR/ojM z5H/j2qHhJMshkHVjQPvhesD+A3Wh7Y6anYJZW8VZ2z2XO+OJ95Izs4iP5uQul1zFjPwpESqDbE mq9nYoBhzovN3a+HEzxqbFAI= X-Received: by 127.0.0.2 with SMTP id zFbyYY1788612xTeqX3Nci4P; Tue, 01 Aug 2023 00:57:56 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.48]) by mx.groups.io with SMTP id smtpd.web11.7805.1690876676091729211 for ; Tue, 01 Aug 2023 00:57:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UuqgT1V3m059kAg7axWhRCk0XdBVhbN85k1LwSsQhEBheMvs9oXjkO9HjanIeZkAX2wbvUU59K6WsIrT73szjGNV+5GZyeVlvhCK+ln8bTyoHV2NCthdz6YcdYHDuZHbbx++cUTjwCP6FTTO/T0lLeJ9d+seQoS1seyd95SuIeW2kIumUicyvJighB93M52TUlbtRtvE3rM47w4ZyOZXtgD8GOfY+uLW2gHBm2PHebtS37Wzp1or55ntaS20FJtBSn4c7e5ev0KxR28I7mnjJsoNmKA8QPBGvEhCwgQgFy+ZmwcpcF01QPCOr8TBpHGj33zSQkz05MhhpYGHKol04A== 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=Npy86+/cAQIwKizCLnTCtk3SHfG54UhmI0tFTndK6VeCsN+Xaesxit5jUVCxD2sVntiR8RwVtDnHGqy97ujSP00FQvrKwR+arOWqAQZkCUaPvC07N6qZdH9fHWTRp54/aMzu3IWQUE/TGMMpn6EZ7KO63qLKmdv+udouVhdF4k1/RShXWsr5gKx9MHWgT01k/DOB8MjxtTCzE6adk8sj0gvtc+OYZ4MnbN0h9QK6HyajKkP7/ukmdEwsuVMGufxuAXx2kQIbO1uNdyHGv2bYgPIrzAKkU1Xs4H1v5CoRk8UXFes6EoYV4cmDzhJXk7+E/AMXC5GkbCPv1HlItX0jCg== 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 CYXPR03CA0037.namprd03.prod.outlook.com (2603:10b6:930:d2::28) by IA1PR12MB7544.namprd12.prod.outlook.com (2603:10b6:208:42c::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.43; Tue, 1 Aug 2023 07:57:52 +0000 X-Received: from CY4PEPF0000EE34.namprd05.prod.outlook.com (2603:10b6:930:d2:cafe::ce) by CYXPR03CA0037.outlook.office365.com (2603:10b6:930:d2::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Tue, 1 Aug 2023 07:57:52 +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+107422+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 CY4PEPF0000EE34.mail.protection.outlook.com (10.167.242.40) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:57:51 +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; Tue, 1 Aug 2023 02:57:50 -0500 From: "Chang, Abner via groups.io" To: CC: Jian J Wang , Liming Gao , Abdul Lateef Attar Subject: [edk2-devel] [PATCH V2 5/6] MdeModulePkg: Add SPI NOR FLash SFDP drivers to DSC Date: Tue, 1 Aug 2023 15:57:24 +0800 Message-ID: <20230801075725.1102-6-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE34:EE_|IA1PR12MB7544:EE_ X-MS-Office365-Filtering-Correlation-Id: 9f5739c3-2e81-4842-fc95-08db926501af X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 2IArqzKd/KnhYVQ8BUia2vnWOhH8ANRikAm0ilgPdggu0OI4/SwlCubDdTS+uJr9fstEiIxOUp92ChbEnK7LHGMhuo81Ms93Cb2z4saJUu9jFmFIRuIu4Ukq9zQhvsPM59EYy3pwvuemHOCF8Ath3cR+nXvHm35/Q6z8/0B8S24WRBlmdMSiaRyR/izsZf1CXgPKFAGx4bdCE0Tv48FH0ww3uyl9/Cm8jdI71MAEoYNpd0jpl7N/2dCGyonlJnhTod8z+fsiiCEgF2Uzb5bZD30fesOFoNrkcJ8PAa9bb7kRNgMDoAuEuBemsorMvZ+tme+BzvIe0vu2dOVfewUoivD0FIPz4TEdjBfDkA7rMQf84sh6rM0WlumgD7uAuP8BhOTTsgAN9hYJKbWORqc/fhY/PF2Cu6TWozAgkgZ7gIol/Ndvf7MnwaJUaAHLbk03x+ThTA9MZ/utmQF7lTOsta4JFwaG6W58P5IrZElG198sBRAix+gyH1Mj5+c3KgKvOkzdYiDHLnsg42ZRutjZRsklcMtedeA9Kh4P/hgRdIK/ilJTsJQsi4LE+LXYAKxlrz5dOpQo+OqkVggQH3BrQRzQGzlNmiECG7D5fpZA3+W6PyQC/eEQOnva20EI2zlHgdbh5+2gdKGW7ila5qR0txL8Pe0TG3ExhP7XUs5IqHgdJxi1DluHKzktaYASxrOpxbGkj3dQ8nvZDsh4B3imoBJnlAK1hPm7twMbEV2FwIvdU/jFo0Me730dWJ8+jb6DEr8X5w04H4Pwcr3bSxkpsw== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:57:51.9782 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9f5739c3-2e81-4842-fc95-08db926501af 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: CY4PEPF0000EE34.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB7544 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: qIEMsLuOtBHVuY0Ex03pfALJx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876677839100002 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 (#107422): https://edk2.groups.io/g/devel/message/107422 Mute This Topic: https://groups.io/mt/100478923/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 Sun Feb 8 09:33:03 2026 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+107424+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 169087669265275.3535334304405; Tue, 1 Aug 2023 00:58:12 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=2kfoidCioZIhm+QfLK2/DBHhi0v4l1TzlE480rX9W7g=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:X-Originating-IP:X-ClientProxiedBy:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:X-Gm-Message-State:Content-Transfer-Encoding:Content-Type; s=20140610; t=1690876692; v=1; b=a36dD2pVvba9Qt/Vhmv5ON9CQdIn9XYm3QwtzGpa3l2b83W3wcg4H5RUBn5n2g+Z3dhwDtI+ HjW4/LHVIo13pYh3qo6jEFW2vOVn9MGyTBeNHUuZmqBepYcpikDcso3A6/UFmCLVhQqkiei3LF0 gt5IElWD0ibEk8fU6s2c7KT0= X-Received: by 127.0.0.2 with SMTP id cU7CYY1788612xBtmv3qPvdg; Tue, 01 Aug 2023 00:58:12 -0700 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.43]) by mx.groups.io with SMTP id smtpd.web11.7809.1690876691773687584 for ; Tue, 01 Aug 2023 00:58:11 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eZXYFTnM8ebEDvHQvuf51xJxNr6RxF6Q8kMb2X0SW35uDVUT6kLmfkozpKWzqfZJI7i5QK4zFfPUlCK1oOrCzqoQ7xydd2ZucamERgpaWR3fXlci7t3PcH60eB0BGcTEPgXfBJAj3iSSgtxJT2HczzdvlCz11uD8scNT4veF4jt33XntNpcDh3v6sGaK1PMx6LJs8nS624xqZE4rzN3C51JmzEWVnQd81lD/yI3Wlv2qcciMQnq1c/+SEQBZNZhRvwyMGASOZdYHnwXNchzjLWWit6BDR7nUqfSotAnJQAXIV4XrVLfgYKVqsI7svEY7lcwz0WF1BT2P4/llnQdl6g== 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=ImbVYvWrfUpxokgJAD80PriluB1mKot2vOtWJFDnaE8=; b=VM/QOkbCLPHn+gZa07o7yFqfwL5YwwMoO8wuBmTdCv/qOQGZ7wxCDGrgJX8dSWH7tAXkOmqm6BWyEU+WfAdAfeZZMN+itOFZdX3bdyrglb8c4dBkIs4w2Mu0Tmygmsfkr8X8AOsGoUWk5dx7pwhWNRockR6Cl+mK5OlIcpDBQCBpU+GKKk6ldK3LX9QyWvxnfzUGZ2zrRiCwNeX7RmzjEdfW95sOM4PJw0vbvwx4WsOF9Pq4eyHBW3zt8DWmf0l+ID+aBzjeFwIxpIrxfkbiJUSMU6N63BsKhWObZhxoZ5hHX58e5Pf7P0byIuhAtUC29nNSTiwepqsNipew7UZllw== 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 CY8PR22CA0005.namprd22.prod.outlook.com (2603:10b6:930:45::9) by BN9PR12MB5115.namprd12.prod.outlook.com (2603:10b6:408:118::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44; Tue, 1 Aug 2023 07:58:09 +0000 X-Received: from CY4PEPF0000EE32.namprd05.prod.outlook.com (2603:10b6:930:45:cafe::de) by CY8PR22CA0005.outlook.office365.com (2603:10b6:930:45::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.44 via Frontend Transport; Tue, 1 Aug 2023 07:58:09 +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+107424+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 CY4PEPF0000EE32.mail.protection.outlook.com (10.167.242.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.29 via Frontend Transport; Tue, 1 Aug 2023 07:58:08 +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; Tue, 1 Aug 2023 02:57:51 -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 V2 6/6] Maintainers.txt: Update maintainer for SPI modules Date: Tue, 1 Aug 2023 15:57:25 +0800 Message-ID: <20230801075725.1102-7-abner.chang@amd.com> In-Reply-To: <20230801075725.1102-1-abner.chang@amd.com> References: <20230801075725.1102-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: CY4PEPF0000EE32:EE_|BN9PR12MB5115:EE_ X-MS-Office365-Filtering-Correlation-Id: d7e60ad1-5231-432f-803c-08db92650bcb X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: AuNZE7f4aUXjsjBR/ufJzuMe6qJN0jVAK4QQ/Js88tmdb3CNt5Hy5Ay82aEVXhbQ0TsI4Gq610x86F4oDP3ka/YxJ6zfKWnkYgWnYZLh8BkPJ4hqk3CKK/C7wEJPQPOK94Yy3sgEY+FqOE4AusNe6jVEXKUqaw+JKPPZ60jzRu95eLdicgG+gUi7jPKmHynisVSSMa/SuZO8w1BBevtrDjPX9tvamyNgJAxb1MS7mpVgIt43KTY0Xyf2Z9BjrwOtI2DDMq3Gh4iyx3C6tGmaO7cVWec8sy3H9LsiHYZZisroYrMhEecDMBcyGQD/O7JLXN2Vr6KCDBEKcLNEFj+vnuvQS4zdXaahA2z5vRPZOssa1PzhN2C7xc2r5DuDQi0/u+C7C8+0w+54Y5Ksr+W63SKPT5jYBGmIDjxYBtAW19YWl9Jj2A0GcRYWxUl3duqbW6uzZDf9x+TUZJqThd1jDWcTr99d9hB9V4UyNgGLy4wgrKEjrsd0nYx4AxKdTu0DGk8eYFGHysAVUjhvL+NzngMjyZenZrO2rwDV1E/pemLOwsddXJxNCq5dR8R7HIzbrQXCXZwLyVYMH2RNt1+auhVrBJq5vgFgw1L7ZPsfL5NwqyYmbTGdDRf3lBSFvhQxrtsfIovPgXXT2w70ZnfFlesFgJyjE+GqK8BB2gnl9VhNLgYYj+5c83lUaumrWFjcfoNVrZdgU3gT28C73h18/yzOmHwcSzN0iYWin2yopn4uKsvthihlAJH0sV8mio9vUXBMJ90YJz+wbGj4bK5TPw== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Aug 2023 07:58:08.8576 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d7e60ad1-5231-432f-803c-08db92650bcb 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: CY4PEPF0000EE32.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN9PR12MB5115 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: 3I7CX3xwepD7TKxXB1tEs8Q0x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690876694449100003 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 --- 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 (#107424): https://edk2.groups.io/g/devel/message/107424 Mute This Topic: https://groups.io/mt/100478929/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-