TianoCore EDK2 master
Loading...
Searching...
No Matches
Tcg2Smm.c
Go to the documentation of this file.
1
18#include "Tcg2Smm.h"
19
20EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL;
21TCG_NVS *mTcgNvs = NULL;
22UINTN mPpSoftwareSmi;
23UINTN mMcSoftwareSmi;
24EFI_HANDLE mReadyToLockHandle;
25
48EFIAPI
50 IN EFI_HANDLE DispatchHandle,
51 IN CONST VOID *RegisterContext,
52 IN OUT VOID *CommBuffer,
53 IN OUT UINTN *CommBufferSize
54 )
55{
56 EFI_STATUS Status;
57 UINTN TempCommBufferSize;
58 TPM_NVS_MM_COMM_BUFFER *CommParams;
59
60 DEBUG ((DEBUG_VERBOSE, "%a()\n", __func__));
61
62 //
63 // If input is invalid, stop processing this SMI
64 //
65 if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
66 return EFI_SUCCESS;
67 }
68
69 TempCommBufferSize = *CommBufferSize;
70
71 if (TempCommBufferSize != sizeof (TPM_NVS_MM_COMM_BUFFER)) {
72 DEBUG ((DEBUG_ERROR, "[%a] MM Communication buffer size is invalid for this handler!\n", __func__));
73 return EFI_ACCESS_DENIED;
74 }
75
76 CommParams = (TPM_NVS_MM_COMM_BUFFER *)CommBuffer;
77
78 //
79 // The Primary Buffer validation
80 //
81 if (!Tcg2IsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) {
82 DEBUG ((DEBUG_ERROR, "[%a] - MM Communication buffer in invalid location!\n", __func__));
83 return EFI_ACCESS_DENIED;
84 }
85
86 //
87 // The NonPrimary Buffer validation
88 //
89 if (!Tcg2IsNonPrimaryBufferValid (CommParams->TargetAddress, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (TCG_NVS))))) {
90 DEBUG ((DEBUG_ERROR, "[%a] - MM NonPrimary buffer pointed from Communication buffer in invalid location!\n", __func__));
91 return EFI_ACCESS_DENIED;
92 }
93
94 //
95 // Farm out the job to individual functions based on what was requested.
96 //
97 Status = EFI_SUCCESS;
98 switch (CommParams->Function) {
99 case TpmNvsMmExchangeInfo:
100 DEBUG ((DEBUG_VERBOSE, "[%a] - Function requested: MM_EXCHANGE_NVS_INFO\n", __func__));
101 CommParams->RegisteredPpSwiValue = mPpSoftwareSmi;
102 CommParams->RegisteredMcSwiValue = mMcSoftwareSmi;
103 mTcgNvs = (TCG_NVS *)(UINTN)CommParams->TargetAddress;
104 break;
105
106 default:
107 DEBUG ((DEBUG_INFO, "[%a] - Unknown function %d!\n", __func__, CommParams->Function));
108 Status = EFI_UNSUPPORTED;
109 break;
110 }
111
112 CommParams->ReturnStatus = (UINT64)Status;
113 return EFI_SUCCESS;
114}
115
134EFIAPI
136 IN EFI_HANDLE DispatchHandle,
137 IN CONST VOID *Context,
138 IN OUT VOID *CommBuffer,
139 IN OUT UINTN *CommBufferSize
140 )
141{
142 UINT32 MostRecentRequest;
143 UINT32 Response;
144 UINT32 OperationRequest;
145 UINT32 RequestParameter;
146
147 if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {
148 mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
149 &MostRecentRequest,
150 &Response
151 );
152 mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest;
153 mTcgNvs->PhysicalPresence.Response = Response;
154 return EFI_SUCCESS;
155 } else if ( (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)
156 || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2))
157 {
158 OperationRequest = mTcgNvs->PhysicalPresence.Request;
159 RequestParameter = mTcgNvs->PhysicalPresence.RequestParameter;
160 mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
161 &OperationRequest,
162 &RequestParameter
163 );
164 mTcgNvs->PhysicalPresence.Request = OperationRequest;
165 mTcgNvs->PhysicalPresence.RequestParameter = RequestParameter;
166 } else if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
167 mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (mTcgNvs->PPRequestUserConfirm);
168 }
169
170 return EFI_SUCCESS;
171}
172
184EFIAPI
186 IN CONST EFI_GUID *Protocol,
187 IN VOID *Interface,
188 IN EFI_HANDLE Handle
189 )
190{
191 EFI_STATUS Status;
192
193 Status = EFI_SUCCESS;
194
195 if (mReadyToLockHandle != NULL) {
196 Status = gMmst->MmiHandlerUnRegister (mReadyToLockHandle);
197 mReadyToLockHandle = NULL;
198 }
199
200 return Status;
201}
202
215 VOID
216 )
217{
218 EFI_STATUS Status;
221 EFI_HANDLE PpSwHandle;
222 EFI_HANDLE McSwHandle;
223 EFI_HANDLE NotifyHandle;
224
225 if (!IsTpm20Dtpm ()) {
226 DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required!\n"));
227 return EFI_UNSUPPORTED;
228 }
229
230 // Initialize variables first
231 mReadyToLockHandle = NULL;
232 SwDispatch = NULL;
233 PpSwHandle = NULL;
234 McSwHandle = NULL;
235 NotifyHandle = NULL;
236
237 // Register a root handler to communicate the NVS region and SMI channel between MM and DXE
238 Status = gMmst->MmiHandlerRegister (TpmNvsCommunciate, &gTpmNvsMmGuid, &mReadyToLockHandle);
239 ASSERT_EFI_ERROR (Status);
240 if (EFI_ERROR (Status)) {
241 DEBUG ((DEBUG_ERROR, "[%a] Failed to register NVS communicate as root MM handler - %r!\n", __func__, Status));
242 goto Cleanup;
243 }
244
245 //
246 // Get the Sw dispatch protocol and register SMI callback functions.
247 //
248 Status = gMmst->MmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **)&SwDispatch);
249 ASSERT_EFI_ERROR (Status);
250 if (EFI_ERROR (Status)) {
251 DEBUG ((DEBUG_ERROR, "[%a] Failed to locate Sw dispatch protocol - %r!\n", __func__, Status));
252 goto Cleanup;
253 }
254
255 SwContext.SwSmiInputValue = (UINTN)-1;
256 Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &PpSwHandle);
257 ASSERT_EFI_ERROR (Status);
258 if (EFI_ERROR (Status)) {
259 DEBUG ((DEBUG_ERROR, "[%a] Failed to register PP callback as SW MM handler - %r!\n", __func__, Status));
260 goto Cleanup;
261 }
262
263 mPpSoftwareSmi = SwContext.SwSmiInputValue;
264
265 //
266 // Locate SmmVariableProtocol.
267 //
268 Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
269 ASSERT_EFI_ERROR (Status);
270 if (EFI_ERROR (Status)) {
271 // Should not happen
272 DEBUG ((DEBUG_ERROR, "[%a] Failed to locate SMM variable protocol - %r!\n", __func__, Status));
273 goto Cleanup;
274 }
275
276 // Turn off the light before leaving the room... at least, take a remote...
277 Status = gMmst->MmRegisterProtocolNotify (&gEfiMmReadyToLockProtocolGuid, TcgMmReadyToLock, &NotifyHandle);
278 ASSERT_EFI_ERROR (Status);
279 if (EFI_ERROR (Status)) {
280 DEBUG ((DEBUG_ERROR, "[%a] Failed to register ready to lock notification - %r!\n", __func__, Status));
281 goto Cleanup;
282 }
283
285
286Cleanup:
287 if (EFI_ERROR (Status)) {
288 // Something is whacked, clean up the mess...
289 if (NotifyHandle != NULL) {
290 gMmst->MmRegisterProtocolNotify (&gEfiMmReadyToLockProtocolGuid, NULL, &NotifyHandle);
291 }
292
293 if ((McSwHandle != NULL) && (SwDispatch != NULL)) {
294 SwDispatch->UnRegister (SwDispatch, McSwHandle);
295 }
296
297 if ((PpSwHandle != NULL) && (SwDispatch != NULL)) {
298 SwDispatch->UnRegister (SwDispatch, PpSwHandle);
299 }
300
301 if (mReadyToLockHandle != NULL) {
302 gMmst->MmiHandlerUnRegister (mReadyToLockHandle);
303 }
304 }
305
306 return Status;
307}
UINT64 UINTN
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT32 EFIAPI Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction(OUT UINT32 *MostRecentRequest, OUT UINT32 *Response)
UINT32 EFIAPI Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction(IN UINT32 OperationRequest)
UINT32 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(IN OUT UINT32 *OperationRequest, IN OUT UINT32 *RequestParameter)
EFI_STATUS EFIAPI TcgMmReadyToLock(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
Definition: Tcg2Smm.c:185
EFI_STATUS EFIAPI TpmNvsCommunciate(IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
Definition: Tcg2Smm.c:49
EFI_STATUS InitializeTcgCommon(VOID)
Definition: Tcg2Smm.c:214
EFI_STATUS EFIAPI PhysicalPresenceCallback(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
Definition: Tcg2Smm.c:135
BOOLEAN IsTpm20Dtpm(VOID)
BOOLEAN Tcg2IsNonPrimaryBufferValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
VOID Tcg2NotifyMmReady(VOID)
BOOLEAN Tcg2IsPrimaryBufferValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Base.h:213