VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),\r
SmmVariableGetStatistics() should also do validation based on its own knowledge.\r
\r
-Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Protocol/SmmVariable.h>\r
#include <Protocol/SmmFirmwareVolumeBlock.h>\r
#include <Protocol/SmmFaultTolerantWrite.h>\r
-#include <Protocol/SmmEndOfDxe.h>\r
+#include <Protocol/MmEndOfDxe.h>\r
#include <Protocol/SmmVarCheck.h>\r
\r
-#include <Library/SmmServicesTableLib.h>\r
-#include <Library/SmmMemLib.h>\r
+#include <Library/MmServicesTableLib.h>\r
\r
#include <Guid/SmmVariableCommon.h>\r
#include "Variable.h"\r
\r
-extern VARIABLE_INFO_ENTRY *gVariableInfo;\r
-EFI_HANDLE mSmmVariableHandle = NULL;\r
-EFI_HANDLE mVariableHandle = NULL;\r
BOOLEAN mAtRuntime = FALSE;\r
UINT8 *mVariableBufferPayload = NULL;\r
UINTN mVariableBufferPayloadSize;\r
-extern BOOLEAN mEndOfDxe;\r
-extern VAR_CHECK_REQUEST_SOURCE mRequestSource;\r
\r
/**\r
SecureBoot Hook for SetVariable.\r
//\r
// Locate Smm Fault Tolerent Write protocol\r
//\r
- Status = gSmst->SmmLocateProtocol (\r
+ Status = gMmst->MmLocateProtocol (\r
&gEfiSmmFaultTolerantWriteProtocolGuid,\r
NULL,\r
FtwProtocol\r
//\r
// To get the SMM FVB protocol interface on the handle\r
//\r
- return gSmst->SmmHandleProtocol (\r
+ return gMmst->MmHandleProtocol (\r
FvBlockHandle,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
(VOID **) FvBlock\r
BufferSize = 0;\r
*NumberHandles = 0;\r
*Buffer = NULL;\r
- Status = gSmst->SmmLocateHandle (\r
+ Status = gMmst->MmLocateHandle (\r
ByProtocol,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
NULL,\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Status = gSmst->SmmLocateHandle (\r
+ Status = gMmst->MmLocateHandle (\r
ByProtocol,\r
&gEfiSmmFirmwareVolumeBlockProtocolGuid,\r
NULL,\r
return EFI_SUCCESS;\r
}\r
\r
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+ if (!VariableSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
return EFI_SUCCESS;\r
}\r
goto EXIT;\r
}\r
\r
+ //\r
+ // The VariableSpeculationBarrier() call here is to ensure the previous\r
+ // range/content checks for the CommBuffer have been completed before the\r
+ // subsequent consumption of the CommBuffer content.\r
+ //\r
+ VariableSpeculationBarrier ();\r
if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') {\r
//\r
// Make sure VariableName is A Null-terminated string.\r
goto EXIT;\r
}\r
\r
+ //\r
+ // The VariableSpeculationBarrier() call here is to ensure the previous\r
+ // range/content checks for the CommBuffer have been completed before the\r
+ // subsequent consumption of the CommBuffer content.\r
+ //\r
+ VariableSpeculationBarrier ();\r
if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') {\r
//\r
// Make sure VariableName is A Null-terminated string.\r
break;\r
}\r
if (!mEndOfDxe) {\r
+ MorLockInitAtEndOfDxe ();\r
mEndOfDxe = TRUE;\r
VarCheckLibInitializeAtEndOfDxe (NULL);\r
//\r
goto EXIT;\r
}\r
\r
+ //\r
+ // The VariableSpeculationBarrier() call here is to ensure the previous\r
+ // range/content checks for the CommBuffer have been completed before the\r
+ // subsequent consumption of the CommBuffer content.\r
+ //\r
+ VariableSpeculationBarrier ();\r
if (CommVariableProperty->NameSize < sizeof (CHAR16) || CommVariableProperty->Name[CommVariableProperty->NameSize/sizeof (CHAR16) - 1] != L'\0') {\r
//\r
// Make sure VariableName is A Null-terminated string.\r
)\r
{\r
DEBUG ((EFI_D_INFO, "[Variable]SMM_END_OF_DXE is signaled\n"));\r
+ MorLockInitAtEndOfDxe ();\r
mEndOfDxe = TRUE;\r
VarCheckLibInitializeAtEndOfDxe (NULL);\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Initializes variable write service for SMM.\r
+\r
+**/\r
+VOID\r
+VariableWriteServiceInitializeSmm (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = VariableWriteServiceInitialize ();\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
+ }\r
+\r
+ //\r
+ // Notify the variable wrapper driver the variable write service is ready\r
+ //\r
+ VariableNotifySmmWriteReady ();\r
+}\r
+\r
/**\r
SMM Fault Tolerant Write protocol notification event handler.\r
\r
)\r
{\r
EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;\r
EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;\r
EFI_PHYSICAL_ADDRESS NvStorageVariableBase;\r
ASSERT (PcdGet32 (PcdFlashNvStorageVariableSize) <= FtwMaxBlockSize);\r
}\r
\r
+ NvStorageVariableBase = NV_STORAGE_VARIABLE_BASE;\r
+ VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;\r
+\r
+ //\r
+ // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.\r
+ //\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
+\r
//\r
// Find the proper FVB protocol for variable.\r
//\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
- if (NvStorageVariableBase == 0) {\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- }\r
Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);\r
if (EFI_ERROR (Status)) {\r
return EFI_NOT_FOUND;\r
\r
mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
\r
- Status = VariableWriteServiceInitialize ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
- }\r
-\r
//\r
- // Notify the variable wrapper driver the variable write service is ready\r
+ // Initializes variable write service after FTW was ready.\r
//\r
- Status = gBS->InstallProtocolInterface (\r
- &mSmmVariableHandle,\r
- &gSmmVariableWriteGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ VariableWriteServiceInitializeSmm ();\r
\r
return EFI_SUCCESS;\r
}\r
for variable read and write services being available. It also registers\r
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
- @param[in] SystemTable A pointer to the EFI System Table.\r
-\r
@retval EFI_SUCCESS Variable service successfully initialized.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-VariableServiceInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+MmVariableServiceInitialize (\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
// Install the Smm Variable Protocol on a new handle.\r
//\r
VariableHandle = NULL;\r
- Status = gSmst->SmmInstallProtocolInterface (\r
+ Status = gMmst->MmInstallProtocolInterface (\r
&VariableHandle,\r
&gEfiSmmVariableProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = gSmst->SmmInstallProtocolInterface (\r
+ Status = gMmst->MmInstallProtocolInterface (\r
&VariableHandle,\r
&gEdkiiSmmVarCheckProtocolGuid,\r
EFI_NATIVE_INTERFACE,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- mVariableBufferPayloadSize = GetNonVolatileMaxVariableSize () +\r
+ mVariableBufferPayloadSize = GetMaxVariableSize () +\r
OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - GetVariableHeaderSize ();\r
\r
- Status = gSmst->SmmAllocatePool (\r
+ Status = gMmst->MmAllocatePool (\r
EfiRuntimeServicesData,\r
mVariableBufferPayloadSize,\r
(VOID **)&mVariableBufferPayload\r
/// Register SMM variable SMI handler\r
///\r
VariableHandle = NULL;\r
- Status = gSmst->SmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);\r
+ Status = gMmst->MmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Notify the variable wrapper driver the variable service is ready\r
//\r
- Status = SystemTable->BootServices->InstallProtocolInterface (\r
- &mVariableHandle,\r
- &gEfiSmmVariableProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &gSmmVariable\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ VariableNotifySmmReady ();\r
\r
//\r
// Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.\r
//\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmEndOfDxeProtocolGuid,\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiMmEndOfDxeProtocolGuid,\r
SmmEndOfDxeCallback,\r
&SmmEndOfDxeRegistration\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Register FtwNotificationEvent () notify function.\r
- //\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEfiSmmFaultTolerantWriteProtocolGuid,\r
- SmmFtwNotificationEvent,\r
- &SmmFtwRegistration\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- SmmFtwNotificationEvent (NULL, NULL, NULL);\r
+ if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {\r
+ //\r
+ // Register FtwNotificationEvent () notify function.\r
+ //\r
+ Status = gMmst->MmRegisterProtocolNotify (\r
+ &gEfiSmmFaultTolerantWriteProtocolGuid,\r
+ SmmFtwNotificationEvent,\r
+ &SmmFtwRegistration\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ SmmFtwNotificationEvent (NULL, NULL, NULL);\r
+ } else {\r
+ //\r
+ // Emulated non-volatile variable mode does not depend on FVB and FTW.\r
+ //\r
+ VariableWriteServiceInitializeSmm ();\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r