1 /** @file 2 A helper driver to save information to SMRAM after SMRR is enabled. 3 4 This driver is for ECP platforms. 5 6 Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> 7 8 This program and the accompanying materials are licensed and made available under 10 the terms and conditions of the BSD License that accompanies this distribution. 12 The full text of the license may be found at 14 http://opensource.org/licenses/bsd-license.php. 16 18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 22 24 26 **/ 27 28 #include <PiSmm.h> 29 #include <Library/DebugLib.h> 30 #include <Library/UefiDriverEntryPoint.h> 31 #include <Library/UefiRuntimeServicesTableLib.h> 32 #include <Library/SmmServicesTableLib.h> 33 #include <Library/BaseLib.h> 34 #include <Library/BaseMemoryLib.h> 35 #include <Library/IoLib.h> 36 #include <Protocol/SmmSwDispatch.h> 37 #include <Protocol/SmmReadyToLock.h> 38 #include <Protocol/SmmControl.h> 39 #include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h> 40 41 #define SMM_FROM_SMBASE_DRIVER 0x55 42 #define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81 43 44 #define EFI_SMRAM_CPU_NVS_HEADER_GUID \ 45 { \ 46 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \ 47 } 48 49 UINT8 mSmiDataRegister; 50 BOOLEAN mLocked = FALSE; 51 EFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID; 52 53 /** 54 Dispatch function for a Software SMI handler. 55 56 @param DispatchHandle The handle of this dispatch function. 57 @param DispatchContext The pointer to the dispatch function's context. 58 The SwSmiInputValue field is filled in 59 by the software dispatch driver prior to 60 invoking this dispatch function. 61 The dispatch function will only be called 62 for input values for which it is registered. 63 64 @return None 65 66 **/ 67 VOID 68 EFIAPI 69 SmramSaveInfoHandler ( 70 IN EFI_HANDLE DispatchHandle, 71 IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext 72 ) 73 { 74 ASSERT (DispatchContext != NULL); 75 ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER); 76 77 if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) { 78 CopyMem ( 79 (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxDataAddress)), 80 (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuSmramCpuDataAddress)), 81 (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize)) 82 ); 83 } 84 } 85 86 /** 87 Smm Ready To Lock event notification handler. 88 89 It sets a flag indicating that SMRAM has been locked. 90 91 @param[in] Protocol Points to the protocol's unique identifier. 92 @param[in] Interface Points to the interface instance. 93 @param[in] Handle The handle on which the interface was installed. 94 95 @retval EFI_SUCCESS Notification handler runs successfully. 96 **/ 97 EFI_STATUS 98 EFIAPI 99 SmmReadyToLockEventNotify ( 100 IN CONST EFI_GUID *Protocol, 101 IN VOID *Interface, 102 IN EFI_HANDLE Handle 103 ) 104 { 105 mLocked = TRUE; 106 return EFI_SUCCESS; 107 } 108 109 /** 110 Entry point function of this driver. 111 112 @param[in] ImageHandle The firmware allocated handle for the EFI image. 113 @param[in] SystemTable A pointer to the EFI System Table. 114 115 @retval EFI_SUCCESS The entry point is executed successfully. 116 @retval other Some error occurs when executing this entry point. 117 **/ 118 EFI_STATUS 119 EFIAPI 120 SmramSaveInfoHandlerSmmMain ( 121 IN EFI_HANDLE ImageHandle, 122 IN EFI_SYSTEM_TABLE *SystemTable 123 ) 124 { 125 EFI_STATUS Status; 126 EFI_SMM_SW_DISPATCH_PROTOCOL *SmmSwDispatch; 127 EFI_SMM_SW_DISPATCH_CONTEXT SmmSwDispatchContext; 128 EFI_HANDLE DispatchHandle; 129 EFI_SMM_CONTROL_PROTOCOL *SmmControl; 130 EFI_SMM_CONTROL_REGISTER SmmControlRegister; 131 VOID *Registration; 132 133 // 134 // Get SMI data register 135 // 136 Status = SystemTable->BootServices->LocateProtocol ( 137 &gEfiSmmControlProtocolGuid, 138 NULL, 139 (VOID **)&SmmControl 140 ); 141 ASSERT_EFI_ERROR (Status); 142 Status = SmmControl->GetRegisterInfo (SmmControl, &SmmControlRegister); 143 ASSERT_EFI_ERROR (Status); 144 mSmiDataRegister = SmmControlRegister.SmiDataRegister; 145 146 // 147 // Register software SMI handler 148 // 149 150 Status = SystemTable->BootServices->LocateProtocol ( 151 &gEfiSmmSwDispatchProtocolGuid, 152 NULL, 153 (VOID **)&SmmSwDispatch 154 ); 155 ASSERT_EFI_ERROR (Status); 156 157 SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER; 158 Status = SmmSwDispatch->Register ( 159 SmmSwDispatch, 160 &SmramSaveInfoHandler, 161 &SmmSwDispatchContext, 162 &DispatchHandle 163 ); 164 ASSERT_EFI_ERROR (Status); 165 166 // 167 // Register SMM Ready To Lock Protocol notification 168 // 169 Status = gSmst->SmmRegisterProtocolNotify ( 170 &gEfiSmmReadyToLockProtocolGuid, 171 SmmReadyToLockEventNotify, 172 &Registration 173 ); 174 ASSERT_EFI_ERROR (Status); 175 176 return Status; 177 } 178 179