UefiCpuPkg/CpuDxe: Remove unused codes and files

v5:
  1. Remove unused PcdCpuApStackSize and PcdCpuApInitTimeOutInMicroSeconds.

v4:
  1. Keep GDT table setup to fix IA32 S3 boot issue.

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
Jeff Fan 2016-07-30 01:32:25 +08:00
parent 0b9f0dd635
commit 39d49a73a5
9 changed files with 1 additions and 1359 deletions

View File

@ -1,478 +0,0 @@
/** @file
CPU DXE AP Startup
Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "CpuDxe.h"
#include "CpuGdt.h"
#include "CpuMp.h"
#pragma pack(1)
typedef struct {
UINT8 MoveIa32EferMsrToEcx[5];
UINT8 ReadIa32EferMsr[2];
UINT8 SetExecuteDisableBitEnableBit[4];
UINT8 WriteIa32EferMsr[2];
#if defined (MDE_CPU_IA32)
UINT8 MovEaxCr3;
UINT32 Cr3Value;
UINT8 MovCr3Eax[3];
UINT8 MoveCr4ToEax[3];
UINT8 SetCr4Bit5[4];
UINT8 MoveEaxToCr4[3];
UINT8 MoveCr0ToEax[3];
UINT8 SetCr0PagingBit[4];
UINT8 MoveEaxToCr0[3];
#endif
} ENABLE_EXECUTE_DISABLE_CODE;
ENABLE_EXECUTE_DISABLE_CODE mEnableExecuteDisableCodeTemplate = {
{ 0xB9, 0x80, 0x00, 0x00, 0xC0 }, // mov ecx, 0xc0000080
{ 0x0F, 0x32 }, // rdmsr
{ 0x0F, 0xBA, 0xE8, 0x0B }, // bts eax, 11
{ 0x0F, 0x30 }, // wrmsr
#if defined (MDE_CPU_IA32)
0xB8, 0x00000000, // mov eax, cr3 value
{ 0x0F, 0x22, 0xd8 }, // mov cr3, eax
{ 0x0F, 0x20, 0xE0 }, // mov eax, cr4
{ 0x0F, 0xBA, 0xE8, 0x05 }, // bts eax, 5
{ 0x0F, 0x22, 0xE0 }, // mov cr4, eax
{ 0x0F, 0x20, 0xC0 }, // mov eax, cr0
{ 0x0F, 0xBA, 0xE8, 0x1F }, // bts eax, 31
{ 0x0F, 0x22, 0xC0 }, // mov cr0, eax
#endif
};
typedef struct {
UINT8 JmpToCli[2];
UINT16 GdtLimit;
UINT32 GdtBase;
UINT8 Cli;
UINT8 MovAxRealSegment; UINT16 RealSegment;
UINT8 MovDsAx[2];
UINT8 MovBxGdtr[3];
UINT8 LoadGdt[5];
UINT8 MovEaxCr0[2];
UINT32 MovEaxCr0Value;
UINT8 MovCr0Eax[3];
UINT8 FarJmp32Flat[2]; UINT32 FlatJmpOffset; UINT16 FlatJmpSelector;
//
// Now in IA32
//
UINT8 MovEaxCr4;
UINT32 MovEaxCr4Value;
UINT8 MovCr4Eax[3];
UINT8 MoveDataSelectorIntoAx[2]; UINT16 FlatDataSelector;
UINT8 MoveFlatDataSelectorFromAxToDs[2];
UINT8 MoveFlatDataSelectorFromAxToEs[2];
UINT8 MoveFlatDataSelectorFromAxToFs[2];
UINT8 MoveFlatDataSelectorFromAxToGs[2];
UINT8 MoveFlatDataSelectorFromAxToSs[2];
//
// Code placeholder to enable PAE Execute Disable for IA32
// and enable Execute Disable Bit for X64
//
ENABLE_EXECUTE_DISABLE_CODE EnableExecuteDisable;
#if defined (MDE_CPU_X64)
//
// Transition to X64
//
UINT8 MovEaxCr3;
UINT32 Cr3Value;
UINT8 MovCr3Eax[3];
UINT8 MoveCr4ToEax[3];
UINT8 SetCr4Bit5[4];
UINT8 MoveEaxToCr4[3];
UINT8 MoveLongModeEnableMsrToEcx[5];
UINT8 ReadLmeMsr[2];
UINT8 SetLongModeEnableBit[4];
UINT8 WriteLmeMsr[2];
UINT8 MoveCr0ToEax[3];
UINT8 SetCr0PagingBit[4];
UINT8 MoveEaxToCr0[3];
//UINT8 DeadLoop[2];
UINT8 FarJmp32LongMode; UINT32 LongJmpOffset; UINT16 LongJmpSelector;
#endif // defined (MDE_CPU_X64)
#if defined (MDE_CPU_X64)
UINT8 MovEaxOrRaxCpuDxeEntry[2]; UINTN CpuDxeEntryValue;
#else
UINT8 MovEaxOrRaxCpuDxeEntry; UINTN CpuDxeEntryValue;
#endif
UINT8 JmpToCpuDxeEntry[2];
} STARTUP_CODE;
#pragma pack()
/**
This .asm code used for translating processor from 16 bit real mode into
64 bit long mode. which help to create the mStartupCodeTemplate value.
To assemble:
* nasm -o ApStartup ApStartup.asm
Then disassemble:
* ndisasm -b 16 ApStartup
* ndisasm -b 16 -e 6 ApStartup
* ndisasm -b 32 -e 32 ApStartup (This -e offset may need adjustment)
* ndisasm -b 64 -e 0x83 ApStartup (This -e offset may need adjustment)
%define DEFAULT_CR0 0x00000023
%define DEFAULT_CR4 0x640
BITS 16
jmp short TransitionFromReal16To32BitFlat
ALIGN 2
Gdtr:
dw 0x5a5a
dd 0x5a5a5a5a
;
; Modified: EAX, EBX
;
TransitionFromReal16To32BitFlat:
cli
mov ax, 0x5a5a
mov ds, ax
mov bx, Gdtr
o32 lgdt [ds:bx]
mov eax, cr4
btc eax, 5
mov cr4, eax
mov eax, DEFAULT_CR0
mov cr0, eax
jmp 0x5a5a:dword jumpTo32BitAndLandHere
BITS 32
jumpTo32BitAndLandHere:
mov eax, DEFAULT_CR4
mov cr4, eax
mov ax, 0x5a5a
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;
; Jump to CpuDxe for IA32
;
mov eax, 0x5a5a5a5a
or eax, eax
jz Transition32FlatTo64Flat
jmp eax
;
; Transition to X64
;
Transition32FlatTo64Flat:
mov eax, 0x5a5a5a5a
mov cr3, eax
mov eax, cr4
bts eax, 5 ; enable PAE
mov cr4, eax
mov ecx, 0xc0000080
rdmsr
bts eax, 8 ; set LME
wrmsr
mov eax, cr0
bts eax, 31 ; set PG
mov cr0, eax ; enable paging
;
; Jump to CpuDxe for X64
;
jmp 0x5a5a:jumpTo64BitAndLandHere
BITS 64
jumpTo64BitAndLandHere:
mov rax, 0xcdcdcdcdcdcdcdcd
jmp rax
**/
STARTUP_CODE mStartupCodeTemplate = {
{ 0xeb, 0x06 }, // Jump to cli
0, // GDT Limit
0, // GDT Base
0xfa, // cli (Clear Interrupts)
0xb8, 0x0000, // mov ax, RealSegment
{ 0x8e, 0xd8 }, // mov ds, ax
{ 0xBB, 0x02, 0x00 }, // mov bx, Gdtr
{ 0x3e, 0x66, 0x0f, 0x01, 0x17 }, // lgdt [ds:bx]
{ 0x66, 0xB8 }, 0x00000023, // mov eax, cr0 value
{ 0x0F, 0x22, 0xC0 }, // mov cr0, eax
{ 0x66, 0xEA }, // far jmp to 32-bit flat
OFFSET_OF(STARTUP_CODE, MovEaxCr4),
LINEAR_CODE_SEL,
0xB8, 0x00000640, // mov eax, cr4 value
{ 0x0F, 0x22, 0xe0 }, // mov cr4, eax
{ 0x66, 0xb8 }, CPU_DATA_SEL, // mov ax, FlatDataSelector
{ 0x8e, 0xd8 }, // mov ds, ax
{ 0x8e, 0xc0 }, // mov es, ax
{ 0x8e, 0xe0 }, // mov fs, ax
{ 0x8e, 0xe8 }, // mov gs, ax
{ 0x8e, 0xd0 }, // mov ss, ax
#if defined (MDE_CPU_X64)
//
// Code placeholder to enable Execute Disable Bit for X64
// Default is all NOP - No Operation
//
{
{ 0x90, 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90 },
{ 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90 },
},
0xB8, 0x00000000, // mov eax, cr3 value
{ 0x0F, 0x22, 0xd8 }, // mov cr3, eax
{ 0x0F, 0x20, 0xE0 }, // mov eax, cr4
{ 0x0F, 0xBA, 0xE8, 0x05 }, // bts eax, 5
{ 0x0F, 0x22, 0xE0 }, // mov cr4, eax
{ 0xB9, 0x80, 0x00, 0x00, 0xC0 }, // mov ecx, 0xc0000080
{ 0x0F, 0x32 }, // rdmsr
{ 0x0F, 0xBA, 0xE8, 0x08 }, // bts eax, 8
{ 0x0F, 0x30 }, // wrmsr
{ 0x0F, 0x20, 0xC0 }, // mov eax, cr0
{ 0x0F, 0xBA, 0xE8, 0x1F }, // bts eax, 31
{ 0x0F, 0x22, 0xC0 }, // mov cr0, eax
0xEA, // FarJmp32LongMode
OFFSET_OF(STARTUP_CODE, MovEaxOrRaxCpuDxeEntry),
LINEAR_CODE64_SEL,
#else
//
// Code placeholder to enable PAE Execute Disable for IA32
// Default is all NOP - No Operation
//
{
{ 0x90, 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90 },
{ 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90 },
0x90, 0x90909090,
{ 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90, 0x90 },
{ 0x90, 0x90, 0x90 },
},
#endif
//0xeb, 0xfe, // jmp $
#if defined (MDE_CPU_X64)
{ 0x48, 0xb8 }, 0x0, // mov rax, X64 CpuDxe MP Entry Point
#else
0xB8, 0x0, // mov eax, IA32 CpuDxe MP Entry Point
#endif
{ 0xff, 0xe0 }, // jmp to eax/rax (CpuDxe MP Entry Point)
};
volatile STARTUP_CODE *StartupCode = NULL;
/**
The function will check if BSP Execute Disable is enabled.
DxeIpl may have enabled Execute Disable for BSP,
APs need to get the status and sync up the settings.
@retval TRUE BSP Execute Disable is enabled.
@retval FALSE BSP Execute Disable is not enabled.
**/
BOOLEAN
IsBspExecuteDisableEnabled (
VOID
)
{
UINT32 RegEax;
UINT32 RegEdx;
UINT64 MsrRegisters;
BOOLEAN Enabled;
Enabled = FALSE;
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
if (RegEax >= 0x80000001) {
AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
//
// Cpuid 0x80000001
// Bit 20: Execute Disable Bit available.
//
if ((RegEdx & BIT20) != 0) {
MsrRegisters = AsmReadMsr64 (0xC0000080);
//
// Msr 0xC0000080
// Bit 11: Execute Disable Bit enable.
//
if ((MsrRegisters & BIT11) != 0) {
Enabled = TRUE;
}
}
}
return Enabled;
}
/**
Prepares Startup Code for APs.
This function prepares Startup Code for APs.
@retval EFI_SUCCESS The APs were started
@retval EFI_OUT_OF_RESOURCES Cannot allocate memory to start APs
**/
EFI_STATUS
PrepareAPStartupCode (
VOID
)
{
EFI_STATUS Status;
IA32_DESCRIPTOR Gdtr;
EFI_PHYSICAL_ADDRESS StartAddress;
StartAddress = BASE_1MB;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIMemoryNVS,
EFI_SIZE_TO_PAGES (sizeof (*StartupCode)),
&StartAddress
);
if (EFI_ERROR (Status)) {
return Status;
}
StartupCode = (STARTUP_CODE*)(VOID*)(UINTN) StartAddress;
CopyMem ((VOID*) StartupCode, &mStartupCodeTemplate, sizeof (*StartupCode));
StartupCode->RealSegment = (UINT16) (((UINTN) StartAddress) >> 4);
AsmReadGdtr (&Gdtr);
StartupCode->GdtLimit = Gdtr.Limit;
StartupCode->GdtBase = (UINT32) Gdtr.Base;
StartupCode->CpuDxeEntryValue = (UINTN) AsmApEntryPoint;
StartupCode->FlatJmpOffset += (UINT32) StartAddress;
if (IsBspExecuteDisableEnabled ()) {
CopyMem (
(VOID*) &StartupCode->EnableExecuteDisable,
&mEnableExecuteDisableCodeTemplate,
sizeof (ENABLE_EXECUTE_DISABLE_CODE)
);
}
#if defined (MDE_CPU_X64)
StartupCode->Cr3Value = (UINT32) AsmReadCr3 ();
StartupCode->LongJmpOffset += (UINT32) StartAddress;
#else
StartupCode->EnableExecuteDisable.Cr3Value = (UINT32) AsmReadCr3 ();
#endif
return EFI_SUCCESS;
}
/**
Free the code buffer of startup AP.
**/
VOID
FreeApStartupCode (
VOID
)
{
if (StartupCode != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)(VOID*) StartupCode,
EFI_SIZE_TO_PAGES (sizeof (*StartupCode)));
}
}
/**
Starts the Application Processors and directs them to jump to the
specified routine.
The processor jumps to this code in flat mode, but the processor's
stack is not initialized.
@retval EFI_SUCCESS The APs were started
**/
EFI_STATUS
StartApsStackless (
VOID
)
{
SendInitSipiSipiAllExcludingSelf ((UINT32)(UINTN)(VOID*) StartupCode);
//
// Wait for APs to arrive at the ApEntryPoint routine
//
MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
return EFI_SUCCESS;
}
/**
Resets the Application Processor and directs it to jump to the
specified routine.
The processor jumps to this code in flat mode, but the processor's
stack is not initialized.
@param ProcessorId the AP of ProcessorId was reset
**/
VOID
ResetApStackless (
IN UINT32 ProcessorId
)
{
SendInitSipiSipi (ProcessorId,
(UINT32)(UINTN)(VOID*) StartupCode);
}

View File

@ -36,7 +36,6 @@
#include <Library/UefiCpuLib.h>
#include <Library/UefiLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/TimerLib.h>
#include <Library/HobLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/MpInitLib.h>

View File

@ -46,7 +46,6 @@
MpInitLib
[Sources]
ApStartup.c
CpuDxe.c
CpuDxe.h
CpuGdt.c
@ -58,15 +57,11 @@
Ia32/CpuAsm.asm
Ia32/CpuAsm.nasm
Ia32/CpuAsm.S
Ia32/MpAsm.asm
Ia32/MpAsm.nasm
[Sources.X64]
X64/CpuAsm.asm
X64/CpuAsm.nasm
X64/CpuAsm.S
X64/MpAsm.asm
X64/MpAsm.nasm
[Protocols]
gEfiCpuArchProtocolGuid ## PRODUCES
@ -82,8 +77,6 @@
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
[Depex]
TRUE

View File

@ -15,20 +15,8 @@
#include "CpuDxe.h"
#include "CpuMp.h"
UINTN gMaxLogicalProcessorNumber;
UINTN gApStackSize;
UINTN gPollInterval = 100; // 100 microseconds
MP_SYSTEM_DATA mMpSystemData;
EFI_HANDLE mMpServiceHandle = NULL;
UINTN mNumberOfProcessors = 1;
EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL;
VOID *mCommonStack = 0;
VOID *mTopOfApCommonStack = 0;
VOID *mApStackStart = 0;
volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;
EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
GetNumberOfProcessors,
@ -40,372 +28,6 @@ EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
WhoAmI
};
/**
Get Mp Service Lock.
@param CpuData the pointer to CPU_DATA_BLOCK of specified processor
**/
VOID
GetMpSpinLock (
IN CPU_DATA_BLOCK *CpuData
)
{
while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
CpuPause ();
}
CpuData->LockSelf = GetApicId ();
}
/**
Release Mp Service Lock.
@param CpuData the pointer to CPU_DATA_BLOCK of specified processor
**/
VOID
ReleaseMpSpinLock (
IN CPU_DATA_BLOCK *CpuData
)
{
ReleaseSpinLock (&CpuData->CpuDataLock);
}
/**
Check whether caller processor is BSP.
@retval TRUE the caller is BSP
@retval FALSE the caller is AP
**/
BOOLEAN
IsBSP (
VOID
)
{
UINTN CpuIndex;
CPU_DATA_BLOCK *CpuData;
CpuData = NULL;
WhoAmI (&mMpServicesTemplate, &CpuIndex);
CpuData = &mMpSystemData.CpuDatas[CpuIndex];
return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE;
}
/**
Get the Application Processors state.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
@retval CPU_STATE the AP status
**/
STATIC
CPU_STATE
GetApState (
IN CPU_DATA_BLOCK *CpuData
)
{
CPU_STATE State;
GetMpSpinLock (CpuData);
State = CpuData->State;
ReleaseMpSpinLock (CpuData);
return State;
}
/**
Set the Application Processors state.
@param CpuData The pointer to CPU_DATA_BLOCK of specified AP
@param State The AP status
**/
STATIC
VOID
SetApState (
IN CPU_DATA_BLOCK *CpuData,
IN CPU_STATE State
)
{
GetMpSpinLock (CpuData);
CpuData->State = State;
ReleaseMpSpinLock (CpuData);
}
/**
Set the Application Processor prepare to run a function specified
by Params.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
@param Procedure A pointer to the function to be run on enabled APs of the system
@param ProcedureArgument Pointer to the optional parameter of the assigned function
**/
VOID
SetApProcedure (
IN CPU_DATA_BLOCK *CpuData,
IN EFI_AP_PROCEDURE Procedure,
IN VOID *ProcedureArgument
)
{
GetMpSpinLock (CpuData);
CpuData->Parameter = ProcedureArgument;
CpuData->Procedure = Procedure;
ReleaseMpSpinLock (CpuData);
}
/**
Check the Application Processors Status whether contains the Flags.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
@param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
@retval TRUE the AP status includes the StatusFlag
@retval FALSE the AP status excludes the StatusFlag
**/
BOOLEAN
TestCpuStatusFlag (
IN CPU_DATA_BLOCK *CpuData,
IN UINT32 Flags
)
{
UINT32 Ret;
GetMpSpinLock (CpuData);
Ret = CpuData->Info.StatusFlag & Flags;
ReleaseMpSpinLock (CpuData);
return (BOOLEAN) (Ret != 0);
}
/**
Bitwise-Or of the Application Processors Status with the Flags.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
@param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
**/
VOID
CpuStatusFlagOr (
IN CPU_DATA_BLOCK *CpuData,
IN UINT32 Flags
)
{
GetMpSpinLock (CpuData);
CpuData->Info.StatusFlag |= Flags;
ReleaseMpSpinLock (CpuData);
}
/**
Bitwise-AndNot of the Application Processors Status with the Flags.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
@param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
**/
VOID
CpuStatusFlagAndNot (
IN CPU_DATA_BLOCK *CpuData,
IN UINT32 Flags
)
{
GetMpSpinLock (CpuData);
CpuData->Info.StatusFlag &= ~Flags;
ReleaseMpSpinLock (CpuData);
}
/**
Searches for the next blocking AP.
Search for the next AP that is put in blocking state by single-threaded StartupAllAPs().
@param NextNumber Pointer to the processor number of the next blocking AP.
@retval EFI_SUCCESS The next blocking AP has been found.
@retval EFI_NOT_FOUND No blocking AP exists.
**/
EFI_STATUS
GetNextBlockedNumber (
OUT UINTN *NextNumber
)
{
UINTN Number;
CPU_STATE CpuState;
CPU_DATA_BLOCK *CpuData;
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
CpuData = &mMpSystemData.CpuDatas[Number];
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
//
// Skip BSP
//
continue;
}
CpuState = GetApState (CpuData);
if (CpuState == CpuStateBlocked) {
*NextNumber = Number;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/**
Check if the APs state are finished, and update them to idle state
by StartupAllAPs().
**/
VOID
CheckAndUpdateAllAPsToIdleState (
VOID
)
{
UINTN ProcessorNumber;
UINTN NextNumber;
CPU_DATA_BLOCK *CpuData;
EFI_STATUS Status;
CPU_STATE CpuState;
for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
//
// Skip BSP
//
continue;
}
if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
//
// Skip Disabled processors
//
continue;
}
CpuState = GetApState (CpuData);
if (CpuState == CpuStateFinished) {
mMpSystemData.FinishCount++;
if (mMpSystemData.SingleThread) {
Status = GetNextBlockedNumber (&NextNumber);
if (!EFI_ERROR (Status)) {
SetApState (&mMpSystemData.CpuDatas[NextNumber], CpuStateReady);
SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],
mMpSystemData.Procedure,
mMpSystemData.ProcedureArgument);
//
// If this AP previous state is blocked, we should
// wake up this AP by sent a SIPI. and avoid
// re-involve the sleeping state. we must call
// SetApProcedure() first.
//
ResetProcessorToIdleState (&mMpSystemData.CpuDatas[NextNumber]);
}
}
SetApState (CpuData, CpuStateIdle);
}
}
}
/**
Check if all APs are in state CpuStateSleeping.
Return TRUE if all APs are in the CpuStateSleeping state. Do not
check the state of the BSP or any disabled APs.
@retval TRUE All APs are in CpuStateSleeping state.
@retval FALSE One or more APs are not in CpuStateSleeping state.
**/
BOOLEAN
CheckAllAPsSleeping (
VOID
)
{
UINTN ProcessorNumber;
CPU_DATA_BLOCK *CpuData;
for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
//
// Skip BSP
//
continue;
}
if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
//
// Skip Disabled processors
//
continue;
}
if (GetApState (CpuData) != CpuStateSleeping) {
return FALSE;
}
}
return TRUE;
}
/**
If the timeout expires before all APs returns from Procedure,
we should forcibly terminate the executing AP and fill FailedList back
by StartupAllAPs().
**/
VOID
ResetAllFailedAPs (
VOID
)
{
CPU_DATA_BLOCK *CpuData;
UINTN Number;
CPU_STATE CpuState;
if (mMpSystemData.FailedList != NULL) {
*mMpSystemData.FailedList = AllocatePool ((mMpSystemData.StartCount - mMpSystemData.FinishCount + 1) * sizeof(UINTN));
ASSERT (*mMpSystemData.FailedList != NULL);
}
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
CpuData = &mMpSystemData.CpuDatas[Number];
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
//
// Skip BSP
//
continue;
}
if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
//
// Skip Disabled processors
//
continue;
}
CpuState = GetApState (CpuData);
if (CpuState != CpuStateIdle &&
CpuState != CpuStateSleeping) {
if (mMpSystemData.FailedList != NULL) {
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;
}
ResetProcessorToIdleState (CpuData);
}
}
if (mMpSystemData.FailedList != NULL) {
(*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex] = END_OF_CPU_LIST;
}
}
/**
This service retrieves the number of logical processor in the platform
and the number of those logical processors that are enabled on this boot.
@ -978,28 +600,6 @@ CollectBistDataFromHob (
}
}
/**
Callback function for ExitBootServices.
@param Event Event whose notification function is being invoked.
@param Context The pointer to the notification function's context,
which is implementation-dependent.
**/
VOID
EFIAPI
ExitBootServicesCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//
// Avoid APs access invalid buff datas which allocated by BootServices,
// so we send INIT IPI to APs to let them wait for SIPI state.
//
SendInitIpiAllExcludingSelf ();
}
/**
Initialize Multi-processor support.

View File

@ -1,7 +1,7 @@
/** @file
CPU DXE MP support
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -15,11 +15,6 @@
#ifndef _CPU_MP_H_
#define _CPU_MP_H_
#include <Ppi/SecPlatformInformation.h>
#include <Ppi/SecPlatformInformation2.h>
#include <Protocol/MpService.h>
#include <Library/SynchronizationLib.h>
/**
Initialize Multi-processor support.
@ -29,120 +24,6 @@ InitializeMpSupport (
VOID
);
typedef
VOID
(EFIAPI *STACKLESS_AP_ENTRY_POINT)(
VOID
);
/**
Starts the Application Processors and directs them to jump to the
specified routine.
The processor jumps to this code in flat mode, but the processor's
stack is not initialized.
@retval EFI_SUCCESS The APs were started
**/
EFI_STATUS
StartApsStackless (
VOID
);
/**
The AP entry point that the Startup-IPI target code will jump to.
The processor jumps to this code in flat mode, but the processor's
stack is not initialized.
**/
VOID
EFIAPI
AsmApEntryPoint (
VOID
);
/**
Releases the lock preventing other APs from using the shared AP
stack.
Once the AP has transitioned to using a new stack, it can call this
function to allow another AP to proceed with using the shared stack.
**/
VOID
EFIAPI
AsmApDoneWithCommonStack (
VOID
);
typedef enum {
CpuStateIdle,
CpuStateBlocked,
CpuStateReady,
CpuStateBusy,
CpuStateFinished,
CpuStateSleeping
} CPU_STATE;
/**
Define Individual Processor Data block.
**/
typedef struct {
EFI_PROCESSOR_INFORMATION Info;
SPIN_LOCK CpuDataLock;
INTN LockSelf;
volatile CPU_STATE State;
volatile EFI_AP_PROCEDURE Procedure;
volatile VOID* Parameter;
BOOLEAN *Finished;
INTN Timeout;
EFI_EVENT WaitEvent;
BOOLEAN TimeoutActive;
EFI_EVENT CheckThisAPEvent;
VOID *TopOfStack;
} CPU_DATA_BLOCK;
/**
Define MP data block which consumes individual processor block.
**/
typedef struct {
CPU_DATA_BLOCK *CpuDatas;
UINTN NumberOfProcessors;
UINTN NumberOfEnabledProcessors;
EFI_AP_PROCEDURE Procedure;
VOID *ProcedureArgument;
UINTN StartCount;
UINTN FinishCount;
BOOLEAN SingleThread;
UINTN **FailedList;
UINTN FailedListIndex;
INTN Timeout;
EFI_EVENT WaitEvent;
BOOLEAN TimeoutActive;
EFI_EVENT CheckAllAPsEvent;
} MP_SYSTEM_DATA;
/**
This function is called by all processors (both BSP and AP) once and collects MP related data.
@param Bsp TRUE if the CPU is BSP
@param ProcessorNumber The specific processor number
@retval EFI_SUCCESS Data for the processor collected and filled in
**/
EFI_STATUS
FillInProcessorInformation (
IN BOOLEAN Bsp,
IN UINTN ProcessorNumber
);
/**
This service retrieves the number of logical processor in the platform
and the number of those logical processors that are enabled on this boot.
@ -591,68 +472,5 @@ WhoAmI (
OUT UINTN *ProcessorNumber
);
/**
Terminate AP's task and set it to idle state.
This function terminates AP's task due to timeout by sending INIT-SIPI,
and sends it to idle state.
@param CpuData the pointer to CPU_DATA_BLOCK of specified AP
**/
VOID
ResetProcessorToIdleState (
IN CPU_DATA_BLOCK *CpuData
);
/**
Prepares Startup Code for APs.
This function prepares Startup Code for APs.
@retval EFI_SUCCESS The APs were started
@retval EFI_OUT_OF_RESOURCES Cannot allocate memory to start APs
**/
EFI_STATUS
PrepareAPStartupCode (
VOID
);
/**
Free the code buffer of startup AP.
**/
VOID
FreeApStartupCode (
VOID
);
/**
Resets the Application Processor and directs it to jump to the
specified routine.
The processor jumps to this code in flat mode, but the processor's
stack is not initialized.
@param ProcessorId the AP of ProcessorId was reset
**/
VOID
ResetApStackless (
IN UINT32 ProcessorId
);
/**
A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
@param[in] Buffer Pointer to an MTRR_SETTINGS object, to be passed to
MtrrSetAllMtrrs().
**/
VOID
EFIAPI
SetMtrrsFromBuffer (
IN VOID *Buffer
);
#endif // _CPU_MP_H_

View File

@ -1,76 +0,0 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php.
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;------------------------------------------------------------------------------
.686
.xmm
.model flat, C
extern mTopOfApCommonStack:DWORD
extern ApEntryPointInC:PROC
.code
;
; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
;
ApStackLock dd 0
;.code
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApEntryPoint (
; VOID
; );
;------------------------------------------------------------------------------
AsmApEntryPoint PROC
cli
AsmApEntryPointAcquireLock:
lock bts dword ptr [ApStackLock], 0
pause
jc AsmApEntryPointAcquireLock
mov esp, [mTopOfApCommonStack]
call ApEntryPointInC
cli
lock btc dword ptr [ApStackLock], 0
mov eax, 100h
AsmApEntryPointShareLock:
pause
dec eax
jnz AsmApEntryPointShareLock
jmp AsmApEntryPoint
AsmApEntryPoint ENDP
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApDoneWithCommonStack (
; VOID
; );
;------------------------------------------------------------------------------
AsmApDoneWithCommonStack PROC PUBLIC
lock btc dword ptr [ApStackLock], 0
ret
AsmApDoneWithCommonStack ENDP
END

View File

@ -1,68 +0,0 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php.
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;------------------------------------------------------------------------------
extern ASM_PFX(mTopOfApCommonStack)
extern ASM_PFX(ApEntryPointInC)
SECTION .data
;
; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
;
ApStackLock:
dd 0
SECTION .text
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApEntryPoint (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmApEntryPoint)
ASM_PFX(AsmApEntryPoint):
cli
AsmApEntryPointAcquireLock:
lock bts dword [ApStackLock], 0
pause
jc AsmApEntryPointAcquireLock
mov esp, [ASM_PFX(mTopOfApCommonStack)]
call ASM_PFX(ApEntryPointInC)
cli
lock btc dword [ApStackLock], 0
mov eax, 0x100
AsmApEntryPointShareLock:
pause
dec eax
jnz AsmApEntryPointShareLock
jmp ASM_PFX(AsmApEntryPoint)
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApDoneWithCommonStack (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmApDoneWithCommonStack)
ASM_PFX(AsmApDoneWithCommonStack):
lock btc dword [ApStackLock], 0
ret

View File

@ -1,76 +0,0 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php.
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;------------------------------------------------------------------------------
#include <Base.h>
extern ASM_PFX(mTopOfApCommonStack):QWORD
extern ASM_PFX(ApEntryPointInC):PROC
.data
;
; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
;
ApStackLock:
dd 0
.code
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApEntryPoint (
; VOID
; );
;------------------------------------------------------------------------------
ASM_PFX(AsmApEntryPoint) PROC PUBLIC
cli
AsmApEntryPointAcquireLock:
lock bts dword ptr [ApStackLock], 0
pause
jc AsmApEntryPointAcquireLock
mov rsp, [ASM_PFX(mTopOfApCommonStack)]
call ASM_PFX(ApEntryPointInC)
cli
lock btc dword ptr [ApStackLock], 0
mov eax, 100h
AsmApEntryPointShareLock:
pause
dec eax
jnz AsmApEntryPointShareLock
jmp ASM_PFX(AsmApEntryPoint)
ASM_PFX(AsmApEntryPoint) ENDP
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApDoneWithCommonStack (
; VOID
; );
;------------------------------------------------------------------------------
ASM_PFX(AsmApDoneWithCommonStack) PROC PUBLIC
lock btc dword ptr [ApStackLock], 0
ret
ASM_PFX(AsmApDoneWithCommonStack) ENDP
END

View File

@ -1,70 +0,0 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
; This program and the accompanying materials
; are licensed and made available under the terms and conditions of the BSD License
; which accompanies this distribution. The full text of the license may be found at
; http://opensource.org/licenses/bsd-license.php.
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;------------------------------------------------------------------------------
extern ASM_PFX(mTopOfApCommonStack)
extern ASM_PFX(ApEntryPointInC)
DEFAULT REL
SECTION .data
;
; This lock only allows one AP to use the mTopOfApCommonStack stack at a time
;
ApStackLock:
dd 0
SECTION .text
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApEntryPoint (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmApEntryPoint)
ASM_PFX(AsmApEntryPoint):
cli
AsmApEntryPointAcquireLock:
lock bts dword [ApStackLock], 0
pause
jc AsmApEntryPointAcquireLock
mov rsp, [ASM_PFX(mTopOfApCommonStack)]
call ASM_PFX(ApEntryPointInC)
cli
lock btc dword [ApStackLock], 0
mov eax, 0x100
AsmApEntryPointShareLock:
pause
dec eax
jnz AsmApEntryPointShareLock
jmp ASM_PFX(AsmApEntryPoint)
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; AsmApDoneWithCommonStack (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmApDoneWithCommonStack)
ASM_PFX(AsmApDoneWithCommonStack):
lock btc dword [ApStackLock], 0
ret