]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c
Fix ICC11(VS2005) build failure.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / Acpi / AcpiS3SaveDxe / AcpiS3Save.c
CommitLineData
13d4af68 1/** @file\r
2 This is an implementation of the ACPI S3 Save protocol. This is defined in\r
3 S3 boot path specification 0.9.\r
4\r
73f0127f 5Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
13d4af68 6\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions\r
9of the BSD License which accompanies this distribution. The\r
10full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include <PiDxe.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
22#include <Library/UefiRuntimeServicesTableLib.h>\r
c56b6566 23#include <Library/HobLib.h>\r
13d4af68 24#include <Library/LockBoxLib.h>\r
25#include <Library/PcdLib.h>\r
26#include <Library/DebugLib.h>\r
27#include <Guid/AcpiVariableCompatibility.h>\r
28#include <Guid/AcpiS3Context.h>\r
29#include <Guid/Acpi.h>\r
30#include <Protocol/AcpiS3Save.h>\r
31#include <IndustryStandard/Acpi.h>\r
32\r
33#include "AcpiS3Save.h"\r
34\r
35/**\r
36 Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.\r
37**/\r
38VOID\r
39InstallAcpiS3SaveThunk (\r
40 VOID\r
41 );\r
42\r
43/**\r
44 Hook point for AcpiVariableThunkPlatform for S3Ready.\r
45\r
46 @param AcpiS3Context ACPI s3 context\r
47**/\r
48VOID\r
49S3ReadyThunkPlatform (\r
50 IN ACPI_S3_CONTEXT *AcpiS3Context\r
51 );\r
52\r
53UINTN mLegacyRegionSize;\r
54\r
55EFI_ACPI_S3_SAVE_PROTOCOL mS3Save = {\r
56 LegacyGetS3MemorySize,\r
57 S3Ready,\r
58};\r
59\r
60EFI_GUID mAcpiS3IdtrProfileGuid = {\r
ce68d3bc 61 0xdea652b0, 0xd587, 0x4c54, { 0xb5, 0xb4, 0xc6, 0x82, 0xe7, 0xa0, 0xaa, 0x3d }\r
13d4af68 62};\r
63\r
64/**\r
091249f4 65 Allocate memory below 4G memory address.\r
13d4af68 66\r
091249f4 67 This function allocates memory below 4G memory address.\r
13d4af68 68\r
091249f4 69 @param MemoryType Memory type of memory to allocate.\r
13d4af68 70 @param Size Size of memory to allocate.\r
71 \r
72 @return Allocated address for output.\r
73\r
74**/\r
75VOID*\r
091249f4 76AllocateMemoryBelow4G (\r
73f0127f
SZ
77 IN EFI_MEMORY_TYPE MemoryType,\r
78 IN UINTN Size\r
13d4af68 79 )\r
80{\r
81 UINTN Pages;\r
82 EFI_PHYSICAL_ADDRESS Address;\r
83 EFI_STATUS Status;\r
84 VOID* Buffer;\r
85\r
86 Pages = EFI_SIZE_TO_PAGES (Size);\r
87 Address = 0xffffffff;\r
88\r
89 Status = gBS->AllocatePages (\r
90 AllocateMaxAddress,\r
091249f4 91 MemoryType,\r
13d4af68 92 Pages,\r
93 &Address\r
94 );\r
95 ASSERT_EFI_ERROR (Status);\r
96\r
97 Buffer = (VOID *) (UINTN) Address;\r
98 ZeroMem (Buffer, Size);\r
99\r
100 return Buffer;\r
101}\r
102\r
c93776c2
JY
103/**\r
104\r
105 This function scan ACPI table in RSDT.\r
106\r
107 @param Rsdt ACPI RSDT\r
108 @param Signature ACPI table signature\r
109\r
110 @return ACPI table\r
111\r
112**/\r
113VOID *\r
114ScanTableInRSDT (\r
115 IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt,\r
116 IN UINT32 Signature\r
117 )\r
118{\r
119 UINTN Index;\r
120 UINT32 EntryCount;\r
121 UINT32 *EntryPtr;\r
122 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
123\r
124 if (Rsdt == NULL) {\r
125 return NULL;\r
126 }\r
127\r
128 EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);\r
129 \r
130 EntryPtr = (UINT32 *)(Rsdt + 1);\r
131 for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {\r
132 Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));\r
133 if (Table->Signature == Signature) {\r
134 return Table;\r
135 }\r
136 }\r
137 \r
138 return NULL;\r
139}\r
140\r
141/**\r
142\r
143 This function scan ACPI table in XSDT.\r
144\r
145 @param Xsdt ACPI XSDT\r
146 @param Signature ACPI table signature\r
147\r
148 @return ACPI table\r
149\r
150**/\r
151VOID *\r
152ScanTableInXSDT (\r
153 IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt,\r
154 IN UINT32 Signature\r
155 )\r
156{\r
157 UINTN Index;\r
158 UINT32 EntryCount;\r
159 UINT64 EntryPtr;\r
160 UINTN BasePtr;\r
161 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
162\r
163 if (Xsdt == NULL) {\r
164 return NULL;\r
165 }\r
166\r
167 EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);\r
168 \r
169 BasePtr = (UINTN)(Xsdt + 1);\r
170 for (Index = 0; Index < EntryCount; Index ++) {\r
171 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));\r
172 Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr));\r
173 if (Table->Signature == Signature) {\r
174 return Table;\r
175 }\r
176 }\r
177 \r
178 return NULL;\r
179}\r
180\r
181/**\r
182 To find Facs in FADT.\r
183\r
184 @param Fadt FADT table pointer\r
185 \r
186 @return Facs table pointer.\r
187**/\r
188EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
189FindAcpiFacsFromFadt (\r
190 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
191 )\r
192{\r
193 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
194 UINT64 Data64;\r
195\r
196 if (Fadt == NULL) {\r
197 return NULL;\r
198 }\r
199\r
200 if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
201 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;\r
202 } else {\r
203 if (Fadt->FirmwareCtrl != 0) {\r
204 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;\r
205 } else {\r
206 CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64));\r
207 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Data64;\r
208 }\r
209 }\r
210 return Facs;\r
211}\r
212\r
13d4af68 213/**\r
214 To find Facs in Acpi tables.\r
215 \r
216 To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored \r
217 in the table.\r
218\r
219 @param AcpiTableGuid The guid used to find ACPI table in UEFI ConfigurationTable.\r
220 \r
221 @return Facs table pointer.\r
222**/\r
223EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
224FindAcpiFacsTableByAcpiGuid (\r
225 IN EFI_GUID *AcpiTableGuid\r
226 )\r
227{\r
228 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
229 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
c93776c2 230 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
13d4af68 231 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
232 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
233 UINTN Index;\r
c93776c2 234\r
13d4af68 235 Rsdp = NULL;\r
13d4af68 236 //\r
237 // found ACPI table RSD_PTR from system table\r
238 //\r
239 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
240 if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {\r
241 //\r
242 // A match was found.\r
243 //\r
244 Rsdp = gST->ConfigurationTable[Index].VendorTable;\r
245 break;\r
246 }\r
247 }\r
248\r
249 if (Rsdp == NULL) {\r
250 return NULL;\r
251 }\r
252\r
c93776c2
JY
253 //\r
254 // Search XSDT\r
255 //\r
256 if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
257 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;\r
258 Fadt = ScanTableInXSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);\r
259 if (Fadt != NULL) {\r
260 Facs = FindAcpiFacsFromFadt (Fadt);\r
261 if (Facs != NULL) {\r
262 return Facs;\r
263 }\r
13d4af68 264 }\r
265 }\r
266\r
c93776c2
JY
267 //\r
268 // Search RSDT\r
269 //\r
270 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;\r
271 Fadt = ScanTableInRSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);\r
272 if (Fadt != NULL) {\r
273 Facs = FindAcpiFacsFromFadt (Fadt);\r
274 if (Facs != NULL) {\r
275 return Facs;\r
276 }\r
13d4af68 277 }\r
278\r
c93776c2 279 return NULL;\r
13d4af68 280}\r
281\r
282/**\r
283 To find Facs in Acpi tables.\r
284 \r
285 To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored \r
286 in the table.\r
287 \r
288 @return Facs table pointer.\r
289**/\r
290EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
291FindAcpiFacsTable (\r
292 VOID\r
293 )\r
294{\r
295 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
296\r
297 Facs = FindAcpiFacsTableByAcpiGuid (&gEfiAcpi20TableGuid);\r
298 if (Facs != NULL) {\r
299 return Facs;\r
300 }\r
301\r
302 return FindAcpiFacsTableByAcpiGuid (&gEfiAcpi10TableGuid);\r
303}\r
304\r
305/**\r
306 Allocates and fills in the Page Directory and Page Table Entries to\r
307 establish a 1:1 Virtual to Physical mapping.\r
308 If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1 \r
309 virtual to physical mapping page table.\r
310 If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. \r
311 \r
312 @return the 1:1 Virtual to Physical identity mapping page table base address. \r
313\r
314**/\r
315EFI_PHYSICAL_ADDRESS\r
316S3CreateIdentityMappingPageTables (\r
317 VOID\r
318 )\r
319{ \r
320 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
321 UINT32 RegEax;\r
c56b6566 322 UINT32 RegEdx;\r
13d4af68 323 UINT8 PhysicalAddressBits;\r
c56b6566
JY
324 UINT32 NumberOfPml4EntriesNeeded;\r
325 UINT32 NumberOfPdpEntriesNeeded;\r
13d4af68 326 EFI_PHYSICAL_ADDRESS S3NvsPageTableAddress;\r
327 UINTN TotalPageTableSize;\r
c56b6566
JY
328 VOID *Hob;\r
329 BOOLEAN Page1GSupport;\r
c56b6566
JY
330\r
331 Page1GSupport = FALSE;\r
378175d2
JY
332 if (PcdGetBool(PcdUse1GPageTable)) {\r
333 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
334 if (RegEax >= 0x80000001) {\r
335 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
336 if ((RegEdx & BIT26) != 0) {\r
337 Page1GSupport = TRUE;\r
338 }\r
c56b6566
JY
339 }\r
340 }\r
13d4af68 341\r
342 //\r
343 // Get physical address bits supported.\r
344 //\r
c56b6566
JY
345 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
346 if (Hob != NULL) {\r
347 PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
13d4af68 348 } else {\r
c56b6566
JY
349 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
350 if (RegEax >= 0x80000008) {\r
351 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
352 PhysicalAddressBits = (UINT8) RegEax;\r
353 } else {\r
354 PhysicalAddressBits = 36;\r
355 }\r
13d4af68 356 }\r
357 \r
c56b6566
JY
358 //\r
359 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
360 //\r
361 ASSERT (PhysicalAddressBits <= 52);\r
362 if (PhysicalAddressBits > 48) {\r
363 PhysicalAddressBits = 48;\r
364 }\r
365\r
13d4af68 366 //\r
367 // Calculate the table entries needed.\r
368 //\r
369 if (PhysicalAddressBits <= 39 ) {\r
370 NumberOfPml4EntriesNeeded = 1;\r
c56b6566 371 NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));\r
13d4af68 372 } else {\r
c56b6566 373 NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));\r
13d4af68 374 NumberOfPdpEntriesNeeded = 512;\r
375 }\r
376\r
377 //\r
378 // We need calculate whole page size then allocate once, because S3 restore page table does not know each page in Nvs.\r
379 //\r
c56b6566
JY
380 if (!Page1GSupport) {\r
381 TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded);\r
382 } else {\r
383 TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);\r
384 }\r
13d4af68 385 DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", TotalPageTableSize));\r
386\r
387 //\r
091249f4 388 // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
13d4af68 389 //\r
091249f4 390 S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));\r
13d4af68 391 ASSERT (S3NvsPageTableAddress != 0);\r
091249f4 392 return S3NvsPageTableAddress;\r
13d4af68 393 } else {\r
394 //\r
395 // If DXE is running 32-bit mode, no need to establish page table.\r
396 //\r
397 return (EFI_PHYSICAL_ADDRESS) 0; \r
398 }\r
399}\r
400\r
401/**\r
402 Gets the buffer of legacy memory below 1 MB \r
403 This function is to get the buffer in legacy memory below 1MB that is required during S3 resume.\r
404\r
405 @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.\r
406 @param Size The returned size of legacy memory below 1 MB.\r
407\r
408 @retval EFI_SUCCESS Size is successfully returned.\r
409 @retval EFI_INVALID_PARAMETER The pointer Size is NULL.\r
410\r
411**/\r
412EFI_STATUS\r
413EFIAPI\r
414LegacyGetS3MemorySize (\r
415 IN EFI_ACPI_S3_SAVE_PROTOCOL *This,\r
416 OUT UINTN *Size\r
417 )\r
418{\r
419 if (Size == NULL) {\r
420 return EFI_INVALID_PARAMETER;\r
421 }\r
422\r
423 *Size = mLegacyRegionSize;\r
424 return EFI_SUCCESS;\r
425}\r
426\r
427/**\r
428 Prepares all information that is needed in the S3 resume boot path.\r
429 \r
430 Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path \r
431 \r
432 @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.\r
433 @param LegacyMemoryAddress The base address of legacy memory.\r
434\r
435 @retval EFI_NOT_FOUND Some necessary information cannot be found.\r
436 @retval EFI_SUCCESS All information was saved successfully.\r
437 @retval EFI_OUT_OF_RESOURCES Resources were insufficient to save all the information.\r
438 @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB.\r
439\r
440**/\r
441EFI_STATUS\r
442EFIAPI\r
443S3Ready (\r
444 IN EFI_ACPI_S3_SAVE_PROTOCOL *This,\r
445 IN VOID *LegacyMemoryAddress\r
446 )\r
447{\r
448 EFI_STATUS Status;\r
449 EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer;\r
450 ACPI_S3_CONTEXT *AcpiS3Context;\r
451 STATIC BOOLEAN AlreadyEntered;\r
452 IA32_DESCRIPTOR *Idtr;\r
453 IA32_IDT_GATE_DESCRIPTOR *IdtGate;\r
454\r
455 DEBUG ((EFI_D_INFO, "S3Ready!\n"));\r
456\r
457 //\r
458 // Platform may invoke AcpiS3Save->S3Save() before ExitPmAuth, because we need save S3 information there, while BDS ReadyToBoot may invoke it again.\r
459 // So if 2nd S3Save() is triggered later, we need ignore it.\r
460 //\r
461 if (AlreadyEntered) {\r
462 return EFI_SUCCESS;\r
463 }\r
464 AlreadyEntered = TRUE;\r
465\r
091249f4 466 AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context));\r
13d4af68 467 ASSERT (AcpiS3Context != NULL);\r
468 AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;\r
469\r
470 //\r
471 // Get ACPI Table because we will save its position to variable\r
472 //\r
473 AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable ();\r
474 ASSERT (AcpiS3Context->AcpiFacsTable != 0);\r
475\r
091249f4 476 IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR));\r
13d4af68 477 Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100);\r
478 Idtr->Base = (UINTN)IdtGate;\r
479 Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1);\r
480 AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr;\r
481\r
482 Status = SaveLockBox (\r
483 &mAcpiS3IdtrProfileGuid,\r
484 (VOID *)(UINTN)Idtr,\r
485 (UINTN)sizeof(IA32_DESCRIPTOR)\r
486 );\r
487 ASSERT_EFI_ERROR (Status);\r
488\r
489 Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
490 ASSERT_EFI_ERROR (Status);\r
491\r
492 //\r
493 // Allocate page table\r
494 //\r
495 AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables ();\r
496\r
497 //\r
498 // Allocate stack\r
499 //\r
500 AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize);\r
091249f4 501 AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize));\r
13d4af68 502 ASSERT (AcpiS3Context->BootScriptStackBase != 0);\r
503\r
504 //\r
f4a25e81 505 // Allocate a code buffer < 4G for S3 debug to load external code, set invalid code instructions in it.\r
13d4af68 506 //\r
091249f4 507 AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE);\r
f4a25e81 508 SetMem ((VOID *)(UINTN)AcpiS3Context->S3DebugBufferAddress, EFI_PAGE_SIZE, 0xff);\r
13d4af68 509\r
510 DEBUG((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8x\n", AcpiS3Context->AcpiFacsTable));\r
511 DEBUG((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8x\n", AcpiS3Context->IdtrProfile));\r
512 DEBUG((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8x\n", AcpiS3Context->S3NvsPageTableAddress));\r
513 DEBUG((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8x\n", AcpiS3Context->S3DebugBufferAddress));\r
514\r
515 Status = SaveLockBox (\r
516 &gEfiAcpiVariableGuid,\r
517 &AcpiS3ContextBuffer,\r
518 sizeof(AcpiS3ContextBuffer)\r
519 );\r
520 ASSERT_EFI_ERROR (Status);\r
521\r
522 Status = SaveLockBox (\r
523 &gEfiAcpiS3ContextGuid,\r
524 (VOID *)(UINTN)AcpiS3Context,\r
525 (UINTN)sizeof(*AcpiS3Context)\r
526 );\r
527 ASSERT_EFI_ERROR (Status);\r
528\r
529 Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
530 ASSERT_EFI_ERROR (Status);\r
531\r
532 if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {\r
533 S3ReadyThunkPlatform (AcpiS3Context);\r
534 }\r
535\r
536 return EFI_SUCCESS;\r
537}\r
538\r
539/**\r
540 The Driver Entry Point.\r
541 \r
542 The function is the driver Entry point which will produce AcpiS3SaveProtocol.\r
543 \r
544 @param ImageHandle A handle for the image that is initializing this driver\r
545 @param SystemTable A pointer to the EFI system table\r
546\r
547 @retval EFI_SUCCESS: Driver initialized successfully\r
548 @retval EFI_LOAD_ERROR: Failed to Initialize or has been loaded\r
549 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources\r
550\r
551**/\r
552EFI_STATUS\r
553EFIAPI\r
554InstallAcpiS3Save (\r
555 IN EFI_HANDLE ImageHandle,\r
556 IN EFI_SYSTEM_TABLE *SystemTable\r
557 )\r
558{\r
559 EFI_STATUS Status;\r
560\r
561 if (!FeaturePcdGet(PcdPlatformCsmSupport)) {\r
562 //\r
563 // More memory for no CSM tip, because GDT need relocation\r
564 //\r
565 mLegacyRegionSize = 0x250;\r
566 } else {\r
567 mLegacyRegionSize = 0x100;\r
568 }\r
569\r
570 if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {\r
571 InstallAcpiS3SaveThunk ();\r
572 }\r
573\r
574 Status = gBS->InstallProtocolInterface (\r
575 &ImageHandle,\r
576 &gEfiAcpiS3SaveProtocolGuid,\r
577 EFI_NATIVE_INTERFACE,\r
578 &mS3Save\r
579 );\r
580 ASSERT_EFI_ERROR (Status);\r
581 return Status;\r
582}\r