]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c
EdkCompatibilityPkg: Fix some typos of "according"
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / SmmBaseOnSmmBase2Thunk / SmmBaseOnSmmBase2Thunk.c
CommitLineData
9e620719 1/** @file\r
2 SMM Base Protocol on SMM Base2 Protocol Thunk driver.\r
3\r
4 This driver co-operates with SMM Base Helper SMM driver to provide SMM Base Protocol\r
5 based on SMM Base2 Protocol.\r
6\r
7 This thunk driver is expected to be loaded before PI SMM IPL driver so that\r
8 SMM BASE Protocol can be published immediately after SMM Base2 Protocol is installed to\r
9 make SMM Base Protocol.InSmm() as early as possible.\r
10\r
584d5652
HT
11 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
12 This program and the accompanying materials\r
9e620719 13 are licensed and made available under the terms and conditions of the BSD License\r
14 which accompanies this distribution. The full text of the license may be found at\r
15 http://opensource.org/licenses/bsd-license.php\r
16\r
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
19\r
20**/\r
21\r
f5501a65 22#include <PiDxe.h>\r
23#include <FrameworkSmm.h>\r
9e620719 24\r
f5501a65 25#include <Protocol/SmmBase2.h>\r
26#include <Protocol/SmmCommunication.h>\r
27#include <Protocol/SmmBaseHelperReady.h>\r
28\r
29#include <Guid/SmmBaseThunkCommunication.h>\r
30#include <Guid/EventGroup.h>\r
31\r
32#include <Library/DebugLib.h>\r
33#include <Library/UefiBootServicesTableLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/UefiRuntimeLib.h>\r
37\r
f5501a65 38SMMBASETHUNK_COMMUNICATION_DATA mCommunicationData = {\r
9e620719 39 EFI_SMM_BASE_THUNK_COMMUNICATION_GUID,\r
40 sizeof (SMMBASE_FUNCTION_DATA)\r
41};\r
42\r
f5501a65 43EFI_HANDLE mSmmBaseHandle = NULL;\r
9e620719 44EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL;\r
45EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;\r
46EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady = NULL;\r
8edfbe02 47BOOLEAN mAtRuntime = FALSE;\r
9e620719 48\r
17d2c9a3 49/**\r
50 Determine if in SMM mode.\r
51\r
52 @retval TRUE In SMM mode.\r
53 @retval FALSE Not in SMM mode.\r
54**/\r
9e620719 55BOOLEAN\r
56IsInSmm (\r
57 VOID\r
58 )\r
59{\r
60 EFI_STATUS Status;\r
61 BOOLEAN InSmm;\r
62 \r
63 Status = mSmmBase2->InSmm (mSmmBase2, &InSmm);\r
64 ASSERT_EFI_ERROR (Status);\r
65 return InSmm;\r
66}\r
67\r
68/**\r
69 Invoke services provided by SMM Base Helper SMM driver.\r
70**/\r
71VOID\r
72SmmBaseHelperService (\r
73 VOID\r
74 )\r
75{\r
76 UINTN DataSize;\r
77\r
f5501a65 78 mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;\r
673c1498 79 mCommunicationData.FunctionData.SmmBaseImageHandle = mSmmBaseHandle;\r
9e620719 80\r
26a76fbc 81 if ((mCommunicationData.FunctionData.Function != SmmBaseFunctionCommunicate) && IsInSmm()) {\r
9e620719 82 ///\r
83 /// If in SMM mode, directly call services in SMM Base Helper.\r
84 ///\r
9e620719 85 DataSize = (UINTN)(sizeof (SMMBASE_FUNCTION_DATA));\r
86 mSmmBaseHelperReady->ServiceEntry (\r
87 NULL,\r
88 NULL,\r
f5501a65 89 &mCommunicationData.FunctionData,\r
9e620719 90 &DataSize\r
91 );\r
92 } else {\r
93 ///\r
bade9bf5 94 /// Call services in SMM Base Helper via SMM Communication Protocol.\r
9e620719 95 ///\r
f5501a65 96 DataSize = (UINTN)(sizeof (mCommunicationData));\r
9e620719 97 mSmmCommunication->Communicate (\r
98 mSmmCommunication,\r
f5501a65 99 &mCommunicationData,\r
9e620719 100 &DataSize\r
101 );\r
102 }\r
103}\r
104\r
105/**\r
106 Register a given driver into SMRAM. This is the equivalent of performing\r
107 the LoadImage/StartImage into System Management Mode.\r
108\r
109 @param[in] This Protocol instance pointer.\r
110 @param[in] FilePath Location of the image to be installed as the handler.\r
111 @param[in] SourceBuffer Optional source buffer in case the image file\r
112 is in memory.\r
113 @param[in] SourceSize Size of the source image file, if in memory.\r
114 @param[out] ImageHandle The handle that the base driver uses to decode \r
115 the handler. Unique among SMM handlers only, \r
116 not unique across DXE/EFI.\r
117 @param[in] LegacyIA32Binary An optional parameter specifying that the associated \r
118 file is a real-mode IA-32 binary.\r
119\r
120 @retval EFI_SUCCESS The operation was successful.\r
121 @retval EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler\r
122 @retval EFI_UNSUPPORTED This platform does not support 16-bit handlers.\r
123 @retval EFI_UNSUPPORTED Platform is in runtime.\r
124 @retval EFI_INVALID_PARAMETER The handlers was not the correct image type\r
125**/\r
126EFI_STATUS\r
127EFIAPI\r
128SmmBaseRegister (\r
129 IN EFI_SMM_BASE_PROTOCOL *This,\r
130 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
131 IN VOID *SourceBuffer,\r
132 IN UINTN SourceSize,\r
133 OUT EFI_HANDLE *ImageHandle,\r
134 IN BOOLEAN LegacyIA32Binary\r
135 )\r
136{\r
8edfbe02 137 if (mAtRuntime || LegacyIA32Binary) {\r
9e620719 138 return EFI_UNSUPPORTED;\r
139 }\r
140\r
26a76fbc 141 mCommunicationData.FunctionData.Function = SmmBaseFunctionRegister;\r
f5501a65 142 mCommunicationData.FunctionData.Args.Register.FilePath = FilePath;\r
143 mCommunicationData.FunctionData.Args.Register.SourceBuffer = SourceBuffer;\r
144 mCommunicationData.FunctionData.Args.Register.SourceSize = SourceSize;\r
145 mCommunicationData.FunctionData.Args.Register.ImageHandle = ImageHandle;\r
146 mCommunicationData.FunctionData.Args.Register.LegacyIA32Binary = LegacyIA32Binary;\r
9e620719 147\r
148 SmmBaseHelperService ();\r
f5501a65 149 return mCommunicationData.FunctionData.Status;\r
9e620719 150}\r
151\r
152/**\r
153 Removes a handler from execution within SMRAM. This is the equivalent of performing\r
154 the UnloadImage in System Management Mode.\r
155\r
156 @param[in] This Protocol instance pointer.\r
157 @param[in] ImageHandle The handler to be removed.\r
158\r
159 @retval EFI_SUCCESS The operation was successful\r
160 @retval EFI_INVALID_PARAMETER The handler did not exist\r
161 @retval EFI_UNSUPPORTED Platform is in runtime.\r
162**/\r
163EFI_STATUS\r
164EFIAPI\r
165SmmBaseUnregister (\r
166 IN EFI_SMM_BASE_PROTOCOL *This,\r
167 IN EFI_HANDLE ImageHandle\r
168 )\r
169{\r
8edfbe02 170 if (mAtRuntime) {\r
171 return EFI_UNSUPPORTED;\r
172 }\r
173\r
26a76fbc 174 mCommunicationData.FunctionData.Function = SmmBaseFunctionUnregister;\r
f5501a65 175 mCommunicationData.FunctionData.Args.UnRegister.ImageHandle = ImageHandle;\r
9e620719 176\r
177 SmmBaseHelperService ();\r
f5501a65 178 return mCommunicationData.FunctionData.Status;\r
9e620719 179}\r
180\r
181/**\r
182 The SMM Inter-module Communicate Service Communicate() function\r
183 provides a service to send/receive messages from a registered\r
184 EFI service. The BASE protocol driver is responsible for doing\r
185 any of the copies such that the data lives in boot-service-accessible RAM.\r
186\r
187 @param[in] This Protocol instance pointer.\r
188 @param[in] ImageHandle The handle of the registered driver.\r
26a76fbc
LG
189 @param[in, out] CommunicationBuffer Pointer to the buffer to convey into SMRAM.\r
190 @param[in, out] BufferSize The size of the data buffer being passed in.\r
9e620719 191 On exit, the size of data being returned.\r
192 Zero if the handler does not wish to reply with any data.\r
193\r
194 @retval EFI_SUCCESS The message was successfully posted\r
195 @retval EFI_INVALID_PARAMETER The buffer was NULL\r
196**/\r
197EFI_STATUS\r
198EFIAPI\r
199SmmBaseCommunicate (\r
200 IN EFI_SMM_BASE_PROTOCOL *This,\r
201 IN EFI_HANDLE ImageHandle,\r
202 IN OUT VOID *CommunicationBuffer,\r
203 IN OUT UINTN *BufferSize\r
204 )\r
205{\r
bade9bf5 206 ///\r
207 /// Note this is a runtime interface\r
208 ///\r
209\r
1329da44 210 if (CommunicationBuffer == NULL || BufferSize == NULL) {\r
211 return EFI_INVALID_PARAMETER;\r
212 }\r
213\r
26a76fbc 214 mCommunicationData.FunctionData.Function = SmmBaseFunctionCommunicate;\r
bade9bf5 215 mCommunicationData.FunctionData.Args.Communicate.ImageHandle = ImageHandle;\r
216 mCommunicationData.FunctionData.Args.Communicate.CommunicationBuffer = CommunicationBuffer;\r
217 mCommunicationData.FunctionData.Args.Communicate.SourceSize = BufferSize;\r
9e620719 218\r
bade9bf5 219 SmmBaseHelperService ();\r
220 return mCommunicationData.FunctionData.Status;\r
9e620719 221}\r
222\r
223/**\r
224 Register a callback to execute within SMM.\r
225 This allows receipt of messages created with EFI_SMM_BASE_PROTOCOL.Communicate().\r
226\r
227 @param[in] This Protocol instance pointer.\r
228 @param[in] SmmImageHandle Handle of the callback service.\r
229 @param[in] CallbackAddress Address of the callback service.\r
230 @param[in] MakeLast If present, will stipulate that the handler is posted to \r
231 be executed last in the dispatch table.\r
232 @param[in] FloatingPointSave An optional parameter that informs the\r
233 EFI_SMM_ACCESS_PROTOCOL Driver core if it needs to save\r
234 the floating point register state. If any handler\r
235 require this, the state will be saved for all handlers.\r
236\r
237 @retval EFI_SUCCESS The operation was successful\r
238 @retval EFI_OUT_OF_RESOURCES Not enough space in the dispatch queue\r
239 @retval EFI_UNSUPPORTED Platform is in runtime.\r
240 @retval EFI_UNSUPPORTED The caller is not in SMM.\r
241**/\r
242EFI_STATUS\r
243EFIAPI\r
244SmmBaseRegisterCallback (\r
245 IN EFI_SMM_BASE_PROTOCOL *This,\r
246 IN EFI_HANDLE SmmImageHandle,\r
247 IN EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress,\r
248 IN BOOLEAN MakeLast,\r
249 IN BOOLEAN FloatingPointSave\r
250 )\r
251{\r
252 if (!IsInSmm()) {\r
253 return EFI_UNSUPPORTED;\r
254 }\r
255\r
26a76fbc 256 mCommunicationData.FunctionData.Function = SmmBaseFunctionRegisterCallback;\r
f5501a65 257 mCommunicationData.FunctionData.Args.RegisterCallback.SmmImageHandle = SmmImageHandle;\r
258 mCommunicationData.FunctionData.Args.RegisterCallback.CallbackAddress = CallbackAddress;\r
259 mCommunicationData.FunctionData.Args.RegisterCallback.MakeLast = MakeLast;\r
260 mCommunicationData.FunctionData.Args.RegisterCallback.FloatingPointSave = FloatingPointSave;\r
9e620719 261\r
262 SmmBaseHelperService();\r
f5501a65 263 return mCommunicationData.FunctionData.Status;\r
9e620719 264}\r
265\r
266/**\r
267 This routine tells caller if execution context is SMM or not.\r
268\r
269 @param[in] This Protocol instance pointer.\r
270 @param[out] InSmm Whether the caller is inside SMM for IA-32\r
271 or servicing a PMI for the Itanium processor\r
272 family.\r
273\r
274 @retval EFI_SUCCESS The operation was successful\r
275 @retval EFI_INVALID_PARAMETER InSmm was NULL.\r
276**/\r
277EFI_STATUS\r
278EFIAPI\r
279SmmBaseInSmm (\r
280 IN EFI_SMM_BASE_PROTOCOL *This,\r
281 OUT BOOLEAN *InSmm\r
282 )\r
283{\r
284 return mSmmBase2->InSmm (mSmmBase2, InSmm);\r
285}\r
286\r
287/**\r
288 The SmmAllocatePool() function allocates a memory region of Size bytes from memory of\r
289 type PoolType and returns the address of the allocated memory in the location referenced\r
290 by Buffer. This function allocates pages from EFI SMRAM Memory as needed to grow the\r
291 requested pool type. All allocations are eight-byte aligned.\r
292\r
293 @param[in] This Protocol instance pointer.\r
294 @param[in] PoolType The type of pool to allocate.\r
295 The only supported type is EfiRuntimeServicesData;\r
296 the interface will internally map this runtime request to \r
297 SMRAM for IA-32 and leave as this type for the Itanium \r
298 processor family. Other types can be ignored.\r
299 @param[in] Size The number of bytes to allocate from the pool.\r
300 @param[out] Buffer A pointer to a pointer to the allocated buffer if the call\r
301 succeeds; undefined otherwise.\r
302\r
303 @retval EFI_SUCCESS The requested number of bytes was allocated.\r
304 @retval EFI_OUT_OF_RESOURCES The pool requested could not be allocated.\r
305 @retval EFI_UNSUPPORTED Platform is in runtime.\r
306**/\r
307EFI_STATUS\r
308EFIAPI\r
309SmmBaseSmmAllocatePool (\r
310 IN EFI_SMM_BASE_PROTOCOL *This,\r
311 IN EFI_MEMORY_TYPE PoolType,\r
312 IN UINTN Size,\r
313 OUT VOID **Buffer\r
314 )\r
315{\r
8edfbe02 316 if (mAtRuntime) {\r
317 return EFI_UNSUPPORTED;\r
318 }\r
319\r
26a76fbc 320 mCommunicationData.FunctionData.Function = SmmBaseFunctionAllocatePool;\r
f5501a65 321 mCommunicationData.FunctionData.Args.AllocatePool.PoolType = PoolType;\r
322 mCommunicationData.FunctionData.Args.AllocatePool.Size = Size;\r
323 mCommunicationData.FunctionData.Args.AllocatePool.Buffer = Buffer;\r
9e620719 324\r
325 SmmBaseHelperService ();\r
f5501a65 326 return mCommunicationData.FunctionData.Status;\r
9e620719 327}\r
328\r
329/**\r
330 The SmmFreePool() function returns the memory specified by Buffer to the system.\r
331 On return, the memory's type is EFI SMRAM Memory. The Buffer that is freed must\r
332 have been allocated by SmmAllocatePool().\r
333\r
334 @param[in] This Protocol instance pointer.\r
335 @param[in] Buffer Pointer to the buffer allocation.\r
336\r
337 @retval EFI_SUCCESS The memory was returned to the system.\r
338 @retval EFI_INVALID_PARAMETER Buffer was invalid.\r
339 @retval EFI_UNSUPPORTED Platform is in runtime.\r
340**/\r
341EFI_STATUS\r
342EFIAPI\r
343SmmBaseSmmFreePool (\r
344 IN EFI_SMM_BASE_PROTOCOL *This,\r
345 IN VOID *Buffer\r
346 )\r
347{\r
8edfbe02 348 if (mAtRuntime) {\r
349 return EFI_UNSUPPORTED;\r
350 }\r
351\r
26a76fbc 352 mCommunicationData.FunctionData.Function = SmmBaseFunctionFreePool;\r
f5501a65 353 mCommunicationData.FunctionData.Args.FreePool.Buffer = Buffer;\r
9e620719 354\r
355 SmmBaseHelperService ();\r
f5501a65 356 return mCommunicationData.FunctionData.Status;\r
9e620719 357}\r
358\r
359/**\r
360 The GetSmstLocation() function returns the location of the System Management\r
361 Service Table. The use of the API is such that a driver can discover the\r
362 location of the SMST in its entry point and then cache it in some driver\r
363 global variable so that the SMST can be invoked in subsequent callbacks.\r
364\r
365 @param[in] This Protocol instance pointer.\r
26a76fbc 366 @param[out] Smst Pointer to the SMST.\r
9e620719 367\r
368 @retval EFI_SUCCESS The operation was successful\r
369 @retval EFI_INVALID_PARAMETER Smst was invalid.\r
370 @retval EFI_UNSUPPORTED Not in SMM.\r
371**/\r
372EFI_STATUS\r
373EFIAPI\r
374SmmBaseGetSmstLocation (\r
375 IN EFI_SMM_BASE_PROTOCOL *This,\r
376 OUT EFI_SMM_SYSTEM_TABLE **Smst\r
377 )\r
378{\r
9e620719 379 if (!IsInSmm ()) {\r
380 return EFI_UNSUPPORTED;\r
381 }\r
382\r
383 if (Smst == NULL) {\r
384 return EFI_INVALID_PARAMETER;\r
385 }\r
386\r
387 *Smst = mSmmBaseHelperReady->FrameworkSmst;\r
388 return EFI_SUCCESS;\r
389}\r
390\r
fb03ca1a 391/**\r
392 Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
393\r
394 This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
395 It convers pointer to new virtual address.\r
396\r
397 @param Event Event whose notification function is being invoked\r
398 @param Context Pointer to the notification function's context\r
399**/\r
400VOID\r
401EFIAPI\r
402SmmBaseAddressChangeEvent (\r
403 IN EFI_EVENT Event,\r
404 IN VOID *Context\r
405 )\r
406{\r
bade9bf5 407 EfiConvertPointer (0x0, (VOID **) &mSmmCommunication);\r
fb03ca1a 408}\r
409\r
26a76fbc
LG
410///\r
411/// SMM Base Protocol instance\r
412///\r
413EFI_SMM_BASE_PROTOCOL mSmmBase = {\r
414 SmmBaseRegister,\r
415 SmmBaseUnregister,\r
416 SmmBaseCommunicate,\r
417 SmmBaseRegisterCallback,\r
418 SmmBaseInSmm,\r
419 SmmBaseSmmAllocatePool,\r
420 SmmBaseSmmFreePool,\r
421 SmmBaseGetSmstLocation\r
422};\r
423\r
8edfbe02 424/**\r
425 Notification function on Exit Boot Services Event.\r
426\r
427 This function sets a flag indicating it is in Runtime phase.\r
428\r
429 @param Event Event whose notification function is being invoked\r
430 @param Context Pointer to the notification function's context\r
431**/\r
432VOID\r
433EFIAPI\r
434SmmBaseExitBootServicesEventNotify (\r
435 IN EFI_EVENT Event,\r
436 IN VOID *Context\r
437 )\r
438{\r
439 mAtRuntime = TRUE;\r
440}\r
441\r
9e620719 442/**\r
443 Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver.\r
444\r
445 @param[in] ImageHandle Image handle of this driver.\r
446 @param[in] SystemTable A Pointer to the EFI System Table.\r
447\r
448 @retval EFI_SUCCESS The entry point is executed successfully.\r
449**/\r
450EFI_STATUS\r
451EFIAPI\r
452SmmBaseThunkMain (\r
453 IN EFI_HANDLE ImageHandle,\r
454 IN EFI_SYSTEM_TABLE *SystemTable\r
455 )\r
456{\r
f5501a65 457 EFI_STATUS Status;\r
458 EFI_EVENT Event;\r
9e620719 459\r
673c1498 460 mSmmBaseHandle = ImageHandle;\r
461\r
f5501a65 462 //\r
463 // Assume only one instance of SMM Base2 Protocol in the system\r
464 // Locate SMM Base2 Protocol\r
465 //\r
466 Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **) &mSmmBase2);\r
467 ASSERT_EFI_ERROR (Status);\r
468\r
469 //\r
470 // Assume only one instance of SMM Communication Protocol in the system\r
471 // Locate SMM Communication Protocol\r
472 //\r
983ae8ce 473 Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);\r
f5501a65 474 ASSERT_EFI_ERROR (Status);\r
475\r
476 //\r
477 // Assume only one instance of SMM Base Helper Ready Protocol in the system\r
478 // Locate SMM Base Helper Ready Protocol\r
479 //\r
480 Status = gBS->LocateProtocol (&gEfiSmmBaseHelperReadyProtocolGuid, NULL, (VOID **) &mSmmBaseHelperReady);\r
481 ASSERT_EFI_ERROR (Status);\r
9e620719 482\r
8edfbe02 483 //\r
484 // Create event notification on Exit Boot Services event.\r
485 //\r
486 Status = gBS->CreateEventEx (\r
487 EVT_NOTIFY_SIGNAL,\r
488 TPL_NOTIFY,\r
489 SmmBaseExitBootServicesEventNotify,\r
490 NULL,\r
491 &gEfiEventExitBootServicesGuid,\r
492 &Event\r
493 );\r
494 ASSERT_EFI_ERROR (Status);\r
495\r
f5501a65 496 //\r
497 // Create event on SetVirtualAddressMap() to convert mSmmCommunication from a physical address to a virtual address\r
498 //\r
fb03ca1a 499 Status = gBS->CreateEventEx (\r
500 EVT_NOTIFY_SIGNAL,\r
501 TPL_NOTIFY,\r
502 SmmBaseAddressChangeEvent,\r
503 NULL,\r
504 &gEfiEventVirtualAddressChangeGuid,\r
f5501a65 505 &Event\r
fb03ca1a 506 );\r
507 ASSERT_EFI_ERROR (Status);\r
f5501a65 508 \r
509 //\r
510 // Publish Framework SMM BASE Protocol immediately after SMM Base2 Protocol is installed to\r
511 // make SMM Base Protocol.InSmm() available as early as possible.\r
512 //\r
513 Status = gBS->InstallMultipleProtocolInterfaces (\r
514 &mSmmBaseHandle,\r
515 &gEfiSmmBaseProtocolGuid, &mSmmBase,\r
516 NULL\r
517 );\r
518 ASSERT_EFI_ERROR (Status);\r
519 \r
9e620719 520 return EFI_SUCCESS;\r
521}\r