From 1c837cd545b6b91c41f1fbebf84b54cb7ccf499e Mon Sep 17 00:00:00 2001 From: jljusten Date: Tue, 19 Jul 2011 20:47:28 +0000 Subject: MdeModulePkg: Add SMM LockBox This includes: * LockBox protocol definition * LockBoxLib library interface definition * SmmLockBox GUID * LockBoxNullLib library implementation * 2 SmmLockBoxLib library implementations * SmmLockBox SMM driver Signed-off-by: jljusten Reviewed-by: mdkinney Reviewed-by: geekboy15a Reviewed-by: jyao1 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12029 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/LockBox/SmmLockBox/SmmLockBox.c | 373 +++++++++++++++++++++ .../Universal/LockBox/SmmLockBox/SmmLockBox.inf | 59 ++++ 2 files changed, 432 insertions(+) create mode 100644 MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c create mode 100644 MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf (limited to 'MdeModulePkg/Universal/LockBox') diff --git a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c new file mode 100644 index 0000000000..1f9c3b4836 --- /dev/null +++ b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c @@ -0,0 +1,373 @@ +/** @file + +Copyright (c) 2010, Intel Corporation. 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. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN mLocked = FALSE; + +EFI_SMRAM_DESCRIPTOR *mSmramRanges; +UINTN mSmramRangeCount; + +/** + This function check if the address is in SMRAM. + + @param Buffer the buffer address to be checked. + @param Length the buffer length to be checked. + + @retval TRUE this address is in SMRAM. + @retval FALSE this address is NOT in SMRAM. +**/ +BOOLEAN +IsAddressInSmram ( + IN EFI_PHYSICAL_ADDRESS Buffer, + IN UINT64 Length + ) +{ + UINTN Index; + + for (Index = 0; Index < mSmramRangeCount; Index ++) { + if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) || + ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) { + return TRUE; + } + } + + return FALSE; +} + +/** + Dispatch function for SMM lock box save. + + @param LockBoxParameterSave parameter of lock box save +**/ +VOID +SmmLockBoxSave ( + IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave + ) +{ + EFI_STATUS Status; + + // + // Sanity check + // + if (mLocked) { + DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n")); + LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED; + return ; + } + + // + // Save data + // + Status = SaveLockBox ( + &LockBoxParameterSave->Guid, + (VOID *)(UINTN)LockBoxParameterSave->Buffer, + (UINTN)LockBoxParameterSave->Length + ); + LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status; + return ; +} + +/** + Dispatch function for SMM lock box set attributes. + + @param LockBoxParameterSetAttributes parameter of lock box set attributes +**/ +VOID +SmmLockBoxSetAttributes ( + IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes + ) +{ + EFI_STATUS Status; + + // + // Sanity check + // + if (mLocked) { + DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n")); + LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED; + return ; + } + + // + // Update data + // + Status = SetLockBoxAttributes ( + &LockBoxParameterSetAttributes->Guid, + LockBoxParameterSetAttributes->Attributes + ); + LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status; + return ; +} + +/** + Dispatch function for SMM lock box update. + + @param LockBoxParameterUpdate parameter of lock box update +**/ +VOID +SmmLockBoxUpdate ( + IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate + ) +{ + EFI_STATUS Status; + + // + // Sanity check + // + if (mLocked) { + DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n")); + LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED; + return ; + } + + // + // Update data + // + Status = UpdateLockBox ( + &LockBoxParameterUpdate->Guid, + (UINTN)LockBoxParameterUpdate->Offset, + (VOID *)(UINTN)LockBoxParameterUpdate->Buffer, + (UINTN)LockBoxParameterUpdate->Length + ); + LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status; + return ; +} + +/** + Dispatch function for SMM lock box restore. + + @param LockBoxParameterRestore parameter of lock box restore +**/ +VOID +SmmLockBoxRestore ( + IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore + ) +{ + EFI_STATUS Status; + + // + // Sanity check + // + if (IsAddressInSmram (LockBoxParameterRestore->Buffer, LockBoxParameterRestore->Length)) { + DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM!\n")); + LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED; + return ; + } + + // + // Restore data + // + Status = RestoreLockBox ( + &LockBoxParameterRestore->Guid, + (VOID *)(UINTN)LockBoxParameterRestore->Buffer, + (UINTN *)&LockBoxParameterRestore->Length + ); + LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status; + return ; +} + +/** + Dispatch function for SMM lock box restore all in place. + + @param LockBoxParameterRestoreAllInPlace parameter of lock box restore all in place +**/ +VOID +SmmLockBoxRestoreAllInPlace ( + IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace + ) +{ + EFI_STATUS Status; + + Status = RestoreAllLockBoxInPlace (); + LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status; + return ; +} + +/** + Dispatch function for a Software SMI handler. + + @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the + handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-SMM environment into an SMM environment. + @param CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS Command is handled successfully. + +**/ +EFI_STATUS +EFIAPI +SmmLockBoxHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_SMM_LOCK_BOX_PARAMETER_HEADER *LockBoxParameterHeader; + + DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Enter\n")); + + LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER *)((UINTN)CommBuffer); + + LockBoxParameterHeader->ReturnStatus = (UINT64)-1; + + DEBUG ((EFI_D_ERROR, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN)LockBoxParameterHeader)); + + DEBUG ((EFI_D_ERROR, "SmmLockBox Command - %x\n", (UINTN)LockBoxParameterHeader->Command)); + + switch (LockBoxParameterHeader->Command) { + case EFI_SMM_LOCK_BOX_COMMAND_SAVE: + SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)(UINTN)LockBoxParameterHeader); + break; + case EFI_SMM_LOCK_BOX_COMMAND_UPDATE: + SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)LockBoxParameterHeader); + break; + case EFI_SMM_LOCK_BOX_COMMAND_RESTORE: + SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)(UINTN)LockBoxParameterHeader); + break; + case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES: + SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)(UINTN)LockBoxParameterHeader); + break; + case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE: + SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)(UINTN)LockBoxParameterHeader); + break; + default: + break; + } + + LockBoxParameterHeader->Command = (UINT32)-1; + + DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Exit\n")); + + return EFI_SUCCESS; +} + +/** + Smm Ready To Lock event notification handler. + + It sets a flag indicating that SMRAM has been locked. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification handler runs successfully. + **/ +EFI_STATUS +EFIAPI +SmmReadyToLockEventNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + mLocked = TRUE; + return EFI_SUCCESS; +} + +/** + Entry Point for LockBox SMM driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable A Pointer to the EFI System Table. + + @retval EFI_SUCEESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +SmmLockBoxEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE DispatchHandle; + VOID *Registration; + EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; + UINTN Size; + + // + // Get SMRAM information + // + Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess); + ASSERT_EFI_ERROR (Status); + + Size = 0; + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + + Status = gSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + Size, + (VOID **)&mSmramRanges + ); + ASSERT_EFI_ERROR (Status); + + Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges); + ASSERT_EFI_ERROR (Status); + + mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); + + // + // Register LockBox communication handler + // + Status = gSmst->SmiHandlerRegister ( + SmmLockBoxHandler, + &gEfiSmmLockBoxCommunicationGuid, + &DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Register SMM Ready To Lock Protocol notification + // + Status = gSmst->SmmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + SmmReadyToLockEventNotify, + &Registration + ); + ASSERT_EFI_ERROR (Status); + + // + // Install NULL to DXE data base as notify + // + ImageHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gEfiLockBoxProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf new file mode 100644 index 0000000000..94ec412221 --- /dev/null +++ b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf @@ -0,0 +1,59 @@ +## @file +# Component description file for LockBox SMM driver. +# +# Copyright (c) 2010, Intel Corporation. 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 = SmmLockBox + FILE_GUID = 33FB3535-F15E-4c17-B303-5EB94595ECB6 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = SmmLockBoxEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SmmLockBox.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + SmmServicesTableLib + BaseLib + BaseMemoryLib + DebugLib + LockBoxLib + +[Guids] + gEfiSmmLockBoxCommunicationGuid ## PRODUCED + +[Protocols] + gEfiSmmReadyToLockProtocolGuid ## CONSUMED + gEfiSmmAccess2ProtocolGuid ## CONSUMED + gEfiLockBoxProtocolGuid ## PRODUCED + +[Depex] + gEfiSmmSwDispatch2ProtocolGuid + -- cgit v1.2.3