mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 07:34:06 +02:00
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/UefiCpuLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/CpuExceptionHandlerLib.h>
|
#include <Library/CpuExceptionHandlerLib.h>
|
||||||
#include <Library/TimerLib.h>
|
|
||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
#include <Library/ReportStatusCodeLib.h>
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
#include <Library/MpInitLib.h>
|
#include <Library/MpInitLib.h>
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
MpInitLib
|
MpInitLib
|
||||||
|
|
||||||
[Sources]
|
[Sources]
|
||||||
ApStartup.c
|
|
||||||
CpuDxe.c
|
CpuDxe.c
|
||||||
CpuDxe.h
|
CpuDxe.h
|
||||||
CpuGdt.c
|
CpuGdt.c
|
||||||
@ -58,15 +57,11 @@
|
|||||||
Ia32/CpuAsm.asm
|
Ia32/CpuAsm.asm
|
||||||
Ia32/CpuAsm.nasm
|
Ia32/CpuAsm.nasm
|
||||||
Ia32/CpuAsm.S
|
Ia32/CpuAsm.S
|
||||||
Ia32/MpAsm.asm
|
|
||||||
Ia32/MpAsm.nasm
|
|
||||||
|
|
||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/CpuAsm.asm
|
X64/CpuAsm.asm
|
||||||
X64/CpuAsm.nasm
|
X64/CpuAsm.nasm
|
||||||
X64/CpuAsm.S
|
X64/CpuAsm.S
|
||||||
X64/MpAsm.asm
|
|
||||||
X64/MpAsm.nasm
|
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiCpuArchProtocolGuid ## PRODUCES
|
gEfiCpuArchProtocolGuid ## PRODUCES
|
||||||
@ -82,8 +77,6 @@
|
|||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
|
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
|
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
TRUE
|
TRUE
|
||||||
|
@ -15,20 +15,8 @@
|
|||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
#include "CpuMp.h"
|
#include "CpuMp.h"
|
||||||
|
|
||||||
UINTN gMaxLogicalProcessorNumber;
|
|
||||||
UINTN gApStackSize;
|
|
||||||
UINTN gPollInterval = 100; // 100 microseconds
|
|
||||||
|
|
||||||
MP_SYSTEM_DATA mMpSystemData;
|
|
||||||
EFI_HANDLE mMpServiceHandle = NULL;
|
EFI_HANDLE mMpServiceHandle = NULL;
|
||||||
UINTN mNumberOfProcessors = 1;
|
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 = {
|
EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
|
||||||
GetNumberOfProcessors,
|
GetNumberOfProcessors,
|
||||||
@ -40,372 +28,6 @@ EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
|
|||||||
WhoAmI
|
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
|
This service retrieves the number of logical processor in the platform
|
||||||
and the number of those logical processors that are enabled on this boot.
|
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.
|
Initialize Multi-processor support.
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
CPU DXE MP support
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -15,11 +15,6 @@
|
|||||||
#ifndef _CPU_MP_H_
|
#ifndef _CPU_MP_H_
|
||||||
#define _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.
|
Initialize Multi-processor support.
|
||||||
|
|
||||||
@ -29,120 +24,6 @@ InitializeMpSupport (
|
|||||||
VOID
|
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
|
This service retrieves the number of logical processor in the platform
|
||||||
and the number of those logical processors that are enabled on this boot.
|
and the number of those logical processors that are enabled on this boot.
|
||||||
@ -591,68 +472,5 @@ WhoAmI (
|
|||||||
OUT UINTN *ProcessorNumber
|
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_
|
#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…
x
Reference in New Issue
Block a user