Reviewed-by: Chao Li <lichao@loongson.cn>
Add pflash driver for loongarch. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Bibo Mao <maobibo@loongson.cn> Cc: Chao Li <lichao@loongson.cn> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: xianglai li <lixianglai@loongson.cn> --- .../Library/NorFlashQemuLib/NorFlashQemuLib.c | 141 ++++++++++++++++++ .../NorFlashQemuLib/NorFlashQemuLib.inf | 43 ++++++ 2 files changed, 184 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c new file mode 100644 index 0000000000..2e0bf3cef0 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c @@ -0,0 +1,141 @@ +/** @file + + Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/VirtNorFlashPlatformLib.h> + +#include <Protocol/FdtClient.h> + +#define QEMU_NOR_BLOCK_SIZE SIZE_128KB + +EFI_STATUS +VirtNorFlashPlatformInitialization ( + VOID + ) +{ + return EFI_SUCCESS; +} + +STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices; + +EFI_STATUS +VirtNorFlashPlatformGetDevices ( + OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions, + OUT UINT32 *Count + ) +{ + FDT_CLIENT_PROTOCOL *FdtClient; + INT32 Node; + EFI_STATUS Status; + EFI_STATUS FindNodeStatus; + CONST UINT32 *Reg; + UINT32 PropSize; + UINT64 Base; + UINT64 Size; + + Status = gBS->LocateProtocol ( + &gFdtClientProtocolGuid, + NULL, + (VOID **)&FdtClient + ); + ASSERT_EFI_ERROR (Status); + + FindNodeStatus = FdtClient->FindCompatibleNode ( + FdtClient, + "cfi-flash", + &Node + ); + ASSERT_EFI_ERROR (FindNodeStatus); + + Status = FdtClient->GetNodeProperty ( + FdtClient, + Node, + "reg", + (CONST VOID **)&Reg, + &PropSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: GetNodeProperty () failed (Status == %r)\n", + __FUNCTION__, + Status + )); + return Status; + } + + ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0); + + if (PropSize < (4 * sizeof (UINT32))) { + DEBUG (( + DEBUG_ERROR, + "%a: reg node size(%d) is too small \n", + __FUNCTION__, + PropSize + )); + return EFI_NOT_FOUND; + } + + Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0])); + Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2])); + + mNorFlashDevices.DeviceBaseAddress = (UINTN)Base; + mNorFlashDevices.RegionBaseAddress = (UINTN)Base; + mNorFlashDevices.Size = (UINTN)Size; + mNorFlashDevices.BlockSize = QEMU_NOR_BLOCK_SIZE; + + Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base); + ASSERT_EFI_ERROR (Status); + + /* + * Base is the value of PcdFlashNvStorageVariableBase, + * PcdFlashNvStorageFtwWorkingBase can be got by + * PcdFlashNvStorageVariableBase + PcdFlashNvStorageVariableSize + */ + Base += PcdGet32 (PcdFlashNvStorageVariableSize); + Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, Base); + ASSERT_EFI_ERROR (Status); + + /* + * Now,Base is the value of PcdFlashNvStorageFtwWorkingBase, + * PcdFlashNvStorageFtwSpareBase can be got by + * PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize. + */ + Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize); + Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base); + ASSERT_EFI_ERROR (Status); + + // + // UEFI takes ownership of the NOR flash, and exposes its functionality + // through the UEFI Runtime Services GetVariable, SetVariable, etc. This + // means we need to disable it in the device tree to prevent the OS from + // attaching its device driver as well. + // Note that this also hides other flash banks, but the only other flash + // bank we expect to encounter is the one that carries the UEFI executable + // code, which is not intended to be guest updatable, and is usually backed + // in a readonly manner by QEMU anyway. + // + Status = FdtClient->SetNodeProperty ( + FdtClient, + Node, + "status", + "disabled", + sizeof ("disabled") + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 'disabled'\n")); + } + + *NorFlashDescriptions = &mNorFlashDevices; + *Count = 1; + + return EFI_SUCCESS; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf new file mode 100644 index 0000000000..da05ca0898 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf @@ -0,0 +1,43 @@ +## @file +# +# Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = NorFlashQemuLib + FILE_GUID = 339B7829-4C5F-4EFC-B2DD-5050E530DECE + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = VirtNorFlashPlatformLib + +[Sources.common] + NorFlashQemuLib.c + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + OvmfPkg/OvmfPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Depex] + gFdtClientProtocolGuid + +[Pcd] +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase