From eae81b7bc8001339059d31c6577a7bd7e019a724 Mon Sep 17 00:00:00 2001 From: Aiden Park Date: Wed, 29 Apr 2020 21:23:56 -0700 Subject: [PATCH] [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 --- .../Library/AcpiInitLib/AcpiInitLib.c | 8 +++- .../Library/AcpiInitLib/X64/S3Wake.nasm | 38 ++++++++++-------- .../Library/MpInitLib/MpInitLib.c | 39 +++++++++++-------- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/BootloaderCorePkg/Library/AcpiInitLib/AcpiInitLib.c b/BootloaderCorePkg/Library/AcpiInitLib/AcpiInitLib.c index 060af1fd..d13f4a0a 100644 --- a/BootloaderCorePkg/Library/AcpiInitLib/AcpiInitLib.c +++ b/BootloaderCorePkg/Library/AcpiInitLib/AcpiInitLib.c @@ -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; - Facs = (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Facp->FirmwareCtrl; + 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); diff --git a/BootloaderCorePkg/Library/AcpiInitLib/X64/S3Wake.nasm b/BootloaderCorePkg/Library/AcpiInitLib/X64/S3Wake.nasm index 00ee7b98..6c197c14 100644 --- a/BootloaderCorePkg/Library/AcpiInitLib/X64/S3Wake.nasm +++ b/BootloaderCorePkg/Library/AcpiInitLib/X64/S3Wake.nasm @@ -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): diff --git a/BootloaderCorePkg/Library/MpInitLib/MpInitLib.c b/BootloaderCorePkg/Library/MpInitLib/MpInitLib.c index fc2604e7..b8730666 100644 --- a/BootloaderCorePkg/Library/MpInitLib/MpInitLib.c +++ b/BootloaderCorePkg/Library/MpInitLib/MpInitLib.c @@ -7,13 +7,13 @@ **/ #include -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,17 +143,15 @@ 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) { - for (CpuIdx = 0; CpuIdx < SmmBaseInfo->SmmBaseHdr.Count; CpuIdx++) { - if (ApicId == SmmBaseInfo->SmmBase[CpuIdx].ApicId) { - SmmRebase (Index, ApicId, SmmBaseInfo->SmmBase[CpuIdx].SmmBase); - break; - } + 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); + break; } - ASSERT (CpuIdx < SmmBaseInfo->SmmBaseHdr.Count); } + 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