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 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions\r
- of the BSD License which accompanies this distribution. The\r
- full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Guid/ExtendedFirmwarePerformance.h>\r
#include <Guid/EndOfS3Resume.h>\r
#include <Guid/S3SmmInitDone.h>\r
-#include <Ppi/ReadOnlyVariable2.h>\r
#include <Ppi/S3Resume2.h>\r
#include <Ppi/SmmAccess.h>\r
#include <Ppi/PostBootScriptTable.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseLib.h>\r
-#include <Library/TimerLib.h>\r
#include <Library/PeimEntryPoint.h>\r
#include <Library/PeiServicesLib.h>\r
#include <Library/HobLib.h>\r
#include <Library/DebugAgentLib.h>\r
#include <Library/LocalApicLib.h>\r
#include <Library/ReportStatusCodeLib.h>\r
-#include <Library/PrintLib.h>\r
+\r
#include <Library/HobLib.h>\r
#include <Library/LockBoxLib.h>\r
#include <IndustryStandard/Acpi.h>\r
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
- UINT64 MustBe1:1; // Must be 1 \r
+ UINT64 MustBe1:1; // Must be 1\r
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
UINT64 Available:3; // Available for use by system software\r
UINT64 PAT:1; //\r
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
- UINT64 MustBe1:1; // Must be 1 \r
+ UINT64 MustBe1:1; // Must be 1\r
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
UINT64 Available:3; // Available for use by system software\r
UINT64 PAT:1; //\r
//\r
/**\r
a ASM function to transfer control to OS.\r
- \r
+\r
@param S3WakingVector The S3 waking up vector saved in ACPI Facs table\r
- @param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer \r
+ @param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer\r
**/\r
typedef\r
VOID\r
if (Facs->XFirmwareWakingVector != 0) {\r
if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
- ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
+ ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
// Both BIOS and OS wants 64bit vector\r
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
return TRUE;\r
}\r
\r
//\r
- // NOTE: Because Debug Timer interrupt and system interrupts will be disabled \r
+ // NOTE: Because Debug Timer interrupt and system interrupts will be disabled\r
// in BootScriptExecuteDxe, the rest code in S3ResumeBootOs() cannot be halted\r
// by soft debugger.\r
//\r
\r
- PERF_END (NULL, "ScriptExec", NULL, 0);\r
+ PERF_INMODULE_END ("ScriptExec");\r
\r
//\r
// Install BootScriptDonePpi\r
//\r
- PERF_START_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_START_ID);\r
+ PERF_INMODULE_BEGIN ("BootScriptDonePpi");\r
\r
Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);\r
ASSERT_EFI_ERROR (Status);\r
\r
- PERF_END_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_END_ID);\r
+ PERF_INMODULE_END ("BootScriptDonePpi");\r
\r
//\r
// Get ACPI Table Address\r
//\r
// Install EndOfPeiPpi\r
//\r
- PERF_START_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_START_ID);\r
+ PERF_INMODULE_BEGIN("EndOfPeiPpi");\r
\r
Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);\r
ASSERT_EFI_ERROR (Status);\r
\r
- PERF_END_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_END_ID);\r
+ PERF_INMODULE_END("EndOfPeiPpi");\r
\r
- PERF_START_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_START_ID);\r
+ PERF_INMODULE_BEGIN("EndOfS3Resume");\r
\r
DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));\r
//\r
//\r
SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid);\r
\r
- PERF_END_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_END_ID);\r
+ PERF_INMODULE_END ("EndOfS3Resume");\r
\r
//\r
// report status code on S3 resume\r
));\r
if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
- ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
+ ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
//\r
// X64 long mode waking vector\r
//\r
EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
(EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)\r
);\r
- DEBUG (( EFI_D_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));\r
+ DEBUG (( DEBUG_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));\r
ASSERT (FALSE);\r
CpuDeadLoop ();\r
return ;\r
\r
/**\r
Restore S3 page table because we do not trust ACPINvs content.\r
- If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. \r
+ If BootScriptExector driver will not run in 64-bit mode, this function will do nothing.\r
\r
@param S3NvsPageTableAddress PageTableAddress in ACPINvs\r
@param Build4GPageTableOnly If BIOS just build 4G page table only\r
//\r
PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;\r
S3NvsPageTableAddress += SIZE_4KB;\r
- \r
+\r
Page1GSupport = FALSE;\r
if (PcdGetBool(PcdUse1GPageTable)) {\r
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
}\r
}\r
}\r
- \r
+\r
//\r
// Get physical address bits supported.\r
//\r
PhysicalAddressBits = 36;\r
}\r
}\r
- \r
+\r
//\r
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
//\r
NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));\r
NumberOfPdpEntriesNeeded = 512;\r
}\r
- \r
+\r
PageMapLevel4Entry = PageMap;\r
PageAddress = 0;\r
for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {\r
//\r
PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;\r
S3NvsPageTableAddress += SIZE_4KB;\r
- \r
+\r
//\r
// Make a PML4 Entry\r
//\r
\r
if (Page1GSupport) {\r
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;\r
- \r
+\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
//\r
// Fill in the Page Directory entries\r
//\r
// Each Directory Pointer entries points to a page of Page Directory entires.\r
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
- // \r
+ //\r
PageDirectoryEntry = (PAGE_TABLE_ENTRY *)S3NvsPageTableAddress;\r
S3NvsPageTableAddress += SIZE_4KB;\r
- \r
+\r
//\r
// Fill in a Page Directory Pointer Entries\r
//\r
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;\r
PageDirectoryPointerEntry->Bits.ReadWrite = 1;\r
PageDirectoryPointerEntry->Bits.Present = 1;\r
- \r
+\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
//\r
// Fill in the Page Directory entries\r
}\r
return ;\r
} else {\r
- //\r
- // If DXE is running 32-bit mode, no need to establish page table.\r
- //\r
+ //\r
+ // If DXE is running 32-bit mode, no need to establish page table.\r
+ //\r
return ;\r
}\r
}\r
PEI_SMM_ACCESS_PPI *SmmAccess;\r
UINTN Index;\r
VOID *GuidHob;\r
- IA32_DESCRIPTOR *IdtDescriptor;\r
- VOID *IdtBuffer;\r
PEI_S3_RESUME_STATE *PeiS3ResumeState;\r
BOOLEAN InterruptStatus;\r
\r
\r
//\r
// Send SMI to APs\r
- // \r
+ //\r
SendSmiIpiAllExcludingSelf ();\r
//\r
// Send SMI to BSP\r
);\r
if (!EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_INFO, "Close all SMRAM regions before executing boot script\n"));\r
- \r
+\r
for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
}\r
\r
DEBUG ((DEBUG_INFO, "Lock all SMRAM regions before executing boot script\n"));\r
- \r
+\r
for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
}\r
AsmWriteCr3 ((UINTN)AcpiS3Context->S3NvsPageTableAddress);\r
}\r
\r
- if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
- //\r
- // On some platform, such as ECP, a dispatch node in boot script table may execute a 32-bit PEIM which may need PeiServices\r
- // pointer. So PeiServices need preserve in (IDTBase- sizeof (UINTN)). \r
- //\r
- IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);\r
- //\r
- // Make sure the newly allocated IDT align with 16-bytes\r
- // \r
- IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));\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
- // \r
- ZeroMem (IdtBuffer, 16);\r
- AsmReadIdtr ((IA32_DESCRIPTOR *)IdtBuffer);\r
- CopyMem ((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1));\r
- IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16);\r
- *(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer ();\r
- }\r
-\r
InterruptStatus = SaveAndDisableInterrupts ();\r
//\r
// Need to make sure the GDT is loaded with values that support long mode and real mode.\r
// Save IDT\r
//\r
AsmReadIdtr (&PeiS3ResumeState->Idtr);\r
- \r
+\r
//\r
// Report Status Code to indicate S3 boot script execution\r
//\r
REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT);\r
\r
- PERF_START (NULL, "ScriptExec", NULL, 0);\r
+ PERF_INMODULE_BEGIN ("ScriptExec");\r
\r
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
//\r
VOID *GuidHob;\r
BOOLEAN Build4GPageTableOnly;\r
BOOLEAN InterruptStatus;\r
+ IA32_CR0 Cr0;\r
\r
TempAcpiS3Context = 0;\r
TempEfiBootScriptExecutorVariable = 0;\r
DEBUG (( DEBUG_INFO, "AcpiS3Context = %x\n", AcpiS3Context));\r
DEBUG (( DEBUG_INFO, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector));\r
DEBUG (( DEBUG_INFO, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable));\r
- DEBUG (( DEBUG_INFO, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile)); \r
+ DEBUG (( DEBUG_INFO, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile));\r
DEBUG (( DEBUG_INFO, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));\r
DEBUG (( DEBUG_INFO, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));\r
DEBUG (( DEBUG_INFO, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));\r
//\r
GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);\r
if (GuidHob != NULL) {\r
+ //\r
+ // Below SwitchStack/AsmEnablePaging64 function has\r
+ // assumption that it's in 32 bits mode now.\r
+ // Add ASSERT code to indicate this assumption.\r
+ //\r
+ ASSERT(sizeof (UINTN) == sizeof (UINT32));\r
+\r
Status = PeiServicesLocatePpi (\r
&gPeiSmmAccessPpiGuid,\r
0,\r
AsmWriteGdtr (&mGdt);\r
//\r
// update segment selectors per the new GDT.\r
- // \r
+ //\r
AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR);\r
//\r
// Restore interrupt state.\r
//\r
SetInterruptState (InterruptStatus);\r
\r
+ Cr0.UintN = AsmReadCr0 ();\r
+ if (Cr0.Bits.PG != 0) {\r
+ //\r
+ // We're in 32-bit mode, with paging enabled. We can't set CR3 to\r
+ // the 64-bit page tables without first disabling paging.\r
+ //\r
+ Cr0.Bits.PG = 0;\r
+ AsmWriteCr0 (Cr0.UintN);\r
+ }\r
AsmWriteCr3 ((UINTN)SmmS3ResumeState->SmmS3Cr3);\r
\r
//\r
Main entry for S3 Resume PEIM.\r
\r
This routine is to install EFI_PEI_S3_RESUME2_PPI.\r
- \r
+\r
@param FileHandle Handle of the file being invoked.\r
@param PeiServices Pointer to PEI Services table.\r
\r
\r
return EFI_SUCCESS;\r
}\r
-\r