/** @file\r
- This module produces the EFI_PEI_S3_RESUME_PPI.\r
+ This module produces the EFI_PEI_S3_RESUME2_PPI.\r
This module works with StandAloneBootScriptExecutor to S3 resume to OS.\r
- This module will excute the boot script saved during last boot and after that,\r
+ This module will execute the boot script saved during last boot and after that,\r
control is passed to OS waking up handler.\r
\r
- Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
#include <Library/LockBoxLib.h>\r
#include <IndustryStandard/Acpi.h>\r
\r
+/**\r
+ This macro aligns the address of a variable with auto storage\r
+ duration down to CPU_STACK_ALIGNMENT.\r
+\r
+ Since the stack grows downward, the result preserves more of the\r
+ stack than the original address (or the same amount), not less.\r
+**/\r
+#define STACK_ALIGN_DOWN(Ptr) \\r
+ ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1))\r
+\r
#pragma pack(1)\r
typedef union {\r
struct {\r
UINT64 Freq;\r
\r
//\r
- // Retrive time stamp count as early as possilbe\r
+ // Retrieve time stamp count as early as possible\r
//\r
Ticker = GetPerformanceCounter ();\r
\r
if ((AsciiStrnCmp (Token, "PEIM", PEI_PERFORMANCE_STRING_SIZE) == 0) && (Handle != NULL)) {\r
AsciiSPrint (PerfData->Token, PERF_TOKEN_LENGTH, "0x%11p", Handle);\r
} else {\r
- AsciiStrnCpy (PerfData->Token, Token, PERF_TOKEN_LENGTH);\r
+ AsciiStrnCpyS (PerfData->Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);\r
}\r
if (StartTicker == 1) {\r
StartTicker = StartValue;\r
// NOTE: We have to ASSUME the page table generation format, because we do not know whole page table information.\r
// The whole page table is too large to be saved in SMRAM.\r
//\r
- // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page.\r
+ // The assumption is : whole page table is allocated in CONTINUOUS memory and CR3 points to TOP page.\r
//\r
DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));\r
\r
//\r
- // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.\r
+ // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
//\r
PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;\r
S3NvsPageTableAddress += SIZE_4KB;\r
//\r
IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);\r
//\r
- // Make sure the newly allcated IDT align with 16-bytes\r
+ // Make sure the newly allocated IDT align with 16-bytes\r
// \r
IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));\r
- ASSERT (IdtBuffer != NULL);\r
+ if (IdtBuffer == NULL) {\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)\r
+ );\r
+ ASSERT (FALSE);\r
+ }\r
//\r
// Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer\r
// IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code\r
// Prepare data for return back\r
//\r
PeiS3ResumeState = AllocatePool (sizeof(*PeiS3ResumeState));\r
- ASSERT (PeiS3ResumeState != NULL);\r
+ if (PeiS3ResumeState == NULL) {\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)\r
+ );\r
+ ASSERT (FALSE);\r
+ }\r
DEBUG (( EFI_D_ERROR, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState));\r
PeiS3ResumeState->ReturnCs = 0x10;\r
PeiS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs;\r
- PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)(UINTN)&Status;\r
+ PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
//\r
// Save IDT\r
//\r
DEBUG (( EFI_D_ERROR, "AcpiS3Context = %x\n", AcpiS3Context));\r
DEBUG (( EFI_D_ERROR, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector));\r
DEBUG (( EFI_D_ERROR, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable));\r
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile)); \r
DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));\r
DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));\r
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));\r
+ DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize));\r
DEBUG (( EFI_D_ERROR, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint));\r
\r
//\r
SmmS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeExecuteBootScript;\r
SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;\r
SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable;\r
- SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)(UINTN)&Status;\r
+ SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
\r
DEBUG (( EFI_D_ERROR, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature));\r
DEBUG (( EFI_D_ERROR, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase));\r