From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.101.70; helo=foss.arm.com; envelope-from=jagadeesh.ujja@arm.com; receiver=edk2-devel@lists.01.org Received: from foss.arm.com (foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id 7047321962301 for ; Mon, 10 Dec 2018 22:22:14 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4F59F15AD; Mon, 10 Dec 2018 22:22:14 -0800 (PST) Received: from usa.arm.com (a075555-lin.blr.arm.com [10.162.2.152]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C32BA3F6A8; Mon, 10 Dec 2018 22:22:12 -0800 (PST) From: Jagadeesh Ujja To: edk2-devel@lists.01.org, liming.gao@intel.com, chao.b.zhang@intel.com, leif.lindholm@linaro.org Date: Tue, 11 Dec 2018 11:51:40 +0530 Message-Id: <1544509302-1000-11-git-send-email-jagadeesh.ujja@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1544509302-1000-1-git-send-email-jagadeesh.ujja@arm.com> References: <1544509302-1000-1-git-send-email-jagadeesh.ujja@arm.com> Subject: [RFC PATCH v4 10/12] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 X-List-Received-Date: Tue, 11 Dec 2018 06:22:14 -0000 Adapt the NorFlashDxe driver to be used as a MM_STANDALONE driver to allow access to NOR flash for code executing in MM_STANDALONE mode. This allows storing of EFI variables on NOR flash which is accessible only via the MM STANDALONE mode software. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jagadeesh Ujja --- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c | 2 +- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c | 210 ++++++++++++++++---- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h | 4 +- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf | 3 + ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c | 96 ++++----- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf | 76 +++++++ 6 files changed, 302 insertions(+), 89 deletions(-) diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c index 279b77c..4c002c7 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c @@ -1,6 +1,6 @@ /** @file NorFlashBlockIoDxe.c - Copyright (c) 2011-2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2011-2018, ARM Ltd. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c index af40a4c..9c56010 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c @@ -1,6 +1,6 @@ /** @file NorFlashDxe.c - Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -138,29 +138,102 @@ NorFlashCreateInstance ( if (SupportFvb) { NorFlashFvbInitialize (Instance); + if (!InMm ()) { + Status = gBS->InstallMultipleProtocolInterfaces ( + &Instance->Handle, + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, + &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol, + NULL + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + } else { + //Install DevicePath Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiDevicePathProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->DevicePath + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + //Install BlockIo Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiBlockIoProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->BlockIoProtocol + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } - Status = gBS->InstallMultipleProtocolInterfaces ( - &Instance->Handle, - &gEfiDevicePathProtocolGuid, &Instance->DevicePath, - &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, - &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol, - NULL - ); - if (EFI_ERROR(Status)) { - FreePool (Instance); - return Status; + //Install FirmwareVolumeBlock Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->FvbProtocol + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } } } else { - Status = gBS->InstallMultipleProtocolInterfaces ( - &Instance->Handle, - &gEfiDevicePathProtocolGuid, &Instance->DevicePath, - &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, - &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol, - NULL - ); - if (EFI_ERROR(Status)) { - FreePool (Instance); - return Status; + if (!InMm ()) { + Status = gBS->InstallMultipleProtocolInterfaces ( + &Instance->Handle, + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, + &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, + &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol, + NULL + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + } else { + //Install DevicePath Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiDevicePathProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->DevicePath + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + //Install BlockIo Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiBlockIoProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->BlockIoProtocol + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + + //Install DiskIO Protocol + Status = gMmst->MmInstallProtocolInterface ( + &Instance->Handle, + &gEfiDiskIoProtocolGuid, + EFI_NATIVE_INTERFACE, + &Instance->DiskIoProtocol + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } } } @@ -342,13 +415,15 @@ NorFlashUnlockAndEraseSingleBlock ( UINTN Index; EFI_TPL OriginalTPL; - if (!EfiAtRuntime ()) { - // Raise TPL to TPL_HIGH to stop anyone from interrupting us. - OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); - } else { - // This initialization is only to prevent the compiler to complain about the - // use of uninitialized variables - OriginalTPL = TPL_HIGH_LEVEL; + if (!InMm ()) { + if (!EfiAtRuntime ()) { + // Raise TPL to TPL_HIGH to stop anyone from interrupting us. + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + } else { + // This initialization is only to prevent the compiler to complain about the + // use of uninitialized variables + OriginalTPL = TPL_HIGH_LEVEL; + } } Index = 0; @@ -367,9 +442,11 @@ NorFlashUnlockAndEraseSingleBlock ( DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index)); } - if (!EfiAtRuntime ()) { - // Interruptions can resume. - gBS->RestoreTPL (OriginalTPL); + if (!InMm ()) { + if (!EfiAtRuntime ()) { + // Interruptions can resume. + gBS->RestoreTPL (OriginalTPL); + } } return Status; @@ -595,13 +672,15 @@ NorFlashWriteFullBlock ( // Start writing from the first address at the start of the block WordAddress = BlockAddress; - if (!EfiAtRuntime ()) { - // Raise TPL to TPL_HIGH to stop anyone from interrupting us. - OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); - } else { - // This initialization is only to prevent the compiler to complain about the - // use of uninitialized variables - OriginalTPL = TPL_HIGH_LEVEL; + if (!InMm ()) { + if (!EfiAtRuntime ()) { + // Raise TPL to TPL_HIGH to stop anyone from interrupting us. + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + } else { + // This initialization is only to prevent the compiler to complain about the + // use of uninitialized variables + OriginalTPL = TPL_HIGH_LEVEL; + } } Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress); @@ -661,9 +740,11 @@ NorFlashWriteFullBlock ( } EXIT: - if (!EfiAtRuntime ()) { - // Interruptions can resume. - gBS->RestoreTPL (OriginalTPL); + if (!InMm ()) { + if (!EfiAtRuntime ()) { + // Interruptions can resume. + gBS->RestoreTPL (OriginalTPL); + } } if (EFI_ERROR(Status)) { @@ -1334,6 +1415,53 @@ NorFlashInitialise ( &mNorFlashVirtualAddrChangeEvent ); ASSERT_EFI_ERROR (Status); + return Status; +} + +EFI_STATUS +EFIAPI +StandaloneMmNorFlashInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 Index; + NOR_FLASH_DESCRIPTION* NorFlashDevices; + BOOLEAN ContainVariableStorage; + + Status = NorFlashPlatformInitialization (); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n")); + return Status; + } + + Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n")); + return Status; + } + + mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount); + for (Index = 0; Index < mNorFlashDeviceCount; Index++) { + // Check if this NOR Flash device contain the variable storage region + ContainVariableStorage = + (NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) && + (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <= NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size); + + Status = NorFlashCreateInstance ( + NorFlashDevices[Index].DeviceBaseAddress, + NorFlashDevices[Index].RegionBaseAddress, + NorFlashDevices[Index].Size, + Index, + NorFlashDevices[Index].BlockSize, + ContainVariableStorage, + &mNorFlashInstances[Index] + ); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index)); + } + } return Status; } diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h index c0563f6..5b23d95 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h @@ -1,6 +1,6 @@ /** @file NorFlashDxe.h - Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #define NOR_FLASH_ERASE_RETRY 10 diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf index a59a21a..a704f69 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf @@ -32,6 +32,7 @@ MdeModulePkg/MdeModulePkg.dec ArmPlatformPkg/ArmPlatformPkg.dec EmbeddedPkg/EmbeddedPkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec [LibraryClasses] IoLib @@ -44,6 +45,7 @@ UefiBootServicesTableLib UefiRuntimeLib DxeServicesTableLib + StandaloneMmRuntimeDxe [Guids] gEfiSystemNvDataFvGuid @@ -57,6 +59,7 @@ gEfiDevicePathProtocolGuid gEfiFirmwareVolumeBlockProtocolGuid gEfiDiskIoProtocolGuid + gEfiSmmFirmwareVolumeBlockProtocolGuid [Pcd.common] gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c index e62ffbb..e4d7100 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c @@ -1,6 +1,6 @@ /*++ @file NorFlashFvbDxe.c - Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -720,27 +720,29 @@ NorFlashFvbInitialize ( DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); ASSERT((Instance != NULL)); - // - // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME - // - - // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory; - // even if we only use the small block region at the top of the NOR Flash. - // The reason is when the NOR Flash memory is set into program mode, the command - // is written as the base of the flash region (ie: Instance->DeviceBaseAddress) - RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size; - - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeMemoryMappedIo, - Instance->DeviceBaseAddress, RuntimeMmioRegionSize, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME - ); - ASSERT_EFI_ERROR (Status); - - Status = gDS->SetMemorySpaceAttributes ( - Instance->DeviceBaseAddress, RuntimeMmioRegionSize, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); - ASSERT_EFI_ERROR (Status); + if (!InMm ()) { + // + // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME + // + + // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory; + // even if we only use the small block region at the top of the NOR Flash. + // The reason is when the NOR Flash memory is set into program mode, the command + // is written as the base of the flash region (ie: Instance->DeviceBaseAddress) + RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size; + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Instance->DeviceBaseAddress, RuntimeMmioRegionSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status = gDS->SetMemorySpaceAttributes ( + Instance->DeviceBaseAddress, RuntimeMmioRegionSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); + ASSERT_EFI_ERROR (Status); + } mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase); @@ -777,30 +779,32 @@ NorFlashFvbInitialize ( } } - // - // The driver implementing the variable read service can now be dispatched; - // the varstore headers are in place. - // - Status = gBS->InstallProtocolInterface ( - &gImageHandle, - &gEdkiiNvVarStoreFormattedGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Register for the virtual address change event - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - FvbVirtualNotifyEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &mFvbVirtualAddrChangeEvent - ); - ASSERT_EFI_ERROR (Status); + if (!InMm ()) { + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mFvbVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + } return Status; } diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf new file mode 100644 index 0000000..a6d0581 --- /dev/null +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf @@ -0,0 +1,76 @@ +#/** @file +# +# Component description file for NorFlashDxe module +# +# Copyright (c) 2018, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = StandaloneMmNorFlash + FILE_GUID = 166F677B-DAC9-4AE4-AD34-2FF2504B0637 + MODULE_TYPE = MM_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + ENTRY_POINT = StandaloneMmNorFlashInitialise + +[Sources.common] + NorFlashDxe.c + NorFlashFvbDxe.c + NorFlashBlockIoDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[LibraryClasses] + StandaloneMmDriverEntryPoint + BaseMemoryLib + ArmSvcLib + ArmLib + IoLib + BaseLib + DebugLib + HobLib + MemoryAllocationLib + NorFlashPlatformLib + MmServicesTableLib + +[Guids] + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSmmFirmwareVolumeBlockProtocolGuid + gEfiDiskIoProtocolGuid + +[Pcd.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + + gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked + +[Depex] + TRUE -- 2.7.4