mirror of https://github.com/acidanthera/audk.git
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:
parent
0b9f0dd635
commit
39d49a73a5
|
@ -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);
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue