From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.8937.1589448752760124432 for ; Thu, 14 May 2020 02:32:32 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: ard.biesheuvel@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5F24531B; Thu, 14 May 2020 02:32:32 -0700 (PDT) Received: from [192.168.1.81] (unknown [10.37.8.255]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 333133F71E; Thu, 14 May 2020 02:32:28 -0700 (PDT) Subject: Re: [PATCH v1 08/11] ArmVirtPkg: Add Kvmtool NOR flash lib To: Sami Mujawar , devel@edk2.groups.io Cc: leif@nuviainc.com, lersek@redhat.com, Alexandru.Elisei@arm.com, Andre.Przywara@arm.com, Matteo.Carlini@arm.com, Laura.Moretta@arm.com, nd@arm.com References: <20200514084019.71368-1-sami.mujawar@arm.com> <20200514084019.71368-9-sami.mujawar@arm.com> From: "Ard Biesheuvel" Message-ID: Date: Thu, 14 May 2020 11:32:26 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20200514084019.71368-9-sami.mujawar@arm.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit On 5/14/20 10:40 AM, Sami Mujawar wrote: > Kvmtool places the base address of the CFI flash in > the device tree it passes to UEFI. This library > parses the kvmtool device tree to read the CFI base > address and initialise the PCDs use by the NOR flash > driver and the variable storage. > > Signed-off-by: Sami Mujawar > --- > ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtool.c | 265 ++++++++++++++++++++ > ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf | 50 ++++ > 2 files changed, 315 insertions(+) > > diff --git a/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtool.c b/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtool.c > new file mode 100644 > index 0000000000000000000000000000000000000000..2e43c2e21bc9ef7dd1dd198eebbd70c3b0b96d1c > --- /dev/null > +++ b/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtool.c > @@ -0,0 +1,265 @@ > +/** @file > + An instance of the NorFlashPlatformLib for Kvmtool platform. > + > + Copyright (c) 2020, ARM Ltd. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + **/ > + > +#include > +#include > +#include > +#include > +#include > + > +/** Macro defining the maximum number of Flash Banks. > + */ > +#define MAX_FLASH_BANKS 4 > + > +STATIC NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS]; > +STATIC UINTN mNorFlashDeviceCount = 0; > + > +/** This function performs platform specific actions to initialise > + the NOR flash, if required. > + > + @retval EFI_SUCCESS Success. > +**/ > +EFI_STATUS > +NorFlashPlatformInitialization ( > + VOID > + ) > +{ > + DEBUG ((DEBUG_INFO, "NorFlashPlatformInitialization\n")); > + // Nothing to do here > + return EFI_SUCCESS; > +} > + > +/** Initialise Non volatile Flash storage variables. > + > + @param [in] FlashDevice Pointer to the NOR Flash device. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_OUT_OF_RESOURCES Insufficient flash storage space. > +**/ > +EFI_STATUS > +SetupVariableStore ( > + IN NOR_FLASH_DESCRIPTION * FlashDevice > + ) > +{ > + UINTN FlashRegion; > + UINTN FlashNvStorageVariableBase; > + UINTN FlashNvStorageFtwWorkingBase; > + UINTN FlashNvStorageFtwSpareBase; > + UINTN FlashNvStorageVariableSize; > + UINTN FlashNvStorageFtwWorkingSize; > + UINTN FlashNvStorageFtwSpareSize; > + > + FlashNvStorageVariableSize = PcdGet32 (PcdFlashNvStorageVariableSize); > + FlashNvStorageFtwWorkingSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize); > + FlashNvStorageFtwSpareSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize); > + > + if ((FlashNvStorageVariableSize == 0) || > + (FlashNvStorageFtwWorkingSize == 0) || > + (FlashNvStorageFtwSpareSize == 0)) { > + DEBUG ((DEBUG_ERROR, "FlashNvStorage size not defined\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + // Setup the variable store > + FlashRegion = FlashDevice->DeviceBaseAddress; > + > + FlashNvStorageVariableBase = FlashRegion; > + FlashRegion += PcdGet32 (PcdFlashNvStorageVariableSize); > + > + FlashNvStorageFtwWorkingBase = FlashRegion; > + FlashRegion += PcdGet32 (PcdFlashNvStorageFtwWorkingSize); > + > + FlashNvStorageFtwSpareBase = FlashRegion; > + FlashRegion += PcdGet32 (PcdFlashNvStorageFtwSpareSize); > + > + if (FlashRegion > (FlashDevice->DeviceBaseAddress + FlashDevice->Size)) { > + DEBUG ((DEBUG_ERROR, "Insufficient flash storage size\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + PcdSet32S ( > + PcdFlashNvStorageVariableBase, > + FlashNvStorageVariableBase > + ); > + > + PcdSet32S ( > + PcdFlashNvStorageFtwWorkingBase, > + FlashNvStorageFtwWorkingBase > + ); > + > + PcdSet32S ( > + PcdFlashNvStorageFtwSpareBase, > + FlashNvStorageFtwSpareBase > + ); > + > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageVariableBase = 0x%x\n", > + FlashNvStorageVariableBase > + )); > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageVariableSize = 0x%x\n", > + FlashNvStorageVariableSize > + )); > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageFtwWorkingBase = 0x%x\n", > + FlashNvStorageFtwWorkingBase > + )); > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageFtwWorkingSize = 0x%x\n", > + FlashNvStorageFtwWorkingSize > + )); > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageFtwSpareBase = 0x%x\n", > + FlashNvStorageFtwSpareBase > + )); > + DEBUG (( > + DEBUG_INFO, > + "PcdFlashNvStorageFtwSpareSize = 0x%x\n", > + FlashNvStorageFtwSpareSize > + )); > + > + return EFI_SUCCESS; > +} > + > +/** Return the Flash devices on the platform. > + > + @param [out] NorFlashDescriptions Pointer to the Flash device description. > + @param [out] Count Number of Flash devices. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_NOT_FOUND Flash device not found. > +**/ > +EFI_STATUS > +NorFlashPlatformGetDevices ( > + OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions, > + OUT UINT32 *Count > + ) > +{ > + if (mNorFlashDeviceCount > 0) { > + *NorFlashDescriptions = mNorFlashDevices; > + *Count = mNorFlashDeviceCount; > + return EFI_SUCCESS; > + } > + return EFI_NOT_FOUND; > +} > + > +/** Entrypoint for NorFlashPlatformLib. > + > + @param [in] ImageHandle The handle to the image. > + @param [in] SystemTable Pointer to the System Table. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND Flash device not found. > +**/ > +EFI_STATUS > +EFIAPI > +NorFlashPlatformLibConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * SystemTable > + ) > +{ > + FDT_CLIENT_PROTOCOL *FdtClient; > + INT32 Node; > + EFI_STATUS Status; > + EFI_STATUS FindNodeStatus; > + CONST UINT32 *Reg; > + UINT32 PropSize; > + UINT64 Base; > + UINT64 Size; > + > + if (mNorFlashDeviceCount != 0) { > + return EFI_SUCCESS; > + } > + > + Status = gBS->LocateProtocol ( > + &gFdtClientProtocolGuid, > + NULL, > + (VOID **)&FdtClient > + ); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + An ASSERT is sufficient here - the DEPEX ensures that this is guaranteed to succeed. > + for (FindNodeStatus = FdtClient->FindCompatibleNode ( > + FdtClient, > + "cfi-flash", > + &Node > + ); > + !EFI_ERROR (FindNodeStatus) && (mNorFlashDeviceCount < MAX_FLASH_BANKS); > + FindNodeStatus = FdtClient->FindNextCompatibleNode ( > + FdtClient, > + "cfi-flash", > + Node, > + &Node > + )) { > + 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)); > + continue; > + } > + > + ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0); > + > + while ((PropSize >= (4 * sizeof (UINT32))) && > + (mNorFlashDeviceCount < MAX_FLASH_BANKS)) { > + Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0])); > + Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2])); > + Reg += 4; > + > + PropSize -= 4 * sizeof (UINT32); > + > + // > + // Disregard any flash devices that overlap with the primary FV. > + // The firmware is not updatable from inside the guest anyway. > + // > + if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) && > + (Base + Size) > PcdGet64 (PcdFvBaseAddress)) { > + continue; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "NOR%d : Base = 0x%lx, Size = 0x%lx\n", > + mNorFlashDeviceCount, > + Base, > + Size > + )); > + > + mNorFlashDevices[mNorFlashDeviceCount].DeviceBaseAddress = (UINTN)Base; > + mNorFlashDevices[mNorFlashDeviceCount].RegionBaseAddress = (UINTN)Base; > + mNorFlashDevices[mNorFlashDeviceCount].Size = (UINTN)Size; > + mNorFlashDevices[mNorFlashDeviceCount].BlockSize = SIZE_256KB; > + mNorFlashDeviceCount++; > + } > + } > + > + // Setup the variable store in the last bank > + if ((mNorFlashDeviceCount > 0) && > + (mNorFlashDevices[mNorFlashDeviceCount - 1].DeviceBaseAddress != 0)) { > + return SetupVariableStore (&mNorFlashDevices[mNorFlashDeviceCount - 1]); > + } > + > + return EFI_NOT_FOUND; > +} > + > diff --git a/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf b/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..8bd6f730dcb52e597b418e59766c1566a9519789 > --- /dev/null > +++ b/ArmVirtPkg/Library/NorFlashKvmtoolLib/NorFlashKvmtoolLib.inf > @@ -0,0 +1,50 @@ > +#/** @file > +# > +# Copyright (c) 2020, ARM Ltd. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +#**/ > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = NorFlashKvmtoolLib > + FILE_GUID = E75F07A1-B160-4893-BDD4-09E32FF847DC > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = NorFlashPlatformLib > + CONSTRUCTOR = NorFlashPlatformLibConstructor > + > +[Sources.common] > + NorFlashKvmtool.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + ArmVirtPkg/ArmVirtPkg.dec > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + PcdLib > + UefiBootServicesTableLib > + > +[Protocols] > + gFdtClientProtocolGuid ## CONSUMES > + > +[Pcd] > + gArmTokenSpaceGuid.PcdFvBaseAddress > + gArmTokenSpaceGuid.PcdFvSize > + > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize > + > + > +[Depex] > + gFdtClientProtocolGuid > + >