[X64] Support S3 resume on 64-bit build (#698)
This will support S3 resume path on X64 thru 16-bit waking vector. - Port WakeUp code from EDKII - Remove duplicated calls of FindS3Info from CpuInit - Verified with Yocto on a WHL board - TBD: 64-bit waking vector with supported OS Signed-off-by: Aiden Park <aiden.park@intel.com>
This commit is contained in:
parent
17828b4e1d
commit
eae81b7bc8
|
@ -727,7 +727,11 @@ FindAcpiWakeVectorAndJump (
|
|||
Hdr = (EFI_ACPI_COMMON_HEADER *) (UINTN)XsdtEntry[Index];
|
||||
if (Hdr->Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
|
||||
Facp = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Hdr;
|
||||
if (Facp->XFirmwareCtrl != 0) {
|
||||
Facs = (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Facp->XFirmwareCtrl;
|
||||
} else {
|
||||
Facs = (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Facp->FirmwareCtrl;
|
||||
}
|
||||
if (Facs->Signature == EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
|
||||
WakeVector = Facs->FirmwareWakingVector;
|
||||
// Calculate CRC32 for 0x00000000 ---> BootLoaderRsvdMemBase and
|
||||
|
@ -737,7 +741,7 @@ FindAcpiWakeVectorAndJump (
|
|||
return;
|
||||
}
|
||||
}
|
||||
CopyMem ((VOID *)(UINTN)WakeUpBuffer, &WakeUp, WakeUpSize);
|
||||
CopyMem ((VOID *)(UINTN)WakeUpBuffer, (VOID *)(UINTN)&WakeUp, WakeUpSize);
|
||||
DoWake = (DOWAKEUP)(UINTN)WakeUpBuffer;
|
||||
DEBUG ((DEBUG_INIT, "Jump to Wake vector = 0x%x\n", WakeVector));
|
||||
DoWake (WakeVector);
|
||||
|
|
|
@ -17,32 +17,36 @@ ASM_PFX(WakeUpBuffer):
|
|||
|
||||
global ASM_PFX(WakeUp)
|
||||
ASM_PFX(WakeUp):
|
||||
push rbp
|
||||
mov ebp, esp
|
||||
mov edx, dword [ASM_PFX(WakeUpBuffer)]
|
||||
lea eax, [jmp_retf - ASM_PFX(WakeUp) + edx ]
|
||||
push 28h ; CS
|
||||
; rcx S3WakingVector :DWORD
|
||||
lea eax, [.0]
|
||||
mov r8, 0x2800000000
|
||||
or rax, r8
|
||||
push rax
|
||||
mov ecx, [ebp + 8]
|
||||
shrd ebx, ecx, 20
|
||||
and ecx, 0fh
|
||||
and ecx, 0xf
|
||||
mov bx, cx
|
||||
lea eax, [os_jmp_addr - ASM_PFX(WakeUp) + edx ]
|
||||
mov [eax], ebx
|
||||
mov [@jmp_addr + 1], ebx
|
||||
retf
|
||||
jmp_retf:
|
||||
db 0b8h, 30h, 0 ; mov ax, 30h as selector
|
||||
BITS 16
|
||||
.0:
|
||||
mov ax, 0x30
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
mov rax, cr0 ; Get control register 0
|
||||
db 66h
|
||||
db 83h, 0e0h, 0feh ; and eax, 0fffffffeh ; Clear PE bit (bit #0)
|
||||
db 0fh, 22h, 0c0h ; mov cr0, eax ; Activate real mode
|
||||
db 0eah ; jmp far @jmp_addr
|
||||
os_jmp_addr dd 0
|
||||
mov eax, cr0
|
||||
mov ebx, cr4
|
||||
and eax, ((~ 0x80000001) & 0xffffffff)
|
||||
and bl, ~ (1 << 5)
|
||||
mov cr0, eax
|
||||
mov ecx, 0xc0000080
|
||||
rdmsr
|
||||
and ah, ~ 1
|
||||
wrmsr
|
||||
mov cr4, ebx
|
||||
@jmp_addr:
|
||||
jmp 0x0:0x0
|
||||
|
||||
global ASM_PFX(WakeUpSize)
|
||||
ASM_PFX(WakeUpSize):
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
**/
|
||||
#include <MpInitLibInternal.h>
|
||||
|
||||
MP_ASSEMBLY_ADDRESS_MAP mAddressMap;
|
||||
ALL_CPU_INFO mSysCpuInfo;
|
||||
volatile ALL_CPU_TASK mSysCpuTask;
|
||||
volatile MP_DATA_EXCHANGE_STRUCT mMpDataStruct;
|
||||
UINT8 *mBackupBuffer;
|
||||
UINT32 mMpInitPhase = EnumMpInitNull;
|
||||
|
||||
STATIC MP_ASSEMBLY_ADDRESS_MAP mAddressMap;
|
||||
STATIC ALL_CPU_INFO mSysCpuInfo;
|
||||
STATIC volatile ALL_CPU_TASK mSysCpuTask;
|
||||
STATIC volatile MP_DATA_EXCHANGE_STRUCT mMpDataStruct;
|
||||
STATIC UINT8 *mBackupBuffer;
|
||||
STATIC UINT32 mMpInitPhase = EnumMpInitNull;
|
||||
STATIC SMMBASE_INFO *mSmmBaseInfo = NULL;
|
||||
|
||||
/**
|
||||
The function is called by PerformQuickSort to sort CPU_INFO by ApicId.
|
||||
|
@ -143,9 +143,8 @@ CpuInit (
|
|||
}
|
||||
|
||||
if (PcdGet8 (PcdSmmRebaseMode) == SMM_REBASE_ENABLE_ON_S3_RESUME_ONLY) {
|
||||
if (GetBootMode() == BOOT_ON_S3_RESUME) {
|
||||
SmmBaseInfo = (SMMBASE_INFO *) FindS3Info (SMMBASE_INFO_COMM_ID);
|
||||
if (SmmBaseInfo != NULL) {
|
||||
if ((GetBootMode() == BOOT_ON_S3_RESUME) && (mSmmBaseInfo != NULL)) {
|
||||
SmmBaseInfo = mSmmBaseInfo;
|
||||
for (CpuIdx = 0; CpuIdx < SmmBaseInfo->SmmBaseHdr.Count; CpuIdx++) {
|
||||
if (ApicId == SmmBaseInfo->SmmBase[CpuIdx].ApicId) {
|
||||
SmmRebase (Index, ApicId, SmmBaseInfo->SmmBase[CpuIdx].SmmBase);
|
||||
|
@ -154,7 +153,6 @@ CpuInit (
|
|||
}
|
||||
ASSERT (CpuIdx < SmmBaseInfo->SmmBaseHdr.Count);
|
||||
}
|
||||
}
|
||||
} else if (PcdGet8 (PcdSmmRebaseMode) == SMM_REBASE_ENABLE) {
|
||||
SmmRebase (Index, ApicId, 0);
|
||||
}
|
||||
|
@ -369,6 +367,15 @@ MpInit (
|
|||
//
|
||||
mMpDataStruct.ApDoneCounter = 0;
|
||||
|
||||
//
|
||||
// Get SMM Base Info for S3 resume
|
||||
//
|
||||
if (GetBootMode() == BOOT_ON_S3_RESUME) {
|
||||
mSmmBaseInfo = (SMMBASE_INFO *) FindS3Info (SMMBASE_INFO_COMM_ID);
|
||||
} else {
|
||||
mSmmBaseInfo = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Send Init-SIPI-SIPI to all APs and wait for completion
|
||||
// It includes a 200us delay for AP's check-in
|
||||
|
|
Loading…
Reference in New Issue