* [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM
@ 2018-11-27 11:26 Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 01/11] MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence Jagadeesh Ujja
` (10 more replies)
0 siblings, 11 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Changes since v1:
- Addressed all the comments from Liming Gao
- Removed the use of #ifdef/#else/#endif and used a Pcd instead to
select between MM and non-MM paths.
- Removed all dependencies on edk2-platforms.
- Dropped the use of mMmst and used gSmst instead.
- Added a dummy implementation UefiRuntimeServiceTableLib for
MM_STANDALONE usage
- Replaced all uses of AsmLfence with MemoryFence from variable
service code.
- Add a new StandaloneMmRuntimeDxe library to for use by non-MM code.
This RFC patch series extends the existing secure variable service support
for use with Standalone MM. This is applicable to paltforms that use
Standalone Management Mode to protect access to non-volatile memory (NOR
flash in case of these patches) used to store the secure EFI variables.
The first patch pulls in additional libraries from the staging branch of
StandaloneMmPkg into the edk2's StandaloneMmPkg. The existing secure
variable service implementation supports only the traditional MM mode
and so the rest of the patches extends the existing secure variable
service support to be useable with Standalone MM mode as well.
This patch series is being posted as an RFC to get feedback on the
approach taken in these patches.
Jagadeesh Ujja (11):
MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence
StandaloneMmPkg: Pull in additonal libraries from staging branch
MdeModulePkg/Library: Add StandaloneMmRuntimeDxe library
ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM
Standalone
MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this
library
MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this
library
CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this
library
CryptoPkg/BaseCryptLib: Hack to get time in MM Standalone mode
.../Drivers/NorFlashDxe/NorFlashDxe.inf | 3 +
.../NorFlashDxe/NorFlashStandaloneMm.inf | 76 ++
.../Library/BaseCryptLib/BaseCryptLib.inf | 8 +-
.../Library/BaseCryptLib/RuntimeCryptLib.inf | 5 +
.../StandaloneMmRuntimeDxe.inf | 43 +
.../Library/VarCheckLib/VarCheckLib.inf | 5 +-
.../FaultTolerantWriteDxe.inf | 2 +
.../FaultTolerantWriteStandaloneMm.inf | 102 +++
.../RuntimeDxe/VariableRuntimeDxe.inf | 2 +
.../RuntimeDxe/VariableSmmRuntimeDxe.inf | 4 +
.../RuntimeDxe/VariableStandaloneMm.inf | 132 +++
.../AuthVariableLib/AuthVariableLib.inf | 5 +-
.../StandaloneMmCoreHobLib.inf | 2 +-
.../StandaloneMmHobLib/StandaloneMmHobLib.inf | 48 +
.../StandaloneMmMemoryAllocationLib.inf | 45 +
.../StandaloneMmServicesTableLib.inf | 36 +
.../Drivers/NorFlashDxe/NorFlashDxe.h | 5 +-
.../Include/Library/StandaloneMmRuntimeDxe.h | 39 +
.../Library/StandaloneMmServicesTableLib.h | 47 +
.../Drivers/NorFlashDxe/NorFlashBlockIoDxe.c | 2 +-
.../Drivers/NorFlashDxe/NorFlashDxe.c | 211 ++++-
.../Drivers/NorFlashDxe/NorFlashFvbDxe.c | 96 +-
.../BaseCryptLib/SysCall/TimerWrapper.c | 27 +-
.../StandaloneMmRuntimeDxe.c | 36 +
.../FaultTolerantWriteSmm.c | 207 +++--
.../UpdateWorkingBlock.c | 27 +-
.../Variable/RuntimeDxe/LoadFenceSmm.c | 2 +-
.../Universal/Variable/RuntimeDxe/Variable.c | 37 +-
.../Variable/RuntimeDxe/VariableSmm.c | 201 ++++-
.../RuntimeDxe/VariableSmmRuntimeDxe.c | 31 +-
MdePkg/Library/BaseLib/X86MemoryFence.c | 2 +-
.../AArch64/StandaloneMmCoreHobLibInternal.c | 64 ++
.../StandaloneMmHobLib/StandaloneMmHobLib.c | 655 ++++++++++++++
.../StandaloneMmMemoryAllocationLib.c | 824 ++++++++++++++++++
.../StandaloneMmServicesTableLib.c | 64 ++
35 files changed, 2860 insertions(+), 235 deletions(-)
create mode 100644 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
create mode 100644 MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
create mode 100644 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
create mode 100644 MdeModulePkg/Include/Library/StandaloneMmRuntimeDxe.h
create mode 100644 StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h
create mode 100644 MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
--
2.19.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC PATCH v2 01/11] MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 02/11] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Replace all uses of AsmLfence with call to MemoryFence to allow
variable service code to be platform independent.
Change-Id: I578719ab038318bd240ec5471d42552c8b7c75db
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c | 4 ++--
MdeModulePkg/Universal/Variable/RuntimeDxe/LoadFenceSmm.c | 2 +-
MdePkg/Library/BaseLib/X86MemoryFence.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
index 27fcab19b6..fabd713c74 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
@@ -419,11 +419,11 @@ SmmFaultTolerantWriteHandler (
);
if (!EFI_ERROR (Status)) {
//
- // The AsmLfence() call here is to ensure the previous range/content
+ // The MemoryFence () call here is to ensure the previous range/content
// checks for the CommBuffer have been completed before calling into
// FtwWrite().
//
- AsmLfence ();
+ MemoryFence ();
Status = FtwWrite(
&mFtwDevice->FtwInstance,
SmmFtwWriteHeader->Lba,
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/LoadFenceSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/LoadFenceSmm.c
index 4b0d7e3e95..7c4b01924e 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/LoadFenceSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/LoadFenceSmm.c
@@ -26,5 +26,5 @@ MemoryLoadFence (
VOID
)
{
- AsmLfence ();
+ MemoryFence ();
}
diff --git a/MdePkg/Library/BaseLib/X86MemoryFence.c b/MdePkg/Library/BaseLib/X86MemoryFence.c
index 77e1c5a4dd..3a7928df9b 100644
--- a/MdePkg/Library/BaseLib/X86MemoryFence.c
+++ b/MdePkg/Library/BaseLib/X86MemoryFence.c
@@ -28,5 +28,5 @@ MemoryFence (
VOID
)
{
- return;
+ AsmLfence ();
}
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 02/11] StandaloneMmPkg: Pull in additonal libraries from staging branch
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 01/11] MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 03/11] MdeModulePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Three additional library packages are being pulled into StandaloneMmPkg
from the staging area in order to support the secure variable service.
The three packages being pulled in are
- StandaloneMmHobLib
- StandaloneMmMemoryAllocationLib
- StandaloneMmServicesTableLib
Change-Id: I4d76eccd93e1e750b526f67ed470b17aab29ad63
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../Library/StandaloneMmServicesTableLib.h | 47 +
.../StandaloneMmCoreHobLib.inf | 2 +-
.../AArch64/StandaloneMmCoreHobLibInternal.c | 64 ++
.../StandaloneMmHobLib/StandaloneMmHobLib.c | 655 ++++++++++++++
.../StandaloneMmHobLib/StandaloneMmHobLib.inf | 48 +
.../StandaloneMmMemoryAllocationLib.c | 824 ++++++++++++++++++
.../StandaloneMmMemoryAllocationLib.inf | 45 +
.../StandaloneMmServicesTableLib.c | 64 ++
.../StandaloneMmServicesTableLib.inf | 36 +
9 files changed, 1784 insertions(+), 1 deletion(-)
create mode 100644 StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
create mode 100644 StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
diff --git a/StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h b/StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h
new file mode 100644
index 0000000000..e7a670d363
--- /dev/null
+++ b/StandaloneMmPkg/Include/Library/StandaloneMmServicesTableLib.h
@@ -0,0 +1,47 @@
+/** @file
+ Provides a service to retrieve a pointer to the Standalone MM Services Table.
+ Only available to Standalone MM module types.
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+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.
+
+**/
+
+#ifndef __MM_SERVICES_TABLE_LIB_H__
+#define __MM_SERVICES_TABLE_LIB_H__
+
+#include <PiMm.h>
+#include <Library/DebugLib.h>
+
+///
+/// Cache pointer to the Standalone MM Services Table
+
+extern EFI_MM_SYSTEM_TABLE *gMmst;
+
+
+/**
+ This function allows the caller to determine if the driver is executing in
+ Standalone Management Mode(SMM).
+
+ This function returns TRUE if the driver is executing in SMM and FALSE if the
+ driver is not executing in SMM.
+
+ @retval TRUE The driver is executing in Standalone Management Mode (SMM).
+ @retval FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+ VOID
+ );
+
+#endif
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
index db19d3c926..ac036e31cf 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
@@ -24,7 +24,7 @@
MODULE_TYPE = MM_CORE_STANDALONE
VERSION_STRING = 1.0
PI_SPECIFICATION_VERSION = 0x00010032
- LIBRARY_CLASS = HobLib|MM_CORE_STANDALONE MM_STANDALONE
+ LIBRARY_CLASS = HobLib|MM_CORE_STANDALONE
#
# VALID_ARCHITECTURES = AARCH64
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
new file mode 100644
index 0000000000..ac5a1c039f
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/AArch64/StandaloneMmCoreHobLibInternal.c
@@ -0,0 +1,64 @@
+/** @file
+ HOB Library implementation for Standalone MM Core.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
+
+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.
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+//
+// Cache copy of HobList pointer.
+//
+extern VOID *gHobList;
+
+EFI_HOB_HANDOFF_INFO_TABLE*
+HobConstructor (
+ IN VOID *EfiMemoryBegin,
+ IN UINTN EfiMemoryLength,
+ IN VOID *EfiFreeMemoryBottom,
+ IN VOID *EfiFreeMemoryTop
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = EfiFreeMemoryBottom;
+ HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
+
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;
+ Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;
+ Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
+
+ gHobList = Hob;
+
+ return Hob;
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
new file mode 100644
index 0000000000..591a78c7f3
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.c
@@ -0,0 +1,655 @@
+/** @file
+ HOB Library implementation for Standalone MM Core.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
+
+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.
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+EFI_MM_SYSTEM_TABLE *gMmst = NULL;
+
+/**
+ The constructor function caches the pointer to HOB list.
+
+ The constructor function gets the start address of HOB list from system configuration table.
+ It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor successfully gets HobList.
+ @retval Other value The constructor can't get HobList.
+
+**/
+EFI_STATUS
+EFIAPI
+HobLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SmmSystemTable
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
+ gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
+ break;
+ }
+ }
+
+ /* HACK: Use the ImageHandle to smuggle the hoblist into the library constructor */
+ if (ImageHandle)
+ gHobList = (VOID *) ImageHandle;
+
+ return EFI_SUCCESS;
+}
+/**
+ Returns the pointer to the HOB list.
+
+ This function returns the pointer to first HOB in the list.
+ If the pointer to the HOB list is NULL, then ASSERT().
+
+ @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+GetHobList (
+ VOID
+ )
+{
+ UINTN Index;
+
+ if (gHobList == NULL) {
+ for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&gEfiHobListGuid, &gMmst->MmConfigurationTable[Index].VendorGuid)) {
+ gHobList = gMmst->MmConfigurationTable[Index].VendorTable;
+ break;
+ }
+ }
+ }
+ ASSERT (gHobList != NULL);
+ return gHobList;
+}
+
+/**
+ Returns the next instance of a HOB type from the starting HOB.
+
+ This function searches the first instance of a HOB type from the starting HOB pointer.
+ If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+
+ If HobStart is NULL, then ASSERT().
+
+ @param Type The HOB type to return.
+ @param HobStart The starting HOB pointer to search from.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextHob (
+ IN UINT16 Type,
+ IN CONST VOID *HobStart
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ ASSERT (HobStart != NULL);
+
+ Hob.Raw = (UINT8 *) HobStart;
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == Type) {
+ return Hob.Raw;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ return NULL;
+}
+
+/**
+ Returns the first instance of a HOB type among the whole HOB list.
+
+ This function searches the first instance of a HOB type among the whole HOB list.
+ If there does not exist such HOB type in the HOB list, it will return NULL.
+
+ If the pointer to the HOB list is NULL, then ASSERT().
+
+ @param Type The HOB type to return.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetFirstHob (
+ IN UINT16 Type
+ )
+{
+ VOID *HobList;
+
+ HobList = GetHobList ();
+ return GetNextHob (Type, HobList);
+}
+
+/**
+ Returns the next instance of the matched GUID HOB from the starting HOB.
+
+ This function searches the first instance of a HOB from the starting HOB pointer.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION, and its GUID Name equals to the input Guid.
+ If such a HOB from the starting HOB pointer does not exist, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size information, respectively.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+
+ If Guid is NULL, then ASSERT().
+ If HobStart is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+ @param HobStart A pointer to a Guid.
+
+ @return The next instance of the matched GUID HOB from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *HobStart
+ )
+{
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ GuidHob.Raw = (UINT8 *) HobStart;
+ while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
+ if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
+ break;
+ }
+ GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+ }
+ return GuidHob.Raw;
+}
+
+/**
+ Returns the first instance of the matched GUID HOB among the whole HOB list.
+
+ This function searches the first instance of a HOB among the whole HOB list.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+ If such a HOB from the starting HOB pointer does not exist, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size information, respectively.
+
+ If the pointer to the HOB list is NULL, then ASSERT().
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+
+ @return The first instance of the matched GUID HOB among the whole HOB list.
+
+**/
+VOID *
+EFIAPI
+GetFirstGuidHob (
+ IN CONST EFI_GUID *Guid
+ )
+{
+ VOID *HobList;
+
+ HobList = GetHobList ();
+ return GetNextGuidHob (Guid, HobList);
+}
+
+/**
+ Get the system boot mode from the HOB list.
+
+ This function returns the system boot mode information from the
+ PHIT HOB in HOB list.
+
+ If the pointer to the HOB list is NULL, then ASSERT().
+
+ @param VOID
+
+ @return The Boot Mode.
+
+**/
+EFI_BOOT_MODE
+EFIAPI
+GetBootModeHob (
+ VOID
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+ HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();
+
+ return HandOffHob->BootMode;
+}
+
+VOID *
+CreateHob (
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+ VOID *Hob;
+
+ HandOffHob = GetHobList ();
+
+ HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < HobLength) {
+ return NULL;
+ }
+
+ Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return Hob;
+}
+
+/**
+ Builds a HOB for a loaded PE32 module.
+
+ This function builds a HOB for a loaded PE32 module.
+ If ModuleName is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ModuleName The GUID File Name of the module.
+ @param MemoryAllocationModule The 64 bit physical address of the module.
+ @param ModuleLength The length of the module in bytes.
+ @param EntryPoint The 64 bit physical address of the module entry point.
+
+**/
+VOID
+EFIAPI
+BuildModuleHob (
+ IN CONST EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
+ IN UINT64 ModuleLength,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ )
+{
+ EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
+
+ ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
+ ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
+
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
+
+ CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
+ Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
+ Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
+ Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
+
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
+
+ CopyGuid (&Hob->ModuleName, ModuleName);
+ Hob->EntryPoint = EntryPoint;
+}
+
+/**
+ Builds a HOB that describes a chunk of system memory.
+
+ This function builds a HOB that describes a chunk of system memory.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
+ ASSERT(Hob != NULL);
+
+ Hob->ResourceType = ResourceType;
+ Hob->ResourceAttribute = ResourceAttribute;
+ Hob->PhysicalStart = PhysicalStart;
+ Hob->ResourceLength = NumberOfBytes;
+}
+
+/**
+ Builds a GUID HOB with a certain data length.
+
+ This function builds a customized HOB tagged with a GUID for identification
+ and returns the start address of GUID HOB data so that caller can fill the customized data.
+ The HOB Header and Name field is already stripped.
+ If Guid is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN DataLength
+ )
+{
+ EFI_HOB_GUID_TYPE *Hob;
+
+ //
+ // Make sure that data length is not too long.
+ //
+ ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
+
+ Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
+ CopyGuid (&Hob->Name, Guid);
+ return Hob + 1;
+}
+
+
+/**
+ Copies a data buffer to a newly-built HOB.
+
+ This function builds a customized HOB tagged with a GUID for identification,
+ copies the input data to the HOB data field and returns the start address of the GUID HOB data.
+ The HOB Header and Name field is already stripped.
+ If Guid is NULL, then ASSERT().
+ If Data is NULL and DataLength > 0, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param Data The data to be copied into the data field of the GUID HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidDataHob (
+ IN CONST EFI_GUID *Guid,
+ IN VOID *Data,
+ IN UINTN DataLength
+ )
+{
+ VOID *HobData;
+
+ ASSERT (Data != NULL || DataLength == 0);
+
+ HobData = BuildGuidHob (Guid, DataLength);
+
+ return CopyMem (HobData, Data, DataLength);
+}
+
+/**
+ Builds a Firmware Volume HOB.
+
+ This function builds a Firmware Volume HOB.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_HOB_FIRMWARE_VOLUME *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
+
+ Hob->BaseAddress = BaseAddress;
+ Hob->Length = Length;
+}
+
+
+/**
+ Builds a EFI_HOB_TYPE_FV2 HOB.
+
+ This function builds a EFI_HOB_TYPE_FV2 HOB.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+ @param FvName The name of the Firmware Volume.
+ @param FileName The name of the file.
+
+**/
+VOID
+EFIAPI
+BuildFv2Hob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN CONST EFI_GUID *FvName,
+ IN CONST EFI_GUID *FileName
+ )
+{
+ EFI_HOB_FIRMWARE_VOLUME2 *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
+
+ Hob->BaseAddress = BaseAddress;
+ Hob->Length = Length;
+ CopyGuid (&Hob->FvName, FvName);
+ CopyGuid (&Hob->FileName, FileName);
+}
+
+
+/**
+ Builds a HOB for the CPU.
+
+ This function builds a HOB for the CPU.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
+ @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
+
+**/
+VOID
+EFIAPI
+BuildCpuHob (
+ IN UINT8 SizeOfMemorySpace,
+ IN UINT8 SizeOfIoSpace
+ )
+{
+ EFI_HOB_CPU *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
+
+ Hob->SizeOfMemorySpace = SizeOfMemorySpace;
+ Hob->SizeOfIoSpace = SizeOfIoSpace;
+
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
+}
+
+/**
+ Builds a HOB for the memory allocation.
+
+ This function builds a HOB for the memory allocation.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the memory.
+ @param Length The length of the memory allocation in bytes.
+ @param MemoryType Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildMemoryAllocationHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ EFI_HOB_MEMORY_ALLOCATION *Hob;
+
+ ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+ ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
+
+ ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = MemoryType;
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
+/**
+ Builds a HOB that describes a chunk of system memory with Owner GUID.
+
+ This function builds a HOB that describes a chunk of system memory.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
+ @param OwnerGUID GUID for the owner of this resource.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ Builds a Capsule Volume HOB.
+
+ This function builds a Capsule Volume HOB.
+ If the platform does not support Capsule Volume HOBs, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Capsule Volume.
+ @param Length The size of the Capsule Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildCvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ Builds a HOB for the BSP store.
+
+ This function builds a HOB for BSP store.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the BSP.
+ @param Length The length of the BSP store in bytes.
+ @param MemoryType Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildBspStoreHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ Builds a HOB for the Stack.
+
+ This function builds a HOB for the stack.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the Stack.
+ @param Length The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+BuildStackHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ ASSERT (FALSE);
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
new file mode 100644
index 0000000000..d73188ec1b
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Instance of HOB Library for Standalone MM Core.
+#
+# HOB Library implementation for the Standalone MM Core. Does not have a constructor.
+# Uses gHobList defined in the Standalone MM Core Entry Point Library.
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# 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 = 0x0001001A
+ BASE_NAME = HobLib
+ FILE_GUID = 8262551B-AB2D-4E76-99FC-5EBB83F4988E
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = HobLib|MM_STANDALONE
+ CONSTRUCTOR = HobLibConstructor
+#
+# VALID_ARCHITECTURES = AARCH64
+#
+[Sources.Common]
+ StandaloneMmHobLib.c
+
+[Sources.AARCH64]
+ AArch64/StandaloneMmCoreHobLibInternal.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ MmServicesTableLib
+
+[Guids]
+ gEfiHobListGuid ## CONSUMES ## SystemTable
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
new file mode 100644
index 0000000000..e989f277c1
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c
@@ -0,0 +1,824 @@
+/** @file
+ Support routines for memory allocation routines based on Standalone MM Core internal functions.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+#include <PiMm.h>
+
+#include <Guid/MmramMemoryReserve.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+extern EFI_MM_SYSTEM_TABLE *gMmst;
+
+/**
+ Allocates one or more 4KB pages of a certain memory type.
+
+ Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
+ buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
+ If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param MemoryType The type of memory to allocate.
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocatePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ return (VOID *) (UINTN) Memory;
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData.
+
+ Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePages (
+ IN UINTN Pages
+ )
+{
+ return InternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiRuntimeServicesData.
+
+ Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePages (
+ IN UINTN Pages
+ )
+{
+ return InternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiReservedMemoryType.
+
+ Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPages (
+ IN UINTN Pages
+ )
+{
+ return NULL;
+}
+
+/**
+ Frees one or more 4KB pages that were previously allocated with one of the page allocation
+ functions in the Memory Allocation Library.
+
+ Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
+ must have been allocated on a previous call to the page allocation services of the Memory
+ Allocation Library. If it is not possible to free allocated pages, then this function will
+ perform no actions.
+
+ If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
+ then ASSERT().
+ If Pages is zero, then ASSERT().
+
+ @param Buffer Pointer to the buffer of pages to free.
+ @param Pages The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreePages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (Pages != 0);
+ Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Allocates one or more 4KB pages of a certain memory type at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
+ specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
+ If there is not enough memory at the specified alignment remaining to satisfy the request, then
+ NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+ If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+ @param MemoryType The type of memory to allocate.
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateAlignedPages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+ UINTN AlignedMemory;
+ UINTN AlignmentMask;
+ UINTN UnalignedPages;
+ UINTN RealPages;
+
+ //
+ // Alignment must be a power of two or zero.
+ //
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ if (Pages == 0) {
+ return NULL;
+ }
+ if (Alignment > EFI_PAGE_SIZE) {
+ //
+ // Calculate the total number of pages since alignment is larger than page size.
+ //
+ AlignmentMask = Alignment - 1;
+ RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
+ //
+ // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
+ //
+ ASSERT (RealPages > Pages);
+
+ Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+ UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
+ if (UnalignedPages > 0) {
+ //
+ // Free first unaligned page(s).
+ //
+ Status = gMmst->MmFreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+ Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
+ UnalignedPages = RealPages - Pages - UnalignedPages;
+ if (UnalignedPages > 0) {
+ //
+ // Free last unaligned page(s).
+ //
+ Status = gMmst->MmFreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ //
+ // Do not over-allocate pages in this case.
+ //
+ Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = (UINTN) Memory;
+ }
+ return (VOID *) AlignedMemory;
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+ If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedPages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+ If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedRuntimePages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
+}
+
+/**
+ Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+ If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedReservedPages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ return NULL;
+}
+
+/**
+ Frees one or more 4KB pages that were previously allocated with one of the aligned page
+ allocation functions in the Memory Allocation Library.
+
+ Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
+ must have been allocated on a previous call to the aligned page allocation services of the Memory
+ Allocation Library. If it is not possible to free allocated pages, then this function will
+ perform no actions.
+
+ If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
+ Library, then ASSERT().
+ If Pages is zero, then ASSERT().
+
+ @param Buffer Pointer to the buffer of pages to free.
+ @param Pages The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreeAlignedPages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (Pages != 0);
+ Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Allocates a buffer of a certain pool type.
+
+ Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
+ pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param MemoryType The type of memory to allocate.
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocatePool (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN AllocationSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Memory;
+
+ Memory = NULL;
+
+ Status = gMmst->MmAllocatePool (MemoryType, AllocationSize, &Memory);
+ if (EFI_ERROR (Status)) {
+ Memory = NULL;
+ }
+ return Memory;
+}
+
+/**
+ Allocates a buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+ pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePool (
+ IN UINTN AllocationSize
+ )
+{
+ return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+ Allocates a buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
+ a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePool (
+ IN UINTN AllocationSize
+ )
+{
+ return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+ Allocates a buffer of type EfiReservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
+ a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPool (
+ IN UINTN AllocationSize
+ )
+{
+ return NULL;
+}
+
+/**
+ Allocates and zeros a buffer of a certain pool type.
+
+ Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
+ with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
+ buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
+ then NULL is returned.
+
+ @param PoolType The type of memory to allocate.
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateZeroPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize
+ )
+{
+ VOID *Memory;
+
+ Memory = InternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = ZeroMem (Memory, AllocationSize);
+ }
+ return Memory;
+}
+
+/**
+ Allocates and zeros a buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+ Allocates and zeros a buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+/**
+ Allocates and zeros a buffer of type EfiReservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return NULL;
+}
+
+/**
+ Copies a buffer to an allocated buffer of a certain pool type.
+
+ Allocates the number bytes specified by AllocationSize of a certain pool type, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param PoolType The type of pool to allocate.
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalAllocateCopyPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = InternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = CopyMem (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+/**
+ Copies a buffer to an allocated buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+/**
+ Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+/**
+ Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return NULL;
+}
+
+/**
+ Reallocates a buffer of a specified memory type.
+
+ Allocates and zeros the number bytes specified by NewSize from memory of the type
+ specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
+ NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+ OldBuffer is freed. A pointer to the newly allocated buffer is returned.
+ If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
+ enough memory remaining to satisfy the request, then NULL is returned.
+
+ If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+ is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+ @param PoolType The type of pool to allocate.
+ @param OldSize The size, in bytes, of OldBuffer.
+ @param NewSize The size, in bytes, of the buffer to reallocate.
+ @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
+ parameter that may be NULL.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+InternalReallocatePool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ )
+{
+ VOID *NewBuffer;
+
+ NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
+ if (NewBuffer != NULL && OldBuffer != NULL) {
+ CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
+ FreePool (OldBuffer);
+ }
+ return NewBuffer;
+}
+
+/**
+ Reallocates a buffer of type EfiBootServicesData.
+
+ Allocates and zeros the number bytes specified by NewSize from memory of type
+ EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
+ NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+ OldBuffer is freed. A pointer to the newly allocated buffer is returned.
+ If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
+ enough memory remaining to satisfy the request, then NULL is returned.
+
+ If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+ is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+ @param OldSize The size, in bytes, of OldBuffer.
+ @param NewSize The size, in bytes, of the buffer to reallocate.
+ @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
+ parameter that may be NULL.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocatePool (
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ )
+{
+ return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
+}
+
+/**
+ Reallocates a buffer of type EfiRuntimeServicesData.
+
+ Allocates and zeros the number bytes specified by NewSize from memory of type
+ EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
+ NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+ OldBuffer is freed. A pointer to the newly allocated buffer is returned.
+ If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
+ enough memory remaining to satisfy the request, then NULL is returned.
+
+ If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+ is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+ @param OldSize The size, in bytes, of OldBuffer.
+ @param NewSize The size, in bytes, of the buffer to reallocate.
+ @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
+ parameter that may be NULL.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateRuntimePool (
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ )
+{
+ return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
+}
+
+/**
+ Reallocates a buffer of type EfiReservedMemoryType.
+
+ Allocates and zeros the number bytes specified by NewSize from memory of type
+ EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
+ NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
+ OldBuffer is freed. A pointer to the newly allocated buffer is returned.
+ If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
+ enough memory remaining to satisfy the request, then NULL is returned.
+
+ If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+ is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+ @param OldSize The size, in bytes, of OldBuffer.
+ @param NewSize The size, in bytes, of the buffer to reallocate.
+ @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
+ parameter that may be NULL.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateReservedPool (
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL
+ )
+{
+ return NULL;
+}
+
+/**
+ Frees a buffer that was previously allocated with one of the pool allocation functions in the
+ Memory Allocation Library.
+
+ Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
+ pool allocation services of the Memory Allocation Library. If it is not possible to free pool
+ resources, then this function will perform no actions.
+
+ If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
+ then ASSERT().
+
+ @param Buffer Pointer to the buffer to free.
+
+**/
+VOID
+EFIAPI
+FreePool (
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gMmst->MmFreePool (Buffer);
+ ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
new file mode 100644
index 0000000000..9ac03df4ca
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Memory Allocation Library instance dedicated to MM Core.
+# The implementation borrows the MM Core Memory Allocation services as the primitive
+# for memory allocation instead of using MM System Table servces in an indirect way.
+# It is assumed that this library instance must be linked with MM Core in this package.
+#
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# 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 = 0x0001001A
+ BASE_NAME = MemoryAllocationLib
+ FILE_GUID = 54646378-A9DC-473F-9BE1-BD027C4C76DE
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = MemoryAllocationLib|MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmMemoryAllocationLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ MmServicesTableLib
+ HobLib
diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
new file mode 100644
index 0000000000..e0e0044062
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.c
@@ -0,0 +1,64 @@
+/** @file
+ MM Core MM Services Table Library.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+#include <PiMm.h>
+#include <Library/DebugLib.h>
+
+extern EFI_MM_SYSTEM_TABLE *gMmst;
+
+/**
+ The constructor function caches the pointer of MM Services Table.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmServicesTableLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ gMmst = MmSystemTable;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function allows the caller to determine if the driver is executing in
+ Standalone Management Mode(SMM).
+
+ This function returns TRUE if the driver is executing in SMM and FALSE if the
+ driver is not executing in SMM.
+
+ @retval TRUE The driver is executing in Standalone Management Mode (SMM).
+ @retval FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+ VOID
+ )
+{
+ //
+ // We are already in Standalone MM
+ //
+ return TRUE;
+}
+
diff --git a/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
new file mode 100644
index 0000000000..c362429142
--- /dev/null
+++ b/StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
@@ -0,0 +1,36 @@
+## @file
+# MM Core MM Services Table Library.
+#
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# 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 = StandaloneMmServicesTableLib
+ FILE_GUID = BEE33A2F-F49D-4B71-AF3E-FFCCB9885DEA
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = MmServicesTableLib|MM_STANDALONE
+ CONSTRUCTOR = StandaloneMmServicesTableLibConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmServicesTableLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 03/11] MdeModulePkg/Library: Add StandaloneMmRuntimeDxe library
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 01/11] MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 02/11] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
To resuse some the libraries in both MM and non-MM mode, a mechanism to
determine the execution mode is required, i.e, in MM or non-MM. Add a
new library for use by non-MM code to determine the current execution
mode.
Change-Id: If0ec88f4691b2b059c770faefed59b2dc29312da
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../Include/Library/StandaloneMmRuntimeDxe.h | 39 +++++++++++++++++
.../StandaloneMmRuntimeDxe.c | 36 ++++++++++++++++
.../StandaloneMmRuntimeDxe.inf | 43 +++++++++++++++++++
3 files changed, 118 insertions(+)
create mode 100644 MdeModulePkg/Include/Library/StandaloneMmRuntimeDxe.h
create mode 100644 MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
create mode 100644 MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
diff --git a/MdeModulePkg/Include/Library/StandaloneMmRuntimeDxe.h b/MdeModulePkg/Include/Library/StandaloneMmRuntimeDxe.h
new file mode 100644
index 0000000000..e4a61f6a7b
--- /dev/null
+++ b/MdeModulePkg/Include/Library/StandaloneMmRuntimeDxe.h
@@ -0,0 +1,39 @@
+/** @file
+ Provides a service to retrieve a pointer to the Standalone MM Services Table.
+ Only available to Standalone MM module types.
+
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+
+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.
+
+**/
+
+#ifndef __STANDALONEMM_RUNTIME_DXE_LIB_H__
+#define __STANDALONEMM_RUNTIME_DXE_LIB_H__
+
+#include <PiDxe.h>
+
+/**
+ This function allows the caller to determine if the driver is executing in
+ Standalone Management Mode(SMM).
+
+ This function returns TRUE if the driver is executing in SMM and FALSE if the
+ driver is not executing in SMM.
+
+ @retval TRUE The driver is executing in Standalone Management Mode (SMM).
+ @retval FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+ VOID
+ );
+
+#endif
diff --git a/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c b/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
new file mode 100644
index 0000000000..61ef59a19a
--- /dev/null
+++ b/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.c
@@ -0,0 +1,36 @@
+/** @file
+ StandaloneMmRuntimeDxe Library.
+
+ Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+#include <PiDxe.h>
+
+/**
+ This function allows the caller to determine if the driver is executing in
+ Standalone Management Mode(SMM).
+
+ This function returns TRUE if the driver is executing in SMM and FALSE if the
+ driver is not executing in SMM.
+
+ @retval TRUE The driver is executing in Standalone Management Mode (SMM).
+ @retval FALSE The driver is not executing in Standalone Management Mode (SMM).
+
+**/
+BOOLEAN
+EFIAPI
+InMm (
+ VOID
+ )
+{
+ return FALSE;
+}
diff --git a/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf b/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
new file mode 100644
index 0000000000..5948fd2708
--- /dev/null
+++ b/MdeModulePkg/Library/StandaloneMmRuntimeDxe/StandaloneMmRuntimeDxe.inf
@@ -0,0 +1,43 @@
+## @file
+# Provides StandaloneMmRuntimeDxe.
+#
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+#
+# 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 = StandaloneMmRuntimeDxe
+ FILE_GUID = 8099cfbf-9564-4c9b-9052-e66b1da88930
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StandaloneMmRuntimeDxe |DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmRuntimeDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (2 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 03/11] MdeModulePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:52 ` Leif Lindholm
2018-11-27 11:26 ` [RFC PATCH v2 05/11] MdeModulePkg/FaultTolerantWriteDxe: " Jagadeesh Ujja
` (6 subsequent siblings)
10 siblings, 1 reply; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
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.
Change-Id: Ic55ea0bc4098aefd6edfea03e11116dd5ccf5f2e
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
Signed-off-by: Vishwanatha HG <vishwanatha.hg@arm.com>
---
.../Drivers/NorFlashDxe/NorFlashBlockIoDxe.c | 2 +-
.../Drivers/NorFlashDxe/NorFlashDxe.c | 211 ++++++++++++++----
.../Drivers/NorFlashDxe/NorFlashDxe.h | 5 +-
.../Drivers/NorFlashDxe/NorFlashDxe.inf | 3 +
.../Drivers/NorFlashDxe/NorFlashFvbDxe.c | 96 ++++----
.../NorFlashDxe/NorFlashStandaloneMm.inf | 76 +++++++
6 files changed, 304 insertions(+), 89 deletions(-)
create mode 100644 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
index 279b77c75e..4c002c7d65 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.<BR>
+ Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
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 46e815beb3..706906a974 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.<BR>
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -134,29 +134,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;
+ }
}
}
@@ -338,13 +411,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;
@@ -363,9 +438,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;
@@ -591,13 +668,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);
@@ -657,9 +736,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)) {
@@ -1331,6 +1412,54 @@ 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,
+ &NorFlashDevices[Index].Guid,
+ &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 5c07694fbf..e3932a190b 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.<BR>
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
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 <Base.h>
#include <PiDxe.h>
+#include <PiMm.h>
#include <Guid/EventGroup.h>
#include <Protocol/BlockIo.h>
@@ -30,6 +31,8 @@
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeLib.h>
+#include <Library/StandaloneMmServicesTableLib.h>
+#include <Library/StandaloneMmRuntimeDxe.h>
#define NOR_FLASH_ERASE_RETRY 10
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
index a59a21a03e..a704f69ef3 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 e62ffbb433..e4d7100ee1 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.<BR>
+ Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
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 0000000000..a6d0581b79
--- /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.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 05/11] MdeModulePkg/FaultTolerantWriteDxe: allow reusability as a MM driver
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (3 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 06/11] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Adapt the FaultTolerantWriteDxe driver to be used as a MM_STANDALONE
driver to provide UEFI fault tolerant write protocol functionality
for variable reclaim operation on EFI variables stored on a NOR flash
that is only accessible to code executing in MM Standalone mode.
Change-Id: Ife29e7d6e7f5d17829abb3ce4ddf0eb94f8e7b28
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../FaultTolerantWriteDxe.inf | 2 +
.../FaultTolerantWriteSmm.c | 203 +++++++++++++-----
.../FaultTolerantWriteStandaloneMm.inf | 102 +++++++++
.../UpdateWorkingBlock.c | 27 +--
4 files changed, 273 insertions(+), 61 deletions(-)
create mode 100644 MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
index dcde58d632..db45be0a98 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
@@ -41,6 +41,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
[LibraryClasses]
UefiBootServicesTableLib
@@ -69,6 +70,7 @@
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
index fabd713c74..ace39fd4d2 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
@@ -44,6 +44,7 @@
This driver need to make sure the CommBuffer is not in the SMRAM range.
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
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
@@ -55,13 +56,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiSmm.h>
+#include <PiMm.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/SmmMemLib.h>
+#include <Library/StandaloneMmMemLib.h>
#include <Library/BaseLib.h>
#include <Protocol/SmmSwapAddressRange.h>
#include "FaultTolerantWrite.h"
#include "FaultTolerantWriteSmmCommon.h"
#include <Protocol/SmmEndOfDxe.h>
+#include <Library/StandaloneMmServicesTableLib.h>
EFI_EVENT mFvbRegistration = NULL;
EFI_FTW_DEVICE *mFtwDevice = NULL;
@@ -92,11 +96,19 @@ FtwGetFvbByHandle (
//
// To get the SMM FVB protocol interface on the handle
//
- return gSmst->SmmHandleProtocol (
- FvBlockHandle,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- (VOID **) FvBlock
- );
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ return gSmst->SmmHandleProtocol (
+ FvBlockHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+ } else {
+ return gMmst->MmHandleProtocol (
+ FvBlockHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+ }
}
/**
@@ -119,11 +131,19 @@ FtwGetSarProtocol (
//
// Locate Smm Swap Address Range protocol
//
- Status = gSmst->SmmLocateProtocol (
- &gEfiSmmSwapAddressRangeProtocolGuid,
- NULL,
- SarProtocol
- );
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSwapAddressRangeProtocolGuid,
+ NULL,
+ SarProtocol
+ );
+ } else {
+ Status = gMmst->MmLocateProtocol (
+ &gEfiSmmSwapAddressRangeProtocolGuid,
+ NULL,
+ SarProtocol
+ );
+ }
return Status;
}
@@ -158,13 +178,23 @@ GetFvbCountAndBuffer (
BufferSize = 0;
*NumberHandles = 0;
*Buffer = NULL;
- Status = gSmst->SmmLocateHandle (
- ByProtocol,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- NULL,
- &BufferSize,
- *Buffer
- );
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ } else {
+ Status = gMmst->MmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ }
if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_FOUND;
}
@@ -173,15 +203,23 @@ GetFvbCountAndBuffer (
if (*Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
- Status = gSmst->SmmLocateHandle (
- ByProtocol,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- NULL,
- &BufferSize,
- *Buffer
- );
-
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ } else {
+ Status = gMmst->MmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ }
*NumberHandles = BufferSize / sizeof(EFI_HANDLE);
if (EFI_ERROR(Status)) {
*NumberHandles = 0;
@@ -335,10 +373,16 @@ SmmFaultTolerantWriteHandler (
return EFI_SUCCESS;
}
CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;
-
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
- DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
- return EFI_SUCCESS;
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (!MmIsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ return EFI_SUCCESS;
+ }
}
SmmFtwFunctionHeader = (SMM_FTW_COMMUNICATE_FUNCTION_HEADER *)CommBuffer;
@@ -531,11 +575,19 @@ FvbNotificationEvent (
// Just return to avoid install SMM FaultTolerantWriteProtocol again
// if SMM Fault Tolerant Write protocol had been installed.
//
- Status = gSmst->SmmLocateProtocol (
- &gEfiSmmFaultTolerantWriteProtocolGuid,
- NULL,
- (VOID **) &FtwProtocol
- );
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ NULL,
+ (VOID **) &FtwProtocol
+ );
+ } else {
+ Status = gMmst->MmLocateProtocol (
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ NULL,
+ (VOID **) &FtwProtocol
+ );
+ }
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
@@ -551,31 +603,45 @@ FvbNotificationEvent (
//
// Install protocol interface
//
- Status = gSmst->SmmInstallProtocolInterface (
- &mFtwDevice->Handle,
- &gEfiSmmFaultTolerantWriteProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mFtwDevice->FtwInstance
- );
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmmInstallProtocolInterface (
+ &mFtwDevice->Handle,
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mFtwDevice->FtwInstance
+ );
+ } else {
+ Status = gMmst->MmInstallProtocolInterface (
+ &mFtwDevice->Handle,
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mFtwDevice->FtwInstance
+ );
+ }
ASSERT_EFI_ERROR (Status);
///
/// Register SMM FTW SMI handler
///
- Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
- ASSERT_EFI_ERROR (Status);
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
+ ASSERT_EFI_ERROR (Status);
- //
- // Notify the Ftw wrapper driver SMM Ftw is ready
- //
- FtwHandle = NULL;
- Status = gBS->InstallProtocolInterface (
+ //
+ // Notify the Ftw wrapper driver SMM Ftw is ready
+ //
+ FtwHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
&FtwHandle,
&gEfiSmmFaultTolerantWriteProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
- ASSERT_EFI_ERROR (Status);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ Status = gMmst->MmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);
+ ASSERT_EFI_ERROR (Status);
+ }
return EFI_SUCCESS;
}
@@ -655,3 +721,42 @@ SmmFaultTolerantWriteInitialize (
return EFI_SUCCESS;
}
+
+/**
+ This function is the entry point of the Fault Tolerant Write driver.
+
+ @param[in] ImageHandle A handle for the image that is initializing this driver
+ @param[in] SystemTable A pointer to the EFI system table
+
+ @retval EFI_SUCCESS The initialization finished successfully.
+ @retval EFI_OUT_OF_RESOURCES Allocate memory error
+ @retval EFI_INVALID_PARAMETER Workspace or Spare block does not exist
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmFaultTolerantWriteInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Allocate private data structure for SMM FTW protocol and do some initialization
+ //
+ Status = InitFtwDevice (&mFtwDevice);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ Status = gMmst->MmRegisterProtocolNotify (
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ FvbNotificationEvent,
+ &mFvbRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ FvbNotificationEvent (NULL, NULL, NULL);
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
new file mode 100644
index 0000000000..724534b09b
--- /dev/null
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf
@@ -0,0 +1,102 @@
+## @file
+# Fault Tolerant Write Smm Driver.
+#
+# This driver installs SMM Fault Tolerant Write (FTW) protocol, which provides fault
+# tolerant write capability in SMM environment for block devices. Its implementation
+# depends on the full functionality SMM FVB protocol that support read, write/erase
+# flash access.
+#
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+#
+# 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 = 0x0001001A
+ BASE_NAME = FaultTolerantWriteMmStandalone
+ MODULE_UNI_FILE = SmmFaultTolerantWriteDxe.uni
+ FILE_GUID = 470CB248-E8AC-473c-BB4F-81069A1FE6FD
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = StandaloneMmFaultTolerantWriteInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ FtwMisc.c
+ UpdateWorkingBlock.c
+ FaultTolerantWrite.c
+ FaultTolerantWriteSmm.c
+ FaultTolerantWrite.h
+ FaultTolerantWriteSmmCommon.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ ReportStatusCodeLib
+ MemLib
+ StandaloneMmDriverEntryPoint
+ BaseLib
+ MmServicesTableLib
+
+[Guids]
+ #
+ # Signature in EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER
+ #
+ ## CONSUMES ## GUID
+ ## PRODUCES ## GUID
+ gEdkiiWorkingBlockSignatureGuid
+
+[Protocols]
+ gEfiSmmSwapAddressRangeProtocolGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## SOMETIMES_CONSUMES
+ ## NOTIFY
+ ## CONSUMES
+ gEfiSmmFirmwareVolumeBlockProtocolGuid
+ ## PRODUCES
+ ## UNDEFINED # SmiHandlerRegister
+ gEfiSmmFaultTolerantWriteProtocolGuid
+ gEfiSmmEndOfDxeProtocolGuid ## CONSUMES
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFullFtwServiceEnable ## CONSUMES
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES
+
+#
+# gBS->CalculateCrc32() is consumed in EntryPoint.
+# PI spec said: When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL
+# has been installed, then the Boot Service CalculateCrc32() is available.
+# So add gEfiRuntimeArchProtocolGuid Depex here.
+#
+[Depex]
+ TRUE
+ #gEfiSmmFirmwareVolumeBlockProtocolGuid AND gEfiRuntimeArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ SmmFaultTolerantWriteDxeExtra.uni
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
index 50d3421b88..85af89a5aa 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
@@ -3,6 +3,7 @@
Internal functions to operate Working Block Space.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
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
@@ -57,19 +58,21 @@ InitializeLocalWorkSpaceHeader (
);
mWorkingBlockHeader.WriteQueueSize = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);
- //
- // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.
- //
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ //
+ // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.
+ //
- //
- // Calculate the Crc of woking block header
- //
- Status = gBS->CalculateCrc32 (
- &mWorkingBlockHeader,
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
- &mWorkingBlockHeader.Crc
- );
- ASSERT_EFI_ERROR (Status);
+ //
+ // Calculate the Crc of woking block header
+ //
+ Status = gBS->CalculateCrc32 (
+ &mWorkingBlockHeader,
+ sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
+ &mWorkingBlockHeader.Crc
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
mWorkingBlockHeader.WorkingBlockValid = FTW_VALID_STATE;
mWorkingBlockHeader.WorkingBlockInvalid = FTW_INVALID_STATE;
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 06/11] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (4 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 05/11] MdeModulePkg/FaultTolerantWriteDxe: " Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 07/11] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Adapt the VariableSmmRuntimeDxe driver to communicate with a VariableSmm
driver that is implemented as a MM Standalone driver.
Change-Id: I328be6df99eaf1a815d6352fe86f0679792b3468
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../RuntimeDxe/VariableRuntimeDxe.inf | 2 ++
.../RuntimeDxe/VariableSmmRuntimeDxe.c | 31 ++++++++++++-------
.../RuntimeDxe/VariableSmmRuntimeDxe.inf | 4 +++
3 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index 868981ccaf..f414b461d8 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -51,6 +51,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
[LibraryClasses]
MemoryAllocationLib
@@ -135,6 +136,7 @@
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
index 85d655dc19..da4af5f30e 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -14,6 +14,8 @@
InitCommunicateBuffer() is really function to check the variable data size.
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+
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
@@ -179,7 +181,11 @@ SendCommunicateBuffer (
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
- Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBufferPhysical, &CommSize);
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBuffer, &CommSize);
+ } else {
+ Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBufferPhysical, &CommSize);
+ }
ASSERT_EFI_ERROR (Status);
SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) mVariableBuffer;
@@ -991,9 +997,11 @@ SmmVariableReady (
{
EFI_STATUS Status;
- Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
- if (EFI_ERROR (Status)) {
- return;
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
}
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
@@ -1069,13 +1077,14 @@ SmmVariableWriteReady (
{
EFI_STATUS Status;
VOID *ProtocolOps;
-
- //
- // Check whether the protocol is installed or not.
- //
- Status = gBS->LocateProtocol (&gSmmVariableWriteGuid, NULL, (VOID **) &ProtocolOps);
- if (EFI_ERROR (Status)) {
- return;
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ //
+ // Check whether the protocol is installed or not.
+ //
+ Status = gBS->LocateProtocol (&gSmmVariableWriteGuid, NULL, (VOID **) &ProtocolOps);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
}
//
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
index bd73f7ac29..b409fa2f58 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
@@ -48,6 +48,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
[LibraryClasses]
MemoryAllocationLib
@@ -87,6 +88,9 @@
## SOMETIMES_CONSUMES ## Variable:L"dbt"
gEfiImageSecurityDatabaseGuid
+[FeaturePcd]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
+
[Depex]
gEfiSmmCommunicationProtocolGuid
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 07/11] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (5 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 06/11] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 08/11] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
Adapt the variable runtime dxe driver to be used as a MM_STANDALONE
driver to provide variable storage service in MM Standalone mode.
Change-Id: Ia1c60d15a24a47d235a6d2a88164b84f39fcf81b
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../Universal/Variable/RuntimeDxe/Variable.c | 37 ++--
.../Variable/RuntimeDxe/VariableSmm.c | 201 ++++++++++++++----
.../RuntimeDxe/VariableStandaloneMm.inf | 132 ++++++++++++
3 files changed, 312 insertions(+), 58 deletions(-)
create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 8e8db71bd2..226464c964 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -18,6 +18,7 @@
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
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
@@ -3247,19 +3248,21 @@ VariableServiceSetVariable (
}
}
- //
- // Special Handling for MOR Lock variable.
- //
- Status = SetVariableCheckHandlerMor (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));
- if (Status == EFI_ALREADY_STARTED) {
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
//
- // EFI_ALREADY_STARTED means the SetVariable() action is handled inside of SetVariableCheckHandlerMor().
- // Variable driver can just return SUCCESS.
+ // Special Handling for MOR Lock variable.
//
- return EFI_SUCCESS;
- }
- if (EFI_ERROR (Status)) {
- return Status;
+ Status = SetVariableCheckHandlerMor (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));
+ if (Status == EFI_ALREADY_STARTED) {
+ //
+ // EFI_ALREADY_STARTED means the SetVariable() action is handled inside of SetVariableCheckHandlerMor().
+ // Variable driver can just return SUCCESS.
+ //
+ return EFI_SUCCESS;
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
Status = VarCheckLibSetVariableCheck (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize), mRequestSource);
@@ -4068,12 +4071,14 @@ VariableWriteServiceInitialize (
}
}
- ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
- //
- // Initialize MOR Lock variable.
- //
- MorLockInit ();
+ //
+ // Initialize MOR Lock variable.
+ //
+ MorLockInit ();
+ }
return Status;
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
index 6dc19c24db..cbbb446669 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
@@ -15,6 +15,7 @@
SmmVariableGetStatistics() should also do validation based on its own knowledge.
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
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
@@ -34,6 +35,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/SmmServicesTableLib.h>
#include <Library/SmmMemLib.h>
+#include <Library/StandaloneMmMemLib.h>
+#include <Library/StandaloneMmServicesTableLib.h>
#include <Guid/SmmVariableCommon.h>
#include "Variable.h"
@@ -218,11 +221,19 @@ GetFtwProtocol (
//
// Locate Smm Fault Tolerent Write protocol
//
- Status = gSmst->SmmLocateProtocol (
- &gEfiSmmFaultTolerantWriteProtocolGuid,
- NULL,
- FtwProtocol
- );
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gMmst->MmLocateProtocol (
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ NULL,
+ FtwProtocol
+ );
+ } else {
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ NULL,
+ FtwProtocol
+ );
+ }
return Status;
}
@@ -248,11 +259,19 @@ GetFvbByHandle (
//
// To get the SMM FVB protocol interface on the handle
//
- return gSmst->SmmHandleProtocol (
- FvBlockHandle,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- (VOID **) FvBlock
- );
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ return gMmst->MmHandleProtocol (
+ FvBlockHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+ } else {
+ return gSmst->SmmHandleProtocol (
+ FvBlockHandle,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+ }
}
@@ -287,13 +306,23 @@ GetFvbCountAndBuffer (
BufferSize = 0;
*NumberHandles = 0;
*Buffer = NULL;
- Status = gSmst->SmmLocateHandle (
- ByProtocol,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- NULL,
- &BufferSize,
- *Buffer
- );
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gMmst->MmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ } else {
+ Status = gSmst->SmmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ }
if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_FOUND;
}
@@ -303,14 +332,23 @@ GetFvbCountAndBuffer (
return EFI_OUT_OF_RESOURCES;
}
- Status = gSmst->SmmLocateHandle (
- ByProtocol,
- &gEfiSmmFirmwareVolumeBlockProtocolGuid,
- NULL,
- &BufferSize,
- *Buffer
- );
-
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gMmst->MmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ } else {
+ Status = gSmst->SmmLocateHandle (
+ ByProtocol,
+ &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &BufferSize,
+ *Buffer
+ );
+ }
*NumberHandles = BufferSize / sizeof(EFI_HANDLE);
if (EFI_ERROR(Status)) {
*NumberHandles = 0;
@@ -499,10 +537,16 @@ SmmVariableHandler (
DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n"));
return EFI_SUCCESS;
}
-
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
- DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
- return EFI_SUCCESS;
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ if (!MmIsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ return EFI_SUCCESS;
+ }
}
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;
@@ -691,13 +735,17 @@ SmmVariableHandler (
break;
}
if (!mEndOfDxe) {
- MorLockInitAtEndOfDxe ();
- mEndOfDxe = TRUE;
- VarCheckLibInitializeAtEndOfDxe (NULL);
- //
- // The initialization for variable quota.
- //
- InitializeVariableQuota ();
+ if (!PcdGetBool (PcdStandaloneMmEnable)){
+ MorLockInitAtEndOfDxe ();
+ mEndOfDxe = TRUE;
+ VarCheckLibInitializeAtEndOfDxe (NULL);
+ //
+ // The initialization for variable quota.
+ //
+ InitializeVariableQuota ();
+ } else {
+ mEndOfDxe = TRUE;
+ }
}
ReclaimForOS ();
Status = EFI_SUCCESS;
@@ -911,12 +959,22 @@ SmmFtwNotificationEvent (
//
// Notify the variable wrapper driver the variable write service is ready
//
- Status = gBS->InstallProtocolInterface (
- &mSmmVariableHandle,
- &gSmmVariableWriteGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
+ if (PcdGetBool (PcdStandaloneMmEnable)) {
+ Status = gMmst->MmInstallProtocolInterface (
+ &mSmmVariableHandle,
+ &gSmmVariableWriteGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ } else {
+ Status = gBS->InstallProtocolInterface (
+ &mSmmVariableHandle,
+ &gSmmVariableWriteGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ }
+
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
@@ -1026,4 +1084,63 @@ VariableServiceInitialize (
return EFI_SUCCESS;
}
+/**
+ Variable Driver main entry point. The Variable driver places the 4 EFI
+ runtime services in the EFI System Table and installs arch protocols
+ for variable read and write services being available. It also registers
+ a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Variable service successfully initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmVariableServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE VariableHandle;
+ VOID *SmmFtwRegistration;
+
+ //
+ // Variable initialize.
+ //
+ Status = VariableCommonInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ mVariableBufferPayloadSize = GetMaxVariableSize () +
+ OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - GetVariableHeaderSize ();
+
+ Status = gMmst->MmAllocatePool (
+ EfiRuntimeServicesData,
+ mVariableBufferPayloadSize,
+ (VOID **)&mVariableBufferPayload
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Register SMM variable SMI handler
+ ///
+ VariableHandle = NULL;
+ Status = gMmst->MmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Register FtwNotificationEvent () notify function.
+ //
+ Status = gMmst->MmRegisterProtocolNotify (
+ &gEfiSmmFaultTolerantWriteProtocolGuid,
+ SmmFtwNotificationEvent,
+ &SmmFtwRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SmmFtwNotificationEvent (NULL, NULL, NULL);
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
new file mode 100644
index 0000000000..35654f5cfc
--- /dev/null
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
@@ -0,0 +1,132 @@
+## @file
+# Provides MM variable service.
+#
+# The whole MM authentication variable design relies on the integrity of flash part and MM.
+# which is assumed to be protected by platform. All variable code and metadata in flash/MM Memory
+# may not be modified without authorization. If platform fails to protect these resources,
+# the authentication service provided in this driver will be broken, and the behavior is undefined.
+#
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
+# 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 = 0x0001000A
+ BASE_NAME = VariableSmm
+ MODULE_UNI_FILE = VariableSmm.uni
+ FILE_GUID = 23A089B3-EED5-4ac5-B2AB-43E3298C2343
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = StandaloneMmVariableServiceInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ Reclaim.c
+ Variable.c
+ VariableSmm.c
+ VarCheck.c
+ Variable.h
+ PrivilegePolymorphic.h
+ VariableExLib.c
+ TcgMorLockSmm.c
+ LoadFenceSmm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ StandaloneMmDriverEntryPoint
+ MemoryAllocationLib
+ BaseLib
+ SynchronizationLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ PcdLib
+ AuthVariableLib
+ VarCheckLib
+ MemLib
+ MmServicesTableLib
+
+[Protocols]
+ gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES
+ ## CONSUMES
+ ## NOTIFY
+ gEfiSmmFaultTolerantWriteProtocolGuid
+ ## PRODUCES
+ ## UNDEFINED # SmiHandlerRegister
+ gEfiSmmVariableProtocolGuid
+ ##gEfiSmmEndOfDxeProtocolGuid ## NOTIFY
+ gEdkiiSmmVarCheckProtocolGuid ## PRODUCES
+ gEfiTcgProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ ## SOMETIMES_CONSUMES ## GUID # Signature of Variable store header
+ ## SOMETIMES_PRODUCES ## GUID # Signature of Variable store header
+ ## SOMETIMES_CONSUMES ## HOB
+ ## SOMETIMES_PRODUCES ## SystemTable
+ gEfiAuthenticatedVariableGuid
+
+ ## SOMETIMES_CONSUMES ## GUID # Signature of Variable store header
+ ## SOMETIMES_PRODUCES ## GUID # Signature of Variable store header
+ ## SOMETIMES_CONSUMES ## HOB
+ ## SOMETIMES_PRODUCES ## SystemTable
+ gEfiVariableGuid
+
+ ## SOMETIMES_CONSUMES ## Variable:L"PlatformLang"
+ ## SOMETIMES_PRODUCES ## Variable:L"PlatformLang"
+ ## SOMETIMES_CONSUMES ## Variable:L"Lang"
+ ## SOMETIMES_PRODUCES ## Variable:L"Lang"
+ gEfiGlobalVariableGuid
+
+ gEfiMemoryOverwriteControlDataGuid ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl"
+ gEfiMemoryOverwriteRequestControlLockGuid ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControlLock"
+
+ gSmmVariableWriteGuid ## PRODUCES ## GUID # Install protocol
+ gEfiSystemNvDataFvGuid ## CONSUMES ## GUID
+ gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB
+
+ ## SOMETIMES_CONSUMES ## Variable:L"VarErrorFlag"
+ ## SOMETIMES_PRODUCES ## Variable:L"VarErrorFlag"
+ gEdkiiVarErrorFlagGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## CONSUMES
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ VariableSmmExtra.uni
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 08/11] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (6 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 07/11] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 09/11] MdeModulePkg/VarCheckLib: " Jagadeesh Ujja
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
“AuthVariableLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports
Change-Id: I86e7f7162e4a7a9ef11a5c0ba7196f22c184aad0
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
Reviewed-by: Chao Zhang <chao.b.zhang@intel.com>
---
SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
index 572ba4e120..4294d3b1b0 100644
--- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
@@ -2,6 +2,7 @@
# Provides authenticated variable services.
#
# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions
@@ -21,12 +22,12 @@
FILE_GUID = B23CF5FB-6FCC-4422-B145-D855DBC05457
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+ LIBRARY_CLASS = AuthVariableLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#
[Sources]
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 09/11] MdeModulePkg/VarCheckLib: allow MM_STANDALONE drivers to use this library
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (7 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 08/11] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 10/11] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 11/11] CryptoPkg/BaseCryptLib: Hack to get time in MM Standalone mode Jagadeesh Ujja
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
“VarCheckLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports
Change-Id: I09cc068a3a8a4d320789b2074d12978730a1ab50
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
index 099f83dd6a..c8cf81063e 100644
--- a/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+++ b/MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
@@ -2,6 +2,7 @@
# Provides variable check services and database management.
#
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions
@@ -21,12 +22,12 @@
FILE_GUID = 63E12D08-0C5D-47F8-95E4-09F89D7506C5
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
+ LIBRARY_CLASS = VarCheckLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER MM_STANDALONE
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#
[Sources]
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 10/11] CryptoPkg/BaseCryptLib: allow MM_STANDALONE drivers to use this library
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (8 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 09/11] MdeModulePkg/VarCheckLib: " Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 11/11] CryptoPkg/BaseCryptLib: Hack to get time in MM Standalone mode Jagadeesh Ujja
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
“BaseCryptLib” library can be used by MM_STANDALONE drivers as well.
So add MM_STANDALONE as the module type this library supports
Change-Id: I3f3dfd18b0bb62f5317199858c4b9507682895bd
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index f29445ce34..c8aafefbab 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -7,6 +7,7 @@
# buffer overflow or integer overflow.
#
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
# 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
@@ -24,7 +25,7 @@
FILE_GUID = be3bb803-91b6-4da0-bd91-a8b21c18ca5d
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+ LIBRARY_CLASS = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER MM_STANDALONE
#
# The following information is for reference only and not required by the build tools.
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC PATCH v2 11/11] CryptoPkg/BaseCryptLib: Hack to get time in MM Standalone mode
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
` (9 preceding siblings ...)
2018-11-27 11:26 ` [RFC PATCH v2 10/11] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
@ 2018-11-27 11:26 ` Jagadeesh Ujja
10 siblings, 0 replies; 13+ messages in thread
From: Jagadeesh Ujja @ 2018-11-27 11:26 UTC (permalink / raw)
To: edk2-devel, liming.gao, chao.b.zhang, lersek, leif.lindholm,
ard.biesheuvel
This is hack to get the time when executing in MM Standalone mode. It is
not clear how to implement a function that gets the current time. So
using this as a hack for now.
Change-Id: I5b86a31c3023f31f04985e82a1089cf4d022f060
Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
---
.../Library/BaseCryptLib/BaseCryptLib.inf | 5 ++++
.../Library/BaseCryptLib/RuntimeCryptLib.inf | 5 ++++
.../BaseCryptLib/SysCall/TimerWrapper.c | 27 ++++++++++++++-----
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index c8aafefbab..df4aca6c20 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -76,6 +76,7 @@
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
[LibraryClasses]
BaseLib
@@ -86,6 +87,10 @@
OpensslLib
IntrinsicLib
PrintLib
+ PcdLib
+
+[FeaturePcd]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
#
# Remove these [BuildOptions] after this library is cleaned up
diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index 32628c8835..651a6736ba 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -80,6 +80,7 @@
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
[LibraryClasses]
BaseLib
@@ -91,6 +92,10 @@
OpensslLib
IntrinsicLib
PrintLib
+ PcdLib
+
+[FeaturePcd]
+ gStandaloneMmPkgTokenSpaceGuid.PcdStandaloneMmEnable
#
# Remove these [BuildOptions] after this library is cleaned up
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
index 5f9b0c20d7..d01b5c5fc1 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
@@ -3,6 +3,7 @@
for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME).
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2018, ARM Limited. All rights reserved.<BR>
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
@@ -77,12 +78,26 @@ time_t time (time_t *timer)
time_t CalTime;
UINTN Year;
- //
- // Get the current time and date information
- //
- Status = gRT->GetTime (&Time, NULL);
- if (EFI_ERROR (Status) || (Time.Year < 1970)) {
- return 0;
+ if (!PcdGetBool (PcdStandaloneMmEnable)) {
+ //
+ // Get the current time and date information
+ //
+ Status = gRT->GetTime (&Time, NULL);
+ if (EFI_ERROR (Status) || (Time.Year < 1970)) {
+ return 0;
+ }
+ } else {
+ //
+ //[ToDo] Find out a way to get the current time for code executing as MM_STANDALONE
+ //
+ Time.Year = 2007;
+ Time.Month = 11;
+ Time.Day = 29;
+ Time.Hour = 17;
+ Time.Minute = 43;
+ Time.Second = 30;
+
+ Year = (UINTN) (Time.Year % 100);
}
//
--
2.19.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver
2018-11-27 11:26 ` [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
@ 2018-11-27 11:52 ` Leif Lindholm
0 siblings, 0 replies; 13+ messages in thread
From: Leif Lindholm @ 2018-11-27 11:52 UTC (permalink / raw)
To: Jagadeesh Ujja
Cc: edk2-devel, liming.gao, chao.b.zhang, lersek, ard.biesheuvel,
Thomas Abraham
On Tue, Nov 27, 2018 at 04:56:19PM +0530, Jagadeesh Ujja wrote:
> 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.
>
> Change-Id: Ic55ea0bc4098aefd6edfea03e11116dd5ccf5f2e
Please don't litter commit messages with company-internal tracking
data.
> Signed-off-by: Jagadeesh Ujja <jagadeesh.ujja@arm.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@arm.com>
> Signed-off-by: Vishwanatha HG <vishwanatha.hg@arm.com>
There can be only one Signed-off-by for a patch. That sign-off is you
testifying that this code is submissible under the licenses stated.
If you are contributing a patch where you are not the Author, that
will be reflected by the From: header added by git.
> ---
> .../Drivers/NorFlashDxe/NorFlashBlockIoDxe.c | 2 +-
> .../Drivers/NorFlashDxe/NorFlashDxe.c | 211 ++++++++++++++----
> .../Drivers/NorFlashDxe/NorFlashDxe.h | 5 +-
> .../Drivers/NorFlashDxe/NorFlashDxe.inf | 3 +
> .../Drivers/NorFlashDxe/NorFlashFvbDxe.c | 96 ++++----
> .../NorFlashDxe/NorFlashStandaloneMm.inf | 76 +++++++
> 6 files changed, 304 insertions(+), 89 deletions(-)
> create mode 100644 ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashStandaloneMm.inf
Please rework this set and resubmit based on the above comments, and
also ensuring to follow the guidelines in
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers
Regards,
Leif
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c
> index 279b77c75e..4c002c7d65 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.<BR>
> + Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
>
> 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 46e815beb3..706906a974 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.<BR>
> + Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
> This program and the accompanying materials
> are licensed and made available under the terms and conditions of the BSD License
> @@ -134,29 +134,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;
> + }
> }
> }
>
> @@ -338,13 +411,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;
> @@ -363,9 +438,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;
> @@ -591,13 +668,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);
> @@ -657,9 +736,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)) {
> @@ -1331,6 +1412,54 @@ 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,
> + &NorFlashDevices[Index].Guid,
> + &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 5c07694fbf..e3932a190b 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.<BR>
> + Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
> 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 <Base.h>
> #include <PiDxe.h>
>
> +#include <PiMm.h>
> #include <Guid/EventGroup.h>
>
> #include <Protocol/BlockIo.h>
> @@ -30,6 +31,8 @@
> #include <Library/NorFlashPlatformLib.h>
> #include <Library/UefiLib.h>
> #include <Library/UefiRuntimeLib.h>
> +#include <Library/StandaloneMmServicesTableLib.h>
> +#include <Library/StandaloneMmRuntimeDxe.h>
>
> #define NOR_FLASH_ERASE_RETRY 10
>
> diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
> index a59a21a03e..a704f69ef3 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 e62ffbb433..e4d7100ee1 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.<BR>
> + Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
>
> 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 0000000000..a6d0581b79
> --- /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.19.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2018-11-27 11:53 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-27 11:26 [RFC PATCH v2 00/11] Extend secure variable service to be usable from Standalone MM Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 01/11] MdeModulePkg/Variable: replace all uses of AsmLfence with MemoryFence Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 02/11] StandaloneMmPkg: Pull in additonal libraries from staging branch Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 03/11] MdeModulePkg/Library: Add StandaloneMmRuntimeDxe library Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 04/11] ArmPlatformPkg/NorFlashDxe: allow reusability as a MM driver Jagadeesh Ujja
2018-11-27 11:52 ` Leif Lindholm
2018-11-27 11:26 ` [RFC PATCH v2 05/11] MdeModulePkg/FaultTolerantWriteDxe: " Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 06/11] MdeModulePkg/Variable/RuntimeDxe: adapt for usability with MM Standalone Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 07/11] MdeModulePkg/Variable/RuntimeDxe: adapt as a MM Standalone driver Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 08/11] SecurityPkg/AuthVariableLib: allow MM_STANDALONE drivers to use this library Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 09/11] MdeModulePkg/VarCheckLib: " Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 10/11] CryptoPkg/BaseCryptLib: " Jagadeesh Ujja
2018-11-27 11:26 ` [RFC PATCH v2 11/11] CryptoPkg/BaseCryptLib: Hack to get time in MM Standalone mode Jagadeesh Ujja
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox