mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 07:34:06 +02:00
UefiCpuPkg:Remove code to wakeup AP and relocate ap
After the code to load mtrr setting, set register table, handle APIC setting and Interrupt after INIT-SIPI-SIPI is moved, the InitializeCpuProcedure() only contains following code logic: 1.Bsp runs ExecuteFirstSmiInit(). 2.Bsp transfers AP to safe hlt-loop During S3 boot, since APs will be relocated to new safe buffer by the callback of gEdkiiEndOfS3ResumeGuid in PeiMpLib, Bsp doesn't need to transfer AP to safe hlt-loop any more. SmmRestoreCpu() in CpuS3 only needs to runs the ExecuteFirstSmiInit() on BSP. So remove code to wakeup AP by INIT-SIPI-SIPI and remove code to relocate ap to safe hlt-loop. Signed-off-by: Dun Tan <dun.tan@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
This commit is contained in:
parent
525578bdd5
commit
341ee5c31b
@ -8,30 +8,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
|
|
||||||
#include "PiSmmCpuDxeSmm.h"
|
#include "PiSmmCpuDxeSmm.h"
|
||||||
#include <PiPei.h>
|
#include <PiPei.h>
|
||||||
#include <Ppi/MpServices2.h>
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
typedef struct {
|
|
||||||
UINTN Lock;
|
|
||||||
VOID *StackStart;
|
|
||||||
UINTN StackSize;
|
|
||||||
VOID *ApFunction;
|
|
||||||
IA32_DESCRIPTOR GdtrProfile;
|
|
||||||
IA32_DESCRIPTOR IdtrProfile;
|
|
||||||
UINT32 BufferStart;
|
|
||||||
UINT32 Cr3;
|
|
||||||
UINTN InitializeFloatingPointUnitsAddress;
|
|
||||||
} MP_CPU_EXCHANGE_INFO;
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UINT8 *RendezvousFunnelAddress;
|
|
||||||
UINTN PModeEntryOffset;
|
|
||||||
UINTN FlatJumpOffset;
|
|
||||||
UINTN Size;
|
|
||||||
UINTN LModeEntryOffset;
|
|
||||||
UINTN LongJumpOffset;
|
|
||||||
} MP_ASSEMBLY_ADDRESS_MAP;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Flags used when program the register.
|
// Flags used when program the register.
|
||||||
@ -44,30 +20,10 @@ typedef struct {
|
|||||||
// package level semaphore.
|
// package level semaphore.
|
||||||
} PROGRAM_CPU_REGISTER_FLAGS;
|
} PROGRAM_CPU_REGISTER_FLAGS;
|
||||||
|
|
||||||
//
|
|
||||||
// Signal that SMM BASE relocation is complete.
|
|
||||||
//
|
|
||||||
volatile BOOLEAN mInitApsAfterSmmBaseReloc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get starting address and size of the rendezvous entry for APs.
|
|
||||||
Information for fixing a jump instruction in the code is also returned.
|
|
||||||
|
|
||||||
@param AddressMap Output buffer for address map information.
|
|
||||||
**/
|
|
||||||
VOID *
|
|
||||||
EFIAPI
|
|
||||||
AsmGetAddressMap (
|
|
||||||
MP_ASSEMBLY_ADDRESS_MAP *AddressMap
|
|
||||||
);
|
|
||||||
|
|
||||||
#define LEGACY_REGION_SIZE (2 * 0x1000)
|
#define LEGACY_REGION_SIZE (2 * 0x1000)
|
||||||
#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE)
|
#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE)
|
||||||
|
|
||||||
PROGRAM_CPU_REGISTER_FLAGS mCpuFlags;
|
|
||||||
ACPI_CPU_DATA mAcpiCpuData;
|
ACPI_CPU_DATA mAcpiCpuData;
|
||||||
volatile UINT32 mNumberToFinish;
|
|
||||||
MP_CPU_EXCHANGE_INFO *mExchangeInfo;
|
|
||||||
BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;
|
BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -82,191 +38,6 @@ SMM_S3_RESUME_STATE *mSmmS3ResumeState = NULL;
|
|||||||
|
|
||||||
BOOLEAN mAcpiS3Enable = TRUE;
|
BOOLEAN mAcpiS3Enable = TRUE;
|
||||||
|
|
||||||
UINT8 *mApHltLoopCode = NULL;
|
|
||||||
UINT8 mApHltLoopCodeTemplate[] = {
|
|
||||||
0x8B, 0x44, 0x24, 0x04, // mov eax, dword ptr [esp+4]
|
|
||||||
0xF0, 0xFF, 0x08, // lock dec dword ptr [eax]
|
|
||||||
0xFA, // cli
|
|
||||||
0xF4, // hlt
|
|
||||||
0xEB, 0xFC // jmp $-2
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
The function is invoked before SMBASE relocation in S3 path to restores CPU status.
|
|
||||||
|
|
||||||
The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
|
|
||||||
and restores MTRRs for both BSP and APs.
|
|
||||||
|
|
||||||
@param IsBsp The CPU this function executes on is BSP or not.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
InitializeCpuBeforeRebase (
|
|
||||||
IN BOOLEAN IsBsp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Count down the number with lock mechanism.
|
|
||||||
//
|
|
||||||
InterlockedDecrement (&mNumberToFinish);
|
|
||||||
|
|
||||||
if (IsBsp) {
|
|
||||||
//
|
|
||||||
// Bsp wait here till all AP finish the initialization before rebase
|
|
||||||
//
|
|
||||||
while (mNumberToFinish > 0) {
|
|
||||||
CpuPause ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The function is invoked after SMBASE relocation in S3 path to restores CPU status.
|
|
||||||
|
|
||||||
The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
|
|
||||||
data saved by normal boot path for both BSP and APs.
|
|
||||||
|
|
||||||
@param IsBsp The CPU this function executes on is BSP or not.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
InitializeCpuAfterRebase (
|
|
||||||
IN BOOLEAN IsBsp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN TopOfStack;
|
|
||||||
UINT8 Stack[128];
|
|
||||||
|
|
||||||
if (mSmmS3ResumeState->MpService2Ppi == 0) {
|
|
||||||
if (IsBsp) {
|
|
||||||
while (mNumberToFinish > 0) {
|
|
||||||
CpuPause ();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Place AP into the safe code, count down the number with lock mechanism in the safe code.
|
|
||||||
//
|
|
||||||
TopOfStack = (UINTN)Stack + sizeof (Stack);
|
|
||||||
TopOfStack &= ~(UINTN)(CPU_STACK_ALIGNMENT - 1);
|
|
||||||
CopyMem ((VOID *)(UINTN)mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));
|
|
||||||
TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Cpu initialization procedure.
|
|
||||||
|
|
||||||
@param[in,out] Buffer The pointer to private data buffer.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
InitializeCpuProcedure (
|
|
||||||
IN OUT VOID *Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BOOLEAN IsBsp;
|
|
||||||
|
|
||||||
IsBsp = (BOOLEAN)(mBspApicId == GetApicId ());
|
|
||||||
|
|
||||||
//
|
|
||||||
// Skip initialization if mAcpiCpuData is not valid
|
|
||||||
//
|
|
||||||
if (mAcpiCpuData.NumberOfCpus > 0) {
|
|
||||||
//
|
|
||||||
// First time microcode load and restore MTRRs
|
|
||||||
//
|
|
||||||
InitializeCpuBeforeRebase (IsBsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsBsp) {
|
|
||||||
//
|
|
||||||
// Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
|
|
||||||
//
|
|
||||||
ExecuteFirstSmiInit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Skip initialization if mAcpiCpuData is not valid
|
|
||||||
//
|
|
||||||
if (mAcpiCpuData.NumberOfCpus > 0) {
|
|
||||||
if (IsBsp) {
|
|
||||||
//
|
|
||||||
// mNumberToFinish should be set before AP executes InitializeCpuAfterRebase()
|
|
||||||
//
|
|
||||||
mNumberToFinish = (UINT32)(mNumberOfCpus - 1);
|
|
||||||
//
|
|
||||||
// Signal that SMM base relocation is complete and to continue initialization for all APs.
|
|
||||||
//
|
|
||||||
mInitApsAfterSmmBaseReloc = TRUE;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// AP Wait for BSP to signal SMM Base relocation done.
|
|
||||||
//
|
|
||||||
while (!mInitApsAfterSmmBaseReloc) {
|
|
||||||
CpuPause ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Restore MSRs for BSP and all APs
|
|
||||||
//
|
|
||||||
InitializeCpuAfterRebase (IsBsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Prepares startup vector for APs.
|
|
||||||
|
|
||||||
This function prepares startup vector for APs.
|
|
||||||
|
|
||||||
@param WorkingBuffer The address of the work buffer.
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
PrepareApStartupVector (
|
|
||||||
EFI_PHYSICAL_ADDRESS WorkingBuffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_PHYSICAL_ADDRESS StartupVector;
|
|
||||||
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the address map of startup code for AP,
|
|
||||||
// including code size, and offset of long jump instructions to redirect.
|
|
||||||
//
|
|
||||||
ZeroMem (&AddressMap, sizeof (AddressMap));
|
|
||||||
AsmGetAddressMap (&AddressMap);
|
|
||||||
|
|
||||||
StartupVector = WorkingBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Copy AP startup code to startup vector, and then redirect the long jump
|
|
||||||
// instructions for mode switching.
|
|
||||||
//
|
|
||||||
CopyMem ((VOID *)(UINTN)StartupVector, AddressMap.RendezvousFunnelAddress, AddressMap.Size);
|
|
||||||
*(UINT32 *)(UINTN)(StartupVector + AddressMap.FlatJumpOffset + 3) = (UINT32)(StartupVector + AddressMap.PModeEntryOffset);
|
|
||||||
if (AddressMap.LongJumpOffset != 0) {
|
|
||||||
*(UINT32 *)(UINTN)(StartupVector + AddressMap.LongJumpOffset + 2) = (UINT32)(StartupVector + AddressMap.LModeEntryOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the start address of exchange data between BSP and AP.
|
|
||||||
//
|
|
||||||
mExchangeInfo = (MP_CPU_EXCHANGE_INFO *)(UINTN)(StartupVector + AddressMap.Size);
|
|
||||||
ZeroMem ((VOID *)mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));
|
|
||||||
|
|
||||||
CopyMem ((VOID *)(UINTN)&mExchangeInfo->GdtrProfile, (VOID *)(UINTN)mAcpiCpuData.GdtrProfile, sizeof (IA32_DESCRIPTOR));
|
|
||||||
CopyMem ((VOID *)(UINTN)&mExchangeInfo->IdtrProfile, (VOID *)(UINTN)mAcpiCpuData.IdtrProfile, sizeof (IA32_DESCRIPTOR));
|
|
||||||
|
|
||||||
mExchangeInfo->StackStart = (VOID *)(UINTN)mAcpiCpuData.StackAddress;
|
|
||||||
mExchangeInfo->StackSize = mAcpiCpuData.StackSize;
|
|
||||||
mExchangeInfo->BufferStart = (UINT32)StartupVector;
|
|
||||||
mExchangeInfo->Cr3 = (UINT32)(AsmReadCr3 ());
|
|
||||||
mExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits;
|
|
||||||
mExchangeInfo->ApFunction = (VOID *)(UINTN)InitializeCpuProcedure;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Restore SMM Configuration in S3 boot path.
|
Restore SMM Configuration in S3 boot path.
|
||||||
|
|
||||||
@ -320,7 +91,6 @@ SmmRestoreCpu (
|
|||||||
IA32_DESCRIPTOR X64Idtr;
|
IA32_DESCRIPTOR X64Idtr;
|
||||||
IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER];
|
IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER];
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EDKII_PEI_MP_SERVICES2_PPI *Mp2ServicePpi;
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "SmmRestoreCpu()\n"));
|
DEBUG ((DEBUG_INFO, "SmmRestoreCpu()\n"));
|
||||||
|
|
||||||
@ -369,38 +139,10 @@ SmmRestoreCpu (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mBspApicId = GetApicId ();
|
|
||||||
//
|
//
|
||||||
// Skip AP initialization if mAcpiCpuData is not valid
|
// Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
|
||||||
//
|
//
|
||||||
if (mAcpiCpuData.NumberOfCpus > 0) {
|
ExecuteFirstSmiInit ();
|
||||||
if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
|
|
||||||
ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus);
|
|
||||||
} else {
|
|
||||||
ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus);
|
|
||||||
}
|
|
||||||
|
|
||||||
mNumberToFinish = (UINT32)mNumberOfCpus;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.
|
|
||||||
//
|
|
||||||
mInitApsAfterSmmBaseReloc = FALSE;
|
|
||||||
|
|
||||||
if (mSmmS3ResumeState->MpService2Ppi != 0) {
|
|
||||||
Mp2ServicePpi = (EDKII_PEI_MP_SERVICES2_PPI *)(UINTN)mSmmS3ResumeState->MpService2Ppi;
|
|
||||||
Mp2ServicePpi->StartupAllCPUs (Mp2ServicePpi, InitializeCpuProcedure, 0, NULL);
|
|
||||||
} else {
|
|
||||||
PrepareApStartupVector (mAcpiCpuData.StartupVector);
|
|
||||||
//
|
|
||||||
// Send INIT IPI - SIPI to all APs
|
|
||||||
//
|
|
||||||
SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
|
|
||||||
InitializeCpuProcedure (NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
InitializeCpuProcedure (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set a flag to restore SMM configuration in S3 path.
|
// Set a flag to restore SMM configuration in S3 path.
|
||||||
@ -471,8 +213,6 @@ InitSmmS3ResumeState (
|
|||||||
VOID *GuidHob;
|
VOID *GuidHob;
|
||||||
EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
|
EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
|
||||||
SMM_S3_RESUME_STATE *SmmS3ResumeState;
|
SMM_S3_RESUME_STATE *SmmS3ResumeState;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (!mAcpiS3Enable) {
|
if (!mAcpiS3Enable) {
|
||||||
return;
|
return;
|
||||||
@ -524,20 +264,6 @@ InitSmmS3ResumeState (
|
|||||||
//
|
//
|
||||||
InitSmmS3Cr3 ();
|
InitSmmS3Cr3 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate safe memory in ACPI NVS for AP to execute hlt loop in
|
|
||||||
// protected mode on S3 path
|
|
||||||
//
|
|
||||||
Address = BASE_4GB - 1;
|
|
||||||
Status = gBS->AllocatePages (
|
|
||||||
AllocateMaxAddress,
|
|
||||||
EfiACPIMemoryNVS,
|
|
||||||
EFI_SIZE_TO_PAGES (sizeof (mApHltLoopCodeTemplate)),
|
|
||||||
&Address
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
mApHltLoopCode = (UINT8 *)(UINTN)Address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
|
||||||
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
|
||||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
;
|
|
||||||
; Module Name:
|
|
||||||
;
|
|
||||||
; MpFuncs.nasm
|
|
||||||
;
|
|
||||||
; Abstract:
|
|
||||||
;
|
|
||||||
; This is the assembly code for Multi-processor S3 support
|
|
||||||
;
|
|
||||||
;-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
SECTION .text
|
|
||||||
|
|
||||||
extern ASM_PFX(InitializeFloatingPointUnits)
|
|
||||||
|
|
||||||
%define VacantFlag 0x0
|
|
||||||
%define NotVacantFlag 0xff
|
|
||||||
|
|
||||||
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
||||||
%define StackStart LockLocation + 0x4
|
|
||||||
%define StackSize LockLocation + 0x8
|
|
||||||
%define RendezvousProc LockLocation + 0xC
|
|
||||||
%define GdtrProfile LockLocation + 0x10
|
|
||||||
%define IdtrProfile LockLocation + 0x16
|
|
||||||
%define BufferStart LockLocation + 0x1C
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
|
||||||
;IS IN MACHINE CODE.
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
|
|
||||||
|
|
||||||
BITS 16
|
|
||||||
global ASM_PFX(RendezvousFunnelProc)
|
|
||||||
ASM_PFX(RendezvousFunnelProc):
|
|
||||||
RendezvousFunnelProcStart:
|
|
||||||
|
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
|
||||||
|
|
||||||
mov ax, cs
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov ss, ax
|
|
||||||
xor ax, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
flat32Start:
|
|
||||||
|
|
||||||
mov si, BufferStart
|
|
||||||
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer
|
|
||||||
|
|
||||||
mov si, GdtrProfile
|
|
||||||
o32 lgdt [cs:si]
|
|
||||||
|
|
||||||
mov si, IdtrProfile
|
|
||||||
o32 lidt [cs:si]
|
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
mov ds, ax
|
|
||||||
|
|
||||||
mov eax, cr0 ; Get control register 0
|
|
||||||
or eax, 0x000000001 ; Set PE bit (bit #0)
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
FLAT32_JUMP:
|
|
||||||
|
|
||||||
a32 jmp dword 0x20:0x0
|
|
||||||
|
|
||||||
BITS 32
|
|
||||||
PMODE_ENTRY: ; protected mode entry point
|
|
||||||
|
|
||||||
mov ax, 0x8
|
|
||||||
o16 mov ds, ax
|
|
||||||
o16 mov es, ax
|
|
||||||
o16 mov fs, ax
|
|
||||||
o16 mov gs, ax
|
|
||||||
o16 mov ss, ax ; Flat mode setup.
|
|
||||||
|
|
||||||
mov esi, edx
|
|
||||||
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
mov al, NotVacantFlag
|
|
||||||
TestLock:
|
|
||||||
xchg byte [edi], al
|
|
||||||
cmp al, NotVacantFlag
|
|
||||||
jz TestLock
|
|
||||||
|
|
||||||
ProgramStack:
|
|
||||||
|
|
||||||
mov edi, esi
|
|
||||||
add edi, StackSize
|
|
||||||
mov eax, dword [edi]
|
|
||||||
mov edi, esi
|
|
||||||
add edi, StackStart
|
|
||||||
add eax, dword [edi]
|
|
||||||
mov esp, eax
|
|
||||||
mov dword [edi], eax
|
|
||||||
|
|
||||||
Releaselock:
|
|
||||||
|
|
||||||
mov al, VacantFlag
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
xchg byte [edi], al
|
|
||||||
|
|
||||||
;
|
|
||||||
; Call assembly function to initialize FPU.
|
|
||||||
;
|
|
||||||
mov ebx, ASM_PFX(InitializeFloatingPointUnits)
|
|
||||||
call ebx
|
|
||||||
;
|
|
||||||
; Call C Function
|
|
||||||
;
|
|
||||||
mov edi, esi
|
|
||||||
add edi, RendezvousProc
|
|
||||||
mov eax, dword [edi]
|
|
||||||
|
|
||||||
test eax, eax
|
|
||||||
jz GoToSleep
|
|
||||||
call eax ; Call C function
|
|
||||||
|
|
||||||
GoToSleep:
|
|
||||||
cli
|
|
||||||
hlt
|
|
||||||
jmp $-2
|
|
||||||
|
|
||||||
RendezvousFunnelProcEnd:
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
; AsmGetAddressMap (&AddressMap);
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
global ASM_PFX(AsmGetAddressMap)
|
|
||||||
ASM_PFX(AsmGetAddressMap):
|
|
||||||
|
|
||||||
pushad
|
|
||||||
mov ebp,esp
|
|
||||||
|
|
||||||
mov ebx, dword [ebp+0x24]
|
|
||||||
mov dword [ebx], RendezvousFunnelProcStart
|
|
||||||
mov dword [ebx+0x4], PMODE_ENTRY - RendezvousFunnelProcStart
|
|
||||||
mov dword [ebx+0x8], FLAT32_JUMP - RendezvousFunnelProcStart
|
|
||||||
mov dword [ebx+0xc], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
||||||
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
SMM CPU misc functions for Ia32 arch specific.
|
SMM CPU misc functions for Ia32 arch specific.
|
||||||
|
|
||||||
Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@ -141,33 +141,6 @@ InitGdt (
|
|||||||
return GdtTssTables;
|
return GdtTssTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
|
|
||||||
|
|
||||||
@param[in] ApHltLoopCode The address of the safe hlt-loop function.
|
|
||||||
@param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
|
|
||||||
@param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TransferApToSafeState (
|
|
||||||
IN UINTN ApHltLoopCode,
|
|
||||||
IN UINTN TopOfStack,
|
|
||||||
IN UINTN NumberToFinishAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SwitchStack (
|
|
||||||
(SWITCH_STACK_ENTRY_POINT)ApHltLoopCode,
|
|
||||||
(VOID *)NumberToFinishAddress,
|
|
||||||
NULL,
|
|
||||||
(VOID *)TopOfStack
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// It should never reach here
|
|
||||||
//
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize the shadow stack related data structure.
|
Initialize the shadow stack related data structure.
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# This SMM driver performs SMM initialization, deploy SMM Entry Vector,
|
# This SMM driver performs SMM initialization, deploy SMM Entry Vector,
|
||||||
# provides CPU specific services in SMM.
|
# provides CPU specific services in SMM.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||||
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
|
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
|
||||||
# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
|
# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
@ -53,7 +53,6 @@
|
|||||||
Ia32/SmmProfileArch.h
|
Ia32/SmmProfileArch.h
|
||||||
Ia32/SmiEntry.nasm
|
Ia32/SmiEntry.nasm
|
||||||
Ia32/SmiException.nasm
|
Ia32/SmiException.nasm
|
||||||
Ia32/MpFuncs.nasm
|
|
||||||
Ia32/Cet.nasm
|
Ia32/Cet.nasm
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
@ -63,7 +62,6 @@
|
|||||||
X64/SmmProfileArch.h
|
X64/SmmProfileArch.h
|
||||||
X64/SmiEntry.nasm
|
X64/SmiEntry.nasm
|
||||||
X64/SmiException.nasm
|
X64/SmiException.nasm
|
||||||
X64/MpFuncs.nasm
|
|
||||||
X64/Cet.nasm
|
X64/Cet.nasm
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
@ -136,7 +134,6 @@
|
|||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## SOMETIMES_CONSUMES
|
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
;------------------------------------------------------------------------------ ;
|
|
||||||
; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
;
|
|
||||||
; Module Name:
|
|
||||||
;
|
|
||||||
; MpFuncs.nasm
|
|
||||||
;
|
|
||||||
; Abstract:
|
|
||||||
;
|
|
||||||
; This is the assembly code for Multi-processor S3 support
|
|
||||||
;
|
|
||||||
;-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
%define VacantFlag 0x0
|
|
||||||
%define NotVacantFlag 0xff
|
|
||||||
|
|
||||||
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
||||||
%define StackStartAddressLocation LockLocation + 0x8
|
|
||||||
%define StackSizeLocation LockLocation + 0x10
|
|
||||||
%define CProcedureLocation LockLocation + 0x18
|
|
||||||
%define GdtrLocation LockLocation + 0x20
|
|
||||||
%define IdtrLocation LockLocation + 0x2A
|
|
||||||
%define BufferStartLocation LockLocation + 0x34
|
|
||||||
%define Cr3OffsetLocation LockLocation + 0x38
|
|
||||||
%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
|
|
||||||
;procedure serializes all the AP processors through an Init sequence. It must be
|
|
||||||
;noted that APs arrive here very raw...ie: real mode, no stack.
|
|
||||||
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
|
|
||||||
;IS IN MACHINE CODE.
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
|
|
||||||
|
|
||||||
;text SEGMENT
|
|
||||||
DEFAULT REL
|
|
||||||
SECTION .text
|
|
||||||
|
|
||||||
BITS 16
|
|
||||||
global ASM_PFX(RendezvousFunnelProc)
|
|
||||||
ASM_PFX(RendezvousFunnelProc):
|
|
||||||
RendezvousFunnelProcStart:
|
|
||||||
|
|
||||||
; At this point CS = 0x(vv00) and ip= 0x0.
|
|
||||||
|
|
||||||
mov ax, cs
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov ss, ax
|
|
||||||
xor ax, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
flat32Start:
|
|
||||||
|
|
||||||
mov si, BufferStartLocation
|
|
||||||
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer
|
|
||||||
|
|
||||||
mov si, Cr3OffsetLocation
|
|
||||||
mov ecx,dword [si] ; ECX is keeping the value of CR3
|
|
||||||
|
|
||||||
mov si, GdtrLocation
|
|
||||||
o32 lgdt [cs:si]
|
|
||||||
|
|
||||||
mov si, IdtrLocation
|
|
||||||
o32 lidt [cs:si]
|
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
mov ds, ax
|
|
||||||
|
|
||||||
mov eax, cr0 ; Get control register 0
|
|
||||||
or eax, 0x000000001 ; Set PE bit (bit #0)
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
FLAT32_JUMP:
|
|
||||||
|
|
||||||
a32 jmp dword 0x20:0x0
|
|
||||||
|
|
||||||
BITS 32
|
|
||||||
PMODE_ENTRY: ; protected mode entry point
|
|
||||||
|
|
||||||
mov ax, 0x18
|
|
||||||
o16 mov ds, ax
|
|
||||||
o16 mov es, ax
|
|
||||||
o16 mov fs, ax
|
|
||||||
o16 mov gs, ax
|
|
||||||
o16 mov ss, ax ; Flat mode setup.
|
|
||||||
|
|
||||||
mov eax, cr4
|
|
||||||
bts eax, 5
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
mov cr3, ecx
|
|
||||||
|
|
||||||
mov esi, edx ; Save wakeup buffer address
|
|
||||||
|
|
||||||
mov ecx, 0xc0000080 ; EFER MSR number.
|
|
||||||
rdmsr ; Read EFER.
|
|
||||||
bts eax, 8 ; Set LME=1.
|
|
||||||
wrmsr ; Write EFER.
|
|
||||||
|
|
||||||
mov eax, cr0 ; Read CR0.
|
|
||||||
bts eax, 31 ; Set PG=1.
|
|
||||||
mov cr0, eax ; Write CR0.
|
|
||||||
|
|
||||||
LONG_JUMP:
|
|
||||||
|
|
||||||
a16 jmp dword 0x38:0x0
|
|
||||||
|
|
||||||
BITS 64
|
|
||||||
LongModeStart:
|
|
||||||
|
|
||||||
mov ax, 0x30
|
|
||||||
o16 mov ds, ax
|
|
||||||
o16 mov es, ax
|
|
||||||
o16 mov ss, ax
|
|
||||||
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
mov al, NotVacantFlag
|
|
||||||
TestLock:
|
|
||||||
xchg byte [edi], al
|
|
||||||
cmp al, NotVacantFlag
|
|
||||||
jz TestLock
|
|
||||||
|
|
||||||
ProgramStack:
|
|
||||||
|
|
||||||
mov edi, esi
|
|
||||||
add edi, StackSizeLocation
|
|
||||||
mov rax, qword [edi]
|
|
||||||
mov edi, esi
|
|
||||||
add edi, StackStartAddressLocation
|
|
||||||
add rax, qword [edi]
|
|
||||||
mov rsp, rax
|
|
||||||
mov qword [edi], rax
|
|
||||||
|
|
||||||
Releaselock:
|
|
||||||
|
|
||||||
mov al, VacantFlag
|
|
||||||
mov edi, esi
|
|
||||||
add edi, LockLocation
|
|
||||||
xchg byte [edi], al
|
|
||||||
|
|
||||||
;
|
|
||||||
; Call assembly function to initialize FPU.
|
|
||||||
;
|
|
||||||
mov rax, qword [esi + InitializeFloatingPointUnitsAddress]
|
|
||||||
sub rsp, 0x20
|
|
||||||
call rax
|
|
||||||
add rsp, 0x20
|
|
||||||
|
|
||||||
;
|
|
||||||
; Call C Function
|
|
||||||
;
|
|
||||||
mov edi, esi
|
|
||||||
add edi, CProcedureLocation
|
|
||||||
mov rax, qword [edi]
|
|
||||||
|
|
||||||
test rax, rax
|
|
||||||
jz GoToSleep
|
|
||||||
|
|
||||||
sub rsp, 0x20
|
|
||||||
call rax
|
|
||||||
add rsp, 0x20
|
|
||||||
|
|
||||||
GoToSleep:
|
|
||||||
cli
|
|
||||||
hlt
|
|
||||||
jmp $-2
|
|
||||||
|
|
||||||
RendezvousFunnelProcEnd:
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
; AsmGetAddressMap (&AddressMap);
|
|
||||||
;-------------------------------------------------------------------------------------
|
|
||||||
; comments here for definition of address map
|
|
||||||
global ASM_PFX(AsmGetAddressMap)
|
|
||||||
ASM_PFX(AsmGetAddressMap):
|
|
||||||
lea rax, [RendezvousFunnelProcStart]
|
|
||||||
mov qword [rcx], rax
|
|
||||||
mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart
|
|
||||||
mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart
|
|
||||||
mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
|
|
||||||
mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart
|
|
||||||
mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart
|
|
||||||
ret
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
SMM CPU misc functions for x64 arch specific.
|
SMM CPU misc functions for x64 arch specific.
|
||||||
|
|
||||||
Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@ -132,34 +132,6 @@ GetProtectedModeCS (
|
|||||||
return Index * 8;
|
return Index * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
|
|
||||||
|
|
||||||
@param[in] ApHltLoopCode The address of the safe hlt-loop function.
|
|
||||||
@param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
|
|
||||||
@param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
TransferApToSafeState (
|
|
||||||
IN UINTN ApHltLoopCode,
|
|
||||||
IN UINTN TopOfStack,
|
|
||||||
IN UINTN NumberToFinishAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
AsmDisablePaging64 (
|
|
||||||
GetProtectedModeCS (),
|
|
||||||
(UINT32)ApHltLoopCode,
|
|
||||||
(UINT32)NumberToFinishAddress,
|
|
||||||
0,
|
|
||||||
(UINT32)TopOfStack
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// It should never reach here
|
|
||||||
//
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize the shadow stack related data structure.
|
Initialize the shadow stack related data structure.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user