SmramSaveInfoHandlerSmm.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /** @file
  2. A helper driver to save information to SMRAM after SMRR is enabled.
  3. This driver is for ECP platforms.
  4. Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiSmm.h>
  8. #include <Library/DebugLib.h>
  9. #include <Library/UefiDriverEntryPoint.h>
  10. #include <Library/UefiRuntimeServicesTableLib.h>
  11. #include <Library/SmmServicesTableLib.h>
  12. #include <Library/BaseLib.h>
  13. #include <Library/BaseMemoryLib.h>
  14. #include <Library/IoLib.h>
  15. #include <Protocol/SmmSwDispatch.h>
  16. #include <Protocol/SmmReadyToLock.h>
  17. #include <Protocol/SmmControl.h>
  18. #include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h>
  19. #define SMM_FROM_SMBASE_DRIVER 0x55
  20. #define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
  21. #define EFI_SMRAM_CPU_NVS_HEADER_GUID \
  22. { \
  23. 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
  24. }
  25. UINT8 mSmiDataRegister;
  26. BOOLEAN mLocked = FALSE;
  27. EFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID;
  28. /**
  29. Dispatch function for a Software SMI handler.
  30. @param DispatchHandle The handle of this dispatch function.
  31. @param DispatchContext The pointer to the dispatch function's context.
  32. The SwSmiInputValue field is filled in
  33. by the software dispatch driver prior to
  34. invoking this dispatch function.
  35. The dispatch function will only be called
  36. for input values for which it is registered.
  37. @return None
  38. **/
  39. VOID
  40. EFIAPI
  41. SmramSaveInfoHandler (
  42. IN EFI_HANDLE DispatchHandle,
  43. IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
  44. )
  45. {
  46. ASSERT (DispatchContext != NULL);
  47. ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER);
  48. if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
  49. CopyMem (
  50. (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxDataAddress)),
  51. (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuSmramCpuDataAddress)),
  52. (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize))
  53. );
  54. }
  55. }
  56. /**
  57. Smm Ready To Lock event notification handler.
  58. It sets a flag indicating that SMRAM has been locked.
  59. @param[in] Protocol Points to the protocol's unique identifier.
  60. @param[in] Interface Points to the interface instance.
  61. @param[in] Handle The handle on which the interface was installed.
  62. @retval EFI_SUCCESS Notification handler runs successfully.
  63. **/
  64. EFI_STATUS
  65. EFIAPI
  66. SmmReadyToLockEventNotify (
  67. IN CONST EFI_GUID *Protocol,
  68. IN VOID *Interface,
  69. IN EFI_HANDLE Handle
  70. )
  71. {
  72. mLocked = TRUE;
  73. return EFI_SUCCESS;
  74. }
  75. /**
  76. Entry point function of this driver.
  77. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  78. @param[in] SystemTable A pointer to the EFI System Table.
  79. @retval EFI_SUCCESS The entry point is executed successfully.
  80. @retval other Some error occurs when executing this entry point.
  81. **/
  82. EFI_STATUS
  83. EFIAPI
  84. SmramSaveInfoHandlerSmmMain (
  85. IN EFI_HANDLE ImageHandle,
  86. IN EFI_SYSTEM_TABLE *SystemTable
  87. )
  88. {
  89. EFI_STATUS Status;
  90. EFI_SMM_SW_DISPATCH_PROTOCOL *SmmSwDispatch;
  91. EFI_SMM_SW_DISPATCH_CONTEXT SmmSwDispatchContext;
  92. EFI_HANDLE DispatchHandle;
  93. EFI_SMM_CONTROL_PROTOCOL *SmmControl;
  94. EFI_SMM_CONTROL_REGISTER SmmControlRegister;
  95. VOID *Registration;
  96. //
  97. // Get SMI data register
  98. //
  99. Status = SystemTable->BootServices->LocateProtocol (
  100. &gEfiSmmControlProtocolGuid,
  101. NULL,
  102. (VOID **)&SmmControl
  103. );
  104. ASSERT_EFI_ERROR (Status);
  105. Status = SmmControl->GetRegisterInfo (SmmControl, &SmmControlRegister);
  106. ASSERT_EFI_ERROR (Status);
  107. mSmiDataRegister = SmmControlRegister.SmiDataRegister;
  108. //
  109. // Register software SMI handler
  110. //
  111. Status = SystemTable->BootServices->LocateProtocol (
  112. &gEfiSmmSwDispatchProtocolGuid,
  113. NULL,
  114. (VOID **)&SmmSwDispatch
  115. );
  116. ASSERT_EFI_ERROR (Status);
  117. SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER;
  118. Status = SmmSwDispatch->Register (
  119. SmmSwDispatch,
  120. &SmramSaveInfoHandler,
  121. &SmmSwDispatchContext,
  122. &DispatchHandle
  123. );
  124. ASSERT_EFI_ERROR (Status);
  125. //
  126. // Register SMM Ready To Lock Protocol notification
  127. //
  128. Status = gSmst->SmmRegisterProtocolNotify (
  129. &gEfiSmmReadyToLockProtocolGuid,
  130. SmmReadyToLockEventNotify,
  131. &Registration
  132. );
  133. ASSERT_EFI_ERROR (Status);
  134. return Status;
  135. }