From nobody Sun May 12 10:35:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107221+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 1690269074437900.4509601613028; Tue, 25 Jul 2023 00:11:14 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=6XfYIPg5PzwkDLBoE712zfJkt2i1Q8ejY4oNNd9IzoA=; 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=1690269074; v=1; b=PLsxVPGjCP4w1T/B+YSlMikxC5iYKjSpxISeVrtZE12QmQXBuE5tqQhRv+8oEQgywC90MlSO lTN19lkN2ovqrrC7OI4hUsNcs9DVnr9/t0yPm4ZaoAfePFRMNB2i2a46oO77qLFKfeqWbXECeuw aoCIOm92aivMWlTTP+yIUpHY= X-Received: by 127.0.0.2 with SMTP id YakQYY1788612xNOd0G0nCOe; Tue, 25 Jul 2023 00:11:14 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.68]) by mx.groups.io with SMTP id smtpd.web10.15029.1690269073300401675 for ; Tue, 25 Jul 2023 00:11:13 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R9VtNzJA7/DUL0Xzn2O3iFBVpDnV0N5dlQHu+PlpUpmu58ppYLFgnqayElS+5PRyvmfcZ7nw5bIs677hycAGnlhgdJHze90mBfXlbsAQBPXxaqAEq6tmlndhaSLThmItUeY6dY9/N4sdKNewxngc3hF4URD6T935yLeXyceRkhXg27liH0eqkRhRnIExzElXv7ZQV9WAzFB/LsX3JUpmvebENGrwXEvT0W+67VxN7D7SOIFA2SHWav90y980MLM9kLitNhf+mTxI2Ix76RRHPQCCPLVeVzpCWe0jyaP2j4EHJ+MFWYgH9O3gKC24xLsglvSe6RuPe6wvPRPjG2U0hA== 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=QfcHaM8janKUAbmyUYCDH+Wjh10LNKgF8iHkukuE0E8=; b=CxtokehhvDHdFSD77I0jAEUbPZcDYLpoBtUes0pV0FpCMz1G8hvZiInTe5FKs9d1+sY06vh8xP7PTZ+NxrBz4+oAxSWnh4P1M6theNOeyrqiT/0y9qf0J7XJBapKQl8i6BiOfOpEmU6172P6Il7Xa9NrkkCDd+vpKUun9wjCGybKBnHD+slZGckZc2xoWUI/Q5jrT/JioWY61E277EfBkmJkpZSJVMPCCGunG8Yla04UHCOHNeU6jZxTsaPXYF+a/PT9Mkc2zH9aP4TKuHRS7uoEukoW1AP8v5Qub7rYVmYS4fQLOco6TX+3p/pNeRjHNRYN2zoVHBlpWcTiAtDi5w== 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 DM6PR07CA0056.namprd07.prod.outlook.com (2603:10b6:5:74::33) by SN7PR12MB7954.namprd12.prod.outlook.com (2603:10b6:806:344::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.31; Tue, 25 Jul 2023 07:11:10 +0000 X-Received: from DM6NAM11FT031.eop-nam11.prod.protection.outlook.com (2603:10b6:5:74:cafe::6b) by DM6PR07CA0056.outlook.office365.com (2603:10b6:5:74::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33 via Frontend Transport; Tue, 25 Jul 2023 07:11:10 +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+107221+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 DM6NAM11FT031.mail.protection.outlook.com (10.13.172.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.25 via Frontend Transport; Tue, 25 Jul 2023 07:11:09 +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, 25 Jul 2023 02:11:07 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH 1/5] MdePkg/Include: Update definitions of SPI related header files Date: Tue, 25 Jul 2023 15:10:45 +0800 Message-ID: <20230725071049.12-2-abner.chang@amd.com> In-Reply-To: <20230725071049.12-1-abner.chang@amd.com> References: <20230725071049.12-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: DM6NAM11FT031:EE_|SN7PR12MB7954:EE_ X-MS-Office365-Filtering-Correlation-Id: c3cc8fd0-6994-4059-ca9b-08db8cde5288 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 0GmmGE5ypZuqE+IyaMoJPtvnnaEja3LEt/1E/RuVXyAV05lwCi+L/nlxE4/GZiiUdJ/VGEmMIa6HsThThO+wwWN0BtZN4pNNblaE9exSjsY76mgnXi0NoP72kGUcWgyFMI4q3F6yCkC/lvZGwwj0s9/OakwpYj/3nla0sHKDk+fGLXPooakDz7XSNclKyx5XPYTUdQgWkf0F8+xZv3991sNyl/MTsOq2BFr7dz3epSFj5/RAp6zzJ4NZ9kfIN9HlRlTXcITL9ZjBGSiTr8M2SgJXMR9AlQ//pijYDcBGTU5Chi1V57eFfHkV6oRoUQEXf7Gx6aZNWy7yTIiM4nL68HF67k/a8N7l/QutGWdFGpc2C16+32mUDNCCDxmhrCVhMTBzHgtZbVQE4/fmh2rrke6txE0H+v5A643LlXppg8T+G5NxxCU+rhf5RibE2insKB3aYtvwTYL5lp+FiniditiASYA1vptXyHIZII7WxHVtGiACUUR0EyOmq/rUjk7iM6BKGAyKHkaVWYRegk+1dpPMq0Z8PE9kGWokTHS0fp78n7/a6GSjpPNtJK433XLM4anf/4sFniN+k1YFnKXXidBNu1FUR9HUyD0JjFogOO7KHOpp4Rx26nCAWMs0oe76JBagQ9JDKsVQIKv/SUb8J4fcaAS1xK/pZiwqGeXxJxghrxfQvDwcKTJg8eIcZm+vNFyjUJiWJmwMunyG3d6+a0ONQZsqCdBtU8Ox4cIxnkFRQAEyJQGogAo4WJHJgY19yc9iUn2bcMcRT+YnJhvb4A== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 07:11:09.7600 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c3cc8fd0-6994-4059-ca9b-08db8cde5288 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: DM6NAM11FT031.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7954 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: zr4WqfXYK5xkiGLjgKqz2lgUx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690269076290100007 Content-Type: text/plain; charset="utf-8" From: abnchang 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 (#107221): https://edk2.groups.io/g/devel/message/107221 Mute This Topic: https://groups.io/mt/100345721/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 May 12 10:35:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107222+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 169026907555022.39223345649532; Tue, 25 Jul 2023 00:11:15 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=qPkFPMeVzyZq9hXHFrawjyXX7cEweTmsP6UH2cwkoCs=; 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=1690269075; v=1; b=wU45ol3FoD/5bCRFdHLNXfOtAzSld0K8ZZWsmVfpNJO8AHH17EnqIaRjtCR4uyAzahoBR1xf g4mVdFsWTzDHPVYsD+6xihnrNIPqKFjmbtR+5qPRZhhLcWhQktLjk5nlvUV4RdG/gWOSZMUZ8GF UF02RaWdUbTd5AVouahGjxnM= X-Received: by 127.0.0.2 with SMTP id FqmwYY1788612xdwwhbEk9DZ; Tue, 25 Jul 2023 00:11:15 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.54]) by mx.groups.io with SMTP id smtpd.web11.15143.1690269074600982449 for ; Tue, 25 Jul 2023 00:11:14 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=d6Ys0G1thcC+eZMiAms1YsjDd8BROu6GbxKoE2ASKb8zEgS5SvddTGaaG8ET6U6t+OavQBOQIW+a0T8ECMd43+KfyiJGpClh031+qXh1jLBq06VDaXFphYO6wPi7U9rhKfT9st6dMQYXRqtmVOqp5KccEOPUXT2ULSE4Htpbdj92ZxyJo5czPVVN8BXrBI7pDpI3E1wRd+LyPJ95cUdsPzZ+3ey/JZ8LhEBAZ0ZJM2qtZOja4MpkPYKbTZKI0c1VGjLsN1x5VQ0bym35LVECB83nOZhz511PL5w/r3j8h5pHzpJK1ANN/v5hwbKQnJ4PPWvmVF/3URI6PahJJl0a2Q== 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=njfWBrpioqf27drqD2VZL5a6NKDgPq96NpFba1RDq7E=; b=b6aed/DCucRyt1tlkLeu0F5uRO4jWVmO7BArsOEUWJlggUmLapwTpMPPmIU9sn3h6JFoRmX6xfXLEBLp59V6unoYXCesG3WKyxhLaPg1DEkxHp0SQlLdIZ3ev53neOHjlc1KreFiZ3hiTDbln8Ot0vxFgO1tkWfk7sVJ/Nvv50fz/qmJueLkAal4NLwGdVo+5dOQ/W1ep9je0jsJa5F3m4xYEwZb64jN2udh7BKaMEFhUIk0DSkD4wuTlZl5pjfG8fMuPXvjB9D09sN0whOgGtuBT8LOZFiCMTN8qpmSPXKlVikEFKhNrAoABUvRJHn6ASgegMX6wbqwBEbIc4cL8g== 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 DS0PR17CA0018.namprd17.prod.outlook.com (2603:10b6:8:191::18) by LV3PR12MB9142.namprd12.prod.outlook.com (2603:10b6:408:198::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.32; Tue, 25 Jul 2023 07:11:11 +0000 X-Received: from DM6NAM11FT010.eop-nam11.prod.protection.outlook.com (2603:10b6:8:191:cafe::7f) by DS0PR17CA0018.outlook.office365.com (2603:10b6:8:191::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33 via Frontend Transport; Tue, 25 Jul 2023 07:11:11 +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+107222+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 DM6NAM11FT010.mail.protection.outlook.com (10.13.172.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6631.25 via Frontend Transport; Tue, 25 Jul 2023 07:11:11 +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, 25 Jul 2023 02:11:09 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH 2/5] MdePkg/Include: Add SPI NOR Flash JEDEC SFDP header file Date: Tue, 25 Jul 2023 15:10:46 +0800 Message-ID: <20230725071049.12-3-abner.chang@amd.com> In-Reply-To: <20230725071049.12-1-abner.chang@amd.com> References: <20230725071049.12-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: DM6NAM11FT010:EE_|LV3PR12MB9142:EE_ X-MS-Office365-Filtering-Correlation-Id: 5d04b92c-0ab4-4407-94be-08db8cde53b0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: VJJVgwb90rnbF68SgFoYjwi+13bWIv1esaRBuBjbKuUnhrOcP+XFlV9m5YP0zxkACJ6ad8ov8EGuuBrnBGMsX4FyGhL/tgY1X9HhDjzGWmkF5CIXosyEq6O4LsZY6AzrKZ3CgQARkhrNBWApSY21SFCTqM4aXVmJo5x8K9Za3sNxFOOc4D4jhp8L8Std/FrLxbkcMxuH/h7vsqZN5gHIz4K418xZ8m3Ief8ehb0dc+98wd5OX9tyMEeG+kbOZoIK8DuBrxxYs5+PBTLjZ9HuvhetL6TO08zilGGvAY13eG0S5q5BH+59Q9bO76mHMfkPzaVWVhfi9KbCaF1AXokkvTdXCifeZQZItMequa+oH7UJ39FIuVSYKDsDrbRaQZ6r3/ITfO5GtvC+wKltwulsnf06Wt0WEu8Hpspo1N1KFn+T+xLieN1kA5DMOIadydGkGNuN0sGc03LOYjC0/IZnVZ2Mohp+wIHUl+IkGT/P01iFckVkGPxkFrjGAOo1GzvR/uzQjkn+Iy5u68sBwj5ElwP9B9sD5sEo6xF51NfkVC4QvzLK14XDU8sa6CqtFXU9xXf1aqo5gyJUW4bnumYV2XtPAF2THYFuftOpoIrHPYDRHzZwrF7apb6Qz8DN55NbWoiYJ7SJToY99kc8VY4aD1/kipl+FSzxUUwDM073iGwiG3vtLCNgwQYYLGWBXhU3Y/YTQmVTMqQPBv0p/kHEKuS2jAWtxKvqTEV2we1v2UK1Bq9rOBoxwVUAM+0yDbQxoYHESByJI1hNklj+/PC5PA== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 07:11:11.6985 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5d04b92c-0ab4-4407-94be-08db8cde53b0 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: DM6NAM11FT010.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR12MB9142 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: m19dg7Jzyn35tgpQoKiHQyVrx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690269076316100008 Content-Type: text/plain; charset="utf-8" From: abnchang 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 (#107222): https://edk2.groups.io/g/devel/message/107222 Mute This Topic: https://groups.io/mt/100345722/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 May 12 10:35:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107223+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 1690269078285831.5583118629223; Tue, 25 Jul 2023 00:11:18 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=blW0G2Tzn7MOD5Ubfoo1j2lPqLHuaLX9b24zg8XKvq0=; 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=1690269077; v=1; b=jDkEW+wKZGWNWIWGsP+RK+/GDuJ75GFuBYG8xhZdMBbc3py4D/6hPNMdzMKWy0jYosm5WnVo Op8jwbEd57+Cab6BPhJXdut9wgJtCPvxydoxjazjGqjcE77Qe3ohiFi3x98n/hjtnofHSkh0S7D G+Ems9HgIw7SVzov6ZlA6zVw= X-Received: by 127.0.0.2 with SMTP id Fzh7YY1788612xhU93puRFMU; Tue, 25 Jul 2023 00:11:17 -0700 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.45]) by mx.groups.io with SMTP id smtpd.web10.15030.1690269077363738277 for ; Tue, 25 Jul 2023 00:11:17 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=H19YvENFvCqJcqwFJfeUm7NhJGi5Exng9IneS1DtAiBZO+ERK9ne2zvICO8+PZzh4yzDQFjmD09hEbf3UJDXGJPvRzkE/pN2uaZClqNKO/zN1i0R6gtB7kD3TZ7ef9TGlc8iNV+038IC6ClGLaBeShnkjki3eLVRp6jgqKRi9X8BqD+Ke7xd9xTEpoE0dtK4hiU+1u1320GQb21ua2nURTqBu8/8XTmQ/H+L0TvuLFbw3DI9N0TEw2kTshXk6uq87RY3IiI3wztGppJJSDKMCai0+OkkSMI1D5pQss8y29gCzjvSSPrzRexu2VyaRWkljCyPQcefBh7iiR6Oidk0UQ== 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=XAKYEkcHWOjRe8JAqxJweVF26u+6sInwLZd2vZg1vpQ=; b=RF+9KE8uae7S4kEf4dy4TDJcYOBkecMcBP6ZTXZxfvFZSVcVdA+34EyZ+FoXI3QttPmjnVr4QoN6jHIlVtzwNZUHBUU6OTFsR1gecw5/E3mvY4ZBh4NiUFBFhFnJHqc3GsVUYlwu+kdEIzhtB52scAMBiA0Y6/2/C7fbmt/tX+WYvxaPvk8my8SGqSezaBuZovl+x6kWnedniusXM67PDrsuKynA5Q2eAyhQaZGZIcH9JHPVKnYPRt+nh4ky+qpeDQYDjc20Fcez/FL1aiYD+WeG7raUmrF/BnyHRQ5nV6nsrblRVN2Ik87b0qYG62FyDP8oBCDMQPw3hIspwb5v/w== 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 BYAPR05CA0093.namprd05.prod.outlook.com (2603:10b6:a03:e0::34) by BN9PR12MB5033.namprd12.prod.outlook.com (2603:10b6:408:132::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.32; Tue, 25 Jul 2023 07:11:15 +0000 X-Received: from DM6NAM11FT023.eop-nam11.prod.protection.outlook.com (2603:10b6:a03:e0:cafe::44) by BYAPR05CA0093.outlook.office365.com (2603:10b6:a03:e0::34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.25 via Frontend Transport; Tue, 25 Jul 2023 07:11:14 +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+107223+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 DM6NAM11FT023.mail.protection.outlook.com (10.13.173.96) 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, 25 Jul 2023 07:11:13 +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, 25 Jul 2023 02:11:11 -0500 From: "Chang, Abner via groups.io" To: CC: Michael D Kinney , Liming Gao , Zhiguang Liu , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH 3/5] MdePkg: Add definitions in DEC for SPI NOR Flash SPDF driver Date: Tue, 25 Jul 2023 15:10:47 +0800 Message-ID: <20230725071049.12-4-abner.chang@amd.com> In-Reply-To: <20230725071049.12-1-abner.chang@amd.com> References: <20230725071049.12-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: DM6NAM11FT023:EE_|BN9PR12MB5033:EE_ X-MS-Office365-Filtering-Correlation-Id: d62b684b-3444-4be1-1863-08db8cde54c0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: AlAeqQiWKVMTw7qXVbEUHCK72htj4QwXo9La6m8iCqWBsQjCiJkGit3LFjixGd9+3YtLB7xsNZSVLq1e9SMvn0I/NjrfXhk0fxk4j1bH+xvMJzpH6m7RBLgBdUNZ5n2izBBLWxbkiM/oMKHsAqnZMU1Ntm3we+qpV4E6kiqASJyyJQG8csGKLzbBSzepAi6gC0bA63QKVpz2mhHMhqCjjdHk8tuX/xRYVdg6leT/BKOWLRLeSaz/e5ZFF95QfvBJoI4stDU1JfWDfZnBkB75SYfVZFEMRSzpflKVdHEnONMENtbyfa8xgRBUT8Nutk1ZlUOV/pGH0UlGu96/vhBcm3N6G+UIJ2dg/VlsAVM9ZBVOzo4nqOzf9X3WPuT54iwaMpW/yr/1FNKs/5dANlo5wjPJSpx88J/DrigQQ+9JOpIGG4pg9nfPqVTNUZHvxViqdpLgfbRK7OVVBLKcq/m9NnThBrRXxegnGSF/4TCnaPRoYK6NOYJSYHK15nZvklEtp/7agn8dipz/xEMb16twahzTRp49i2tgASDlmreXikXB8EcGOf/iMq1o2Omn3UEMh+ngdhhqRVd9pOVjpkLFauk+5gR7Kg0+fxr99swzWAjwZo9N22aiJPOKEBeu4BeFv3iyQKxBO0icm47EHFKJ/zF3wCOSx+y8kTdcNMdJQN2MnvFUjyPuGdeIPWSKRiJ9Jhv7MLkltkie4yZuLScCJpDuxhq4m+HlrMxsKy49F+rpVdJwWpdIHBKqfc1NTgNcWVJWyk02EOsS/eUjx74rJHCnyJERaQuXu1QzoggHyVUyiO2P3xV+6r0wmTHZG+bd X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 07:11:13.4779 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d62b684b-3444-4be1-1863-08db8cde54c0 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: DM6NAM11FT023.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN9PR12MB5033 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: 24XiRnwzYo7STxKdZ3NLgFOQx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690269080326100015 Content-Type: text/plain; charset="utf-8" From: abnchang 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 (#107223): https://edk2.groups.io/g/devel/message/107223 Mute This Topic: https://groups.io/mt/100345723/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 May 12 10:35:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107225+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 1690269087753444.47301567638715; Tue, 25 Jul 2023 00:11:27 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=ZRPcEvMR8lfs2p3GpyQLvmeOWi/mBR3M5CzIxdPxst4=; 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=1690269087; v=1; b=McvZXePw4DuKhtFq7XrGHG2wjJdv1IOAHXNs9rKqLL3vySAWme8A5tfYdVwHi2YYhP3NP6fa 6dT5WBlRUNh6mlP710FVi19WsfyKIl1T9MePj4ySbKwcsGoMJPo6U/1ZGH0Qu1d5SO/SgcAlB/N DzD6D5wVgJnWnadMSfNaK/v8= X-Received: by 127.0.0.2 with SMTP id zgWHYY1788612xTNI4rjvDLP; Tue, 25 Jul 2023 00:11:27 -0700 X-Received: from NAM02-DM3-obe.outbound.protection.outlook.com (NAM02-DM3-obe.outbound.protection.outlook.com [40.107.95.54]) by mx.groups.io with SMTP id smtpd.web11.15146.1690269086433757295 for ; Tue, 25 Jul 2023 00:11:26 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=d6lMdn7heQOoh/3D/UXbMPCowFW/Udq7tUPTHeVP9LobM2QYUVuGl/cyrhMSG2hexNwcanEHZt1OSoJt1Yy/EbF9iw4LSwoqktoqJ0E0xDInzOPk/u2yfees/eY4/tgGMe3YCNQuUqvhTPne3ZeewezJt0WzRKkDVdnLYWPXXUebdvlpn7/SRvM/a4ATxCucZAa2ja6sKHqYcnf0CxC5KLm3Z8TINjwOH5Kn1MBUviH5NvmAT/99BwHKfjaUcV2VHNYC/JvDV/JBOYtl5wQiEh1FtfSDvsB1CooWvEApCmp5JPRMOlE1HrWJqhofQi4r/HSpLNzErT0ZIJhYVMG/AA== 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=/li02Eyw6mTtjEKZ8pdOqOz1cxNhM7/9X1KLzCwWgJU=; b=AF44ftztAZLJEycjoSkiTzp39wkTM2r4AiQQDTcYU9dN05Oi6Y7yGBZmEVwBPKL/koEBA/CFmZiuhneKWjTPai9p3FbefOPNAWHh30t5Ovwd6jhKMuzxJuMM9ynA+Zf0dxQ6II3L3y+B8wraHVmYxFcH6CNtcZTaI24qIndCwkF78qs5IBdtIGowXBL4/1Kqrwac7hS+n+HJpZRNCZ92CQNCyZJ2owIEdktf26yul+CtAD4jUrnrTpmL+inCA8yUdMIHFRr7bZ7vKiFlbauXW3v2ziMR7++KU84dquQWhwkfK8XSERy0jJ4jzxhgGEjXDUiq3wmaz+VLqFYm8Jd8Rw== 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 BYAPR05CA0100.namprd05.prod.outlook.com (2603:10b6:a03:e0::41) by PH7PR12MB5619.namprd12.prod.outlook.com (2603:10b6:510:136::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33; Tue, 25 Jul 2023 07:11:16 +0000 X-Received: from DM6NAM11FT023.eop-nam11.prod.protection.outlook.com (2603:10b6:a03:e0:cafe::be) by BYAPR05CA0100.outlook.office365.com (2603:10b6:a03:e0::41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.25 via Frontend Transport; Tue, 25 Jul 2023 07:11:16 +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+107225+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 DM6NAM11FT023.mail.protection.outlook.com (10.13.173.96) 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, 25 Jul 2023 07:11:16 +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, 25 Jul 2023 02:11:13 -0500 From: "Chang, Abner via groups.io" To: CC: Hao A Wu , Ray Ni , "Abdul Lateef Attar" Subject: [edk2-devel] [PATCH 4/5] MdeModulePkg/SpiNorFlashJedecSfdp: SPI NOR Flash JEDEC SFDP Date: Tue, 25 Jul 2023 15:10:48 +0800 Message-ID: <20230725071049.12-5-abner.chang@amd.com> In-Reply-To: <20230725071049.12-1-abner.chang@amd.com> References: <20230725071049.12-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: DM6NAM11FT023:EE_|PH7PR12MB5619:EE_ X-MS-Office365-Filtering-Correlation-Id: a6435fb0-428b-4232-9ce2-08db8cde566f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: NZARs6HzYIWP7n6aL8/FasLkYlWCtyBgYRMOuRSj7AO3Tve1hVP94jnbqiMWJirzKdxXH4XahI/ZnQTEni8LNxBCC7LX6W+eeXiEVcLsPXyPr7FzchFwmpQTsyaMT5bPPislRdbGepqCWz9WJLAIH2OKtsYSaNYP7abLWm98yaUdj/rY2u91cKAOflf6WR5M6uE9Dfg90D9U9s7dazgYpbrCaA3VLwIrBX7um0JcTAIPLCXVKnlKP5QNie21BOkvV2HVluFGbID4W2V2ZRSjx9HW0iASumTeIK363Ezj57OCns0zLzM02TQxMwuEeMMRJvFHuwvOyiUo9FhmaR3YmW/2ZnVw8nKBKDRA0fvwXg19a4ODdWo37P5on7/aIP4QNqNBURL5FSWrjG7yyZxtQ198qh0owaPT6szygz5RvxrXLPSoDcRiXMzpAdKjHRyBcAhse4B9YSpPgL8lA+WWSwtSUpx1Q1GBn8GkVGtCTgTp+E4UdJUooOhEoobYEoyV7TwytwobyYgaBRl/zX2G3Ew4SByepvtRQQKPs97EhgpirLTONmHyb1xkNrHku3TI2TRcJXJKYH0Xvux+3PDNfMW7wu+jDbukbPv13iW7doNVuWnbI3rKLRFPpMJ+oNoDm4eYrWvoX0o7OCsdKivlpyYi8bRI+/le+SlU43ExuIrTd/oLtUV3wzbb94UmeOtd1kAIYZYx9zjKavbmi7CiPDY7zUdB3pXxbz+hu0qFnWg1kTFf/c8Dc1VtDN4oP81OXTp+XUuRqhFsujuFKrhCI27aQwEeNeXYh31Gx9mqdW0= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 07:11:16.3059 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a6435fb0-428b-4232-9ce2-08db8cde566f 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: DM6NAM11FT023.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB5619 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: 50qNYyIYkS7rmYtrJzckOdDXx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690269088576100001 Content-Type: text/plain; charset="utf-8" From: abnchang 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 (#107225): https://edk2.groups.io/g/devel/message/107225 Mute This Topic: https://groups.io/mt/100345726/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 May 12 10:35:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+107224+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 1690269080738476.5346451096533; Tue, 25 Jul 2023 00:11:20 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=5UEEmZbMM2rMBKdsoijVUu4dXjK5K5xKUsZ6jLhRUIE=; 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=1690269080; v=1; b=QuldsbkPAfDlShQmvUv0i6PnVWJmFu5WSboRQeaQlgyTtCbo+JZq8THzQ9EwKrGQ3MyWH019 Jc9N016OBzFRgjJPka+9o0QMG1nSLH/RO0hCInY2r+A2vwAOPQMKJJwiMof4V7WBOwZAYMKXbLF QeJcIdY54mXdNOEAMw0s+08M= X-Received: by 127.0.0.2 with SMTP id 0q6WYY1788612xEl2shOz7zK; Tue, 25 Jul 2023 00:11:20 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.70]) by mx.groups.io with SMTP id smtpd.web10.15031.1690269079990749595 for ; Tue, 25 Jul 2023 00:11:20 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CpMv76INdL/0HQPqOXD9SU3y8dSazGQiG7PewGGWphVMYOwxSY/xtAp4X6R+fYHy67YyxKA1qEPl0qtX9Rg+vdJ4Wc87eA50ftQozO600XDNwoeyIn/0Hs210Ab48jU4SulMqEu+CySB5zv0Xuo71J99efQZvRZ07c85mD4tHJzRia2kjIdQYhQY/Rie5XGEx0dxf5lnaUVotP633DF8Hy+JXvEPN0tWJT2TGz1OsPEAVQ7TtQC/0m5dQ9h2M4UM8oWzNFYrSy4akVlYLTjPXtd6vcdy1hrBB3YyLW9Fk7GgDpLCH6NzgabsH/y7uTAn3T0dMZeMnjPWy7G0vrkXyg== 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=PLvQoicCLgA+93M3z/Jqzmex+pYtfPGtzijWUjTFcdM=; b=e7LJFxGZ4P5fuuYqlpFQXqhXIu5cKTj+spR3yGVcchNp+5lpeK9PEhLKsC9obOS75G9e/P92F0w6Kf1P7lYe0id+5zaeoGRX1eGqMLZyO/nYDzXyI8/rJ9svqwJDzlmru1UBuUgw7jjTFcUKuqsOR6EfSto+vhRKrPEu0QEQhthtvXTCShiI9SVIXLhRoR9FLKqn401uAj8vWzfQy2oPU22BznbdxZxaQn0LNvulywYnIElwnhWEi6q1EIGRbQCpZ6IKfT8O/hWS6UVgH/+9cs/nj7FQRv6ftQkUuRzJSxO5CXH/tOGbEIeT9koNEPScSlYmA7v3M4cIzKnQtP4jJA== 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 BYAPR05CA0098.namprd05.prod.outlook.com (2603:10b6:a03:e0::39) by DM4PR12MB6111.namprd12.prod.outlook.com (2603:10b6:8:ac::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33; Tue, 25 Jul 2023 07:11:18 +0000 X-Received: from DM6NAM11FT023.eop-nam11.prod.protection.outlook.com (2603:10b6:a03:e0:cafe::d7) by BYAPR05CA0098.outlook.office365.com (2603:10b6:a03:e0::39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.24 via Frontend Transport; Tue, 25 Jul 2023 07:11:17 +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+107224+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 DM6NAM11FT023.mail.protection.outlook.com (10.13.173.96) 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, 25 Jul 2023 07:11:17 +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, 25 Jul 2023 02:11:15 -0500 From: "Chang, Abner via groups.io" To: CC: Jian J Wang , Liming Gao , Abdul Lateef Attar Subject: [edk2-devel] [PATCH 5/5] MdeModulePkg: Add SPI NOR FLash SFDP drivers to DSC Date: Tue, 25 Jul 2023 15:10:49 +0800 Message-ID: <20230725071049.12-6-abner.chang@amd.com> In-Reply-To: <20230725071049.12-1-abner.chang@amd.com> References: <20230725071049.12-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: DM6NAM11FT023:EE_|DM4PR12MB6111:EE_ X-MS-Office365-Filtering-Correlation-Id: 6c5e43e6-5418-4f38-e00e-08db8cde5737 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: 2YvCfOSXgjMfdqWfOaQ/I8TClEQVd2IoKYgUkOIJ1v1SxENXZtQ1hOYuJVisvxJ0GhRn0KARbimbSLhr8J45sPRvMPQOC3fqg388bA36VMfuDq6kF6BMpKfqI5TbZ2uGrzCEQKJ4t6uSZ1zayzmwYCf1AJfthlJwUvzD75fnAKZZkvYFmg9eubmvbTvV3xA7wkD2cr0qzMbFCGYX/9XaOmOtGl9K7I8IumvPEcR5wYZMUOx08lIrUl46ZPkS6YGAob/a8+rJPeg1CCik9Fw/ydP9IDuxeu7Y3NWgsj4o8OWoiYy1XyU/hfRs3/IlF5EJzcLi1LWvULJDLW/KNTlElPE2iki7h3GyPOzluQGdkjOB+z0m2KuI6E4+lM+z626JdcJr86DRKNSg4SJ3374Wqqe7uT/qpA6X3VF8EYHAOyTVEHu7ngernlgrM6doF1Vm7Vhn/iMhzum05789/XGmVBbvE/BssMkwc1iIV/9x2DAi8zwWIADeG5TNwVTTv5177BciA2Uk0hKHk8Z33G66WIAlhq5Z/MAi2fzgUAQDJXPLLJ8V7KMpOCD9gBH6YFN2YgL4T8PgRlhI4hvr4SFKn80xHc4Ks+sww3YpyTlXwnD+fvFTK85jNQYwMX3PhNa5/gQNi42XgFbyBWuymdKks4nZJNvI+AayPM7jmM6L4gnzliOkvEhaHuorJhWyXgzISblP0nmizKQAF2URW5+uo+ApK80pG/UtoJ/0Lt5lA1gUUHLu1lrx98K3Ef6yDuFdrNkGdKvUODHmDddfyfRTIw== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 07:11:17.6183 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6c5e43e6-5418-4f38-e00e-08db8cde5737 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: DM6NAM11FT023.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6111 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: hDYIAAp5Cl2utUZKwCeXGQyFx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1690269082113100017 Content-Type: text/plain; charset="utf-8" From: abnchang 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 (#107224): https://edk2.groups.io/g/devel/message/107224 Mute This Topic: https://groups.io/mt/100345724/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-