From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id B57CAD80056 for ; Fri, 19 Jan 2024 14:57:56 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=zQ4jcC+0FUwRik9AqWvI5aOXOAvZWBwOx2ZL8MVv9ww=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1705676275; v=1; b=cJBLprDMOlC/lmwJWY8da7ukV/woq0UCEtJNBbKffW9i/8AaIaVb/9bfANca0NlfQ5Ht95He nB1gLRGDplWZAWh0PZ78I6MoMdsngLiWoKZqyJABFaHu/Se2arZ5cFbDdmAmFSjpKYIMS9bVYr9 rFF97CNQa1K32FAAhfRqSOKY= X-Received: by 127.0.0.2 with SMTP id J5upYY7687511xrPRv2aOuxi; Fri, 19 Jan 2024 06:57:55 -0800 X-Received: from NAM02-SN1-obe.outbound.protection.outlook.com (NAM02-SN1-obe.outbound.protection.outlook.com [40.107.96.47]) by mx.groups.io with SMTP id smtpd.web11.5910.1705560768139920994 for ; Wed, 17 Jan 2024 22:52:48 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=O0KDIcKwonNZLkbE2rI08s/ekhRfWkG1RkoiWigVat9m+QkwiUEsDZWtJJDuYc57gOeITWYGE8qjN2434e0rvoPbb5LScnXUZ6O4NGLxGgju3eeF+rII69Q4a40QLt8smcCjYVjYCBy9wmNXsguqV3RS7cnkP5hbLlhJHMsxZh8328WRBZryFzyUTAfmvIZvL2dMQrpYCr+sGujK/scPw8H99UOrmTbQGNgZmlMvySWjlT3JCy3rqCnahyeMPB8QJIquGDGoQYw94m2oB/Mamf/xtdP8Pbjp5nM+4acruJM7hpWIuhUZSYH98oDR13LuemI8On4iJJt7eVMiY+IIUg== 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=hQERtiTwcjWc4JuCLpfpcpgnaZU0Y44WYsNaPFA79r8=; b=jmYiQLHFjT67esienRkFmowAc2+/x7NTr/MZCVMKhsAw+IVZetjjy1vX/jHiiVn6sz6SSgwPwlYScwfhFKDl7uZ0oBPfaBfs1LCZyh7cHD2iHoprY6TTiMsBPQkLDhE78HeoggDnkcjgw/LkLybXZaMqzrVjwLqO6zdQSOaLsTMeL4ojnriTk9fHjSMGhu3HHy0gxjynVRoddZsVt6miCkgbeNs+o56uhphTrARY9F+2MD9hACZqXtOCsDfQXPHoG3FtASGzIPzyRQ1AHPgSKuAf43/dOQ8K8dpir36V5PcjHep2b35Gl4eM6JfyPLaAM7sy/2723CwJLO4hqLkEsg== 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 (0) X-Received: from BYAPR08CA0015.namprd08.prod.outlook.com (2603:10b6:a03:100::28) by SN7PR12MB7322.namprd12.prod.outlook.com (2603:10b6:806:299::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7202.23; Thu, 18 Jan 2024 06:52:43 +0000 X-Received: from CO1PEPF000044F5.namprd05.prod.outlook.com (2603:10b6:a03:100:cafe::d) by BYAPR08CA0015.outlook.office365.com (2603:10b6:a03:100::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7202.23 via Frontend Transport; Thu, 18 Jan 2024 06:52:43 +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 (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=SATLEXMB03.amd.com; pr=C X-Received: from SATLEXMB03.amd.com (165.204.84.17) by CO1PEPF000044F5.mail.protection.outlook.com (10.167.241.75) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7202.16 via Frontend Transport; Thu, 18 Jan 2024 06:52:42 +0000 X-Received: from SATLEXMB06.amd.com (10.181.40.147) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Thu, 18 Jan 2024 00:52:41 -0600 X-Received: from SATLEXMB03.amd.com (10.181.40.144) by SATLEXMB06.amd.com (10.181.40.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Thu, 18 Jan 2024 00:52:35 -0600 X-Received: from SHA-LX-MINGXZHA.amd.com (10.180.168.240) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server id 15.1.2507.34 via Frontend Transport; Thu, 18 Jan 2024 00:52:34 -0600 From: "duke.zhai via groups.io" To: CC: Eric Xing , Ken Yao , Igniculus Fu , Abner Chang Subject: [edk2-devel] [PATCH 24/33] AMD/VanGoghBoard: Check in FchSpi module. Date: Thu, 18 Jan 2024 14:50:37 +0800 Message-ID: <20240118065046.961-25-duke.zhai@amd.com> In-Reply-To: <20240118065046.961-1-duke.zhai@amd.com> References: <20240118065046.961-1-duke.zhai@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1PEPF000044F5:EE_|SN7PR12MB7322:EE_ X-MS-Office365-Filtering-Correlation-Id: 76730fd8-0f2c-4157-de55-08dc17f211ec X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: rlSvnsSjgUXclNWCypiiIlSoTBYOKVn3gS+4wv+FzoI89xBtWHHysXj13d5K63FT6+OoEXyTRfZvWDzAmfOFmDIrUPOI/6Hc59rAMFROuHjEqFs2JKQs1NR9LEfDsmSXJ4CfGVPQN0pHmEeFMvSHhVKd32XA/LUgCfn8WDRZ/z4g6v8oky1vUOb5jbpURbZZ/Z2lMT9c3M/cTEvHcp1jvgF4Y3RSALMmBM19xJW5AGEWk+ihnan8fCDLJV13Ay72vjoVcXZYF6H86W5JJMNDs9DkkUs2GrV/FSTDFxTr/xoLcFrRp+3y+zD0XQPS9dkKEit0Pdk9eRHmWxMa/AOspnw4g2ULALhvvOyozBN1Q4jJCCHJPH9swYL3MaNCWbETAFCiHuac5UiMaTENREctFrIyAHD6zgQxo8ts3yHgTlXLuVX1vfd3yCjqlELqYtrJGaP8M7qGL+GPmvU9rPHI3BiIJlosEKVWqaLAiW2Xvl8Rxu8lHyG5tvdExv/it7AKq/N4FR7uRtFOMEqcdsIZ5FDOKVM/D5ilShlIXsP9i20V9ggpMgRNZb3p+m8r0opbhi0NIFZHft/2LiDHEyA/NCw+Cf+VuGc3qk72mvuCVPQRju2iuGDQD2lCjxmVBpVYRotToo4PSPpGPkom787J3QJ1T6mBv/YGtfSPJqgsrm2MqQtEHVqulUd6WsR5bOuU7vZBn5aMD9neJWjQgxgNXOc478sFhoTukh1WAdTzp/o7ne4B3MuyqLFiGSopz907+n//yhOQD/EMmSl+2BeHJwWjJnTBDoJ7IOUOtfD0frY= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Jan 2024 06:52:42.2372 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 76730fd8-0f2c-4157-de55-08dc17f211ec 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=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1PEPF000044F5.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7322 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,duke.zhai@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: wG5FON085HvrAdfNb5a6gRYLx7686176AA= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=cJBLprDM; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=none; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}") From: Duke Zhai BZ #:4640 Initial FchSpi module. FCH SPI Common Driver implements the SPI Host Controller Compatibility Interface. Signed-off-by: Duke Zhai Cc: Eric Xing Cc: Ken Yao Cc: Igniculus Fu Cc: Abner Chang --- .../Universal/FchSpi/FchSpiProtect.c | 67 ++ .../Universal/FchSpi/FchSpiProtect.h | 38 + .../Universal/FchSpi/FchSpiRuntimeDxe.c | 172 ++++ .../Universal/FchSpi/FchSpiRuntimeDxe.h | 58 ++ .../Universal/FchSpi/FchSpiRuntimeDxe.inf | 91 ++ .../VanGoghBoard/Universal/FchSpi/FchSpiSmm.c | 121 +++ .../VanGoghBoard/Universal/FchSpi/FchSpiSmm.h | 41 + .../Universal/FchSpi/FchSpiSmm.inf | 101 +++ .../VanGoghBoard/Universal/FchSpi/SpiCommon.c | 799 ++++++++++++++++++ .../VanGoghBoard/Universal/FchSpi/SpiInfo.h | 26 + 10 files changed, 1514 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtec= t.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtec= t.h create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntim= eDxe.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntim= eDxe.h create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntim= eDxe.inf create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.h create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.in= f create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiCommon.c create mode 100644 Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiInfo.h diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.c b/P= latform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.c new file mode 100644 index 0000000000..658d9b063d --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.c @@ -0,0 +1,67 @@ +/** @file + Implements FchSpiProtect.c + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "FchSpiProtect.h" + +/** + + Fch Spi Protect Lock + + @param SpiMmioBase + +**/ +EFI_STATUS +EFIAPI +FchSpiProtect_Lock ( + IN UINTN SpiMmioBase + ) +{ + if (!(MmioRead8 (SpiMmioBase + 2) & 0xC0)) { + // Check BIT7+BIT6 + return EFI_SUCCESS; + } else { + MmioWrite8 (SpiMmioBase + 9, 0x6); // P= refixOpCode WRITE_ENABLE + MmioWrite8 (SpiMmioBase + 2, MmioRead8 (SpiMmioBase + 2) & 0x3F); // C= lear BIT7+BIT6 + if (MmioRead8 (SpiMmioBase + 2) & 0xC0) { + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + +/** + + Fch Spi Protect UnLock + + @param SpiMmioBase + +**/ +EFI_STATUS +EFIAPI +FchSpiProtect_UnLock ( + IN UINTN SpiMmioBase + ) +{ + if ((MmioRead8 (SpiMmioBase + 2) & 0xC0) || (6 !=3D MmioRead8 (SpiMmioBa= se + 9))) { + return EFI_SUCCESS; + } else { + MmioWrite8 (SpiMmioBase + 9, 0x0); + MmioWrite8 (SpiMmioBase + 2, MmioRead8 (SpiMmioBase + 2) | 0xC0); // S= et BIT7+BIT6 + } + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.h b/P= latform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.h new file mode 100644 index 0000000000..e12246d5a3 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiProtect.h @@ -0,0 +1,38 @@ +/** @file + Implements FchSpiProtect.h + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _FCH_SPI_PROTECT_H_ +#define _FCH_SPI_PROTECT_H_ + +/** + + Fch Spi Protect Lock + + @param UINTN SpiMmioBase + +**/ +EFI_STATUS +EFIAPI +FchSpiProtect_Lock ( + IN UINTN SpiMmioBase + ); + +/** + + Fch Spi Protect UnLock + + @param UINTN SpiMmioBase + +**/ +EFI_STATUS +EFIAPI +FchSpiProtect_UnLock ( + IN UINTN SpiMmioBase + ); + +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.c = b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.c new file mode 100644 index 0000000000..f7817838f2 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.c @@ -0,0 +1,172 @@ +/** @file + Implements FchSpiRuntimeDxe.c + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +/** @file +PCH SPI Runtime Driver implements the SPI Host Controller Compatibility In= terface. + +Copyright (c) 2013-2015 Intel Corporation. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifdef _MSC_VER + #pragma optimize( "", off ) +#endif + +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC push_options + #pragma GCC optimize ("O0") + #else + #pragma clang optimize off + #endif +#endif + +#include "FchSpiRuntimeDxe.h" + +extern EFI_GUID gEfiEventVirtualAddressChangeGuid; +CONST BOOLEAN gInSmm =3D FALSE; + +// +// Global variables +// +SPI_INSTANCE *mSpiInstance; + +/** + + Fixup internal data pointers so that the services can be called in virtu= al mode. + + @param Event The event registered. + @param Context Event context. Not used in this event handler. + + @retval None + +**/ +VOID +EFIAPI +FchSpiVirtualddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *)&(mSpiInstance->SpiBa= r)); + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *)&(mSpiInstance->SpiPr= otocol.Init)); + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *)&(mSpiInstance->SpiPr= otocol.Lock)); + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *)&(mSpiInstance->SpiPr= otocol.Execute)); + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *)&(mSpiInstance)); +} + +/** + + Entry point for the SPI host controller driver. + + @param ImageHandle Image handle of this driver. + @param SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @retval EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. + +**/ +EFI_STATUS +EFIAPI +InstallFchSpiRuntimeDxe ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT64 BaseAddress; + UINT64 Length; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor; + UINT64 Attributes; + EFI_EVENT Event; + + DEBUG ((DEBUG_INFO, "InstallFchSpiRuntimeDxe() Start\n")); + + // + // Allocate Runtime memory for the SPI protocol instance. + // + mSpiInstance =3D AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE)); + if (mSpiInstance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the SPI protocol instance + // + Status =3D SpiProtocolConstructor (mSpiInstance); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Install the EFI_SPI_PROTOCOL interface + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &(mSpiInstance->Handle), + &gEfiSpiProtocolGuid, + &(mSpiInstance->SpiProtocol), + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (mSpiInstance); + return EFI_DEVICE_ERROR; + } + + Status =3D mSpiInstance->SpiProtocol.Init (&(mSpiInstance->SpiProtocol))= ; + ASSERT_EFI_ERROR (Status); + + // + // Set Spi space in GCD to be RUNTIME so that the range will be supporte= d in + // virtual address mode in EFI aware OS runtime. + // It will assert if Spi Memory Space is not allocated + // The caller is responsible for the existence and allocation of the Spi= Memory Spaces + // + BaseAddress =3D (EFI_PHYSICAL_ADDRESS)(mSpiInstance->SpiBar); + Length =3D 0x1000; + + Status =3D gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdMemorySpaceDe= scriptor); + ASSERT_EFI_ERROR (Status); + + Attributes =3D GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME; + + Status =3D gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + Attributes + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FchSpiVirtualddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "InstallFchSpiRuntimeDxe() End\n")); + + return EFI_SUCCESS; +} + +#ifdef _MSC_VER + #pragma optimize( "", on ) +#endif +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC pop_options + #endif +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.h = b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.h new file mode 100644 index 0000000000..c63a4b3e31 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.h @@ -0,0 +1,58 @@ +/** @file + Implements FchSpiRuntimeDxe.h + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +/** @file +Header file for the PCH SPI Runtime Driver. + +Copyright (c) 2013-2015 Intel Corporation. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _FCH_SPI_RUNTIME_DXE_H +#define _FCH_SPI_RUNTIME_DXE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define EFI_INTERNAL_POINTER 0x00000004 + +/** + + Fixup internal data pointers so that the services can be called in virtu= al mode. + + @param Event The event registered. + @param Context Event context. Not used in this event handler. + + @retval None + +**/ +VOID +EFIAPI +FchSpiVirtualddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.in= f b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.inf new file mode 100644 index 0000000000..00480ff75e --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiRuntimeDxe.inf @@ -0,0 +1,91 @@ +## @file +# Fch Spi Runtime +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +# This file includes code originally published under the following license= . +## @file +# Component description file for the SPI Runtime driver. +# +# Copyright (c) 2013-2015 Intel Corporation. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile= . +# +##########################################################################= ###### +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FchSpiRuntimeDxe + FILE_GUID =3D B9B0740A-B4E9-46FF-AAC7-C632BAC15834 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InstallFchSpiRuntimeDxe + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +##########################################################################= ###### +# +# Sources Section - list of files that are required for the build to succe= ed. +# +##########################################################################= ###### +[Sources] + FchSpiRuntimeDxe.c + FchSpiRuntimeDxe.h + FchSpiProtect.c + FchSpiProtect.h + SpiCommon.c + +##########################################################################= ###### +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +##########################################################################= ###### +[Packages] + MdePkg/MdePkg.dec + ChachaniBoardPkg/Project.dec + VanGoghCommonPkg/AmdCommonPkg.dec + +##########################################################################= ###### +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +##########################################################################= ###### +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiRuntimeLib + UefiBootServicesTableLib + UefiDriverEntryPoint + TimerLib + DxeServicesTableLib + UefiLib + DebugLib + MemoryAllocationLib + PciExpressLib + SpiFlashDeviceLib + +##########################################################################= ###### +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +##########################################################################= ###### +[Protocols] + gEfiSpiProtocolGuid + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize + +[Depex] + TRUE diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.c b/Platf= orm/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.c new file mode 100644 index 0000000000..683d2251df --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.c @@ -0,0 +1,121 @@ +/** @file + Implements FchSpiSmm.c + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +/** @file + +PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interf= ace. + +Copyright (c) 2013-2015 Intel Corporation. + +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ +#ifdef _MSC_VER + #pragma optimize( "", off ) +#endif + +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC push_options + #pragma GCC optimize ("O0") + #else + #pragma clang optimize off + #endif +#endif + +#include "FchSpiSmm.h" + +CONST BOOLEAN gInSmm =3D TRUE; + +// +// Global variables +// +SPI_INSTANCE *mSpiInstance; + +/** + + Entry point for the SPI host controller driver. + + @param ImageHandle Image handle of this driver. + @param SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @retval EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. + +**/ +EFI_STATUS +EFIAPI +InstallFchSpiSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // VOID *SmmReadyToBootRegistration; + + DEBUG ((DEBUG_INFO, "InstallFchSpiSmm() Start\n")); + + Status =3D gSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + sizeof (SPI_INSTANCE), + (VOID **)&mSpiInstance + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ZeroMem (mSpiInstance, sizeof (SPI_INSTANCE)); + + if (mSpiInstance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the SPI protocol instance + // + Status =3D SpiProtocolConstructor (mSpiInstance); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Install the EFI_SPI_PROTOCOL interface + // + Status =3D gSmst->SmmInstallProtocolInterface ( + &(mSpiInstance->Handle), + &gEfiSmmSpiProtocolGuid, + EFI_NATIVE_INTERFACE, + &(mSpiInstance->SpiProtocol) + ); + if (EFI_ERROR (Status)) { + FreePool (mSpiInstance); + return EFI_DEVICE_ERROR; + } + + Status =3D mSpiInstance->SpiProtocol.Init (&(mSpiInstance->SpiProtocol))= ; + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "InstallFchSpiSmm() End\n")); + + return EFI_SUCCESS; +} + +#ifdef _MSC_VER + #pragma optimize( "", on ) +#endif +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC pop_options + #endif +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.h b/Platf= orm/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.h new file mode 100644 index 0000000000..5ed9f62914 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.h @@ -0,0 +1,41 @@ +/** @file + Implements FchSpiSmm.h + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +/** @file +Header file for the PCH SPI SMM Driver. + +Copyright (c) 2013-2015 Intel Corporation. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _FCH_SPI_SMM_H_ +#define _FCH_SPI_SMM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.inf b/Pla= tform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.inf new file mode 100644 index 0000000000..2288d35b84 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/FchSpiSmm.inf @@ -0,0 +1,101 @@ +## @file +# Spi smm driver +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +# This file includes code originally published under the following license= . +## @file +# Spi smm driver +# +# Component description file for the SPI SMM driver. +# +# Copyright (c) 2013-2015 Intel Corporation. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile= . +# +##########################################################################= ###### +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FchSpiSmm + FILE_GUID =3D 9D63F99F-609D-4EB3-A9D1-5ACE2E25792A + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.1 + PI_SPECIFICATION_VERSION =3D 0x0001000A + ENTRY_POINT =3D InstallFchSpiSmm + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +##########################################################################= ###### +# +# Sources Section - list of files that are required for the build to succe= ed. +# +##########################################################################= ###### +[Sources] + FchSpiSmm.c + FchSpiSmm.h + FchSpiProtect.c + FchSpiProtect.h + SpiCommon.c + +[sources.ia32] + +[sources.x64] +##########################################################################= ###### +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +##########################################################################= ###### +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + VanGoghCommonPkg/AmdCommonPkg.dec + ChachaniBoardPkg/Project.dec + +##########################################################################= ###### +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +##########################################################################= ###### +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + UefiDriverEntryPoint + TimerLib + DxeServicesTableLib + UefiLib + DebugLib + MemoryAllocationLib + PciExpressLib + SmmServicesTableLib + SpiFlashDeviceLib + +##########################################################################= ###### +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +##########################################################################= ###### +[Protocols] + gEfiSmmSpiProtocolGuid + gEfiSmmBase2ProtocolGuid + gEdkiiSmmReadyToBootProtocolGuid + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize + +[Depex] + gEfiSmmBase2ProtocolGuid diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiCommon.c b/Platf= orm/AMD/VanGoghBoard/Universal/FchSpi/SpiCommon.c new file mode 100644 index 0000000000..5be5026655 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiCommon.c @@ -0,0 +1,799 @@ +/** @file + Implements SpiCommon.c + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +/** @file +PCH SPI Common Driver implements the SPI Host Controller Compatibility Int= erface. + +Copyright (c) 2013-2015 Intel Corporation. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifdef _MSC_VER + #pragma optimize( "", off ) +#endif + +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC push_options + #pragma GCC optimize ("O0") + #else + #pragma clang optimize off + #endif +#endif + +#include "FchSpiProtect.h" +#include "SpiInfo.h" +#include +#include +#include +#include +#include +#include +#include + +#define SPI_WREN_INDEX 0 // Prefix Opcode 0: SPI_COMM= AND_WRITE_ENABLE +#define SPI_EWSR_INDEX 1 // Prefix Opcode 1: SPI_COMM= AND_WRITE_S_EN + +#define FCH_SPI_MMIO_REG48_TXBYTECOUNT 0x48 +#define FCH_SPI_MMIO_REG4B_RXBYTECOUNT 0x4B +#define FCH_SPI_MMIO_REG80_FIFO 0x80 +#define FCH_SPI_MMIO_REG50_ADDR32CTRL0 0x50 +#define FCH_SPI_MMIO_REG5C_ADDR32CTRL3 0x5C + +volatile UINTN mFchSpiProtect_LOCKED_ReadyToBoot =3D FALSE; +volatile UINTN mSpiMmioBase; +extern CONST BOOLEAN gInSmm; +volatile BOOLEAN mSupport4ByteAddrFlag =3D FALSE; + +STATIC +EFI_STATUS +WaitForSpiDeviceWriteEnabled ( + IN EFI_SPI_PROTOCOL *This + ); + +/** + + Initialize an SPI protocol instance. + The function will assert in debug if FCH SPI has not been initialized + + @param SpiInstance - Pointer to SpiInstance to initialize + + @retval EFI_SUCCESS The protocol instance was properly initialized + @retval EFI_UNSUPPORTED The FCH is not supported by this module + +**/ +EFI_STATUS +SpiProtocolConstructor ( + SPI_INSTANCE *SpiInstance + ) +{ + DEBUG ((DEBUG_INFO, "SpiProtocolConstructor enter!\n")); + + SpiInstance->InitDone =3D FALSE; // Indicate NOT READY. + // + // Initialize the SPI protocol instance + // + SpiInstance->Signature =3D FCH_SPI_PRIVATE_DATA_SIGNATURE; + SpiInstance->Handle =3D NULL; + SpiInstance->SpiProtocol.Init =3D SpiProtocolInit; + SpiInstance->SpiProtocol.Lock =3D SpiProtocolLock; + SpiInstance->SpiProtocol.Execute =3D SpiProtocolExecute; + + // + // Sanity check to ensure FCH SPI initialization has occurred previously= . + // + SpiInstance->SpiBar =3D (EFI_PHYSICAL_ADDRESS)PciRead32 ( + PCI_LIB_ADDRESS ( + 0, + 20, + 3, + 0xA0 + ) + )&0x00000000FFFFFFE0; + ASSERT (SpiInstance->SpiBar !=3D 0); + mSpiMmioBase =3D SpiInstance->SpiBar; + + DEBUG ((DEBUG_VERBOSE, "SpiInstance->SpiBar =3D 0x%x\n", SpiInstance->Sp= iBar)); + return EFI_SUCCESS; +} + +/** + + Initialize the host controller to execute SPI command. + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + + @retval EFI_SUCCESS Initialization completed. + @retval EFI_ACCESS_DENIED The SPI static configuration interface h= as been locked-down. + @retval EFI_INVALID_PARAMETER Bad input parameters. + @retval EFI_UNSUPPORTED Can't get Descriptor mode VSCC values + +**/ +EFI_STATUS +EFIAPI +SpiProtocolInit ( + IN EFI_SPI_PROTOCOL *This + ) +{ + EFI_STATUS Status; + SPI_INSTANCE *SpiInstance; + UINT8 FlashPartId[3]; + UINT8 FlashIndex; + + DEBUG ((DEBUG_INFO, "SpiProtocolInit enter!\n")); + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + CopyMem (&SpiInstance->SpiInitTable, &mSpiInitTable[0], sizeof (SPI_INIT= _TABLE)); + + Status =3D SpiProtocolExecute ( + This, + SPI_OPCODE_JEDEC_ID_INDEX, + 0, + TRUE, + TRUE, + FALSE, + (UINTN)0, + 3, + FlashPartId, + EnumSpiRegionDescriptor + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (FlashIndex =3D 0; FlashIndex < mNumSpiFlashMax; FlashIndex++) { + CopyMem (&SpiInstance->SpiInitTable, &mSpiInitTable[FlashIndex], sizeo= f (SPI_INIT_TABLE)); + + if ((FlashPartId[0] !=3D SpiInstance->SpiInitTable.VendorId) || + (FlashPartId[1] !=3D SpiInstance->SpiInitTable.DeviceId0) || + (FlashPartId[2] !=3D SpiInstance->SpiInitTable.DeviceId1)) + { + DEBUG (( + DEBUG_INFO, + "SpiProtocolInit() Target SPI Flash Device [VendorID 0x%02x, Dev= iceID 0x%02x%02x] ", + FlashPartId[0], + FlashPartId[1], + FlashPartId[2] + )); + DEBUG (( + DEBUG_INFO, + "but Current SPI Flash device [VendorId 0x%02x, DeviceID 0x%02x%02= x]!\n", + SpiInstance->SpiInitTable.VendorId, + SpiInstance->SpiInitTable.DeviceId0, + SpiInstance->SpiInitTable.DeviceId1 + ) + ); + } else { + DEBUG (( + DEBUG_INFO, + "Smm Mode: Supported SPI Flash device found, Vendor Id: 0x%02x, De= vice ID: 0x%02x%02x!\n", + FlashPartId[0], + FlashPartId[1], + FlashPartId[2] + )); + break; + } + } + + if (FlashIndex >=3D mNumSpiFlashMax) { + Status =3D EFI_UNSUPPORTED; + DEBUG (( + DEBUG_ERROR, + "ERROR - Unknown SPI Flash Device, Vendor Id: 0x%02x, Device ID: 0x%= 02x%02x!\n", + FlashPartId[0], + FlashPartId[1], + FlashPartId[2] + )); + ASSERT_EFI_ERROR (Status); + } + + SpiInstance->InitDone =3D TRUE; + + return EFI_SUCCESS; +} + +/** + + Lock the SPI Static Configuration Interface. + Once locked, the interface can not be changed and can only be clear by s= ystem reset. + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + + @retval EFI_SUCCESS Lock operation succeed. + @retval EFI_DEVICE_ERROR Device error, operation failed. + @retval EFI_ACCESS_DENIED The interface has already been locked. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolLock ( + IN EFI_SPI_PROTOCOL *This + ) +{ + if (gInSmm) { + // Trigger FCH SPI Protect/Lock + if (EFI_SUCCESS =3D=3D FchSpiProtect_Lock (mSpiMmioBase)) { + mFchSpiProtect_LOCKED_ReadyToBoot =3D TRUE; + DEBUG ((DEBUG_INFO, "Set FchSpiProtect to LOCK SUCCESS! \n")); + } else { + DEBUG ((DEBUG_INFO, "Set FchSpiProtect to LOCK FAILED!!! \n")); + } + } + + return EFI_SUCCESS; +} + +/** + + Execute SPI commands from the host controller. + This function would be called by runtime driver, please do not use any M= MIO marco here + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + @param OpcodeIndex Index of the command in the OpCode Menu. + @param PrefixOpcodeIndex Index of the first command to run when in an at= omic cycle sequence. + @param DataCycle TRUE if the SPI cycle contains data + @param Atomic TRUE if the SPI cycle is atomic and interleave = cycles are not allowed. + @param ShiftOut If DataByteCount is not zero, TRUE to shift dat= a out and FALSE to shift data in. + @param Address In Descriptor Mode, for Descriptor Region, GbE = Region, ME Region and Platform + Region, this value specifies the offset from the Regio= n Base; for BIOS Region, + this value specifies the offset from the start of the = BIOS Image. In Non + Descriptor Mode, this value specifies the offset from = the start of the BIOS Image. + Please note BIOS Image size may be smaller than BIOS R= egion size (in Descriptor + Mode) or the flash size (in Non Descriptor Mode), and = in this case, BIOS Image is + supposed to be placed at the top end of the BIOS Regio= n (in Descriptor Mode) or + the flash (in Non Descriptor Mode) + @param DataByteCount Number of bytes in the data portion of the SPI = cycle. This function may break the + data transfer into multiple operations. This function = ensures each operation does + not cross 256 byte flash address boundary. + *NOTE: if there is some SPI chip that has a stricter a= ddress boundary requirement + (e.g., its write page size is < 256 byte), then the ca= ller cannot rely on this + function to cut the data transfer at proper address bo= undaries, and it's the + caller's reponsibility to pass in a properly cut DataB= yteCount parameter. + @param Buffer Pointer to caller-allocated buffer containing t= he dada received or sent during the + SPI cycle. + @param SpiRegionType SPI Region type. Values EnumSpiRegionBios, Enum= SpiRegionGbE, EnumSpiRegionMe, + EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData= are only applicable in + Descriptor mode. Value EnumSpiRegionAll is applicable = to both Descriptor Mode + and Non Descriptor Mode, which indicates "SpiRegionOff= set" is actually relative + to base of the 1st flash device (i.e., it is a Flash L= inear Address). + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_UNSUPPORTED Command not supported. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolExecute ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 OpcodeIndex, + IN UINT8 PrefixOpcodeIndex, + IN BOOLEAN DataCycle, + IN BOOLEAN Atomic, + IN BOOLEAN ShiftOut, + IN UINTN Address, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer, + IN SPI_REGION_TYPE SpiRegionType + ) +{ + EFI_STATUS Status; + UINT8 SpiStatus; + + // + // Check if the parameters are valid. + // + if ((OpcodeIndex >=3D SPI_NUM_OPCODE) || (PrefixOpcodeIndex >=3D SPI_NUM= _PREFIX_OPCODE)) { + return EFI_INVALID_PARAMETER; + } + + if (gInSmm) { + if (mFchSpiProtect_LOCKED_ReadyToBoot) { + FchSpiProtect_UnLock (mSpiMmioBase); + DEBUG ((DEBUG_INFO, "FchSpiProtect UnLock!\n")); + } + } + + SendSpiCmd ( + This, + SPI_OPCODE_READ_S_INDEX, + 0, + TRUE, + FALSE, + FALSE, + 0, + 1, + &SpiStatus, + EnumSpiRegionAll + ); + if ((SpiStatus & 1) !=3D 0) { + if ((OpcodeIndex =3D=3D SPI_OPCODE_ERASE_INDEX) && (ShiftOut =3D=3D FA= LSE)) { + return EFI_ALREADY_STARTED; + } + + DEBUG ((DEBUG_INFO, "SPI Busy, WaitForSpiCycleComplete\n")); + WaitForSpiCycleComplete (This); + } + + // + // Enter 4 bytes address + // + if (MmioRead8 (mSpiMmioBase+FCH_SPI_MMIO_REG50_ADDR32CTRL0) & BIT0) { + DEBUG ((DEBUG_INFO, "Enter 4-Byte address mode\n")); + mSupport4ByteAddrFlag =3D TRUE; + Status =3D SendSpiCmd ( + This, + SPI_COMMAND_Enter_4Byte_Addr_INDEX, + SPI_WREN_INDEX, + FALSE, + TRUE, + FALSE, + 0, + 0, + NULL, + EnumSpiRegionDescriptor + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Enter 4-Byte address mode fail\n")); + goto Exit; + } + } + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + OpcodeIndex, + PrefixOpcodeIndex, + DataCycle, + Atomic, + ShiftOut, + Address, + DataByteCount, + Buffer, + SpiRegionType + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Operate SPI Flash fail\n")); + goto Exit; + } + + // + // Exit 32-bit address + // + if (mSupport4ByteAddrFlag) { + mSupport4ByteAddrFlag =3D FALSE; + Status =3D SendSpiCmd ( + This, + SPI_COMMAND_Exit_4Byte_Addr_INDEX, + SPI_WREN_INDEX, + FALSE, + TRUE, + FALSE, + 0, + 0, + NULL, + EnumSpiRegionDescriptor + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Exit 4-Byte address mode fail\n")); + goto Exit; + } + } + +Exit: + if (gInSmm) { + if (mFchSpiProtect_LOCKED_ReadyToBoot) { + FchSpiProtect_Lock (mSpiMmioBase); + DEBUG ((DEBUG_INFO, "FchSpiProtect Lock again!\n")); + } + } + + return Status; +} + +/** + + Waits for SPI device not busy + + @param SpiBar The SPI Bar Address + + @retval EFI_SUCCESS Function successfully returned + @retval EFI_TIMEOUT timeout, SPI device busy more than 6s. + +**/ +EFI_STATUS +FchSpiControllerNotBusy ( + UINTN SpiBar + ) +{ + volatile UINT32 SpiStatus; + UINT64 WaitTicks; + UINT64 WaitCount; + + // + // Convert the wait period allowed into to tick count + // + WaitCount =3D WAIT_TIME / WAIT_PERIOD; + // + // Wait until SPI Conroller Not Busy + // + for (WaitTicks =3D 0; WaitTicks < WaitCount; WaitTicks++) { + SpiStatus =3D MmioRead32 (SpiBar + FCH_SPI_MMIO_REG4C); + if (SpiStatus & FCH_SPI_BUSY) { + MicroSecondDelay (WAIT_PERIOD); + } else { + return EFI_SUCCESS; + } + } + + return EFI_TIMEOUT; +} + +STATIC +EFI_STATUS +ResetFifoIndex ( + SPI_INSTANCE *SpiInstance + ) +{ + return EFI_SUCCESS; +} + +/** + + This function sends the programmed SPI command to the slave device. + + @param OpcodeIndex Index of the command in the OpCode Menu. + @param PrefixOpcodeIndex Index of the first command to run when in an at= omic cycle sequence. + @param DataCycle TRUE if the SPI cycle contains data + @param Atomic TRUE if the SPI cycle is atomic and interleave = cycles are not allowed. + @param ShiftOut If DataByteCount is not zero, TRUE to shift dat= a out and FALSE to shift data in. + @param Address In Descriptor Mode, for Descriptor Region, GbE = Region, ME Region and Platform + Region, this value specifies the offset from th= e Region Base; for BIOS Region, + this value specifies the offset from the start = of the BIOS Image. In Non + Descriptor Mode, this value specifies the offse= t from the start of the BIOS Image. + Please note BIOS Image size may be smaller than= BIOS Region size (in Descriptor + Mode) or the flash size (in Non Descriptor Mode= ), and in this case, BIOS Image is + supposed to be placed at the top end of the BIO= S Region (in Descriptor Mode) or + the flash (in Non Descriptor Mode) + @param DataByteCount Number of bytes in the data portion of the SPI = cycle. This function may break the + data transfer into multiple operations. This fu= nction ensures each operation does + not cross 256 byte flash address boundary. + *NOTE: if there is some SPI chip that has a str= icter address boundary requirement + (e.g., its write page size is < 256 byte), then= the caller cannot rely on this + function to cut the data transfer at proper add= ress boundaries, and it's the + caller's reponsibility to pass in a properly cu= t DataByteCount parameter. + @param Buffer Data received or sent during the SPI cycle. + @param SpiRegionType SPI Region type. Values EnumSpiRegionBios, Enum= SpiRegionGbE, EnumSpiRegionMe, + EnumSpiRegionDescriptor, and EnumSpiRegionPlatf= ormData are only applicable in + Descriptor mode. Value EnumSpiRegionAll is appl= icable to both Descriptor Mode + and Non Descriptor Mode, which indicates "SpiRe= gionOffset" is actually relative + to base of the 1st flash device (i.e., it is a = Flash Linear Address). + + @retval EFI_SUCCESS SPI command completes successfully. + @retval EFI_DEVICE_ERROR Device error, the command aborts abnorma= lly. + @retval EFI_ACCESS_DENIED Some unrecognized command encountered in= hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + +**/ +EFI_STATUS +SendSpiCmd ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 OpcodeIndex, + IN UINT8 PrefixOpcodeIndex, + IN BOOLEAN DataCycle, + IN BOOLEAN Atomic, + IN BOOLEAN ShiftOut, + IN UINTN Address, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer, + IN SPI_REGION_TYPE SpiRegionType + ) +{ + SPI_INSTANCE *SpiInstance; + UINTN SpiBiosSize; + UINT32 SpiDataCount; + UINT32 TxByteCount; + UINT32 RxByteCount; + UINTN Addr, Retry; + INTN Index, CountIndex; + UINTN SpiBar; + BOOLEAN WriteFlag; + BOOLEAN AddressFlag; + UINT8 PrefixOpcode; + SPI_OPCODE_MENU_ENTRY OPCodeMenu; + UINT8 Dummy; + UINT8 AddressByteNum; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + SpiBiosSize =3D SpiInstance->SpiInitTable.BiosSize; + OPCodeMenu =3D SpiInstance->SpiInitTable.OpcodeMenu[OpcodeIndex]; + PrefixOpcode =3D SpiInstance->SpiInitTable.PrefixOpcode[PrefixOpcodeIn= dex]; + SpiBar =3D SpiInstance->SpiBar; + Dummy =3D 0; + AddressByteNum =3D 3; + + AddressFlag =3D (OPCodeMenu.Type =3D=3D EnumSpiOpcodeWrite); + WriteFlag =3D AddressFlag; + AddressFlag |=3D (OPCodeMenu.Type =3D=3D EnumSpiOpcodeRead); + WriteFlag |=3D (OPCodeMenu.Type =3D=3D EnumSpiOpcodeWriteNoAddr); + + // + // Check if the value of opcode register is 0 or the BIOS Size of SpiIni= tTable is 0 + // + if (SpiBiosSize =3D=3D 0) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + if ((DataCycle =3D=3D FALSE) && (DataByteCount > 0)) { + DataByteCount =3D 0; + } + + do { + SpiDataCount =3D DataByteCount; + TxByteCount =3D 0; + RxByteCount =3D 0; + + // + // Calculate the number of bytes to shift in/out during the SPI data c= ycle. + // Valid settings for the number of bytes duing each data portion of t= he + // FCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, = 56, 64 + // + if ((Address & 0xFF) =3D=3D 0) { + SpiDataCount =3D (DataByteCount > 0x100) ? 0x100 : DataByteCount; + } else { + SpiDataCount =3D (DataByteCount > ((~Address + 1) & 0xFF)) ? ((~Addr= ess + 1) & 0xFF) : DataByteCount; + } + + SpiDataCount =3D (SpiDataCount > 64) ? 64 : SpiDataCount; + + if (Atomic) { + Retry =3D 0; + do { + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG45, PrefixOpcode); + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG48_TXBYTECOUNT, 0); + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG4B_RXBYTECOUNT, 0); + MmioOr8 (SpiBar + FCH_SPI_MMIO_REG47, FCH_SPI_EXEC_OPCODE); + if (EFI_ERROR (FchSpiControllerNotBusy (SpiBar))) { + return EFI_DEVICE_ERROR; + } + + if (PrefixOpcodeIndex =3D=3D SPI_WREN_INDEX) { + if (WaitForSpiDeviceWriteEnabled (This) =3D=3D EFI_SUCCESS) { + Retry =3D 0; + } else { + Retry++; + if (Retry >=3D 3) { + return EFI_DEVICE_ERROR; + } + } + } + } while (Retry); + } + + Index =3D 0; + // + // Check Address Mode + // + if (AddressFlag) { + ResetFifoIndex (SpiInstance); + Addr =3D (UINTN)Address; + // if not SPI_COMMAND_READ_SFDP and 32bit address + if ((OPCodeMenu.Code !=3D SPI_COMMAND_READ_SFDP) && mSupport4ByteAdd= rFlag) { + AddressByteNum =3D 4; + Addr =3D Addr | (UINT32)((MmioRead8 (SpiBar+FCH_SPI_MMIO= _REG5C_ADDR32CTRL3) & BIT0) << 24); + } + + for (CountIndex =3D 0; CountIndex < AddressByteNum; CountIndex++) { + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG80_FIFO + Index, (UINT8)((Add= r >> (AddressByteNum - CountIndex - 1) * 8) & 0xff)); + Index++; + } + + TxByteCount +=3D AddressByteNum; + } + + if ((OPCodeMenu.Code =3D=3D SPI_COMMAND_READ_SFDP) || (OPCodeMenu.Code= =3D=3D SPI_COMMAND_RPMC_OP2)) { + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG80_FIFO + Index, Dummy); + Index++; + TxByteCount +=3D 1; + } + + if (DataCycle) { + // + // Check Read/Write Mode + // + if (WriteFlag) { + TxByteCount +=3D SpiDataCount; + for (CountIndex =3D 0; CountIndex < (INTN)(SpiDataCount); CountInd= ex++) { + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG80_FIFO + Index, Buffer[Cou= ntIndex]); + Index++; + } + } else { + RxByteCount =3D SpiDataCount; + } + } + + // Set SPI Command + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG45, OPCodeMenu.Code); + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG48_TXBYTECOUNT, (UINT8)TxByteCoun= t); + MmioWrite8 (SpiBar + FCH_SPI_MMIO_REG4B_RXBYTECOUNT, (UINT8)RxByteCoun= t); + MmioOr8 (SpiBar + FCH_SPI_MMIO_REG47, FCH_SPI_EXEC_OPCODE); + if (EFI_ERROR (FchSpiControllerNotBusy (SpiBar))) { + return EFI_DEVICE_ERROR; + } + + if (ShiftOut) { + Retry =3D 0; + do { + if (WaitForSpiCycleComplete (This)) { + Retry =3D 0; + } else { + Retry++; + if (Retry >=3D FCH_SPI_RETRY_TIMES) { + return EFI_DEVICE_ERROR; + } + } + } while (Retry); + } + + if (DataCycle && RxByteCount) { + // + // Reset Fifo Ptr + // + ResetFifoIndex (SpiInstance); + + for (CountIndex =3D 0; CountIndex < (INTN)(SpiDataCount); CountIndex= ++) { + Buffer[CountIndex] =3D MmioRead8 (SpiBar + FCH_SPI_MMIO_REG80_FIFO= + Index); + Index++; + } + } + + // + // If shifts data in, get data from the SPI data buffer. + // + Address +=3D SpiDataCount; + Buffer +=3D SpiDataCount; + DataByteCount -=3D SpiDataCount; + } while (DataByteCount > 0); + + return EFI_SUCCESS; +} + +/** + + Wait execution cycle to complete on the SPI interface. Check both Hardwa= re + and Software Sequencing status registers + + @param This The SPI protocol instance + + @retval TRUE SPI cycle completed on the interface. + @retval FALSE Time out while waiting the SPI cycle to complete. + It's not safe to program the next command on the SPI interfac= e. + +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN EFI_SPI_PROTOCOL *This + ) +{ + UINT8 SpiStatus; + UINT64 WaitTicks; + UINT64 WaitCount; + + // + // Convert the wait period allowed into to tick count + // + WaitCount =3D WAIT_TIME / WAIT_PERIOD; + + // + // Wait for the SPI cycle to complete. + // + for (WaitTicks =3D 0; WaitTicks < WaitCount; WaitTicks++) { + // + // Execute Read Status Command + // + SendSpiCmd ( + This, + SPI_OPCODE_READ_S_INDEX, + 0, + TRUE, + FALSE, + FALSE, + 0, + 1, + &SpiStatus, + EnumSpiRegionAll + ); + + if ((SpiStatus & 1) !=3D 0) { + MicroSecondDelay (WAIT_PERIOD); + } else { + return TRUE; + } + } + + DEBUG ((DEBUG_VERBOSE, "WaitForSpiCycleComplete() Timeout\n")); + return FALSE; +} + +/** + + Wait execution cycle to complete on the SPI interface. Check both Hardwa= re + and Software Sequencing status registers + + @param This The SPI protocol instance + + @retval EFI_SUCCESS SPI cycle completed on the interface. + @retval EFI_TIMEOUT Time out while waiting the SPI cycle to complete. + It's not safe to program the next command on the SPI interfac= e. + +**/ +STATIC +EFI_STATUS +WaitForSpiDeviceWriteEnabled ( + IN EFI_SPI_PROTOCOL *This + ) +{ + UINT8 SpiStatus; + UINT64 WaitTicks; + UINT64 WaitCount; + + DEBUG ((DEBUG_VERBOSE, "WaitForSpiDeviceWriteEnabled() Enter!\n")); + + // + // Convert the wait period allowed into to tick count + // + WaitCount =3D WAIT_TIME / WAIT_PERIOD; + + // + // Wait for the SPI cycle to complete. + // + for (WaitTicks =3D 0; WaitTicks < WaitCount; WaitTicks++) { + // + // Execute Read Status Command + // + SendSpiCmd ( + This, + SPI_OPCODE_READ_S_INDEX, + 0, + TRUE, + FALSE, + FALSE, + 0, + 1, + &SpiStatus, + EnumSpiRegionAll + ); + + if ((SpiStatus & 2) =3D=3D 0) { + MicroSecondDelay (WAIT_PERIOD); + } else { + DEBUG ((DEBUG_VERBOSE, "WaitForSpiCycleComplete() Exit\n")); + return EFI_SUCCESS; + } + } + + DEBUG ((DEBUG_VERBOSE, "WaitForSpiDeviceWriteEnabled() Exit Timeout !\n"= )); + return EFI_TIMEOUT; +} + +#ifdef _MSC_VER + #pragma optimize( "", on ) +#endif +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC pop_options + #endif +#endif diff --git a/Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiInfo.h b/Platfor= m/AMD/VanGoghBoard/Universal/FchSpi/SpiInfo.h new file mode 100644 index 0000000000..fd51b71c83 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Universal/FchSpi/SpiInfo.h @@ -0,0 +1,26 @@ +/** @file + Implements SpiInfo.h + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/* This file includes code originally published under the following licens= e. */ + +#ifndef _SPI_INFO_H_ +#define _SPI_INFO_H_ + +#include +#include + +#ifdef FCH_SPI_EXEC_OPCODE + #undef FCH_SPI_EXEC_OPCODE +#define FCH_SPI_EXEC_OPCODE BIT7 +#endif + +#define FCH_SPI_MMIO_REG45 0x45 // OpCode Access +#define FCH_SPI_MMIO_REG47 0x47 // Execute Access +#define FCH_SPI_MMIO_REG4C 0x4C // SPI Status + +#endif -- 2.31.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 (#114073): https://edk2.groups.io/g/devel/message/114073 Mute This Topic: https://groups.io/mt/103831196/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-