]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
Adjust library instances used in SecurityPkg by proper module type.
[mirror_edk2.git] / MdeModulePkg / Universal / LockBox / SmmLockBox / SmmLockBox.c
CommitLineData
1c837cd5 1/** @file\r
2\r
1476a257 3Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
1c837cd5 4\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The\r
8full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiSmm.h>\r
17#include <Library/UefiDriverEntryPoint.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
19#include <Library/UefiRuntimeServicesTableLib.h>\r
20#include <Library/SmmServicesTableLib.h>\r
21#include <Library/BaseLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/LockBoxLib.h>\r
25#include <Protocol/SmmReadyToLock.h>\r
26#include <Protocol/SmmCommunication.h>\r
27#include <Protocol/SmmAccess2.h>\r
28#include <Protocol/LockBox.h>\r
29#include <Guid/SmmLockBox.h>\r
30\r
31BOOLEAN mLocked = FALSE;\r
32\r
33EFI_SMRAM_DESCRIPTOR *mSmramRanges;\r
34UINTN mSmramRangeCount;\r
35\r
36/**\r
37 This function check if the address is in SMRAM.\r
38\r
39 @param Buffer the buffer address to be checked.\r
40 @param Length the buffer length to be checked.\r
41\r
42 @retval TRUE this address is in SMRAM.\r
43 @retval FALSE this address is NOT in SMRAM.\r
44**/\r
45BOOLEAN\r
46IsAddressInSmram (\r
47 IN EFI_PHYSICAL_ADDRESS Buffer,\r
48 IN UINT64 Length\r
49 )\r
50{\r
51 UINTN Index;\r
52\r
53 for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
54 if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||\r
55 ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {\r
56 return TRUE;\r
57 }\r
58 }\r
59\r
60 return FALSE;\r
61}\r
62\r
63/**\r
64 Dispatch function for SMM lock box save.\r
65\r
66 @param LockBoxParameterSave parameter of lock box save \r
67**/\r
68VOID\r
69SmmLockBoxSave (\r
70 IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave\r
71 )\r
72{\r
73 EFI_STATUS Status;\r
74\r
75 //\r
76 // Sanity check\r
77 //\r
78 if (mLocked) {\r
79 DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));\r
80 LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
81 return ;\r
82 }\r
83\r
84 //\r
85 // Save data\r
86 //\r
87 Status = SaveLockBox (\r
88 &LockBoxParameterSave->Guid,\r
89 (VOID *)(UINTN)LockBoxParameterSave->Buffer,\r
90 (UINTN)LockBoxParameterSave->Length\r
91 );\r
92 LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;\r
93 return ;\r
94}\r
95\r
96/**\r
97 Dispatch function for SMM lock box set attributes.\r
98\r
99 @param LockBoxParameterSetAttributes parameter of lock box set attributes\r
100**/\r
101VOID\r
102SmmLockBoxSetAttributes (\r
103 IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes\r
104 )\r
105{\r
106 EFI_STATUS Status;\r
107\r
108 //\r
109 // Sanity check\r
110 //\r
111 if (mLocked) {\r
112 DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));\r
113 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
114 return ;\r
115 }\r
116\r
117 //\r
118 // Update data\r
119 //\r
120 Status = SetLockBoxAttributes (\r
121 &LockBoxParameterSetAttributes->Guid,\r
122 LockBoxParameterSetAttributes->Attributes\r
123 );\r
124 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;\r
125 return ;\r
126}\r
127\r
128/**\r
129 Dispatch function for SMM lock box update.\r
130\r
131 @param LockBoxParameterUpdate parameter of lock box update \r
132**/\r
133VOID\r
134SmmLockBoxUpdate (\r
135 IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate\r
136 )\r
137{\r
138 EFI_STATUS Status;\r
139\r
140 //\r
141 // Sanity check\r
142 //\r
143 if (mLocked) {\r
144 DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n"));\r
145 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
146 return ;\r
147 }\r
148\r
149 //\r
150 // Update data\r
151 //\r
152 Status = UpdateLockBox (\r
153 &LockBoxParameterUpdate->Guid,\r
154 (UINTN)LockBoxParameterUpdate->Offset,\r
155 (VOID *)(UINTN)LockBoxParameterUpdate->Buffer,\r
156 (UINTN)LockBoxParameterUpdate->Length\r
157 );\r
158 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;\r
159 return ;\r
160}\r
161\r
162/**\r
163 Dispatch function for SMM lock box restore.\r
164\r
165 @param LockBoxParameterRestore parameter of lock box restore \r
166**/\r
167VOID\r
168SmmLockBoxRestore (\r
169 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore\r
170 )\r
171{\r
172 EFI_STATUS Status;\r
173\r
174 //\r
175 // Sanity check\r
176 //\r
177 if (IsAddressInSmram (LockBoxParameterRestore->Buffer, LockBoxParameterRestore->Length)) {\r
178 DEBUG ((EFI_D_ERROR, "SmmLockBox Restore address in SMRAM!\n"));\r
179 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;\r
180 return ;\r
181 }\r
182\r
183 //\r
184 // Restore data\r
185 //\r
1476a257 186 if ((LockBoxParameterRestore->Length == 0) && (LockBoxParameterRestore->Buffer == 0)) {\r
187 Status = RestoreLockBox (\r
188 &LockBoxParameterRestore->Guid,\r
189 NULL,\r
190 NULL\r
191 );\r
192 } else {\r
193 Status = RestoreLockBox (\r
194 &LockBoxParameterRestore->Guid,\r
195 (VOID *)(UINTN)LockBoxParameterRestore->Buffer,\r
196 (UINTN *)&LockBoxParameterRestore->Length\r
197 );\r
198 }\r
1c837cd5 199 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;\r
200 return ;\r
201}\r
202\r
203/**\r
204 Dispatch function for SMM lock box restore all in place.\r
205\r
206 @param LockBoxParameterRestoreAllInPlace parameter of lock box restore all in place\r
207**/\r
208VOID\r
209SmmLockBoxRestoreAllInPlace (\r
210 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace\r
211 )\r
212{\r
213 EFI_STATUS Status;\r
214\r
215 Status = RestoreAllLockBoxInPlace ();\r
216 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;\r
217 return ;\r
218}\r
219\r
220/**\r
221 Dispatch function for a Software SMI handler.\r
222\r
223 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
224 @param Context Points to an optional handler context which was specified when the\r
225 handler was registered.\r
226 @param CommBuffer A pointer to a collection of data in memory that will\r
227 be conveyed from a non-SMM environment into an SMM environment.\r
228 @param CommBufferSize The size of the CommBuffer.\r
229\r
230 @retval EFI_SUCCESS Command is handled successfully.\r
231\r
232**/\r
233EFI_STATUS\r
234EFIAPI\r
235SmmLockBoxHandler (\r
236 IN EFI_HANDLE DispatchHandle,\r
237 IN CONST VOID *Context OPTIONAL,\r
238 IN OUT VOID *CommBuffer OPTIONAL,\r
239 IN OUT UINTN *CommBufferSize OPTIONAL\r
240 )\r
241{\r
242 EFI_SMM_LOCK_BOX_PARAMETER_HEADER *LockBoxParameterHeader;\r
243\r
244 DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Enter\n"));\r
245\r
246 LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER *)((UINTN)CommBuffer);\r
247\r
248 LockBoxParameterHeader->ReturnStatus = (UINT64)-1;\r
249\r
250 DEBUG ((EFI_D_ERROR, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN)LockBoxParameterHeader));\r
251\r
252 DEBUG ((EFI_D_ERROR, "SmmLockBox Command - %x\n", (UINTN)LockBoxParameterHeader->Command));\r
253\r
254 switch (LockBoxParameterHeader->Command) {\r
255 case EFI_SMM_LOCK_BOX_COMMAND_SAVE:\r
256 SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)(UINTN)LockBoxParameterHeader);\r
257 break;\r
258 case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:\r
259 SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)LockBoxParameterHeader);\r
260 break;\r
261 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:\r
262 SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)(UINTN)LockBoxParameterHeader);\r
263 break;\r
264 case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:\r
265 SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)(UINTN)LockBoxParameterHeader);\r
266 break;\r
267 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:\r
268 SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)(UINTN)LockBoxParameterHeader);\r
269 break;\r
270 default:\r
271 break;\r
272 }\r
273\r
274 LockBoxParameterHeader->Command = (UINT32)-1;\r
275\r
276 DEBUG ((EFI_D_ERROR, "SmmLockBox SmmLockBoxHandler Exit\n"));\r
277\r
278 return EFI_SUCCESS;\r
279}\r
280\r
281/**\r
282 Smm Ready To Lock event notification handler.\r
283\r
284 It sets a flag indicating that SMRAM has been locked.\r
285 \r
286 @param[in] Protocol Points to the protocol's unique identifier.\r
287 @param[in] Interface Points to the interface instance.\r
288 @param[in] Handle The handle on which the interface was installed.\r
289\r
290 @retval EFI_SUCCESS Notification handler runs successfully.\r
291 **/\r
292EFI_STATUS\r
293EFIAPI\r
294SmmReadyToLockEventNotify (\r
295 IN CONST EFI_GUID *Protocol,\r
296 IN VOID *Interface,\r
297 IN EFI_HANDLE Handle\r
298 )\r
299{\r
300 mLocked = TRUE;\r
301 return EFI_SUCCESS;\r
302}\r
303\r
304/**\r
305 Entry Point for LockBox SMM driver.\r
306\r
307 @param[in] ImageHandle Image handle of this driver.\r
308 @param[in] SystemTable A Pointer to the EFI System Table.\r
309\r
310 @retval EFI_SUCEESS \r
311 @return Others Some error occurs.\r
312**/\r
313EFI_STATUS\r
314EFIAPI\r
315SmmLockBoxEntryPoint (\r
316 IN EFI_HANDLE ImageHandle,\r
317 IN EFI_SYSTEM_TABLE *SystemTable\r
318 )\r
319{\r
320 EFI_STATUS Status;\r
321 EFI_HANDLE DispatchHandle;\r
322 VOID *Registration;\r
323 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;\r
324 UINTN Size;\r
325\r
326 //\r
327 // Get SMRAM information\r
328 //\r
329 Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
330 ASSERT_EFI_ERROR (Status);\r
331\r
332 Size = 0;\r
333 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
334 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
335\r
336 Status = gSmst->SmmAllocatePool (\r
337 EfiRuntimeServicesData,\r
338 Size,\r
339 (VOID **)&mSmramRanges\r
340 );\r
341 ASSERT_EFI_ERROR (Status);\r
342\r
343 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
344 ASSERT_EFI_ERROR (Status);\r
345\r
346 mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
347\r
348 //\r
349 // Register LockBox communication handler\r
350 //\r
351 Status = gSmst->SmiHandlerRegister (\r
352 SmmLockBoxHandler,\r
353 &gEfiSmmLockBoxCommunicationGuid,\r
354 &DispatchHandle\r
355 );\r
356 ASSERT_EFI_ERROR (Status);\r
357\r
358 //\r
359 // Register SMM Ready To Lock Protocol notification\r
360 //\r
361 Status = gSmst->SmmRegisterProtocolNotify (\r
362 &gEfiSmmReadyToLockProtocolGuid,\r
363 SmmReadyToLockEventNotify,\r
364 &Registration\r
365 );\r
366 ASSERT_EFI_ERROR (Status);\r
367\r
368 //\r
369 // Install NULL to DXE data base as notify\r
370 //\r
371 ImageHandle = NULL;\r
372 Status = gBS->InstallProtocolInterface (\r
373 &ImageHandle,\r
374 &gEfiLockBoxProtocolGuid,\r
375 EFI_NATIVE_INTERFACE,\r
376 NULL\r
377 );\r
378 ASSERT_EFI_ERROR (Status);\r
379\r
380 return Status;\r
381}\r