/** @file\r
Code for Processor S3 restoration\r
\r
-Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
SmmS3ResumeState = mSmmS3ResumeState;\r
ASSERT (SmmS3ResumeState != NULL);\r
\r
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {\r
+ //\r
+ // Setup 64bit IDT in 64bit SMM env when called from 32bit PEI.\r
+ // Note: 64bit PEI and 32bit DXE is not a supported combination.\r
+ //\r
+ if ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode) == TRUE)) {\r
//\r
// Save the IA32 IDT Descriptor\r
//\r
DEBUG ((DEBUG_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer));\r
\r
//\r
- // If SMM is in 32-bit mode, then use SwitchStack() to resume PEI Phase\r
+ // If SMM is in 32-bit mode or PcdDxeIplSwitchToLongMode is FALSE, then use SwitchStack() to resume PEI Phase.\r
+ // Note: 64bit PEI and 32bit DXE is not a supported combination.\r
//\r
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {\r
+ if ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode) == FALSE)) {\r
DEBUG ((DEBUG_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));\r
\r
SwitchStack (\r
; @file\r
; Transition from 16 bit real mode into 32 bit flat protected mode\r
;\r
-; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2008 - 2022, Intel Corporation. All rights reserved.<BR>\r
; SPDX-License-Identifier: BSD-2-Clause-Patent\r
;\r
;------------------------------------------------------------------------------\r
\r
GDT_BASE:\r
; null descriptor\r
-NULL_SEL equ $-GDT_BASE\r
+NULL_SEL equ $-GDT_BASE ; Selector [0x0]\r
DW 0 ; limit 15:0\r
DW 0 ; base 15:0\r
DB 0 ; base 23:16\r
DB 0 ; limit 19:16, flags\r
DB 0 ; base 31:24\r
\r
+; Spare segment descriptor\r
+SPARE1_SEL equ $-GDT_BASE ; Selector [0x8]\r
+ DW 0 ; limit 15:0\r
+ DW 0 ; base 15:0\r
+ DB 0 ; base 23:16\r
+ DB 0 ; sys flag, dpl, type\r
+ DB 0 ; limit 19:16, flags\r
+ DB 0 ; base 31:24\r
+\r
+; linear code segment descriptor\r
+LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10]\r
+ DW 0xffff ; limit 15:0\r
+ DW 0 ; base 15:0\r
+ DB 0 ; base 23:16\r
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE) ; 09Bh\r
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf) ; 0CFh\r
+ DB 0 ; base 31:24\r
+\r
; linear data segment descriptor\r
-LINEAR_SEL equ $-GDT_BASE\r
+LINEAR_SEL equ $-GDT_BASE ; Selector [0x18]\r
DW 0xffff ; limit 15:0\r
DW 0 ; base 15:0\r
DB 0 ; base 23:16\r
- DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE)\r
- DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)\r
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE) ; 093h\r
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf) ; 0CFh\r
DB 0 ; base 31:24\r
\r
-; linear code segment descriptor\r
-LINEAR_CODE_SEL equ $-GDT_BASE\r
+; Spare segment descriptor\r
+SPARE2_SEL equ $-GDT_BASE ; Selector [0x20]\r
+ DW 0 ; limit 15:0\r
+ DW 0 ; base 15:0\r
+ DB 0 ; base 23:16\r
+ DB 0 ; sys flag, dpl, type\r
+ DB 0 ; limit 19:16, flags\r
+ DB 0 ; base 31:24\r
+\r
+; linear code (16-bit) segment descriptor\r
+LINEAR_CODE16_SEL equ $-GDT_BASE ; Selector [0x28]\r
DW 0xffff ; limit 15:0\r
DW 0 ; base 15:0\r
DB 0 ; base 23:16\r
- DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)\r
- DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)\r
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE) ; 09Bh\r
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMIT(0xf) ; 08Fh\r
DB 0 ; base 31:24\r
\r
-%ifdef ARCH_X64\r
-; linear code (64-bit) segment descriptor\r
-LINEAR_CODE64_SEL equ $-GDT_BASE\r
+; linear data (16-bit) segment descriptor\r
+LINEAR_DATA16_SEL equ $-GDT_BASE ; Selector [0x30]\r
DW 0xffff ; limit 15:0\r
DW 0 ; base 15:0\r
DB 0 ; base 23:16\r
- DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE)\r
- DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf)\r
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE) ; 093h\r
+ DB 0\r
DB 0 ; base 31:24\r
-%endif\r
\r
-; linear code segment descriptor\r
-LINEAR_CODE16_SEL equ $-GDT_BASE\r
+; linear code (64-bit) segment descriptor\r
+LINEAR_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]\r
DW 0xffff ; limit 15:0\r
DW 0 ; base 15:0\r
DB 0 ; base 23:16\r
- DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)\r
- DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)\r
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE) ; 09Bh\r
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf) ; 0AFh\r
DB 0 ; base 31:24\r
\r
GDT_END:\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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0))\r
{\r
// Both BIOS and OS wants 64bit vector\r
- if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
- return TRUE;\r
- }\r
+ ASSERT ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64)));\r
+ return TRUE;\r
}\r
}\r
\r
//\r
// X64 long mode waking vector\r
//\r
- DEBUG ((DEBUG_INFO, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
+ DEBUG ((DEBUG_INFO, "Transfer from PEI to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+ //\r
+ // 32bit PEI calls to 64bit OS S3 waking vector\r
+ //\r
AsmEnablePaging64 (\r
0x38,\r
Facs->XFirmwareWakingVector,\r
(UINT64)(UINTN)TempStackTop\r
);\r
} else {\r
- //\r
- // Report Status code that no valid waking vector is found\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
- (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)\r
- );\r
- DEBUG ((DEBUG_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));\r
- ASSERT (FALSE);\r
- CpuDeadLoop ();\r
- return;\r
+ if (sizeof (UINTN) == sizeof (UINT64)) {\r
+ //\r
+ // 64bit PEI calls to 64bit OS S3 waking vector\r
+ //\r
+ SwitchStack (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,\r
+ NULL,\r
+ NULL,\r
+ (VOID *)(UINTN)TempStackTop\r
+ );\r
+ } else {\r
+ //\r
+ // Report Status code that no valid waking vector is found.\r
+ // Note: 32bit PEI + 32bit DXE firmware calling to 64bit OS S3 waking vector is an invalid configuration.\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)\r
+ );\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
} else {\r
//\r
// IA32 protected mode waking vector (Page disabled)\r
//\r
DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
- SwitchStack (\r
- (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,\r
- NULL,\r
- NULL,\r
- (VOID *)(UINTN)TempStackTop\r
- );\r
+ if (sizeof (UINTN) == sizeof (UINT64)) {\r
+ //\r
+ // 64bit PEI calls to 32bit OS S3 waking vector\r
+ //\r
+ AsmDisablePaging64 (\r
+ 0x10,\r
+ (UINT32)Facs->XFirmwareWakingVector,\r
+ 0,\r
+ 0,\r
+ (UINT32)TempStackTop\r
+ );\r
+ } else {\r
+ //\r
+ // 32bit PEI calls to 32bit OS S3 waking vector\r
+ //\r
+ SwitchStack (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,\r
+ NULL,\r
+ NULL,\r
+ (VOID *)(UINTN)TempStackTop\r
+ );\r
+ }\r
}\r
} else {\r
//\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 BootScriptExecutor 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
IN BOOLEAN Build4GPageTableOnly\r
)\r
{\r
- if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+ if ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64))) {\r
UINT32 RegEax;\r
UINT32 RegEdx;\r
UINT8 PhysicalAddressBits;\r
SignalToSmmByCommunication (&gEdkiiS3SmmInitDoneGuid);\r
}\r
\r
- if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+ if ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64))) {\r
AsmWriteCr3 ((UINTN)AcpiS3Context->S3NvsPageTableAddress);\r
}\r
\r
CpuDeadLoop ();\r
}\r
\r
- if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+ if ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64))) {\r
//\r
// Need reconstruct page table here, since we do not trust ACPINvs.\r
//\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
DEBUG ((DEBUG_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer));\r
DEBUG ((DEBUG_INFO, "SMM S3 Smst = %x\n", SmmS3ResumeState->Smst));\r
\r
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {\r
+ //\r
+ // Directly do the switch stack when PEI and SMM env run in the same execution mode.\r
+ //\r
+ if (((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) && (sizeof (UINTN) == sizeof (UINT32))) ||\r
+ ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (sizeof (UINTN) == sizeof (UINT64))))\r
+ {\r
SwitchStack (\r
(SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->SmmS3ResumeEntryPoint,\r
(VOID *)AcpiS3Context,\r