3 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/UefiDriverEntryPoint.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/UefiRuntimeServicesTableLib.h>
20 #include <Library/SmmServicesTableLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/LockBoxLib.h>
25 #include <Protocol/SmmReadyToLock.h>
26 #include <Protocol/SmmCommunication.h>
27 #include <Protocol/SmmAccess2.h>
28 #include <Protocol/LockBox.h>
29 #include <Guid/SmmLockBox.h>
31 BOOLEAN mLocked
= FALSE
;
33 EFI_SMRAM_DESCRIPTOR
*mSmramRanges
;
34 UINTN mSmramRangeCount
;
37 This function check if the address is in SMRAM.
39 @param Buffer the buffer address to be checked.
40 @param Length the buffer length to be checked.
42 @retval TRUE this address is in SMRAM.
43 @retval FALSE this address is NOT in SMRAM.
47 IN EFI_PHYSICAL_ADDRESS Buffer
,
53 for (Index
= 0; Index
< mSmramRangeCount
; Index
++) {
54 if (((Buffer
>= mSmramRanges
[Index
].CpuStart
) && (Buffer
< mSmramRanges
[Index
].CpuStart
+ mSmramRanges
[Index
].PhysicalSize
)) ||
55 ((mSmramRanges
[Index
].CpuStart
>= Buffer
) && (mSmramRanges
[Index
].CpuStart
< Buffer
+ Length
))) {
64 Dispatch function for SMM lock box save.
66 @param LockBoxParameterSave parameter of lock box save
70 IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
79 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
80 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
87 Status
= SaveLockBox (
88 &LockBoxParameterSave
->Guid
,
89 (VOID
*)(UINTN
)LockBoxParameterSave
->Buffer
,
90 (UINTN
)LockBoxParameterSave
->Length
92 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)Status
;
97 Dispatch function for SMM lock box set attributes.
99 @param LockBoxParameterSetAttributes parameter of lock box set attributes
102 SmmLockBoxSetAttributes (
103 IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
112 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
113 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
120 Status
= SetLockBoxAttributes (
121 &LockBoxParameterSetAttributes
->Guid
,
122 LockBoxParameterSetAttributes
->Attributes
124 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)Status
;
129 Dispatch function for SMM lock box update.
131 @param LockBoxParameterUpdate parameter of lock box update
135 IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
144 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
145 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
152 Status
= UpdateLockBox (
153 &LockBoxParameterUpdate
->Guid
,
154 (UINTN
)LockBoxParameterUpdate
->Offset
,
155 (VOID
*)(UINTN
)LockBoxParameterUpdate
->Buffer
,
156 (UINTN
)LockBoxParameterUpdate
->Length
158 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)Status
;
163 Dispatch function for SMM lock box restore.
165 @param LockBoxParameterRestore parameter of lock box restore
169 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
177 if (IsAddressInSmram (LockBoxParameterRestore
->Buffer
, LockBoxParameterRestore
->Length
)) {
178 DEBUG ((EFI_D_ERROR
, "SmmLockBox Restore address in SMRAM!\n"));
179 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
186 if ((LockBoxParameterRestore
->Length
== 0) && (LockBoxParameterRestore
->Buffer
== 0)) {
187 Status
= RestoreLockBox (
188 &LockBoxParameterRestore
->Guid
,
193 Status
= RestoreLockBox (
194 &LockBoxParameterRestore
->Guid
,
195 (VOID
*)(UINTN
)LockBoxParameterRestore
->Buffer
,
196 (UINTN
*)&LockBoxParameterRestore
->Length
199 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)Status
;
204 Dispatch function for SMM lock box restore all in place.
206 @param LockBoxParameterRestoreAllInPlace parameter of lock box restore all in place
209 SmmLockBoxRestoreAllInPlace (
210 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
215 Status
= RestoreAllLockBoxInPlace ();
216 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)Status
;
221 Dispatch function for a Software SMI handler.
223 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
224 @param Context Points to an optional handler context which was specified when the
225 handler was registered.
226 @param CommBuffer A pointer to a collection of data in memory that will
227 be conveyed from a non-SMM environment into an SMM environment.
228 @param CommBufferSize The size of the CommBuffer.
230 @retval EFI_SUCCESS Command is handled successfully.
236 IN EFI_HANDLE DispatchHandle
,
237 IN CONST VOID
*Context OPTIONAL
,
238 IN OUT VOID
*CommBuffer OPTIONAL
,
239 IN OUT UINTN
*CommBufferSize OPTIONAL
242 EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*LockBoxParameterHeader
;
244 DEBUG ((EFI_D_ERROR
, "SmmLockBox SmmLockBoxHandler Enter\n"));
246 LockBoxParameterHeader
= (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
248 LockBoxParameterHeader
->ReturnStatus
= (UINT64
)-1;
250 DEBUG ((EFI_D_ERROR
, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN
)LockBoxParameterHeader
));
252 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command - %x\n", (UINTN
)LockBoxParameterHeader
->Command
));
254 switch (LockBoxParameterHeader
->Command
) {
255 case EFI_SMM_LOCK_BOX_COMMAND_SAVE
:
256 SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)(UINTN
)LockBoxParameterHeader
);
258 case EFI_SMM_LOCK_BOX_COMMAND_UPDATE
:
259 SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)LockBoxParameterHeader
);
261 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE
:
262 SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)(UINTN
)LockBoxParameterHeader
);
264 case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
:
265 SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)(UINTN
)LockBoxParameterHeader
);
267 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
:
268 SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)(UINTN
)LockBoxParameterHeader
);
274 LockBoxParameterHeader
->Command
= (UINT32
)-1;
276 DEBUG ((EFI_D_ERROR
, "SmmLockBox SmmLockBoxHandler Exit\n"));
282 Smm Ready To Lock event notification handler.
284 It sets a flag indicating that SMRAM has been locked.
286 @param[in] Protocol Points to the protocol's unique identifier.
287 @param[in] Interface Points to the interface instance.
288 @param[in] Handle The handle on which the interface was installed.
290 @retval EFI_SUCCESS Notification handler runs successfully.
294 SmmReadyToLockEventNotify (
295 IN CONST EFI_GUID
*Protocol
,
305 Entry Point for LockBox SMM driver.
307 @param[in] ImageHandle Image handle of this driver.
308 @param[in] SystemTable A Pointer to the EFI System Table.
311 @return Others Some error occurs.
315 SmmLockBoxEntryPoint (
316 IN EFI_HANDLE ImageHandle
,
317 IN EFI_SYSTEM_TABLE
*SystemTable
321 EFI_HANDLE DispatchHandle
;
323 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
327 // Get SMRAM information
329 Status
= gBS
->LocateProtocol (&gEfiSmmAccess2ProtocolGuid
, NULL
, (VOID
**)&SmmAccess
);
330 ASSERT_EFI_ERROR (Status
);
333 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, NULL
);
334 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
336 Status
= gSmst
->SmmAllocatePool (
337 EfiRuntimeServicesData
,
339 (VOID
**)&mSmramRanges
341 ASSERT_EFI_ERROR (Status
);
343 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, mSmramRanges
);
344 ASSERT_EFI_ERROR (Status
);
346 mSmramRangeCount
= Size
/ sizeof (EFI_SMRAM_DESCRIPTOR
);
349 // Register LockBox communication handler
351 Status
= gSmst
->SmiHandlerRegister (
353 &gEfiSmmLockBoxCommunicationGuid
,
356 ASSERT_EFI_ERROR (Status
);
359 // Register SMM Ready To Lock Protocol notification
361 Status
= gSmst
->SmmRegisterProtocolNotify (
362 &gEfiSmmReadyToLockProtocolGuid
,
363 SmmReadyToLockEventNotify
,
366 ASSERT_EFI_ERROR (Status
);
369 // Install NULL to DXE data base as notify
372 Status
= gBS
->InstallProtocolInterface (
374 &gEfiLockBoxProtocolGuid
,
375 EFI_NATIVE_INTERFACE
,
378 ASSERT_EFI_ERROR (Status
);