* [Patch v4 00/46] MP Initialize Library
@ 2016-07-29 18:14 Jeff Fan
2016-07-29 18:14 ` [Patch v4 01/46] UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions Jeff Fan
` (45 more replies)
0 siblings, 46 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel
We add MP Initialize Library defined in UefiCpuPkg/Include/Library/MpInitLib.h.
It will provide basic functionalities of MP services and could be consumed by
CPU MP PEI and CPU MP DXE to produce CPU MP PPI and CPU MP Protocol. Then most
of code could be shared between PEI and DXE modules.
PeiMpInitLib and DxeMpInitLib are added to make the CpuMpPei and CpuDxe more
simply.
I also updated the Ovmf Platform and Quark platform to consume MP Initialize
library. I have tested Ovmf platform and have not tested Quark yet.
v4:
1. Update Patches #2 - #6, #10, #15, #28, #30, #31, #33, #34, #38, #41, #43.
2. Add Patches #7, #8, #42, #44 - #46.
3. Add Reviewed-by: Laszlo Ersek <lersek@redhat.com> on Patches #1, #2.
(Please see the patches commit log for more details)
v3:
1. Update Patch #2, #4 - #8, #28, #33, #36, #38 per Giri's comments to
a. Update SDM date to June, 2016
b. Mention BCD format in CPU_MICROCODE_DATE
c. Rename ProcessorChecksum to Checksum to match SDM.
d. Add whitespace after MpInitLibInitialize
e. Rename MpInitLibSwitchBsp to MpInitLibSwitchBSP to match PI spec.
f. Rename NumApsExecutingLoction to NumApsExecutingLocation
g. Add whitespace after ; in .nasm file
h. Rename *RellocateAp* to *RelocateAp*
2. Update Patch #16, #17, #29-#32 to
a. Use CamelCase for mStopCheckAllApsStatus and CheckAndUpdateApsStatus().
3. Update Patch #36 and #39 to
a. Add PeiMpInitLib instance in UefiCpuPkg.dsc
b. Add DxeMpInitLib instance in UefiCpuPkg.dsc
4. Update Patch #39 and #40 to
a. move the code of consuming MP Initialize library from patch #40 to
patch #39.
5. Update Patch #1, #3 - #8, #16 to
a. Add Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
I fork the whole tree with the updated v3 patches
at https://github.com/vanjeff/edk2/tree/MpInitLibV4 for review.
Jeff Fan (46):
UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions
UefiCpuPkg/MpInitLib: Add microcode definitions defined in IA32 SDM
UefiCpuPkg/CpuS3DataDxe: Move StartupVector allocation to EndOfDxe()
UefiCpuPkg/MpInitLib: Add MP Initialize library class definition
UefiCpuPkg/MpInitLib: Add two instances PeiMpInitLib and DxeMpInitLib
UefiCpuPkg/MpInitLib: Add AP assembly code and MP_CPU_EXCHANGE_INFO
UefiCpuPkg/MpInitLib: Fix typo and clean up the code
UefiCpuPkg/MpInitLib: Add EnableExecuteDisable in MP_CPU_EXCHANGE_INFO
UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code
UefiCpuPkg/MpInitLib: Add MP_ASSEMBLY_ADDRESS_MAP
UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size
UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer
UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs
UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions
UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP
UefiCpuPkg/MpInitLib: Save CPU MP Data pointer
UefiCpuPkg/MpInitLib: Register one End of PEI callback function
UefiCpuPkg/MpInitLib: Register one period event to check APs status
UefiCpuPkg/MpInitLib: Allocate AP reset vector buffer under 1MB
UefiCpuPkg/MpInitLib: Add ApCFunction() executed by assembly code
UefiCpuPkg/MpInitLib: Fill MP_CPU_EXCHANGE_INFO fields
UefiCpuPkg/MpInitLib: Add WakeUpAP()
UefiCpuPkg/MpInitLib: Send INIT-SIPI-SIPI to get processor count
UefiCpuPkg/MpInitLib: Enable x2APIC mode on BSP/APs
UefiCpuPkg/MpInitLib: Sort processor by ascending order of APIC ID
UefiCpuPkg/MpInitLib: Skip collect processor count if GUIDed HOB exist
UefiCpuPkg/MpInitLib: Implementation of
MpInitLibGetNumberOfProcessors()
UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetProcessorInfo()
UefiCpuPkg/MpInitLib: Implementation of MpInitLibWhoAmI()
UefiCpuPkg/MpInitLib: Implementation of MpInitLibSwitchBSP()
UefiCpuPkg/MpInitLib: Implementation of MpInitLibEnableDisableAP()
UefiCpuPkg/MpInitLib: Check APs Status and update APs status
UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupThisAP()
UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupAllAPs()
UefiCpuPkg/MpInitLib: Place APs in safe loop before hand-off to OS
OvmfPkg: Add MpInitLib reference in DSC files.
QuarkPlatformPkg: Add MpInitLib reference in DSC files.
UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
UefiCpuPkg/CpuMpPei: Remove unused files and codes
UefiCpuPkg/CpuMpPei: Delete PeiMpServices.c and PeiMpServices.h
UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol
services
UefiCpuPkg/CpuDxe: Move SetMtrrsFromBuffer() location.
UefiCpuPkg/CpuDxe: Remove unused codes and files
MdePkg/MpService.h: Fixed typo in function header to match PI spec
MdePkg/MpService.h: Trim whitespace at end of line
UefiCpuPkg/CpuDxe: Fixed typo in function header to match PI spec
MdePkg/Include/Protocol/MpService.h | 490 ++---
OvmfPkg/OvmfPkgIa32.dsc | 2 +
OvmfPkg/OvmfPkgIa32X64.dsc | 2 +
OvmfPkg/OvmfPkgX64.dsc | 2 +
QuarkPlatformPkg/Quark.dsc | 1 +
QuarkPlatformPkg/QuarkMin.dsc | 3 +-
UefiCpuPkg/CpuDxe/ApStartup.c | 478 -----
UefiCpuPkg/CpuDxe/CpuDxe.c | 17 +-
UefiCpuPkg/CpuDxe/CpuDxe.h | 13 +-
UefiCpuPkg/CpuDxe/CpuDxe.inf | 12 +-
UefiCpuPkg/CpuDxe/CpuDxe.uni | 10 +-
UefiCpuPkg/CpuDxe/CpuDxeExtra.uni | 4 +-
UefiCpuPkg/CpuDxe/CpuMp.c | 1302 +------------
UefiCpuPkg/CpuDxe/CpuMp.h | 186 +-
UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm | 76 -
UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm | 68 -
UefiCpuPkg/CpuDxe/X64/MpAsm.asm | 76 -
UefiCpuPkg/CpuDxe/X64/MpAsm.nasm | 70 -
UefiCpuPkg/CpuMpPei/CpuBist.c | 53 +-
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 1118 ++++-------
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 515 ++---
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 32 +-
UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm | 250 ---
UefiCpuPkg/CpuMpPei/Microcode.h | 58 -
UefiCpuPkg/CpuMpPei/PeiMpServices.c | 956 ----------
UefiCpuPkg/CpuMpPei/PeiMpServices.h | 377 ----
UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm | 290 ---
UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c | 42 +-
UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf | 2 +-
UefiCpuPkg/Include/Library/MpInitLib.h | 353 ++++
UefiCpuPkg/Include/Register/LocalApic.h | 20 +-
UefiCpuPkg/Include/Register/Microcode.h | 200 ++
UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 29 +-
.../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 51 +-
.../MpInitLib/DxeMpInitLib.inf} | 68 +-
.../MpInitLib/DxeMpInitLib.uni} | 12 +-
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 646 +++++++
.../{CpuMpPei => Library/MpInitLib}/Ia32/MpEqu.inc | 4 +-
.../MpInitLib}/Ia32/MpFuncs.nasm | 66 +-
.../{CpuMpPei => Library/MpInitLib}/Microcode.c | 77 +-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 2018 ++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 529 +++++
.../MpInitLib/PeiMpInitLib.inf} | 60 +-
.../MpInitLib/PeiMpInitLib.uni} | 12 +-
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 640 +++++++
.../{CpuMpPei => Library/MpInitLib}/X64/MpEqu.inc | 6 +-
.../MpInitLib}/X64/MpFuncs.nasm | 84 +-
UefiCpuPkg/UefiCpuPkg.dec | 4 +
UefiCpuPkg/UefiCpuPkg.dsc | 5 +-
49 files changed, 5744 insertions(+), 5645 deletions(-)
delete mode 100644 UefiCpuPkg/CpuDxe/ApStartup.c
delete mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
delete mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
delete mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.asm
delete mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
delete mode 100644 UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
delete mode 100644 UefiCpuPkg/CpuMpPei/Microcode.h
delete mode 100644 UefiCpuPkg/CpuMpPei/PeiMpServices.c
delete mode 100644 UefiCpuPkg/CpuMpPei/PeiMpServices.h
delete mode 100644 UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
create mode 100644 UefiCpuPkg/Include/Library/MpInitLib.h
create mode 100644 UefiCpuPkg/Include/Register/Microcode.h
copy UefiCpuPkg/{CpuMpPei/CpuMpPei.inf => Library/MpInitLib/DxeMpInitLib.inf} (52%)
copy UefiCpuPkg/{CpuDxe/CpuDxeExtra.uni => Library/MpInitLib/DxeMpInitLib.uni} (53%)
create mode 100644 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
rename UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Ia32/MpEqu.inc (88%)
rename UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Ia32/MpFuncs.nasm (77%)
rename UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Microcode.c (68%)
create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLib.c
create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLib.h
copy UefiCpuPkg/{CpuMpPei/CpuMpPei.inf => Library/MpInitLib/PeiMpInitLib.inf} (58%)
copy UefiCpuPkg/{CpuDxe/CpuDxeExtra.uni => Library/MpInitLib/PeiMpInitLib.uni} (53%)
create mode 100644 UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
rename UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/X64/MpEqu.inc (88%)
rename UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/X64/MpFuncs.nasm (73%)
--
2.7.4.windows.1
^ permalink raw reply [flat|nested] 47+ messages in thread
* [Patch v4 01/46] UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 02/46] UefiCpuPkg/MpInitLib: Add microcode definitions defined in IA32 SDM Jeff Fan
` (44 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
#define MSR_IA32_APIC_BASE_ADDRESS is duplicated with #define MSR_IA32_APIC_BASE
defined in UefiCpuPkg/Include/Register/ArchitecturalMsr.h, so we could remove it
and update the modules to use MSR_IA32_APIC_BASE from ArchitecturalMsr.h.
Structure MSR_IA32_APIC_BASE conflicts with #define MSR_IA32_APIC_BASE defined
in UefiCpuPkg/Include/Register/ArchitecturalMsr.h, so we could remove it and
update the modules to use structure MSR_IA32_APIC_BASE_REGISTER from
ArchitecturalMsr.h.
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 1 +
UefiCpuPkg/CpuMpPei/PeiMpServices.c | 20 ++++-----
UefiCpuPkg/Include/Register/LocalApic.h | 20 +--------
UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 29 ++++++------
.../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 51 +++++++++++-----------
5 files changed, 53 insertions(+), 68 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index b2e578b..0d1a14a 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -25,6 +25,7 @@
#include <Register/Cpuid.h>
#include <Register/LocalApic.h>
+#include <Register/Msr.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
index e784377..e06fdf1 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -1,7 +1,7 @@
/** @file
Implementation of Multiple Processor PPI services.
- Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2015 - 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
@@ -729,9 +729,9 @@ PeiSwitchBSP (
IN BOOLEAN EnableOldBSP
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN CallerNumber;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
PeiCpuMpData = GetMpHobData ();
if (PeiCpuMpData == NULL) {
@@ -774,9 +774,9 @@ PeiSwitchBSP (
//
// Clear the BSP bit of MSR_IA32_APIC_BASE
//
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
- ApicBaseMsr.Bits.Bsp = 0;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.BSP = 0;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
PeiCpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE;
@@ -805,9 +805,9 @@ PeiSwitchBSP (
//
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
//
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
- ApicBaseMsr.Bits.Bsp = 1;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.BSP = 1;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
//
// Set old BSP enable state
//
diff --git a/UefiCpuPkg/Include/Register/LocalApic.h b/UefiCpuPkg/Include/Register/LocalApic.h
index 346cce6..cfb6d76 100644
--- a/UefiCpuPkg/Include/Register/LocalApic.h
+++ b/UefiCpuPkg/Include/Register/LocalApic.h
@@ -1,7 +1,7 @@
/** @file
IA32 Local APIC Definitions.
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 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
@@ -16,11 +16,6 @@
#define __LOCAL_APIC_H__
//
-// Definitions for IA32 architectural MSRs
-//
-#define MSR_IA32_APIC_BASE_ADDRESS 0x1B
-
-//
// Definition for Local APIC registers and related values
//
#define XAPIC_ID_OFFSET 0x20
@@ -53,19 +48,6 @@
#define LOCAL_APIC_DESTINATION_SHORTHAND_ALL_INCLUDING_SELF 2
#define LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF 3
-typedef union {
- struct {
- UINT32 Reserved0:8; ///< Reserved.
- UINT32 Bsp:1; ///< Processor is BSP.
- UINT32 Reserved1:1; ///< Reserved.
- UINT32 Extd:1; ///< Enable x2APIC mode.
- UINT32 En:1; ///< xAPIC global enable/disable.
- UINT32 ApicBaseLow:20; ///< APIC Base physical address. The actual field width depends on physical address width.
- UINT32 ApicBaseHigh:32;
- } Bits;
- UINT64 Uint64;
-} MSR_IA32_APIC_BASE;
-
//
// Local APIC Version Register.
//
diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
index 1fca66e..8d0fb02 100644
--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
@@ -3,7 +3,7 @@
This local APIC library instance supports xAPIC mode only.
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 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,6 +15,7 @@
**/
#include <Register/Cpuid.h>
+#include <Register/Msr.h>
#include <Register/LocalApic.h>
#include <Library/BaseLib.h>
@@ -67,7 +68,7 @@ GetLocalApicBaseAddress (
VOID
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
if (!LocalApicBaseAddressMsrSupported ()) {
//
@@ -77,10 +78,10 @@ GetLocalApicBaseAddress (
return PcdGet32 (PcdCpuLocalApicBaseAddress);
}
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
- (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 12);
+ return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHi, 32)) +
+ (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
}
/**
@@ -97,7 +98,7 @@ SetLocalApicBaseAddress (
IN UINTN BaseAddress
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
@@ -108,12 +109,12 @@ SetLocalApicBaseAddress (
return;
}
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
- ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
+ ApicBaseMsr.Bits.ApicBase = (UINT32) (BaseAddress >> 12);
+ ApicBaseMsr.Bits.ApicBaseHi = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
}
/**
@@ -246,18 +247,18 @@ GetApicMode (
{
DEBUG_CODE (
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
//
// Check to see if the CPU supports the APIC Base Address MSR
//
if (LocalApicBaseAddressMsrSupported ()) {
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
//
// Local APIC should have been enabled
//
- ASSERT (ApicBaseMsr.Bits.En != 0);
- ASSERT (ApicBaseMsr.Bits.Extd == 0);
+ ASSERT (ApicBaseMsr.Bits.EN != 0);
+ ASSERT (ApicBaseMsr.Bits.EXTD == 0);
}
}
);
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
index 38f5370..4c42696 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -4,7 +4,7 @@
This local APIC library instance supports x2APIC capable processors
which have xAPIC and x2APIC modes.
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 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
@@ -16,6 +16,7 @@
**/
#include <Register/Cpuid.h>
+#include <Register/Msr.h>
#include <Register/LocalApic.h>
#include <Library/BaseLib.h>
@@ -68,7 +69,7 @@ GetLocalApicBaseAddress (
VOID
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
if (!LocalApicBaseAddressMsrSupported ()) {
//
@@ -78,10 +79,10 @@ GetLocalApicBaseAddress (
return PcdGet32 (PcdCpuLocalApicBaseAddress);
}
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
- (((UINTN)ApicBaseMsr.Bits.ApicBaseLow) << 12);
+ return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHi, 32)) +
+ (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
}
/**
@@ -98,7 +99,7 @@ SetLocalApicBaseAddress (
IN UINTN BaseAddress
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
@@ -109,12 +110,12 @@ SetLocalApicBaseAddress (
return;
}
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
- ApicBaseMsr.Bits.ApicBaseHigh = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
+ ApicBaseMsr.Bits.ApicBase = (UINT32) (BaseAddress >> 12);
+ ApicBaseMsr.Bits.ApicBaseHi = (UINT32) (RShiftU64((UINT64) BaseAddress, 32));
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
}
/**
@@ -301,7 +302,7 @@ GetApicMode (
VOID
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
if (!LocalApicBaseAddressMsrSupported ()) {
//
@@ -310,12 +311,12 @@ GetApicMode (
return LOCAL_APIC_MODE_XAPIC;
}
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
//
// Local APIC should have been enabled
//
- ASSERT (ApicBaseMsr.Bits.En != 0);
- if (ApicBaseMsr.Bits.Extd != 0) {
+ ASSERT (ApicBaseMsr.Bits.EN != 0);
+ if (ApicBaseMsr.Bits.EXTD != 0) {
return LOCAL_APIC_MODE_X2APIC;
} else {
return LOCAL_APIC_MODE_XAPIC;
@@ -339,8 +340,8 @@ SetApicMode (
IN UINTN ApicMode
)
{
- UINTN CurrentMode;
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ UINTN CurrentMode;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
if (!LocalApicBaseAddressMsrSupported ()) {
//
@@ -355,9 +356,9 @@ SetApicMode (
case LOCAL_APIC_MODE_XAPIC:
break;
case LOCAL_APIC_MODE_X2APIC:
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
- ApicBaseMsr.Bits.Extd = 1;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.EXTD = 1;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
break;
default:
ASSERT (FALSE);
@@ -369,12 +370,12 @@ SetApicMode (
// Transition from x2APIC mode to xAPIC mode is a two-step process:
// x2APIC -> Local APIC disabled -> xAPIC
//
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
- ApicBaseMsr.Bits.Extd = 0;
- ApicBaseMsr.Bits.En = 0;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
- ApicBaseMsr.Bits.En = 1;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE_ADDRESS, ApicBaseMsr.Uint64);
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.EXTD = 0;
+ ApicBaseMsr.Bits.EN = 0;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
+ ApicBaseMsr.Bits.EN = 1;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
break;
case LOCAL_APIC_MODE_X2APIC:
break;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 02/46] UefiCpuPkg/MpInitLib: Add microcode definitions defined in IA32 SDM
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
2016-07-29 18:14 ` [Patch v4 01/46] UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 03/46] UefiCpuPkg/CpuS3DataDxe: Move StartupVector allocation to EndOfDxe() Jeff Fan
` (43 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Add microcode definitions defined in Intel(R) 64 and IA-32 Architectures
Software Developer's Manual Volume 3A, Section 9.11.
v4:
1. ProcessorSignature type changed to CPU_MICROCODE_PROCESSOR_SIGNATURE
2. Add pack(1) for structure CPU_MICROCODE_HEADER and
CPU_MICROCODE_EXTENDED_TABLE.
v3:
1. Update SDM date to June, 2016
2. Mention BCD format in CPU_MICROCODE_DATE
3. Rename ProcessorChecksum to Checksum to match SDM.
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: Laszlo Ersek <lersek@redhat.com>
---
UefiCpuPkg/Include/Register/Microcode.h | 200 ++++++++++++++++++++++++++++++++
1 file changed, 200 insertions(+)
create mode 100644 UefiCpuPkg/Include/Register/Microcode.h
diff --git a/UefiCpuPkg/Include/Register/Microcode.h b/UefiCpuPkg/Include/Register/Microcode.h
new file mode 100644
index 0000000..94529a1
--- /dev/null
+++ b/UefiCpuPkg/Include/Register/Microcode.h
@@ -0,0 +1,200 @@
+/** @file
+ Microcode Definitions.
+
+ Microcode Definitions based on contents of the
+ Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3A, Section 9.11 Microcode Definitions
+
+ Copyright (c) 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
+ 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.
+
+ @par Specification Reference:
+ Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Volume 3A,
+ June 2016, Chapter 9 Processor Management and Initialization, Section 9-11.
+
+**/
+
+#ifndef __MICROCODE_H__
+#define __MICROCODE_H__
+
+///
+/// CPU Microcode Date in BCD format
+///
+typedef union {
+ struct {
+ UINT32 Year:16;
+ UINT32 Day:8;
+ UINT32 Month:8;
+ } Bits;
+ UINT32 Uint32;
+} CPU_MICROCODE_DATE;
+
+///
+/// CPU Microcode Processor Signature format
+///
+typedef union {
+ struct {
+ UINT32 Stepping:4;
+ UINT32 Model:4;
+ UINT32 Family:4;
+ UINT32 Type:2;
+ UINT32 Reserved1:2;
+ UINT32 ExtendedModel:4;
+ UINT32 ExtendedFamily:8;
+ UINT32 Reserved2:4;
+ } Bits;
+ UINT32 Uint32;
+} CPU_MICROCODE_PROCESSOR_SIGNATURE;
+
+#pragma pack (1)
+
+///
+/// Microcode Update Format definition
+///
+typedef struct {
+ ///
+ /// Version number of the update header
+ ///
+ UINT32 HeaderVersion;
+ ///
+ /// Unique version number for the update, the basis for the update
+ /// signature provided by the processor to indicate the current update
+ /// functioning within the processor. Used by the BIOS to authenticate
+ /// the update and verify that the processor loads successfully. The
+ /// value in this field cannot be used for processor stepping identification
+ /// alone. This is a signed 32-bit number.
+ ///
+ UINT32 UpdateRevision;
+ ///
+ /// Date of the update creation in binary format: mmddyyyy (e.g.
+ /// 07/18/98 is 07181998H).
+ ///
+ CPU_MICROCODE_DATE Date;
+ ///
+ /// Extended family, extended model, type, family, model, and stepping
+ /// of processor that requires this particular update revision (e.g.,
+ /// 00000650H). Each microcode update is designed specifically for a
+ /// given extended family, extended model, type, family, model, and
+ /// stepping of the processor.
+ /// The BIOS uses the processor signature field in conjunction with the
+ /// CPUID instruction to determine whether or not an update is
+ /// appropriate to load on a processor. The information encoded within
+ /// this field exactly corresponds to the bit representations returned by
+ /// the CPUID instruction.
+ ///
+ CPU_MICROCODE_PROCESSOR_SIGNATURE ProcessorSignature;
+ ///
+ /// Checksum of Update Data and Header. Used to verify the integrity of
+ /// the update header and data. Checksum is correct when the
+ /// summation of all the DWORDs (including the extended Processor
+ /// Signature Table) that comprise the microcode update result in
+ /// 00000000H.
+ ///
+ UINT32 Checksum;
+ ///
+ /// Version number of the loader program needed to correctly load this
+ /// update. The initial version is 00000001H
+ ///
+ UINT32 LoaderRevision;
+ ///
+ /// Platform type information is encoded in the lower 8 bits of this 4-
+ /// byte field. Each bit represents a particular platform type for a given
+ /// CPUID. The BIOS uses the processor flags field in conjunction with
+ /// the platform Id bits in MSR (17H) to determine whether or not an
+ /// update is appropriate to load on a processor. Multiple bits may be set
+ /// representing support for multiple platform IDs.
+ ///
+ UINT32 ProcessorFlags;
+ ///
+ /// Specifies the size of the encrypted data in bytes, and must be a
+ /// multiple of DWORDs. If this value is 00000000H, then the microcode
+ /// update encrypted data is 2000 bytes (or 500 DWORDs).
+ ///
+ UINT32 DataSize;
+ ///
+ /// Specifies the total size of the microcode update in bytes. It is the
+ /// summation of the header size, the encrypted data size and the size of
+ /// the optional extended signature table. This value is always a multiple
+ /// of 1024.
+ ///
+ UINT32 TotalSize;
+ ///
+ /// Reserved fields for future expansion.
+ ///
+ UINT8 Reserved[12];
+} CPU_MICROCODE_HEADER;
+
+///
+/// Extended Signature Table Header Field Definitions
+///
+typedef struct {
+ ///
+ /// Specifies the number of extended signature structures (Processor
+ /// Signature[n], processor flags[n] and checksum[n]) that exist in this
+ /// microcode update
+ ///
+ UINT32 ExtendedSignatureCount;
+ ///
+ /// Checksum of update extended processor signature table. Used to
+ /// verify the integrity of the extended processor signature table.
+ /// Checksum is correct when the summation of the DWORDs that
+ /// comprise the extended processor signature table results in
+ /// 00000000H.
+ ///
+ UINT32 ExtendedChecksum;
+ ///
+ /// Reserved fields.
+ ///
+ UINT8 Reserved[12];
+} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+///
+/// Extended Signature Table Field Definitions
+///
+typedef struct {
+ ///
+ /// Extended family, extended model, type, family, model, and stepping
+ /// of processor that requires this particular update revision (e.g.,
+ /// 00000650H). Each microcode update is designed specifically for a
+ /// given extended family, extended model, type, family, model, and
+ /// stepping of the processor.
+ /// The BIOS uses the processor signature field in conjunction with the
+ /// CPUID instruction to determine whether or not an update is
+ /// appropriate to load on a processor. The information encoded within
+ /// this field exactly corresponds to the bit representations returned by
+ /// the CPUID instruction.
+ ///
+ CPU_MICROCODE_PROCESSOR_SIGNATURE ProcessorSignature;
+ ///
+ /// Platform type information is encoded in the lower 8 bits of this 4-
+ /// byte field. Each bit represents a particular platform type for a given
+ /// CPUID. The BIOS uses the processor flags field in conjunction with
+ /// the platform Id bits in MSR (17H) to determine whether or not an
+ /// update is appropriate to load on a processor. Multiple bits may be set
+ /// representing support for multiple platform IDs.
+ ///
+ UINT32 ProcessorFlag;
+ ///
+ /// Used by utility software to decompose a microcode update into
+ /// multiple microcode updates where each of the new updates is
+ /// constructed without the optional Extended Processor Signature
+ /// Table.
+ /// To calculate the Checksum, substitute the Primary Processor
+ /// Signature entry and the Processor Flags entry with the
+ /// corresponding Extended Patch entry. Delete the Extended Processor
+ /// Signature Table entries. The Checksum is correct when the
+ /// summation of all DWORDs that comprise the created Extended
+ /// Processor Patch results in 00000000H.
+ ///
+ UINT32 Checksum;
+} CPU_MICROCODE_EXTENDED_TABLE;
+
+#pragma pack ()
+
+#endif
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 03/46] UefiCpuPkg/CpuS3DataDxe: Move StartupVector allocation to EndOfDxe()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
2016-07-29 18:14 ` [Patch v4 01/46] UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions Jeff Fan
2016-07-29 18:14 ` [Patch v4 02/46] UefiCpuPkg/MpInitLib: Add microcode definitions defined in IA32 SDM Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 04/46] UefiCpuPkg/MpInitLib: Add MP Initialize library class definition Jeff Fan
` (42 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Currently, we will allocate StartupVector buffer under 1MB at entry point
function. But some modules may allocate some hard code address under 1MB.
For example, LegacyBiosDxe driver tries to manage some legacy range under
640KB.
To avoid the conflicts, we move StartupVector buffer allocation to End Of
DXE event callback function.
v4:
Update the Context parameter is used as a pointer to AcpiCpuDataEx, then
we needn't to add the global variable.
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c | 42 +++++++++++++++++---------------
UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf | 2 +-
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
index 9fb47dc..7bd928f 100644
--- a/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
+++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
@@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not
support hot plug CPUs. This module can be copied into a CPU specific package
and customized if these additional features are required.
-Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Red Hat, Inc.
This program and the accompanying materials
@@ -84,20 +84,36 @@ AllocateAcpiNvsMemoryBelow4G (
/**
Callback function executed when the EndOfDxe event group is signaled.
- We delay saving the MTRR settings until BDS signals EndOfDxe.
+ We delay allocating StartupVector and saving the MTRR settings until BDS signals EndOfDxe.
@param[in] Event Event whose notification function is being invoked.
@param[out] Context Pointer to the MTRR_SETTINGS buffer to fill in.
**/
VOID
EFIAPI
-SaveMtrrsOnEndOfDxe (
+CpuS3DataOnEndOfDxe (
IN EFI_EVENT Event,
OUT VOID *Context
)
{
+ EFI_STATUS Status;
+ ACPI_CPU_DATA_EX *AcpiCpuDataEx;
+
+ AcpiCpuDataEx = (ACPI_CPU_DATA_EX *) Context;
+ //
+ // Allocate a 4KB reserved page below 1MB
+ //
+ AcpiCpuDataEx->AcpiCpuData.StartupVector = BASE_1MB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ 1,
+ &AcpiCpuDataEx->AcpiCpuData.StartupVector
+ );
+ ASSERT_EFI_ERROR (Status);
+
DEBUG ((EFI_D_VERBOSE, "%a\n", __FUNCTION__));
- MtrrGetAllMtrrs (Context);
+ MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
//
// Close event, so it will not be invoked again.
@@ -162,18 +178,6 @@ CpuS3DataInitialize (
ASSERT_EFI_ERROR (Status);
//
- // Allocate a 4KB reserved page below 1MB
- //
- AcpiCpuData->StartupVector = BASE_1MB - 1;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- 1,
- &AcpiCpuData->StartupVector
- );
- ASSERT_EFI_ERROR (Status);
-
- //
// Get the number of CPUs
//
Status = MpServices->GetNumberOfProcessors (
@@ -255,13 +259,13 @@ CpuS3DataInitialize (
//
// Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
- // The notification function saves MTRRs for ACPI_CPU_DATA
+ // The notification function allocates StartupVector and saves MTRRs for ACPI_CPU_DATA
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
- SaveMtrrsOnEndOfDxe,
- &AcpiCpuDataEx->MtrrTable,
+ CpuS3DataOnEndOfDxe,
+ AcpiCpuData,
&gEfiEndOfDxeEventGroupGuid,
&Event
);
diff --git a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
index 857e12b..608e19f 100644
--- a/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+++ b/UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
@@ -9,7 +9,7 @@
# support hot plug CPUs. This module can be copied into a CPU specific package
# and customized if these additional features are required.
#
-# Copyright (c) 2013-2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015, Red Hat, Inc.
#
# This program and the accompanying materials
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 04/46] UefiCpuPkg/MpInitLib: Add MP Initialize library class definition
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (2 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 03/46] UefiCpuPkg/CpuS3DataDxe: Move StartupVector allocation to EndOfDxe() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 05/46] UefiCpuPkg/MpInitLib: Add two instances PeiMpInitLib and DxeMpInitLib Jeff Fan
` (41 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
MP Initialize library provides basic functionalities to do APs initialization,
to manage MP information and to wakeup APs to execute AP task.
It could be consumed by CPU MP PEI or DXE drivers to provide CPU MP PPI/Protocol
services.
v4:
1. MpInitLibGetProcessorInfo():
Update HealthData type from UINT32 to EFI_HEALTH_FLAGS.
Add #include <Ppi/SecPlatformInformation.h>
2. MpInitLibSwitchBSP():
Return EFI_DEVICE_ERROR instead of EFI_SUCCESS if the calling processor is
an AP.
3. MpInitLibStartupThisAP():
Fix several incorrect references to "APs" to match PI spec.
4. MpInitLibSwitchBSP() and MpInitLibEnableDisableAP():
Fix incorrect description on ProcessorNumber.
5. Trim whitespace at end of line.
v3:
1. Add whitespace after MpInitLibInitialize
2. Rename MpInitLibSwitchBsp to MpInitLibSwitchBSP to match PI spec
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/Include/Library/MpInitLib.h | 353 +++++++++++++++++++++++++++++++++
UefiCpuPkg/UefiCpuPkg.dec | 4 +
2 files changed, 357 insertions(+)
create mode 100644 UefiCpuPkg/Include/Library/MpInitLib.h
diff --git a/UefiCpuPkg/Include/Library/MpInitLib.h b/UefiCpuPkg/Include/Library/MpInitLib.h
new file mode 100644
index 0000000..3e19382
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/MpInitLib.h
@@ -0,0 +1,353 @@
+/** @file
+ Multiple-Processor initialization Library.
+
+ Copyright (c) 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
+ 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.
+
+**/
+
+#ifndef __MP_INIT_LIB_H__
+#define __MP_INIT_LIB_H__
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Protocol/MpService.h>
+
+/**
+ MP Initialize Library initialization.
+
+ This service will allocate AP reset vector and wakeup all APs to do APs
+ initialization.
+
+ This service must be invoked before all other MP Initialize Library
+ service are invoked.
+
+ @retval EFI_SUCCESS MP initialization succeeds.
+ @retval Others MP initialization fails.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibInitialize (
+ VOID
+ );
+
+/**
+ Retrieves the number of logical processor in the platform and the number of
+ those logical processors that are enabled on this boot. This service may only
+ be called from the BSP.
+
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including the BSP
+ and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
+ processors that exist in system, including
+ the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
+ is NULL.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetNumberOfProcessors (
+ OUT UINTN *NumberOfProcessors, OPTIONAL
+ OUT UINTN *NumberOfEnabledProcessors OPTIONAL
+ );
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+ @param[out] HealthData Return processor health data.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetProcessorInfo (
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,
+ OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
+ );
+
+/**
+ This service executes a caller provided function on all enabled APs.
+
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroSeconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by MpInitLibStartupAllAPs() or
+ MPInitLibStartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
+ if all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+ The buffer is allocated by MP Initialization
+ library, and it's the caller's responsibility to
+ free the buffer with FreePool() service.
+ In blocking mode, it is ready for consumption
+ when the call returns. In non-blocking mode,
+ it is ready when WaitEvent is signaled. The
+ list of failed CPU is terminated by
+ END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
+ supported.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupAllAPs (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ );
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function.
+
+ @param[in] Procedure A pointer to the function to be run on the
+ designated AP of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ MpInitLibGetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until this AP finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on this AP,
+ and go on executing immediately. If this AP
+ return from Procedure or TimeoutInMicroSeconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ this AP to finish this Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ this AP returns from Procedure, then Procedure
+ on the AP is terminated. The
+ AP is available for next function assigned
+ by MpInitLibStartupAllAPs() or
+ MpInitLibStartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure on the
+ specified AP.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
+ supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibStartupThisAP (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ );
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ MpInitLibGetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibSwitchBSP (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ @param[in] ProcessorNumber The handle number of AP.
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ MpInitLibGetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibEnableDisableAP (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ @param[out] ProcessorNumber Pointer to the handle number of AP.
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ MpInitLibGetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibWhoAmI (
+ OUT UINTN *ProcessorNumber
+ );
+
+#endif
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index ef46318..8674533 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -50,6 +50,10 @@ [LibraryClasses.IA32, LibraryClasses.X64]
##
SmmCpuFeaturesLib|Include/Library/SmmCpuFeaturesLib.h
+ ## @libraryclass Provides functions to support MP services on CpuMpPei and CpuDxe module.
+ ##
+ MpInitLib|Include/Library/MpInitLib.h
+
[Guids]
gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 05/46] UefiCpuPkg/MpInitLib: Add two instances PeiMpInitLib and DxeMpInitLib
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (3 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 04/46] UefiCpuPkg/MpInitLib: Add MP Initialize library class definition Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 06/46] UefiCpuPkg/MpInitLib: Add AP assembly code and MP_CPU_EXCHANGE_INFO Jeff Fan
` (40 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Add two MP Initialize Library instances PeiMpInitLib.inf and DxeMpInitLib.inf
with NULL implementation.
One PeiMpInitLib.inf is consumed by PEI MP driver. Another DxeMpInitLib.inf is
consumed by DXE MP driver.
Place MpInitLibStartupAllAPs()/MpInitLibStartupThisAp()/MpInitLibSwitchBSP()/
MpInitLibEnableDisableAP() into PeiMpLib.c and DxeMpLib.c, because they have
the different implementations and will be updated in latter patches.
v4:
1. Return EFI_UNSUPPORTED instead of EFI_SUCCESS for NULL implementation of
all Functions.
2. Sync MpInitLibxxx functions header updating described in v4 part of Patch
#4.
v3:
1. Rename MpInitLibSwitchBsp to MpInitLibSwitchBSP to match PI spec
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 61 ++++++++++
.../Library/MpInitLib/DxeMpInitLib.uni | 12 +-
.../MpInitLib.h => Library/MpInitLib/DxeMpLib.c} | 123 +++------------------
UefiCpuPkg/Library/MpInitLib/MpLib.c | 119 ++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 40 +++++++
.../MpInitLib/PeiMpInitLib.inf} | 65 +++--------
.../Library/MpInitLib/PeiMpInitLib.uni | 12 +-
.../MpInitLib.h => Library/MpInitLib/PeiMpLib.c} | 123 ++++-----------------
UefiCpuPkg/UefiCpuPkg.dsc | 3 +-
9 files changed, 291 insertions(+), 267 deletions(-)
create mode 100644 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
copy MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni => UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni (60%)
copy UefiCpuPkg/{Include/Library/MpInitLib.h => Library/MpInitLib/DxeMpLib.c} (78%)
create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLib.c
create mode 100644 UefiCpuPkg/Library/MpInitLib/MpLib.h
copy UefiCpuPkg/{CpuMpPei/CpuMpPei.inf => Library/MpInitLib/PeiMpInitLib.inf} (54%)
copy MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni => UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni (60%)
copy UefiCpuPkg/{Include/Library/MpInitLib.h => Library/MpInitLib/PeiMpLib.c} (78%)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
new file mode 100644
index 0000000..1f131c0
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -0,0 +1,61 @@
+## @file
+# MP Initialize Library instance for DXE driver.
+#
+# Copyright (c) 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
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeMpInitLib
+ MODULE_UNI_FILE = DxeMpInitLib.uni
+ FILE_GUID = B88F7146-9834-4c55-BFAC-481CC0C33736
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.1
+ LIBRARY_CLASS = MpInitLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ DxeMpLib.c
+ MpLib.c
+ MpLib.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ LocalApicLib
+ MemoryAllocationLib
+ HobLib
+ MtrrLib
+ CpuLib
+ UefiCpuLib
+ UefiBootServicesTableLib
+ HobLib
+
+[Guids]
+ gEfiEventExitBootServicesGuid ## CONSUMES ## Event
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## SOMETIMES_CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
+
diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni
similarity index 60%
copy from MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni
copy to UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni
index 14b3a69..99d7997 100644
--- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.uni
@@ -1,5 +1,7 @@
// /** @file
-// SmmCommunicationBuffer Localized Strings and Content
+// MP Initialize Library instance for DXE driver.
+//
+// MP Initialize Library instance for DXE driver.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
@@ -13,6 +15,8 @@
//
// **/
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"SMM Communication Buffer DXE Driver"
+
+#string STR_MODULE_ABSTRACT #language en-US "MP Initialize Library instance for DXE driver."
+
+#string STR_MODULE_DESCRIPTION #language en-US "MP Initialize Library instance for DXE driver."
+
diff --git a/UefiCpuPkg/Include/Library/MpInitLib.h b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
similarity index 78%
copy from UefiCpuPkg/Include/Library/MpInitLib.h
copy to UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 3e19382..46a48a4 100644
--- a/UefiCpuPkg/Include/Library/MpInitLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -1,5 +1,5 @@
/** @file
- Multiple-Processor initialization Library.
+ MP initialize support functions for DXE phase.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -12,82 +12,7 @@
**/
-#ifndef __MP_INIT_LIB_H__
-#define __MP_INIT_LIB_H__
-
-#include <Ppi/SecPlatformInformation.h>
-#include <Protocol/MpService.h>
-
-/**
- MP Initialize Library initialization.
-
- This service will allocate AP reset vector and wakeup all APs to do APs
- initialization.
-
- This service must be invoked before all other MP Initialize Library
- service are invoked.
-
- @retval EFI_SUCCESS MP initialization succeeds.
- @retval Others MP initialization fails.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibInitialize (
- VOID
- );
-
-/**
- Retrieves the number of logical processor in the platform and the number of
- those logical processors that are enabled on this boot. This service may only
- be called from the BSP.
-
- @param[out] NumberOfProcessors Pointer to the total number of logical
- processors in the system, including the BSP
- and disabled APs.
- @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
- processors that exist in system, including
- the BSP.
-
- @retval EFI_SUCCESS The number of logical processors and enabled
- logical processors was retrieved.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
- is NULL.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibGetNumberOfProcessors (
- OUT UINTN *NumberOfProcessors, OPTIONAL
- OUT UINTN *NumberOfEnabledProcessors OPTIONAL
- );
-
-/**
- Gets detailed MP-related information on the requested processor at the
- instant this call is made. This service may only be called from the BSP.
-
- @param[in] ProcessorNumber The handle number of processor.
- @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
- the requested processor is deposited.
- @param[out] HealthData Return processor health data.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibGetProcessorInfo (
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,
- OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
- );
+#include "MpLib.h"
/**
This service executes a caller provided function on all enabled APs.
@@ -173,7 +98,10 @@ MpInitLibStartupAllAPs (
IN UINTN TimeoutInMicroseconds,
IN VOID *ProcedureArgument OPTIONAL,
OUT UINTN **FailedCpuList OPTIONAL
- );
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service lets the caller get one enabled AP to execute a caller-provided
@@ -255,7 +183,10 @@ MpInitLibStartupThisAP (
IN UINTN TimeoutInMicroseconds,
IN VOID *ProcedureArgument OPTIONAL,
OUT BOOLEAN *Finished OPTIONAL
- );
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service switches the requested AP to be the BSP from that point onward.
@@ -288,7 +219,10 @@ EFIAPI
MpInitLibSwitchBSP (
IN UINTN ProcessorNumber,
IN BOOLEAN EnableOldBSP
- );
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service lets the caller enable or disable an AP from this point onward.
@@ -326,28 +260,7 @@ MpInitLibEnableDisableAP (
IN UINTN ProcessorNumber,
IN BOOLEAN EnableAP,
IN UINT32 *HealthFlag OPTIONAL
- );
-
-/**
- This return the handle number for the calling processor. This service may be
- called from the BSP and APs.
-
- @param[out] ProcessorNumber Pointer to the handle number of AP.
- The range is from 0 to the total number of
- logical processors minus 1. The total number of
- logical processors can be retrieved by
- MpInitLibGetNumberOfProcessors().
-
- @retval EFI_SUCCESS The current processor handle number was returned
- in ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibWhoAmI (
- OUT UINTN *ProcessorNumber
- );
-
-#endif
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
new file mode 100644
index 0000000..12bd04e
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -0,0 +1,119 @@
+/** @file
+ CPU MP Initialize Library common functions.
+
+ Copyright (c) 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
+ 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 "MpLib.h"
+
+
+/**
+ MP Initialize Library initialization.
+
+ This service will allocate AP reset vector and wakeup all APs to do APs
+ initialization.
+
+ This service must be invoked before all other MP Initialize Library
+ service are invoked.
+
+ @retval EFI_SUCCESS MP initialization succeeds.
+ @retval Others MP initialization fails.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibInitialize (
+ VOID
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+ @param[out] HealthData Return processor health data.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetProcessorInfo (
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,
+ OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ @param[out] ProcessorNumber Pointer to the handle number of AP.
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ MpInitLibGetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibWhoAmI (
+ OUT UINTN *ProcessorNumber
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+/**
+ Retrieves the number of logical processor in the platform and the number of
+ those logical processors that are enabled on this boot. This service may only
+ be called from the BSP.
+
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including the BSP
+ and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
+ processors that exist in system, including
+ the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
+ is NULL.
+ @retval EFI_NOT_READY MP Initialize Library is not initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+MpInitLibGetNumberOfProcessors (
+ OUT UINTN *NumberOfProcessors, OPTIONAL
+ OUT UINTN *NumberOfEnabledProcessors OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
new file mode 100644
index 0000000..66425d3
--- /dev/null
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -0,0 +1,40 @@
+/** @file
+ Common header file for MP Initialize Library.
+
+ Copyright (c) 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
+ 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.
+
+**/
+
+#ifndef _MP_LIB_H_
+#define _MP_LIB_H_
+
+#include <PiPei.h>
+
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <Register/LocalApic.h>
+#include <Register/Microcode.h>
+
+#include <Library/MpInitLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/CpuLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/HobLib.h>
+
+
+#endif
+
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
similarity index 54%
copy from UefiCpuPkg/CpuMpPei/CpuMpPei.inf
copy to UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 5f45662..014a248 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -1,7 +1,7 @@
## @file
-# CPU driver installs CPU PI Multi-processor PPI.
+# MP Initialize Library instance for PEI driver.
#
-# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 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
@@ -14,12 +14,12 @@
[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = CpuMpPei
- MODULE_UNI_FILE = CpuMpPei.uni
- FILE_GUID = EDADEB9D-DDBA-48BD-9D22-C1C169C8C5C6
+ BASE_NAME = PeiMpInitLib
+ MODULE_UNI_FILE = PeiMpInitLib.uni
+ FILE_GUID = B00F6090-7739-4830-B906-E0032D388987
MODULE_TYPE = PEIM
- VERSION_STRING = 1.0
- ENTRY_POINT = CpuMpPeimInit
+ VERSION_STRING = 1.1
+ LIBRARY_CLASS = MpInitLib|PEIM
#
# The following information is for reference only and not required by the build tools.
@@ -27,55 +27,28 @@ [Defines]
# VALID_ARCHITECTURES = IA32 X64
#
-[Sources]
- CpuMpPei.h
- CpuMpPei.c
- CpuBist.c
- Microcode.h
- Microcode.c
- PeiMpServices.h
- PeiMpServices.c
-
-[Sources.IA32]
- Ia32/MpEqu.inc
- Ia32/MpFuncs.asm
- Ia32/MpFuncs.nasm
-
-[Sources.X64]
- X64/MpEqu.inc
- X64/MpFuncs.asm
- X64/MpFuncs.nasm
+[Sources.common]
+ PeiMpLib.c
+ MpLib.c
+ MpLib.h
[Packages]
MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
BaseLib
- BaseMemoryLib
- DebugLib
- HobLib
LocalApicLib
- MtrrLib
- PcdLib
- PeimEntryPoint
+ MemoryAllocationLib
+ HobLib
PeiServicesLib
- ReportStatusCodeLib
- SynchronizationLib
- TimerLib
- UefiCpuLib
+ MtrrLib
CpuLib
- CpuExceptionHandlerLib
+ UefiCpuLib
+ SynchronizationLib
[Ppis]
- gEfiPeiMpServicesPpiGuid ## PRODUCES
gEfiEndOfPeiSignalPpiGuid ## NOTIFY
- gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
- ## SOMETIMES_CONSUMES
- ## SOMETIMES_PRODUCES
- gEfiSecPlatformInformation2PpiGuid
- gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
@@ -86,9 +59,3 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
-[Depex]
- gEfiPeiMemoryDiscoveredPpiGuid
-
-[UserExtensions.TianoCore."ExtraFiles"]
- CpuMpPeiExtra.uni
-
diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni
similarity index 60%
copy from MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni
copy to UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni
index 14b3a69..d16f306 100644
--- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferExtraDxe.uni
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.uni
@@ -1,5 +1,7 @@
// /** @file
-// SmmCommunicationBuffer Localized Strings and Content
+// MP Initialize Library instance for PEI driver.
+//
+// MP Initialize Library instance for PEI driver.
//
// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
//
@@ -13,6 +15,8 @@
//
// **/
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"SMM Communication Buffer DXE Driver"
+
+#string STR_MODULE_ABSTRACT #language en-US "MP Initialize Library instance for PEI driver."
+
+#string STR_MODULE_DESCRIPTION #language en-US "MP Initialize Library instance for PEI driver."
+
diff --git a/UefiCpuPkg/Include/Library/MpInitLib.h b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
similarity index 78%
copy from UefiCpuPkg/Include/Library/MpInitLib.h
copy to UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 3e19382..a7e9fb8 100644
--- a/UefiCpuPkg/Include/Library/MpInitLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -1,5 +1,5 @@
/** @file
- Multiple-Processor initialization Library.
+ MP initialize support functions for PEI phase.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -12,82 +12,7 @@
**/
-#ifndef __MP_INIT_LIB_H__
-#define __MP_INIT_LIB_H__
-
-#include <Ppi/SecPlatformInformation.h>
-#include <Protocol/MpService.h>
-
-/**
- MP Initialize Library initialization.
-
- This service will allocate AP reset vector and wakeup all APs to do APs
- initialization.
-
- This service must be invoked before all other MP Initialize Library
- service are invoked.
-
- @retval EFI_SUCCESS MP initialization succeeds.
- @retval Others MP initialization fails.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibInitialize (
- VOID
- );
-
-/**
- Retrieves the number of logical processor in the platform and the number of
- those logical processors that are enabled on this boot. This service may only
- be called from the BSP.
-
- @param[out] NumberOfProcessors Pointer to the total number of logical
- processors in the system, including the BSP
- and disabled APs.
- @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
- processors that exist in system, including
- the BSP.
-
- @retval EFI_SUCCESS The number of logical processors and enabled
- logical processors was retrieved.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
- is NULL.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibGetNumberOfProcessors (
- OUT UINTN *NumberOfProcessors, OPTIONAL
- OUT UINTN *NumberOfEnabledProcessors OPTIONAL
- );
-
-/**
- Gets detailed MP-related information on the requested processor at the
- instant this call is made. This service may only be called from the BSP.
-
- @param[in] ProcessorNumber The handle number of processor.
- @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
- the requested processor is deposited.
- @param[out] HealthData Return processor health data.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibGetProcessorInfo (
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,
- OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
- );
+#include "MpLib.h"
/**
This service executes a caller provided function on all enabled APs.
@@ -173,7 +98,10 @@ MpInitLibStartupAllAPs (
IN UINTN TimeoutInMicroseconds,
IN VOID *ProcedureArgument OPTIONAL,
OUT UINTN **FailedCpuList OPTIONAL
- );
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service lets the caller get one enabled AP to execute a caller-provided
@@ -255,7 +183,10 @@ MpInitLibStartupThisAP (
IN UINTN TimeoutInMicroseconds,
IN VOID *ProcedureArgument OPTIONAL,
OUT BOOLEAN *Finished OPTIONAL
- );
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service switches the requested AP to be the BSP from that point onward.
@@ -287,8 +218,11 @@ EFI_STATUS
EFIAPI
MpInitLibSwitchBSP (
IN UINTN ProcessorNumber,
- IN BOOLEAN EnableOldBSP
- );
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ return EFI_UNSUPPORTED;
+}
/**
This service lets the caller enable or disable an AP from this point onward.
@@ -326,28 +260,9 @@ MpInitLibEnableDisableAP (
IN UINTN ProcessorNumber,
IN BOOLEAN EnableAP,
IN UINT32 *HealthFlag OPTIONAL
- );
-
-/**
- This return the handle number for the calling processor. This service may be
- called from the BSP and APs.
+ )
+{
+ return EFI_UNSUPPORTED;
+}
- @param[out] ProcessorNumber Pointer to the handle number of AP.
- The range is from 0 to the total number of
- logical processors minus 1. The total number of
- logical processors can be retrieved by
- MpInitLibGetNumberOfProcessors().
-
- @retval EFI_SUCCESS The current processor handle number was returned
- in ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
- @retval EFI_NOT_READY MP Initialize Library is not initialized.
-
-**/
-EFI_STATUS
-EFIAPI
-MpInitLibWhoAmI (
- OUT UINTN *ProcessorNumber
- );
-#endif
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index b35f41b..598c797 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -114,7 +114,8 @@ [Components.IA32, Components.X64]
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
- UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+ UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 06/46] UefiCpuPkg/MpInitLib: Add AP assembly code and MP_CPU_EXCHANGE_INFO
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (4 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 05/46] UefiCpuPkg/MpInitLib: Add two instances PeiMpInitLib and DxeMpInitLib Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 07/46] UefiCpuPkg/MpInitLib: Fix typo and clean up the code Jeff Fan
` (39 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Add assembly code for AP reset vector and the definition of MP_CPU_EXCHANGE_INFO
that are used to exchange the data between C code and assembly code when AP wake
up.
v4:
1. Copy MP_CPU_EXCHANGE_INFO from UefiCpuPkg/CpuMpPei/CpuMpPei.h
2. Copy MpEqu.inc and MpFuncs.nasm from UefiCpuPkg/CpuMpPei.
v3:
1. Rename NumApsExecutingLoction to NumApsExecutingLocation
2. Add whitespace after ; in .nasm file
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 8 ++++++++
.../{CpuMpPei => Library/MpInitLib}/Ia32/MpEqu.inc | 0
.../MpInitLib}/Ia32/MpFuncs.nasm | 0
UefiCpuPkg/Library/MpInitLib/MpLib.h | 24 ++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 8 ++++++++
.../{CpuMpPei => Library/MpInitLib}/X64/MpEqu.inc | 0
.../MpInitLib}/X64/MpFuncs.nasm | 0
7 files changed, 40 insertions(+)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Ia32/MpEqu.inc (100%)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Ia32/MpFuncs.nasm (100%)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/X64/MpEqu.inc (100%)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/X64/MpFuncs.nasm (100%)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 1f131c0..e9a2725 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -27,6 +27,14 @@ [Defines]
# VALID_ARCHITECTURES = IA32 X64
#
+[Sources.IA32]
+ Ia32/MpEqu.inc
+ Ia32/MpFuncs.nasm
+
+[Sources.X64]
+ X64/MpEqu.inc
+ X64/MpFuncs.nasm
+
[Sources.common]
DxeMpLib.c
MpLib.c
diff --git a/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
similarity index 100%
copy from UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
copy to UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
diff --git a/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
similarity index 100%
copy from UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
copy to UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 66425d3..0453c22 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -36,5 +36,29 @@
#include <Library/HobLib.h>
+#pragma pack(1)
+
+//
+// MP CPU exchange information for AP reset code
+// This structure is required to be packed because fixed field offsets
+// into this structure are used in assembly code in this module
+//
+typedef struct {
+ UINTN Lock;
+ UINTN StackStart;
+ UINTN StackSize;
+ UINTN CFunction;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ UINTN BufferStart;
+ UINTN ModeOffset;
+ UINTN NumApsExecuting;
+ UINTN CodeSegment;
+ UINTN DataSegment;
+ UINTN Cr3;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+} MP_CPU_EXCHANGE_INFO;
+
+#pragma pack()
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 014a248..c195a38 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -27,6 +27,14 @@ [Defines]
# VALID_ARCHITECTURES = IA32 X64
#
+[Sources.IA32]
+ Ia32/MpEqu.inc
+ Ia32/MpFuncs.nasm
+
+[Sources.X64]
+ X64/MpEqu.inc
+ X64/MpFuncs.nasm
+
[Sources.common]
PeiMpLib.c
MpLib.c
diff --git a/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
similarity index 100%
copy from UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
copy to UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
diff --git a/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
similarity index 100%
copy from UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
copy to UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 07/46] UefiCpuPkg/MpInitLib: Fix typo and clean up the code
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (5 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 06/46] UefiCpuPkg/MpInitLib: Add AP assembly code and MP_CPU_EXCHANGE_INFO Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 08/46] UefiCpuPkg/MpInitLib: Add EnableExecuteDisable in MP_CPU_EXCHANGE_INFO Jeff Fan
` (38 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
1. Rename NumApsExecutingLoction to NumApsExecutingLocation
2. Update some comments in NASM files.
3. Remove PeiCpuMpData from MP_CPU_EXCHANGE_INFO.
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>
---
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 10 +++++-----
UefiCpuPkg/Library/MpInitLib/MpLib.h | 1 -
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 2 +-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 14 +++++++-------
5 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
index 773eab3..015396a 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
@@ -33,7 +33,7 @@ GdtrLocation equ LockLocation + 10h
IdtrLocation equ LockLocation + 16h
BufferStartLocation equ LockLocation + 1Ch
ModeOffsetLocation equ LockLocation + 20h
-NumApsExecutingLoction equ LockLocation + 24h
+NumApsExecutingLocation equ LockLocation + 24h
CodeSegmentLocation equ LockLocation + 28h
DataSegmentLocation equ LockLocation + 2Ch
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 0852a5b..7050413 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -71,8 +71,8 @@ o32 lidt [cs:si]
xor ax, ax
mov ds, ax
- mov eax, cr0 ;Get control register 0
- or eax, 000000003h ;Set PE bit (bit #0) & MP
+ mov eax, cr0 ; Get control register 0
+ or eax, 000000003h ; Set PE bit (bit #0) & MP
mov cr0, eax
jmp 0:strict dword 0 ; far jump to protected mode
@@ -95,7 +95,7 @@ TestLock:
jz TestLock
mov edi, esi
- add edi, NumApsExecutingLoction
+ add edi, NumApsExecutingLocation
inc dword [edi]
mov ebx, [edi]
@@ -133,9 +133,9 @@ CProcedureInvoke:
add edi, ApProcedureLocation
mov eax, [edi]
- call eax ; invoke C function
+ call eax ; Invoke C function
- jmp $ ; never reach here
+ jmp $ ; Never reach here
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 0453c22..92d1dd9 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -56,7 +56,6 @@ typedef struct {
UINTN CodeSegment;
UINTN DataSegment;
UINTN Cr3;
- PEI_CPU_MP_DATA *PeiCpuMpData;
} MP_CPU_EXCHANGE_INFO;
#pragma pack()
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
index 00f57ce..5aac212 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
@@ -33,7 +33,7 @@ GdtrLocation equ LockLocation + 20h
IdtrLocation equ LockLocation + 2Ah
BufferStartLocation equ LockLocation + 34h
ModeOffsetLocation equ LockLocation + 3Ch
-NumApsExecutingLoction equ LockLocation + 44h
+NumApsExecutingLocation equ LockLocation + 44h
CodeSegmentLocation equ LockLocation + 4Ch
DataSegmentLocation equ LockLocation + 54h
Cr3Location equ LockLocation + 5Ch
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index f19c75f..848992c 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -57,7 +57,7 @@ BITS 16
mov di, CodeSegmentLocation
mov edx, [di]
mov di, ax
- sub di, 02h
+ sub di, 02h
mov [di],dx ; Patch long mode CS
sub di, 04h
add eax, ebx
@@ -117,7 +117,7 @@ TestLock:
jz TestLock
mov edi, esi
- add edi, NumApsExecutingLoction
+ add edi, NumApsExecutingLocation
inc dword [edi]
mov ebx, [edi]
@@ -138,8 +138,8 @@ Releaselock:
xchg qword [edi], rax
CProcedureInvoke:
- push rbp ; push BIST data at top of AP stack
- xor rbp, rbp ; clear ebp for call stack trace
+ push rbp ; Push BIST data at top of AP stack
+ xor rbp, rbp ; Clear ebp for call stack trace
push rbp
mov rbp, rsp
@@ -157,9 +157,9 @@ CProcedureInvoke:
mov rax, qword [edi]
sub rsp, 20h
- call rax ; invoke C function
+ call rax ; Invoke C function
add rsp, 20h
- jmp $
+ jmp $ ; Should never reach here
RendezvousFunnelProcEnd:
@@ -176,7 +176,7 @@ ASM_PFX(AsmGetAddressMap):
;-------------------------------------------------------------------------------------
;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
-;about to become an AP. It switches it'stack with the current AP.
+;about to become an AP. It switches its stack with the current AP.
;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmExchangeRole)
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 08/46] UefiCpuPkg/MpInitLib: Add EnableExecuteDisable in MP_CPU_EXCHANGE_INFO
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (6 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 07/46] UefiCpuPkg/MpInitLib: Fix typo and clean up the code Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 09/46] UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code Jeff Fan
` (37 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
EnableExecuteDisable in MP_CPU_EXCHANGE_INFO is used to tell AP reset vector if
enable execute disable feature on APs. This feature should be enabled before CR3
is written.
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>
---
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 ++
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 30 ++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 1 +
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +++-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 13 +++++++++++
5 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
index 015396a..60add86 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
@@ -36,4 +36,6 @@ ModeOffsetLocation equ LockLocation + 20h
NumApsExecutingLocation equ LockLocation + 24h
CodeSegmentLocation equ LockLocation + 28h
DataSegmentLocation equ LockLocation + 2Ch
+EnableExecuteDisableLocation equ LockLocation + 30h
+Cr3Location equ LockLocation + 3Ch
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 7050413..8bacb42 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -85,6 +85,36 @@ Flat32Start: ; protected mode entry point
mov ss, dx
mov esi, ebx
+
+ mov edi, esi
+ add edi, EnableExecuteDisableLocation
+ cmp byte [edi], 0
+ jz SkipEnableExecuteDisable
+
+ ;
+ ; Enable IA32 PAE execute disable
+ ;
+
+ mov ecx, 0xc0000080
+ rdmsr
+ bts eax, 11
+ wrmsr
+
+ mov edi, esi
+ add edi, Cr3Location
+ mov eax, dword [edi]
+ mov cr3, eax
+
+ mov eax, cr4
+ bts eax, 5
+ mov cr4, eax
+
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax
+
+SkipEnableExecuteDisable:
+
mov edi, esi
add edi, LockLocation
mov eax, NotVacantFlag
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 92d1dd9..28a3cd4 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -55,6 +55,7 @@ typedef struct {
UINTN NumApsExecuting;
UINTN CodeSegment;
UINTN DataSegment;
+ UINTN EnableExecuteDisable;
UINTN Cr3;
} MP_CPU_EXCHANGE_INFO;
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
index 5aac212..d533741 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
@@ -36,6 +36,8 @@ ModeOffsetLocation equ LockLocation + 3Ch
NumApsExecutingLocation equ LockLocation + 44h
CodeSegmentLocation equ LockLocation + 4Ch
DataSegmentLocation equ LockLocation + 54h
-Cr3Location equ LockLocation + 5Ch
+EnableExecuteDisableLocation equ LockLocation + 5Ch
+Cr3Location equ LockLocation + 64h
+
;-------------------------------------------------------------------------------
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 848992c..3c55ffa 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -69,6 +69,19 @@ o32 lgdt [cs:si]
mov si, IdtrLocation
o32 lidt [cs:si]
+ mov si, EnableExecuteDisableLocation
+ cmp byte [si], 0
+ jz SkipEnableExecuteDisableBit
+
+ ;
+ ; Enable execute disable bit
+ ;
+ mov ecx, 0c0000080h ; EFER MSR number
+ rdmsr ; Read EFER
+ bts eax, 11 ; Enable Execute Disable Bit
+ wrmsr ; Write EFER
+
+SkipEnableExecuteDisableBit:
mov di, DataSegmentLocation
mov edi, [di] ; Save long mode DS in edi
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 09/46] UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (7 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 08/46] UefiCpuPkg/MpInitLib: Add EnableExecuteDisable in MP_CPU_EXCHANGE_INFO Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 10/46] UefiCpuPkg/MpInitLib: Add MP_ASSEMBLY_ADDRESS_MAP Jeff Fan
` (36 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
AsmRelocateApLoop() is used to place APs into MWAIT-loop if MonitorMwait
feature is supported before hand-off to OS, or place APs into HLT-loop if
MonitorMwait feature is not supported.
If the current mode is long mode, we will switch APs to protected mode
before placing APs in MWAIT-loop or HLT-loop. Thus, once APs wakeup from
loop, APs needn't the page table that may be crashed by OS.
v3:
1. Rename AsmRellocateApLoop to AsmRelocateApLoop.
2. Fix typo Proteced to Protected.
3. Fix typo segement to segment
4. Use word MONITOR instead of mwait-monitor.
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 24 ++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 21 ++++++++++
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 54 ++++++++++++++++++++++++++
3 files changed, 99 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 8bacb42..49f5503 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -169,6 +169,30 @@ CProcedureInvoke:
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmRelocateApLoop)
+ASM_PFX(AsmRelocateApLoop):
+AsmRelocateApLoopStart:
+ cmp byte [esp + 4], 1
+ jnz HltLoop
+MwaitLoop:
+ mov eax, esp
+ xor ecx, ecx
+ xor edx, edx
+ monitor
+ mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4]
+ shl eax, 4
+ mwait
+ jmp MwaitLoop
+HltLoop:
+ cli
+ hlt
+ jmp HltLoop
+ ret
+AsmRelocateApLoopEnd:
+
+;-------------------------------------------------------------------------------------
; AsmGetAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmGetAddressMap)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 28a3cd4..39ec5de 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -60,5 +60,26 @@ typedef struct {
} MP_CPU_EXCHANGE_INFO;
#pragma pack()
+/**
+ Assembly code to place AP into safe loop mode.
+
+ Place AP into targeted C-State if MONITOR is supported, otherwise
+ place AP into hlt state.
+ Place AP in protected mode if the current is long mode. Due to AP maybe
+ wakeup by some hardware event. It could avoid accessing page table that
+ may not available during booting to OS.
+
+ @param[in] MwaitSupport TRUE indicates MONITOR is supported.
+ FALSE indicates MONITOR is not supported.
+ @param[in] ApTargetCState Target C-State value.
+ @param[in] PmCodeSegment Protected mode code segment value.
+**/
+typedef
+VOID
+(EFIAPI * ASM_RELOCATE_AP_LOOP) (
+ IN BOOLEAN MwaitSupport,
+ IN UINTN ApTargetCState,
+ IN UINTN PmCodeSegment
+ );
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 3c55ffa..d5d7efe 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -177,6 +177,60 @@ CProcedureInvoke:
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmRelocateApLoop)
+ASM_PFX(AsmRelocateApLoop):
+AsmRelocateApLoopStart:
+ push rcx
+ push rdx
+
+ lea rsi, [PmEntry] ; rsi <- The start address of transition code
+
+ push r8
+ push rsi
+ DB 0x48
+ retf
+BITS 32
+PmEntry:
+ mov eax, cr0
+ btr eax, 31 ; Clear CR0.PG
+ mov cr0, eax ; Disable paging and caches
+
+ mov ebx, edx ; Save EntryPoint to rbx, for rdmsr will overwrite rdx
+ mov ecx, 0xc0000080
+ rdmsr
+ and ah, ~ 1 ; Clear LME
+ wrmsr
+ mov eax, cr4
+ and al, ~ (1 << 5) ; Clear PAE
+ mov cr4, eax
+
+ pop edx
+ add esp, 4
+ pop ecx,
+ add esp, 4
+ cmp cl, 1 ; Check mwait-monitor support
+ jnz HltLoop
+ mov ebx, edx ; Save C-State to ebx
+MwaitLoop:
+ mov eax, esp ; Set Monitor Address
+ xor ecx, ecx ; ecx = 0
+ xor edx, edx ; edx = 0
+ monitor
+ shl ebx, 4
+ mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]
+ mwait
+ jmp MwaitLoop
+HltLoop:
+ cli
+ hlt
+ jmp HltLoop
+ ret
+BITS 64
+AsmRelocateApLoopEnd:
+
+;-------------------------------------------------------------------------------------
; AsmGetAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmGetAddressMap)
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 10/46] UefiCpuPkg/MpInitLib: Add MP_ASSEMBLY_ADDRESS_MAP
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (8 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 09/46] UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 11/46] UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size Jeff Fan
` (35 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
In MpInitLibInitialize(), invoke AsmGetAddress() to get get assembly functions'
entry addresses and the sizes from returned MP_ASSEMBLY_ADDRESS_MAP structure.
v4:
1. Add AsmRelocateApLoop information return in AsmGetAddress().
v3:
1. Rename AsmRellocateApLoop to AsmRelocateApLoop.
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>
---
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 2 ++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 7 ++++++-
UefiCpuPkg/Library/MpInitLib/MpLib.h | 23 +++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 3 +++
4 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 49f5503..8f6f0bf 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -204,6 +204,8 @@ ASM_PFX(AsmGetAddressMap):
mov dword [ebx], RendezvousFunnelProcStart
mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+ mov dword [ebx + 0Ch], AsmRelocateApLoopStart
+ mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
popad
ret
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 12bd04e..3ac79b6 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -34,7 +34,12 @@ MpInitLibInitialize (
VOID
)
{
- return EFI_UNSUPPORTED;
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINTN ApResetVectorSize;
+
+ AsmGetAddressMap (&AddressMap);
+ ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ return EFI_SUCCESS;
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 39ec5de..eeb8d84 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -35,6 +35,16 @@
#include <Library/MtrrLib.h>
#include <Library/HobLib.h>
+//
+// AP reset code information
+//
+typedef struct {
+ UINT8 *RendezvousFunnelAddress;
+ UINTN ModeEntryOffset;
+ UINTN RendezvousFunnelSize;
+ UINT8 *RelocateApLoopFuncAddress;
+ UINTN RelocateApLoopFuncSize;
+} MP_ASSEMBLY_ADDRESS_MAP;
#pragma pack(1)
@@ -81,5 +91,18 @@ VOID
IN UINTN ApTargetCState,
IN UINTN PmCodeSegment
);
+
+/**
+ Assembly code to get starting address and size of the rendezvous entry for APs.
+ Information for fixing a jump instruction in the code is also returned.
+
+ @param[out] AddressMap Output buffer for address map information.
+**/
+VOID
+EFIAPI
+AsmGetAddressMap (
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
+ );
+
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index d5d7efe..090e9fa 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -239,6 +239,9 @@ ASM_PFX(AsmGetAddressMap):
mov qword [rcx], rax
mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
+ mov rax, ASM_PFX(AsmRelocateApLoop)
+ mov qword [rcx + 18h], rax
+ mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
ret
;-------------------------------------------------------------------------------------
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 11/46] UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (9 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 10/46] UefiCpuPkg/MpInitLib: Add MP_ASSEMBLY_ADDRESS_MAP Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 12/46] UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer Jeff Fan
` (34 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Firstly, get ApLoopMode from PcdCpuApLoopMode. If MonitorMwait feature is not
supported, update ApLoopMode to ApHltLoop. If MonitorMwait feature is supported,
get MointorFilter size by CPUID.[EAX=05H]:EBX.BIT0-15.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 63 ++++++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 6 ++++
2 files changed, 69 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 3ac79b6..32bbaee 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -16,6 +16,65 @@
/**
+ Detect whether Mwait-monitor feature is supported.
+
+ @retval TRUE Mwait-monitor feature is supported.
+ @retval FALSE Mwait-monitor feature is not supported.
+**/
+BOOLEAN
+IsMwaitSupport (
+ VOID
+ )
+{
+ CPUID_VERSION_INFO_ECX VersionInfoEcx;
+
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);
+ return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE;
+}
+
+/**
+ Get AP loop mode.
+
+ @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.
+
+ @return The AP loop mode.
+**/
+UINT8
+GetApLoopMode (
+ OUT UINT32 *MonitorFilterSize
+ )
+{
+ UINT8 ApLoopMode;
+ CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx;
+
+ ASSERT (MonitorFilterSize != NULL);
+
+ ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+ ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);
+ if (ApLoopMode == ApInMwaitLoop) {
+ if (!IsMwaitSupport ()) {
+ //
+ // If processor does not support MONITOR/MWAIT feature,
+ // force AP in Hlt-loop mode
+ //
+ ApLoopMode = ApInHltLoop;
+ }
+ }
+
+ if (ApLoopMode != ApInMwaitLoop) {
+ *MonitorFilterSize = sizeof (UINT32);
+ } else {
+ //
+ // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes
+ // CPUID.[EAX=05H].EDX: C-states supported using MWAIT
+ //
+ AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &MonitorMwaitEbx.Uint32, NULL, NULL);
+ *MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize;
+ }
+
+ return ApLoopMode;
+}
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
@@ -35,10 +94,14 @@ MpInitLibInitialize (
)
{
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINT32 MonitorFilterSize;
+ UINT8 ApLoopMode;
UINTN ApResetVectorSize;
AsmGetAddressMap (&AddressMap);
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ ApLoopMode = GetApLoopMode (&MonitorFilterSize);
+
return EFI_SUCCESS;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index eeb8d84..c6dd0b5 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -35,6 +35,12 @@
#include <Library/MtrrLib.h>
#include <Library/HobLib.h>
+typedef enum {
+ ApInHltLoop = 1,
+ ApInMwaitLoop = 2,
+ ApInRunLoop = 3
+} AP_LOOP_MODE;
+
//
// AP reset code information
//
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 12/46] UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (10 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 11/46] UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 13/46] UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs Jeff Fan
` (33 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 49 +++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 77 ++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 32bbaee..f05db7c 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -93,15 +93,64 @@ MpInitLibInitialize (
VOID
)
{
+ UINT32 MaxLogicalProcessorNumber;
+ UINT32 ApStackSize;
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINTN BufferSize;
UINT32 MonitorFilterSize;
+ VOID *MpBuffer;
+ UINTN Buffer;
+ CPU_MP_DATA *CpuMpData;
UINT8 ApLoopMode;
+ UINT8 *MonitorBuffer;
UINTN ApResetVectorSize;
+ UINTN BackupBufferAddr;
+ MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
AsmGetAddressMap (&AddressMap);
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ ApStackSize = PcdGet32(PcdCpuApStackSize);
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
+ BufferSize = ApStackSize * MaxLogicalProcessorNumber;
+ BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;
+ BufferSize += sizeof (CPU_MP_DATA);
+ BufferSize += ApResetVectorSize;
+ BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;
+ MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+ ASSERT (MpBuffer != NULL);
+ ZeroMem (MpBuffer, BufferSize);
+ Buffer = (UINTN) MpBuffer;
+
+ MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber);
+ BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;
+ CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize);
+ CpuMpData->Buffer = Buffer;
+ CpuMpData->CpuApStackSize = ApStackSize;
+ CpuMpData->BackupBuffer = BackupBufferAddr;
+ CpuMpData->BackupBufferSize = ApResetVectorSize;
+ CpuMpData->EndOfPeiFlag = FALSE;
+ CpuMpData->WakeupBuffer = (UINTN) -1;
+ CpuMpData->CpuCount = 1;
+ CpuMpData->BspNumber = 0;
+ CpuMpData->WaitEvent = NULL;
+ CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);
+ CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
+ InitializeSpinLock(&CpuMpData->MpLock);
+ //
+ // Save assembly code information
+ //
+ CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));
+ //
+ // Finally set AP loop mode
+ //
+ CpuMpData->ApLoopMode = ApLoopMode;
+ DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));
+ //
+ // Store BSP's MTRR setting
+ //
+ MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
+
return EFI_SUCCESS;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index c6dd0b5..955de96 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -41,6 +41,38 @@ typedef enum {
ApInRunLoop = 3
} AP_LOOP_MODE;
+typedef enum {
+ ApInitConfig = 1,
+ ApInitReconfig = 2,
+ ApInitDone = 3
+} AP_INIT_STATE;
+
+typedef struct {
+ SPIN_LOCK ApLock;
+ volatile UINT32 *StartupApSignal;
+ volatile UINTN ApFunction;
+ volatile UINTN ApFunctionArgument;
+ UINT32 InitialApicId;
+ UINT32 ApicId;
+ UINT32 Health;
+ BOOLEAN CpuHealthy;
+ BOOLEAN Waiting;
+ BOOLEAN *Finished;
+ UINT64 ExpectedTime;
+ UINT64 CurrentTime;
+ UINT64 TotalTime;
+ EFI_EVENT WaitEvent;
+} CPU_AP_DATA;
+
+//
+// Basic CPU information saved in Guided HOB
+//
+typedef struct {
+ UINT32 InitialApicId;
+ UINT32 ApicId;
+ UINT32 Health;
+} CPU_INFO_IN_HOB;
+
//
// AP reset code information
//
@@ -52,6 +84,8 @@ typedef struct {
UINTN RelocateApLoopFuncSize;
} MP_ASSEMBLY_ADDRESS_MAP;
+typedef struct _CPU_MP_DATA CPU_MP_DATA;
+
#pragma pack(1)
//
@@ -73,9 +107,52 @@ typedef struct {
UINTN DataSegment;
UINTN EnableExecuteDisable;
UINTN Cr3;
+ CPU_MP_DATA *CpuMpData;
} MP_CPU_EXCHANGE_INFO;
#pragma pack()
+
+//
+// CPU MP Data save in memory
+//
+struct _CPU_MP_DATA {
+ UINT64 CpuInfoInHob;
+ UINT32 CpuCount;
+ UINT32 BspNumber;
+ //
+ // The above fields data will be passed from PEI to DXE
+ //
+ SPIN_LOCK MpLock;
+ UINTN Buffer;
+ UINTN CpuApStackSize;
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;
+ UINTN WakeupBuffer;
+ UINTN BackupBuffer;
+ UINTN BackupBufferSize;
+ BOOLEAN EndOfPeiFlag;
+
+ volatile UINT32 StartCount;
+ volatile UINT32 FinishedCount;
+ volatile UINT32 RunningCount;
+ BOOLEAN SingleThread;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcArguments;
+ BOOLEAN *Finished;
+ UINT64 ExpectedTime;
+ UINT64 CurrentTime;
+ UINT64 TotalTime;
+ EFI_EVENT WaitEvent;
+ UINTN **FailedCpuList;
+
+ AP_INIT_STATE InitFlag;
+ BOOLEAN X2ApicEnable;
+ MTRR_SETTINGS MtrrTable;
+ UINT8 ApLoopMode;
+ UINT8 ApTargetCState;
+ UINT16 PmCodeSegment;
+ CPU_AP_DATA *CpuData;
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
+};
/**
Assembly code to place AP into safe loop mode.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 13/46] UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (11 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 12/46] UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 14/46] UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions Jeff Fan
` (32 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Initialize CPU_AP_DATA for CPU APs and add GetApState()/SetApState() helper
functions to get/set AP state.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 76 ++++++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 12 ++++++
2 files changed, 88 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index f05db7c..70e5eb1 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -14,6 +14,37 @@
#include "MpLib.h"
+/**
+ Get the Application Processors state.
+
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP
+
+ @return The AP status
+**/
+CPU_STATE
+GetApState (
+ IN CPU_AP_DATA *CpuData
+ )
+{
+ return CpuData->State;
+}
+
+/**
+ Set the Application Processors state.
+
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP
+ @param[in] State The AP status
+**/
+VOID
+SetApState (
+ IN CPU_AP_DATA *CpuData,
+ IN CPU_STATE State
+ )
+{
+ AcquireSpinLock (&CpuData->ApLock);
+ CpuData->State = State;
+ ReleaseSpinLock (&CpuData->ApLock);
+}
/**
Detect whether Mwait-monitor feature is supported.
@@ -74,6 +105,40 @@ GetApLoopMode (
return ApLoopMode;
}
+/*
+ Initialize CPU AP Data when AP is wakeup at the first time.
+
+ @param[in, out] CpuMpData Pointer to PEI CPU MP Data
+ @param[in] ProcessorNumber The handle number of processor
+ @param[in] BistData Processor BIST data
+
+**/
+VOID
+InitializeApData (
+ IN OUT CPU_MP_DATA *CpuMpData,
+ IN UINTN ProcessorNumber,
+ IN UINT32 BistData
+ )
+{
+ CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
+ CpuMpData->CpuData[ProcessorNumber].Health = BistData;
+ CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;
+ CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
+ CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ if (CpuMpData->CpuData[ProcessorNumber].InitialApicId >= 0xFF) {
+ //
+ // Set x2APIC mode if there are any logical processor reporting
+ // an Initial APIC ID of 255 or greater.
+ //
+ AcquireSpinLock(&CpuMpData->MpLock);
+ CpuMpData->X2ApicEnable = TRUE;
+ ReleaseSpinLock(&CpuMpData->MpLock);
+ }
+
+ InitializeSpinLock(&CpuMpData->CpuData[ProcessorNumber].ApLock);
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
+}
+
/**
MP Initialize Library initialization.
@@ -103,6 +168,7 @@ MpInitLibInitialize (
CPU_MP_DATA *CpuMpData;
UINT8 ApLoopMode;
UINT8 *MonitorBuffer;
+ UINTN Index;
UINTN ApResetVectorSize;
UINTN BackupBufferAddr;
MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
@@ -138,6 +204,10 @@ MpInitLibInitialize (
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock(&CpuMpData->MpLock);
//
+ // Set BSP basic information
+ //
+ InitializeApData (CpuMpData, 0, 0);
+ //
// Save assembly code information
//
CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));
@@ -147,6 +217,12 @@ MpInitLibInitialize (
CpuMpData->ApLoopMode = ApLoopMode;
DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));
//
+ // Set up APs wakeup signal buffer
+ //
+ for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) {
+ CpuMpData->CpuData[Index].StartupApSignal =
+ (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);
+ }
// Store BSP's MTRR setting
//
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 955de96..3f936c2 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -47,6 +47,17 @@ typedef enum {
ApInitDone = 3
} AP_INIT_STATE;
+//
+// AP state
+//
+typedef enum {
+ CpuStateIdle,
+ CpuStateReady,
+ CpuStateBusy,
+ CpuStateFinished,
+ CpuStateDisabled
+} CPU_STATE;
+
typedef struct {
SPIN_LOCK ApLock;
volatile UINT32 *StartupApSignal;
@@ -56,6 +67,7 @@ typedef struct {
UINT32 ApicId;
UINT32 Health;
BOOLEAN CpuHealthy;
+ volatile CPU_STATE State;
BOOLEAN Waiting;
BOOLEAN *Finished;
UINT64 ExpectedTime;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 14/46] UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (12 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 13/46] UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 15/46] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP Jeff Fan
` (31 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Add CPU_VOLATILE_REGISTERS definitions for CRx and DRx required to be restored
after APs received INIT IPI.
Add worker functions SaveVolatileRegisters()/RestoreVolatileRegisters() used to
save/restore CRx and DRx. It also check if Debugging Extensions supported or
not.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 71 ++++++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 13 +++++++
2 files changed, 84 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 70e5eb1..0832228 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -47,6 +47,73 @@ SetApState (
}
/**
+ Save the volatile registers required to be restored following INIT IPI.
+
+ @param[out] VolatileRegisters Returns buffer saved the volatile resisters
+**/
+VOID
+SaveVolatileRegisters (
+ OUT CPU_VOLATILE_REGISTERS *VolatileRegisters
+ )
+{
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;
+
+ VolatileRegisters->Cr0 = AsmReadCr0 ();
+ VolatileRegisters->Cr3 = AsmReadCr3 ();
+ VolatileRegisters->Cr4 = AsmReadCr4 ();
+
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
+ if (VersionInfoEdx.Bits.DE != 0) {
+ //
+ // If processor supports Debugging Extensions feature
+ // by CPUID.[EAX=01H]:EDX.BIT2
+ //
+ VolatileRegisters->Dr0 = AsmReadDr0 ();
+ VolatileRegisters->Dr1 = AsmReadDr1 ();
+ VolatileRegisters->Dr2 = AsmReadDr2 ();
+ VolatileRegisters->Dr3 = AsmReadDr3 ();
+ VolatileRegisters->Dr6 = AsmReadDr6 ();
+ VolatileRegisters->Dr7 = AsmReadDr7 ();
+ }
+}
+
+/**
+ Restore the volatile registers following INIT IPI.
+
+ @param[in] VolatileRegisters Pointer to volatile resisters
+ @param[in] IsRestoreDr TRUE: Restore DRx if supported
+ FALSE: Do not restore DRx
+**/
+VOID
+RestoreVolatileRegisters (
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
+ IN BOOLEAN IsRestoreDr
+ )
+{
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;
+
+ AsmWriteCr0 (VolatileRegisters->Cr0);
+ AsmWriteCr3 (VolatileRegisters->Cr3);
+ AsmWriteCr4 (VolatileRegisters->Cr4);
+
+ if (IsRestoreDr) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
+ if (VersionInfoEdx.Bits.DE != 0) {
+ //
+ // If processor supports Debugging Extensions feature
+ // by CPUID.[EAX=01H]:EDX.BIT2
+ //
+ AsmWriteDr0 (VolatileRegisters->Dr0);
+ AsmWriteDr1 (VolatileRegisters->Dr1);
+ AsmWriteDr2 (VolatileRegisters->Dr2);
+ AsmWriteDr3 (VolatileRegisters->Dr3);
+ AsmWriteDr6 (VolatileRegisters->Dr6);
+ AsmWriteDr7 (VolatileRegisters->Dr7);
+ }
+ }
+}
+
+/**
Detect whether Mwait-monitor feature is supported.
@retval TRUE Mwait-monitor feature is supported.
@@ -204,6 +271,10 @@ MpInitLibInitialize (
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock(&CpuMpData->MpLock);
//
+ // Save BSP's Control registers to APs
+ //
+ SaveVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters);
+ //
// Set BSP basic information
//
InitializeApData (CpuMpData, 0, 0);
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 3f936c2..a455896 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -59,6 +59,18 @@ typedef enum {
} CPU_STATE;
typedef struct {
+ UINTN Cr0;
+ UINTN Cr3;
+ UINTN Cr4;
+ UINTN Dr0;
+ UINTN Dr1;
+ UINTN Dr2;
+ UINTN Dr3;
+ UINTN Dr6;
+ UINTN Dr7;
+} CPU_VOLATILE_REGISTERS;
+
+typedef struct {
SPIN_LOCK ApLock;
volatile UINT32 *StartupApSignal;
volatile UINTN ApFunction;
@@ -68,6 +80,7 @@ typedef struct {
UINT32 Health;
BOOLEAN CpuHealthy;
volatile CPU_STATE State;
+ CPU_VOLATILE_REGISTERS VolatileRegisters;
BOOLEAN Waiting;
BOOLEAN *Finished;
UINT64 ExpectedTime;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 15/46] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (13 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 14/46] UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 16/46] UefiCpuPkg/MpInitLib: Save CPU MP Data pointer Jeff Fan
` (30 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. ProcessorSignature is updated to CPU_MICROCODE_PROCESSOR_SIGNATURE
instead of UINT32.
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 +
.../{CpuMpPei => Library/MpInitLib}/Microcode.c | 77 +++++++++++-----------
UefiCpuPkg/Library/MpInitLib/MpLib.c | 5 ++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 10 +++
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 +
5 files changed, 57 insertions(+), 37 deletions(-)
copy UefiCpuPkg/{CpuMpPei => Library/MpInitLib}/Microcode.c (68%)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index e9a2725..03a8994 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -39,6 +39,7 @@ [Sources.common]
DxeMpLib.c
MpLib.c
MpLib.h
+ Microcode.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/UefiCpuPkg/CpuMpPei/Microcode.c b/UefiCpuPkg/Library/MpInitLib/Microcode.c
similarity index 68%
copy from UefiCpuPkg/CpuMpPei/Microcode.c
copy to UefiCpuPkg/Library/MpInitLib/Microcode.c
index 4fe6f2d..0fd8e8c 100644
--- a/UefiCpuPkg/CpuMpPei/Microcode.c
+++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c
@@ -12,56 +12,55 @@
**/
-#include "CpuMpPei.h"
+#include "MpLib.h"
/**
Get microcode update signature of currently loaded microcode update.
@return Microcode signature.
-
**/
UINT32
GetCurrentMicrocodeSignature (
VOID
)
{
- UINT64 Signature;
+ MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;
- AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
- Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
- return (UINT32) RShiftU64 (Signature, 32);
+ BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+ return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
}
/**
Detect whether specified processor can find matching microcode patch and load it.
- @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
**/
VOID
MicrocodeDetect (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
+ IN CPU_MP_DATA *CpuMpData
)
{
UINT64 MicrocodePatchAddress;
UINT64 MicrocodePatchRegionSize;
UINT32 ExtendedTableLength;
UINT32 ExtendedTableCount;
- EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
- EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
- EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
+ CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
+ CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+ CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
UINTN MicrocodeEnd;
UINTN Index;
UINT8 PlatformId;
- UINT32 RegEax;
+ CPUID_VERSION_INFO_EAX Eax;
UINT32 CurrentRevision;
UINT32 LatestRevision;
UINTN TotalSize;
UINT32 CheckSum32;
BOOLEAN CorrectMicrocode;
- MICROCODE_INFO MicrocodeInfo;
+ VOID *MicrocodeData;
+ MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr;
- ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
if (MicrocodePatchRegionSize == 0) {
@@ -82,18 +81,19 @@ MicrocodeDetect (
ExtendedTableLength = 0;
//
// Here data of CPUID leafs have not been collected into context buffer, so
- // GetProcessorCpuid() cannot be used here to retrieve CPUID data.
+ // GetProcessorCpuid() cannot be used here to retrieve sCPUID data.
//
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
+ AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL);
//
// The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
//
- PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
+ PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+ PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId;
LatestRevision = 0;
MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
do {
//
// Check if the microcode is for the Cpu and the version is newer
@@ -106,44 +106,49 @@ MicrocodeDetect (
// because the padding data should not include 0x00000001 and it should be the repeated
// byte format (like 0xXYXYXYXY....).
//
- if (MicrocodeEntryPoint->ProcessorId == RegEax &&
+ if (MicrocodeEntryPoint->ProcessorSignature.Uint32 == Eax.Uint32 &&
MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
(MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
) {
if (MicrocodeEntryPoint->DataSize == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
+ CheckSum32 = CalculateSum32 ((UINT32 *) MicrocodeEntryPoint, 2048);
} else {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
+ CheckSum32 = CalculateSum32 (
+ (UINT32 *) MicrocodeEntryPoint,
+ MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)
+ );
}
if (CheckSum32 == 0) {
CorrectMicrocode = TRUE;
}
} else if ((MicrocodeEntryPoint->DataSize != 0) &&
(MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
- ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize +
+ sizeof (CPU_MICROCODE_HEADER));
if (ExtendedTableLength != 0) {
//
// Extended Table exist, check if the CPU in support list
//
- ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
+ ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint)
+ + MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
//
// Calculate Extended Checksum
//
if ((ExtendedTableLength % 4) == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
+ CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength);
if (CheckSum32 == 0) {
//
// Checksum correct
//
ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
- ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
+ ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
for (Index = 0; Index < ExtendedTableCount; Index ++) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
+ CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTable, sizeof(CPU_MICROCODE_EXTENDED_TABLE));
if (CheckSum32 == 0) {
//
// Verify Header
//
- if ((ExtendedTable->ProcessorSignature == RegEax) &&
+ if ((ExtendedTable->ProcessorSignature.Uint32 == Eax.Uint32) &&
(ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) {
//
// Find one
@@ -166,7 +171,7 @@ MicrocodeDetect (
// alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
// find the next possible microcode patch header.
//
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
continue;
}
//
@@ -180,12 +185,10 @@ MicrocodeDetect (
if (CorrectMicrocode) {
LatestRevision = MicrocodeEntryPoint->UpdateRevision;
- MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
- MicrocodeInfo.MicrocodeSize = TotalSize;
- MicrocodeInfo.ProcessorId = RegEax;
+ MicrocodeData = (VOID *) ((UINTN) MicrocodeEntryPoint + sizeof (CPU_MICROCODE_HEADER));
}
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
+ MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
} while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
if (LatestRevision > CurrentRevision) {
@@ -196,18 +199,18 @@ MicrocodeDetect (
// revision equal to zero.
//
AsmWriteMsr64 (
- EFI_MSR_IA32_BIOS_UPDT_TRIG,
- (UINT64) (UINTN) MicrocodeInfo.MicrocodeData
- );
+ MSR_IA32_BIOS_UPDT_TRIG,
+ (UINT64) (UINTN) MicrocodeData
+ );
//
// Get and check new microcode signature
//
CurrentRevision = GetCurrentMicrocodeSignature ();
if (CurrentRevision != LatestRevision) {
- AcquireSpinLock(&PeiCpuMpData->MpLock);
+ AcquireSpinLock(&CpuMpData->MpLock);
DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \
loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));
- ReleaseSpinLock(&PeiCpuMpData->MpLock);
+ ReleaseSpinLock(&CpuMpData->MpLock);
}
}
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 0832228..7384f5d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -294,6 +294,11 @@ MpInitLibInitialize (
CpuMpData->CpuData[Index].StartupApSignal =
(UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);
}
+ //
+ // Load Microcode on BSP
+ //
+ MicrocodeDetect (CpuMpData);
+ //
// Store BSP's MTRR setting
//
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a455896..42713f0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -212,5 +212,15 @@ AsmGetAddressMap (
OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
);
+/**
+ Detect whether specified processor can find matching microcode patch and load it.
+
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+MicrocodeDetect (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index c195a38..0c6873d 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -39,6 +39,7 @@ [Sources.common]
PeiMpLib.c
MpLib.c
MpLib.h
+ Microcode.c
[Packages]
MdePkg/MdePkg.dec
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 16/46] UefiCpuPkg/MpInitLib: Save CPU MP Data pointer
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (14 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 15/46] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 17/46] UefiCpuPkg/MpInitLib: Register one End of PEI callback function Jeff Fan
` (29 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
In PeiMpInitLib, save CPU MP Data pointer into one local Guided HOB.
In DxeMpInitLib, save CPU MP Data pointer into one global variable.
Add helper functions GetCpuMpData()/SaveCpuMpData().
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 42 +++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 35 +++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 43 ++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 54 +++++++++++++++++++++++++++++++++
4 files changed, 174 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 46a48a4..e294612 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -13,6 +13,48 @@
**/
#include "MpLib.h"
+CPU_MP_DATA *mCpuMpData = NULL;
+
+/**
+ Get the pointer to CPU MP Data structure.
+
+ @return The pointer to CPU MP Data structure.
+**/
+CPU_MP_DATA *
+GetCpuMpData (
+ VOID
+ )
+{
+ ASSERT (mCpuMpData != NULL);
+ return mCpuMpData;
+}
+
+/**
+ Save the pointer to CPU MP Data structure.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
+**/
+VOID
+SaveCpuMpData (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ mCpuMpData = CpuMpData;
+}
+
+/**
+ Initialize global data for MP support.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+InitMpGlobalData (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ SaveCpuMpData (CpuMpData);
+
+}
/**
This service executes a caller provided function on all enabled APs.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 7384f5d..90ede9c 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -14,6 +14,13 @@
#include "MpLib.h"
+#define CPU_INIT_MP_LIB_HOB_GUID \
+ { \
+ 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \
+ }
+
+EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
+
/**
Get the Application Processors state.
@@ -303,6 +310,12 @@ MpInitLibInitialize (
//
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
+
+ //
+ // Initialize global data for MP support
+ //
+ InitMpGlobalData (CpuMpData);
+
return EFI_SUCCESS;
}
@@ -386,3 +399,25 @@ MpInitLibGetNumberOfProcessors (
{
return EFI_UNSUPPORTED;
}
+/**
+ Get pointer to CPU MP Data structure from GUIDed HOB.
+
+ @return The pointer to CPU MP Data structure.
+**/
+CPU_MP_DATA *
+GetCpuMpDataFromGuidedHob (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = NULL;
+ GuidHob = GetFirstGuidHob (&mCpuInitMpLibHobGuid);
+ if (GuidHob != NULL) {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ CpuMpData = (CPU_MP_DATA *) (*(UINTN *) DataInHob);
+ }
+ return CpuMpData;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 42713f0..5525a96 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -178,6 +178,9 @@ struct _CPU_MP_DATA {
CPU_AP_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
};
+
+extern EFI_GUID mCpuInitMpLibHobGuid;
+
/**
Assembly code to place AP into safe loop mode.
@@ -213,6 +216,46 @@ AsmGetAddressMap (
);
/**
+ Get the pointer to CPU MP Data structure.
+
+ @return The pointer to CPU MP Data structure.
+**/
+CPU_MP_DATA *
+GetCpuMpData (
+ VOID
+ );
+
+/**
+ Save the pointer to CPU MP Data structure.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
+**/
+VOID
+SaveCpuMpData (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
+/**
+ Initialize global data for MP support.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+InitMpGlobalData (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
+/**
+ Get pointer to CPU MP Data structure from GUIDed HOB.
+
+ @return The pointer to CPU MP Data structure.
+**/
+CPU_MP_DATA *
+GetCpuMpDataFromGuidedHob (
+ VOID
+ );
+
+/**
Detect whether specified processor can find matching microcode patch and load it.
@param[in] PeiCpuMpData Pointer to PEI CPU MP Data
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index a7e9fb8..6211e71 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -15,6 +15,60 @@
#include "MpLib.h"
/**
+ Get pointer to CPU MP Data structure.
+
+ @return The pointer to CPU MP Data structure.
+**/
+CPU_MP_DATA *
+GetCpuMpData (
+ VOID
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = GetCpuMpDataFromGuidedHob ();
+ ASSERT (CpuMpData != NULL);
+ return CpuMpData;
+}
+
+/**
+ Save the pointer to CPU MP Data structure.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
+**/
+VOID
+SaveCpuMpData (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ UINT64 Data64;
+ //
+ // Build location of CPU MP DATA buffer in HOB
+ //
+ Data64 = (UINT64) (UINTN) CpuMpData;
+ BuildGuidDataHob (
+ &mCpuInitMpLibHobGuid,
+ (VOID *) &Data64,
+ sizeof (UINT64)
+ );
+}
+
+
+/**
+ Initialize global data for MP support.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+InitMpGlobalData (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+
+ SaveCpuMpData (CpuMpData);
+}
+
+/**
This service executes a caller provided function on all enabled APs.
@param[in] Procedure A pointer to the function to be run on
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 17/46] UefiCpuPkg/MpInitLib: Register one End of PEI callback function
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (15 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 16/46] UefiCpuPkg/MpInitLib: Save CPU MP Data pointer Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 18/46] UefiCpuPkg/MpInitLib: Register one period event to check APs status Jeff Fan
` (28 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
In PeiMpInitLib, register End of PEI callback function CpuMpEndOfPeiCallback().
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.h | 20 +++++++++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 40 +++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 5525a96..a2818e6 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -265,5 +265,25 @@ MicrocodeDetect (
IN CPU_MP_DATA *CpuMpData
);
+/**
+ Notify function on End Of PEI PPI.
+
+ On S3 boot, this function will restore wakeup buffer data.
+ On normal boot, this function will flag wakeup buffer to be un-used type.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS When everything is OK.
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 6211e71..f37e985 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -13,6 +13,14 @@
**/
#include "MpLib.h"
+#include <Ppi/EndOfPeiPhase.h>
+#include <Library/PeiServicesLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mMpInitLibNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ CpuMpEndOfPeiCallback
+};
/**
Get pointer to CPU MP Data structure.
@@ -55,6 +63,32 @@ SaveCpuMpData (
/**
+/**
+ Notify function on End Of PEI PPI.
+
+ On S3 boot, this function will restore wakeup buffer data.
+ On normal boot, this function will flag wakeup buffer to be un-used type.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS When everything is OK.
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+
+ DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n"));
+
+ return EFI_SUCCESS;
+}
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
@@ -64,8 +98,14 @@ InitMpGlobalData (
IN CPU_MP_DATA *CpuMpData
)
{
+ EFI_STATUS Status;
SaveCpuMpData (CpuMpData);
+ //
+ // Register an event for EndOfPei
+ //
+ Status = PeiServicesNotifyPpi (&mMpInitLibNotifyList);
+ ASSERT_EFI_ERROR (Status);
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 18/46] UefiCpuPkg/MpInitLib: Register one period event to check APs status
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (16 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 17/46] UefiCpuPkg/MpInitLib: Register one End of PEI callback function Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 19/46] UefiCpuPkg/MpInitLib: Allocate AP reset vector buffer under 1MB Jeff Fan
` (27 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
In DxeMpInitLib, register one period event callback function CheckAPsStatus()
used to check AP Status.
v3:
1. Use CamelCase for mCheckAllAPsEvent, mStopCheckAllApsStatus and
CheckAndUpdateApsStatus().
2. Move SetTimer() from Patch #17 to Patch 16.
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 63 +++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index e294612..b7b5fd5 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -13,7 +13,13 @@
**/
#include "MpLib.h"
+
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
CPU_MP_DATA *mCpuMpData = NULL;
+EFI_EVENT mCheckAllApsEvent = NULL;
+volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
/**
Get the pointer to CPU MP Data structure.
@@ -43,6 +49,43 @@ SaveCpuMpData (
}
/**
+/**
+ Checks APs status and updates APs status if needed.
+
+**/
+VOID
+CheckAndUpdateApsStatus (
+ VOID
+ )
+{
+}
+
+/**
+ Checks APs' status periodically.
+
+ This function is triggerred by timer perodically to check the
+ state of APs for StartupAllAPs() and StartupThisAP() executed
+ in non-blocking mode.
+
+ @param[in] Event Event triggered.
+ @param[in] Context Parameter passed with the event.
+
+**/
+VOID
+EFIAPI
+CheckApsStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // If CheckApsStatus() is not stopped, otherwise return immediately.
+ //
+ if (!mStopCheckAllApsStatus) {
+ CheckAndUpdateApsStatus ();
+ }
+}
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
@@ -52,8 +95,28 @@ InitMpGlobalData (
IN CPU_MP_DATA *CpuMpData
)
{
+ EFI_STATUS Status;
+
SaveCpuMpData (CpuMpData);
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ CheckApsStatus,
+ NULL,
+ &mCheckAllApsEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set timer to check all APs status.
+ //
+ Status = gBS->SetTimer (
+ mCheckAllApsEvent,
+ TimerPeriodic,
+ EFI_TIMER_PERIOD_MILLISECONDS (100)
+ );
+ ASSERT_EFI_ERROR (Status);
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 19/46] UefiCpuPkg/MpInitLib: Allocate AP reset vector buffer under 1MB
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (17 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 18/46] UefiCpuPkg/MpInitLib: Register one period event to check APs status Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 20/46] UefiCpuPkg/MpInitLib: Add ApCFunction() executed by assembly code Jeff Fan
` (26 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
In PeiMpInitLib, searching unallocated memory under in
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR hobs to find the memory under 1MB for AP reset
vector. After End of PEI event triggered, we need to restore original the buffer
contents to avoid crash the OS on S3 boot.
In DxeMpInitLib, allocate the memory under 1MB for AP reset vector.
Add helper functions AllocateResetVector()/FreeResetVector() used by WakeupAp().
v3:
1. Move SetTimer() from Patch #17 to Patch 16.
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 60 ++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 20 +++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 245 ++++++++++++++++++++++++++++++++
3 files changed, 325 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index b7b5fd5..ce7a554 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -49,6 +49,65 @@ SaveCpuMpData (
}
/**
+ Allocate reset vector buffer.
+
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateResetVector (
+ IN OUT CPU_MP_DATA *CpuMpData
+ )
+{
+ EFI_STATUS Status;
+ UINTN ApResetVectorSize;
+ EFI_PHYSICAL_ADDRESS StartAddress;
+
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
+ sizeof (MP_CPU_EXCHANGE_INFO);
+
+ StartAddress = BASE_1MB;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (ApResetVectorSize),
+ &StartAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CpuMpData->WakeupBuffer = (UINTN) StartAddress;
+ CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)
+ (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);
+ //
+ // copy AP reset code in it
+ //
+ CopyMem (
+ (VOID *) CpuMpData->WakeupBuffer,
+ (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,
+ CpuMpData->AddressMap.RendezvousFunnelSize
+ );
+}
+
+/**
+ Free AP reset vector buffer.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+FreeResetVector (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ EFI_STATUS Status;
+ UINTN ApResetVectorSize;
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
+ sizeof (MP_CPU_EXCHANGE_INFO);
+ Status = gBS->FreePages(
+ (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer,
+ EFI_SIZE_TO_PAGES (ApResetVectorSize)
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
/**
Checks APs status and updates APs status if needed.
@@ -85,6 +144,7 @@ CheckApsStatus (
CheckAndUpdateApsStatus ();
}
}
+
/**
Initialize global data for MP support.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a2818e6..81fea02 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -236,6 +236,26 @@ SaveCpuMpData (
);
/**
+ Allocate reset vector buffer.
+
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateResetVector (
+ IN OUT CPU_MP_DATA *CpuMpData
+ );
+
+/**
+ Free AP reset vector buffer.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+FreeResetVector (
+ IN CPU_MP_DATA *CpuMpData
+ );
+
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index f37e985..2e021c9 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -61,8 +61,45 @@ SaveCpuMpData (
);
}
+/**
+ Get available system memory below 1MB by specified size.
+
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+BackupAndPrepareWakeupBuffer(
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ CopyMem (
+ (VOID *) CpuMpData->BackupBuffer,
+ (VOID *) CpuMpData->WakeupBuffer,
+ CpuMpData->BackupBufferSize
+ );
+ CopyMem (
+ (VOID *) CpuMpData->WakeupBuffer,
+ (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,
+ CpuMpData->AddressMap.RendezvousFunnelSize
+ );
+}
/**
+ Restore wakeup buffer data.
+
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+RestoreWakeupBuffer(
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ CopyMem (
+ (VOID *) CpuMpData->WakeupBuffer,
+ (VOID *) CpuMpData->BackupBuffer,
+ CpuMpData->BackupBufferSize
+ );
+}
+
/**
Notify function on End Of PEI PPI.
@@ -83,11 +120,219 @@ CpuMpEndOfPeiCallback (
IN VOID *Ppi
)
{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ CPU_MP_DATA *CpuMpData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n"));
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ CpuMpData = GetCpuMpData ();
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = GetHobList ();
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ MemoryHob = Hob.MemoryAllocation;
+ if (MemoryHob->AllocDescriptor.MemoryBaseAddress == CpuMpData->WakeupBuffer) {
+ //
+ // Flag this HOB type to un-used
+ //
+ GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
+ break;
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ } else {
+ CpuMpData->EndOfPeiFlag = TRUE;
+ RestoreWakeupBuffer (CpuMpData);
+ }
return EFI_SUCCESS;
}
+
+/**
+ Check if AP wakeup buffer is overlapped with existing allocated buffer.
+
+ @param[in] WakeupBufferStart AP wakeup buffer start address.
+ @param[in] WakeupBufferEnd AP wakeup buffer end address.
+
+ @retval TRUE There is overlap.
+ @retval FALSE There is no overlap.
+**/
+BOOLEAN
+CheckOverlapWithAllocatedBuffer (
+ IN UINTN WakeupBufferStart,
+ IN UINTN WakeupBufferEnd
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
+ BOOLEAN Overlapped;
+ UINTN MemoryStart;
+ UINTN MemoryEnd;
+
+ Overlapped = FALSE;
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = GetHobList ();
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ MemoryHob = Hob.MemoryAllocation;
+ MemoryStart = (UINTN) MemoryHob->AllocDescriptor.MemoryBaseAddress;
+ MemoryEnd = (UINTN) (MemoryHob->AllocDescriptor.MemoryBaseAddress +
+ MemoryHob->AllocDescriptor.MemoryLength);
+ if (!((WakeupBufferStart >= MemoryEnd) || (WakeupBufferEnd <= MemoryStart))) {
+ Overlapped = TRUE;
+ break;
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ return Overlapped;
+}
+
+/**
+ Get available system memory below 1MB by specified size.
+
+ @param[in] WakeupBufferSize Wakeup buffer size required
+
+ @retval other Return wakeup buffer address below 1MB.
+ @retval -1 Cannot find free memory below 1MB.
+**/
+UINTN
+GetWakeupBuffer (
+ IN UINTN WakeupBufferSize
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN WakeupBufferStart;
+ UINTN WakeupBufferEnd;
+
+ WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1);
+
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = GetHobList ();
+
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->PhysicalStart < BASE_1MB) &&
+ (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+ ((Hob.ResourceDescriptor->ResourceAttribute &
+ (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
+ EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED
+ )) == 0)
+ ) {
+ //
+ // Need memory under 1MB to be collected here
+ //
+ WakeupBufferEnd = (UINTN) (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength);
+ if (WakeupBufferEnd > BASE_1MB) {
+ //
+ // Wakeup buffer should be under 1MB
+ //
+ WakeupBufferEnd = BASE_1MB;
+ }
+ while (WakeupBufferEnd > WakeupBufferSize) {
+ //
+ // Wakeup buffer should be aligned on 4KB
+ //
+ WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1);
+ if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {
+ break;
+ }
+ if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) {
+ //
+ // If this range is overlapped with existing allocated buffer, skip it
+ // and find the next range
+ //
+ WakeupBufferEnd -= WakeupBufferSize;
+ continue;
+ }
+ DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",
+ WakeupBufferStart, WakeupBufferSize));
+ //
+ // Create a memory allocation HOB.
+ //
+ BuildMemoryAllocationHob (
+ WakeupBufferStart,
+ WakeupBufferSize,
+ EfiBootServicesData
+ );
+ return WakeupBufferStart;
+ }
+ }
+ }
+ //
+ // Find the next HOB
+ //
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return (UINTN) -1;
+}
+
+/**
+ Allocate reset vector buffer.
+
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateResetVector (
+ IN OUT CPU_MP_DATA *CpuMpData
+ )
+{
+ UINTN ApResetVectorSize;
+
+ if (CpuMpData->WakeupBuffer == (UINTN) -1) {
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
+ sizeof (MP_CPU_EXCHANGE_INFO);
+
+ CpuMpData->WakeupBuffer = GetWakeupBuffer (ApResetVectorSize);
+ CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)
+ (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);
+ BackupAndPrepareWakeupBuffer (CpuMpData);
+ }
+
+ if (CpuMpData->EndOfPeiFlag) {
+ BackupAndPrepareWakeupBuffer (CpuMpData);
+ }
+}
+
+/**
+ Free AP reset vector buffer.
+
+ @param[in] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+FreeResetVector (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ if (CpuMpData->EndOfPeiFlag) {
+ RestoreWakeupBuffer (CpuMpData);
+ }
+}
+
/**
Initialize global data for MP support.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 20/46] UefiCpuPkg/MpInitLib: Add ApCFunction() executed by assembly code
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (18 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 19/46] UefiCpuPkg/MpInitLib: Allocate AP reset vector buffer under 1MB Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 21/46] UefiCpuPkg/MpInitLib: Fill MP_CPU_EXCHANGE_INFO fields Jeff Fan
` (25 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
ApCFunction() is the first C function executed from AP reset vector. When APs
waken up at the first time, it will sync BSP's MTRR setting and load microcode
on APs and collect APs' BIST information.
When AP tasked finished, it will place APs it one loop specified by ApLoopMode.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 198 +++++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 2 +
2 files changed, 200 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 90ede9c..bbf48f6 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -179,6 +179,59 @@ GetApLoopMode (
return ApLoopMode;
}
+
+/**
+ Do sync on APs.
+
+ @param[in, out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+ApInitializeSync (
+ IN OUT VOID *Buffer
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = (CPU_MP_DATA *) Buffer;
+ //
+ // Sync BSP's MTRR table to AP
+ //
+ MtrrSetAllMtrrs (&CpuMpData->MtrrTable);
+ //
+ // Load microcode on AP
+ //
+ MicrocodeDetect (CpuMpData);
+}
+
+/**
+ Find the current Processor number by APIC ID.
+
+ @param[in] CpuMpData Pointer to PEI CPU MP Data
+ @param[in] ProcessorNumber Return the pocessor number found
+
+ @retval EFI_SUCCESS ProcessorNumber is found and returned.
+ @retval EFI_NOT_FOUND ProcessorNumber is not found.
+**/
+EFI_STATUS
+GetProcessorNumber (
+ IN CPU_MP_DATA *CpuMpData,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ UINTN TotalProcessorNumber;
+ UINTN Index;
+
+ TotalProcessorNumber = CpuMpData->CpuCount;
+ for (Index = 0; Index < TotalProcessorNumber; Index ++) {
+ if (CpuMpData->CpuData[Index].ApicId == GetApicId ()) {
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
/*
Initialize CPU AP Data when AP is wakeup at the first time.
@@ -214,6 +267,151 @@ InitializeApData (
}
/**
+ This function will be called from AP reset code if BSP uses WakeUpAP.
+
+ @param[in] ExchangeInfo Pointer to the MP exchange info buffer
+ @param[in] NumApsExecuting Number of current executing AP
+**/
+VOID
+EFIAPI
+ApCFunction (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN UINTN NumApsExecuting
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ UINTN ProcessorNumber;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *Parameter;
+ UINT32 BistData;
+ volatile UINT32 *ApStartupSignalBuffer;
+
+ //
+ // AP finished assembly code and begin to execute C code
+ //
+ CpuMpData = ExchangeInfo->CpuMpData;
+
+ ProgramVirtualWireMode ();
+
+ while (TRUE) {
+ if (CpuMpData->InitFlag == ApInitConfig) {
+ //
+ // Add CPU number
+ //
+ InterlockedIncrement ((UINT32 *) &CpuMpData->CpuCount);
+ ProcessorNumber = NumApsExecuting;
+ //
+ // This is first time AP wakeup, get BIST information from AP stack
+ //
+ BistData = *(UINT32 *) (CpuMpData->Buffer + ProcessorNumber * CpuMpData->CpuApStackSize - sizeof (UINTN));
+ //
+ // Do some AP initialize sync
+ //
+ ApInitializeSync (CpuMpData);
+ //
+ // Sync BSP's Control registers to APs
+ //
+ RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
+ InitializeApData (CpuMpData, ProcessorNumber, BistData);
+ ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
+ } else {
+ //
+ // Execute AP function if AP is ready
+ //
+ GetProcessorNumber (CpuMpData, &ProcessorNumber);
+ //
+ // Clear AP start-up signal when AP waken up
+ //
+ ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
+ InterlockedCompareExchange32 (
+ (UINT32 *) ApStartupSignalBuffer,
+ WAKEUP_AP_SIGNAL,
+ 0
+ );
+ if (CpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Restore AP's volatile registers saved
+ //
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
+ }
+
+ if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
+ Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction;
+ Parameter = (VOID *) CpuMpData->CpuData[ProcessorNumber].ApFunctionArgument;
+ if (Procedure != NULL) {
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateBusy);
+ //
+ // Invoke AP function here
+ //
+ Procedure (Parameter);
+ //
+ // Re-get the CPU APICID and Initial APICID
+ //
+ CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
+ CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ }
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateFinished);
+ }
+ }
+
+ //
+ // AP finished executing C code
+ //
+ InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount);
+
+ //
+ // Place AP is specified loop mode
+ //
+ if (CpuMpData->ApLoopMode == ApInHltLoop) {
+ //
+ // Save AP volatile registers
+ //
+ SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
+ //
+ // Place AP in HLT-loop
+ //
+ while (TRUE) {
+ DisableInterrupts ();
+ CpuSleep ();
+ CpuPause ();
+ }
+ }
+ while (TRUE) {
+ DisableInterrupts ();
+ if (CpuMpData->ApLoopMode == ApInMwaitLoop) {
+ //
+ // Place AP in MWAIT-loop
+ //
+ AsmMonitor ((UINTN) ApStartupSignalBuffer, 0, 0);
+ if (*ApStartupSignalBuffer != WAKEUP_AP_SIGNAL) {
+ //
+ // Check AP start-up signal again.
+ // If AP start-up signal is not set, place AP into
+ // the specified C-state
+ //
+ AsmMwait (CpuMpData->ApTargetCState << 4, 0);
+ }
+ } else if (CpuMpData->ApLoopMode == ApInRunLoop) {
+ //
+ // Place AP in Run-loop
+ //
+ CpuPause ();
+ } else {
+ ASSERT (FALSE);
+ }
+
+ //
+ // If AP start-up signal is written, AP is waken up
+ // otherwise place AP in loop again
+ //
+ if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) {
+ break;
+ }
+ }
+ }
+}
+
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 81fea02..363867a 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -35,6 +35,8 @@
#include <Library/MtrrLib.h>
#include <Library/HobLib.h>
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
+
typedef enum {
ApInHltLoop = 1,
ApInMwaitLoop = 2,
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 21/46] UefiCpuPkg/MpInitLib: Fill MP_CPU_EXCHANGE_INFO fields
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (19 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 20/46] UefiCpuPkg/MpInitLib: Add ApCFunction() executed by assembly code Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 22/46] UefiCpuPkg/MpInitLib: Add WakeUpAP() Jeff Fan
` (24 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
FillExchangeInfoData() is used to fill MP_CPU_EXCHANGE_INFO date exchanged
between C code and assembly code of AP reset vector.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 79 ++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index bbf48f6..1625869 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -22,6 +22,47 @@
EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
/**
+ 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 Eax;
+ CPUID_EXTENDED_CPU_SIG_EDX Edx;
+ MSR_IA32_EFER_REGISTER EferMsr;
+ BOOLEAN Enabled;
+
+ Enabled = FALSE;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL);
+ if (Eax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &Edx.Uint32);
+ //
+ // CPUID 0x80000001
+ // Bit 20: Execute Disable Bit available.
+ //
+ if (Edx.Bits.NX != 0) {
+ EferMsr.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
+ //
+ // MSR 0xC0000080
+ // Bit 11: Execute Disable Bit enable.
+ //
+ if (EferMsr.Bits.NXE != 0) {
+ Enabled = TRUE;
+ }
+ }
+ }
+
+ return Enabled;
+}
+
+/**
Get the Application Processors state.
@param[in] CpuData The pointer to CPU_AP_DATA of specified AP
@@ -412,6 +453,44 @@ ApCFunction (
}
/**
+ This function will fill the exchange info structure.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+
+**/
+VOID
+FillExchangeInfoData (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+
+ ExchangeInfo = CpuMpData->MpCpuExchangeInfo;
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->StackStart = CpuMpData->Buffer;
+ ExchangeInfo->StackSize = CpuMpData->CpuApStackSize;
+ ExchangeInfo->BufferStart = CpuMpData->WakeupBuffer;
+ ExchangeInfo->ModeOffset = CpuMpData->AddressMap.ModeEntryOffset;
+
+ ExchangeInfo->CodeSegment = AsmReadCs ();
+ ExchangeInfo->DataSegment = AsmReadDs ();
+
+ ExchangeInfo->Cr3 = AsmReadCr3 ();
+
+ ExchangeInfo->CFunction = (UINTN) ApCFunction;
+ ExchangeInfo->NumApsExecuting = 0;
+ ExchangeInfo->CpuMpData = CpuMpData;
+
+ ExchangeInfo->EnableExecuteDisable = IsBspExecuteDisableEnabled ();
+
+ //
+ // Get the BSP's data of GDT and IDT
+ //
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile);
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);
+}
+
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 22/46] UefiCpuPkg/MpInitLib: Add WakeUpAP()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (20 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 21/46] UefiCpuPkg/MpInitLib: Fill MP_CPU_EXCHANGE_INFO fields Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 23/46] UefiCpuPkg/MpInitLib: Send INIT-SIPI-SIPI to get processor count Jeff Fan
` (23 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
WakeUpAP() is used to wakeup APs per current ApLoopMode and make sure APs wake
up successfully.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 121 +++++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 19 ++++++
2 files changed, 140 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 1625869..8a333db 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -453,6 +453,29 @@ ApCFunction (
}
/**
+ Wait for AP wakeup and write AP start-up signal till AP is waken up.
+
+ @param[in] ApStartupSignalBuffer Pointer to AP wakeup signal
+**/
+VOID
+WaitApWakeup (
+ IN volatile UINT32 *ApStartupSignalBuffer
+ )
+{
+ //
+ // If AP is waken up, StartupApSignal should be cleared.
+ // Otherwise, write StartupApSignal again till AP waken up.
+ //
+ while (InterlockedCompareExchange32 (
+ (UINT32 *) ApStartupSignalBuffer,
+ WAKEUP_AP_SIGNAL,
+ WAKEUP_AP_SIGNAL
+ ) != 0) {
+ CpuPause ();
+ }
+}
+
+/**
This function will fill the exchange info structure.
@param[in] CpuMpData Pointer to CPU MP Data
@@ -491,6 +514,104 @@ FillExchangeInfoData (
}
/**
+ This function will be called by BSP to wakeup AP.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+ @param[in] Broadcast TRUE: Send broadcast IPI to all APs
+ FALSE: Send IPI to AP by ApicId
+ @param[in] ProcessorNumber The handle number of specified processor
+ @param[in] Procedure The function to be invoked by AP
+ @param[in] ProcedureArgument The argument to be passed into AP function
+**/
+VOID
+WakeUpAP (
+ IN CPU_MP_DATA *CpuMpData,
+ IN BOOLEAN Broadcast,
+ IN UINTN ProcessorNumber,
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL
+ IN VOID *ProcedureArgument OPTIONAL
+ )
+{
+ volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+ UINTN Index;
+ CPU_AP_DATA *CpuData;
+ BOOLEAN ResetVectorRequired;
+
+ CpuMpData->FinishedCount = 0;
+ ResetVectorRequired = FALSE;
+
+ if (CpuMpData->ApLoopMode == ApInHltLoop ||
+ CpuMpData->InitFlag != ApInitDone) {
+ ResetVectorRequired = TRUE;
+ AllocateResetVector (CpuMpData);
+ FillExchangeInfoData (CpuMpData);
+ } else if (CpuMpData->ApLoopMode == ApInMwaitLoop) {
+ //
+ // Get AP target C-state each time when waking up AP,
+ // for it maybe updated by platform again
+ //
+ CpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate);
+ }
+
+ ExchangeInfo = CpuMpData->MpCpuExchangeInfo;
+
+ if (Broadcast) {
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ if (Index != CpuMpData->BspNumber) {
+ CpuData = &CpuMpData->CpuData[Index];
+ CpuData->ApFunction = (UINTN) Procedure;
+ CpuData->ApFunctionArgument = (UINTN) ProcedureArgument;
+ SetApState (CpuData, CpuStateReady);
+ if (CpuMpData->InitFlag != ApInitConfig) {
+ *(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
+ }
+ }
+ }
+ if (ResetVectorRequired) {
+ //
+ // Wakeup all APs
+ //
+ SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+ }
+ if (CpuMpData->InitFlag != ApInitConfig) {
+ //
+ // Wait all APs waken up if this is not the 1st broadcast of SIPI
+ //
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ CpuData = &CpuMpData->CpuData[Index];
+ if (Index != CpuMpData->BspNumber) {
+ WaitApWakeup (CpuData->StartupApSignal);
+ }
+ }
+ }
+ } else {
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+ CpuData->ApFunction = (UINTN) Procedure;
+ CpuData->ApFunctionArgument = (UINTN) ProcedureArgument;
+ SetApState (CpuData, CpuStateReady);
+ //
+ // Wakeup specified AP
+ //
+ ASSERT (CpuMpData->InitFlag != ApInitConfig);
+ *(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
+ if (ResetVectorRequired) {
+ SendInitSipiSipi (
+ CpuData->ApicId,
+ (UINT32) ExchangeInfo->BufferStart
+ );
+ }
+ //
+ // Wait specified AP waken up
+ //
+ WaitApWakeup (CpuData->StartupApSignal);
+ }
+
+ if (ResetVectorRequired) {
+ FreeResetVector (CpuMpData);
+ }
+}
+
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 363867a..aa81d0a 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -258,6 +258,25 @@ FreeResetVector (
);
/**
+ This function will be called by BSP to wakeup AP.
+
+ @param[in] CpuMpData Pointer to CPU MP Data
+ @param[in] Broadcast TRUE: Send broadcast IPI to all APs
+ FALSE: Send IPI to AP by ApicId
+ @param[in] ProcessorNumber The handle number of specified processor
+ @param[in] Procedure The function to be invoked by AP
+ @param[in] ProcedureArgument The argument to be passed into AP function
+**/
+VOID
+WakeUpAP (
+ IN CPU_MP_DATA *CpuMpData,
+ IN BOOLEAN Broadcast,
+ IN UINTN ProcessorNumber,
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL
+ IN VOID *ProcedureArgument OPTIONAL
+ );
+
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 23/46] UefiCpuPkg/MpInitLib: Send INIT-SIPI-SIPI to get processor count
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (21 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 22/46] UefiCpuPkg/MpInitLib: Add WakeUpAP() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 24/46] UefiCpuPkg/MpInitLib: Enable x2APIC mode on BSP/APs Jeff Fan
` (22 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
CollectProcessorCount() will send the 1st INIT-SIPI-SIPI to get processor count
in system.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 40 ++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 8a333db..2ada3c8 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -273,6 +273,42 @@ GetProcessorNumber (
return EFI_NOT_FOUND;
}
+/**
+ This function will get CPU count in the system.
+
+ @param[in] CpuMpData Pointer to PEI CPU MP Data
+
+ @return CPU count detected
+**/
+UINTN
+CollectProcessorCount (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ //
+ // Send 1st broadcast IPI to APs to wakeup APs
+ //
+ CpuMpData->InitFlag = ApInitConfig;
+ CpuMpData->X2ApicEnable = FALSE;
+ WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL);
+ //
+ // Wait for AP task to complete and then exit.
+ //
+ MicroSecondDelay (PcdGet32(PcdCpuApInitTimeOutInMicroSeconds));
+ CpuMpData->InitFlag = ApInitDone;
+ ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ //
+ // Wait for all APs finished the initialization
+ //
+ while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) {
+ CpuPause ();
+ }
+
+ DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount));
+
+ return CpuMpData->CpuCount;
+}
+
/*
Initialize CPU AP Data when AP is wakeup at the first time.
@@ -710,6 +746,10 @@ MpInitLibInitialize (
//
+ // Wakeup all APs and calculate the processor count in system
+ //
+ CollectProcessorCount (CpuMpData);
+ //
// Initialize global data for MP support
//
InitMpGlobalData (CpuMpData);
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 24/46] UefiCpuPkg/MpInitLib: Enable x2APIC mode on BSP/APs
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (22 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 23/46] UefiCpuPkg/MpInitLib: Send INIT-SIPI-SIPI to get processor count Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 25/46] UefiCpuPkg/MpInitLib: Sort processor by ascending order of APIC ID Jeff Fan
` (21 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
If x2APIC flag is set, enable x2APIC mode on all APs and BSP. Before we wakeup
APs to enable x2APIC mode, we should wait all APs have finished initialization.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 2ada3c8..c8d361f 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -222,6 +222,20 @@ GetApLoopMode (
}
/**
+ Enable x2APIC mode on APs.
+
+ @param[in, out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+ApFuncEnableX2Apic (
+ IN OUT VOID *Buffer
+ )
+{
+ SetApicMode (LOCAL_APIC_MODE_X2APIC);
+}
+
+/**
Do sync on APs.
@param[in, out] Buffer Pointer to private data buffer.
@@ -304,6 +318,24 @@ CollectProcessorCount (
CpuPause ();
}
+ if (CpuMpData->X2ApicEnable) {
+ DEBUG ((DEBUG_INFO, "Force x2APIC mode!\n"));
+ //
+ // Wakeup all APs to enable x2APIC mode
+ //
+ WakeUpAP (CpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL);
+ //
+ // Wait for all known APs finished
+ //
+ while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) {
+ CpuPause ();
+ }
+ //
+ // Enable x2APIC on BSP
+ //
+ SetApicMode (LOCAL_APIC_MODE_X2APIC);
+ }
+ DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ()));
DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount));
return CpuMpData->CpuCount;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 25/46] UefiCpuPkg/MpInitLib: Sort processor by ascending order of APIC ID
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (23 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 24/46] UefiCpuPkg/MpInitLib: Enable x2APIC mode on BSP/APs Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 26/46] UefiCpuPkg/MpInitLib: Skip collect processor count if GUIDed HOB exist Jeff Fan
` (20 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 72 ++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index c8d361f..539fbbc 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -222,6 +222,73 @@ GetApLoopMode (
}
/**
+ Sort the APIC ID of all processors.
+
+ This function sorts the APIC ID of all processors so that processor number is
+ assigned in the ascending order of APIC ID which eases MP debugging.
+
+ @param[in] CpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+SortApicId (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ UINTN Index1;
+ UINTN Index2;
+ UINTN Index3;
+ UINT32 ApicId;
+ CPU_AP_DATA CpuData;
+ UINT32 ApCount;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
+
+ ApCount = CpuMpData->CpuCount - 1;
+
+ if (ApCount != 0) {
+ for (Index1 = 0; Index1 < ApCount; Index1++) {
+ Index3 = Index1;
+ //
+ // Sort key is the hardware default APIC ID
+ //
+ ApicId = CpuMpData->CpuData[Index1].ApicId;
+ for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) {
+ if (ApicId > CpuMpData->CpuData[Index2].ApicId) {
+ Index3 = Index2;
+ ApicId = CpuMpData->CpuData[Index2].ApicId;
+ }
+ }
+ if (Index3 != Index1) {
+ CopyMem (&CpuData, &CpuMpData->CpuData[Index3], sizeof (CPU_AP_DATA));
+ CopyMem (
+ &CpuMpData->CpuData[Index3],
+ &CpuMpData->CpuData[Index1],
+ sizeof (CPU_AP_DATA)
+ );
+ CopyMem (&CpuMpData->CpuData[Index1], &CpuData, sizeof (CPU_AP_DATA));
+ }
+ }
+
+ //
+ // Get the processor number for the BSP
+ //
+ ApicId = GetInitialApicId ();
+ for (Index1 = 0; Index1 < CpuMpData->CpuCount; Index1++) {
+ if (CpuMpData->CpuData[Index1].ApicId == ApicId) {
+ CpuMpData->BspNumber = (UINT32) Index1;
+ break;
+ }
+ }
+
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+ for (Index1 = 0; Index1 < CpuMpData->CpuCount; Index1++) {
+ CpuInfoInHob[Index1].InitialApicId = CpuMpData->CpuData[Index1].InitialApicId;
+ CpuInfoInHob[Index1].ApicId = CpuMpData->CpuData[Index1].ApicId;
+ CpuInfoInHob[Index1].Health = CpuMpData->CpuData[Index1].Health;
+ }
+ }
+}
+
+/**
Enable x2APIC mode on APs.
@param[in, out] Buffer Pointer to private data buffer.
@@ -336,6 +403,11 @@ CollectProcessorCount (
SetApicMode (LOCAL_APIC_MODE_X2APIC);
}
DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ()));
+ //
+ // Sort BSP/Aps by CPU APIC ID in ascending order
+ //
+ SortApicId (CpuMpData);
+
DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount));
return CpuMpData->CpuCount;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 26/46] UefiCpuPkg/MpInitLib: Skip collect processor count if GUIDed HOB exist
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (24 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 25/46] UefiCpuPkg/MpInitLib: Sort processor by ascending order of APIC ID Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 27/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetNumberOfProcessors() Jeff Fan
` (19 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
If GUIDed HOB mCpuInitMpLibHobGuid exists, we could get the processor count and
processor APICID and Initial APICID from CPU_INFO_IN_HOB. We needn't to delay
for broadcast INIT-SIPI-SIPI results and could improve performance.
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 60 +++++++++++++++++++++++++++++++++---
1 file changed, 55 insertions(+), 5 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 539fbbc..775bbcf 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -770,6 +770,8 @@ MpInitLibInitialize (
VOID
)
{
+ CPU_MP_DATA *OldCpuMpData;
+ CPU_INFO_IN_HOB *CpuInfoInHob;
UINT32 MaxLogicalProcessorNumber;
UINT32 ApStackSize;
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
@@ -783,7 +785,13 @@ MpInitLibInitialize (
UINTN Index;
UINTN ApResetVectorSize;
UINTN BackupBufferAddr;
- MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
+
+ OldCpuMpData = GetCpuMpDataFromGuidedHob ();
+ if (OldCpuMpData == NULL) {
+ MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
+ } else {
+ MaxLogicalProcessorNumber = OldCpuMpData->CpuCount;
+ }
AsmGetAddressMap (&AddressMap);
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
@@ -848,12 +856,53 @@ MpInitLibInitialize (
//
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
+ if (OldCpuMpData == NULL) {
+ //
+ // Wakeup all APs and calculate the processor count in system
+ //
+ CollectProcessorCount (CpuMpData);
+ } else {
+ //
+ // APs have been wakeup before, just get the CPU Information
+ // from HOB
+ //
+ CpuMpData->CpuCount = OldCpuMpData->CpuCount;
+ CpuMpData->BspNumber = OldCpuMpData->BspNumber;
+ CpuMpData->InitFlag = ApInitReconfig;
+ CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) OldCpuMpData->CpuInfoInHob;
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ InitializeSpinLock(&CpuMpData->CpuData[Index].ApLock);
+ CpuMpData->CpuData[Index].ApicId = CpuInfoInHob[Index].ApicId;
+ CpuMpData->CpuData[Index].InitialApicId = CpuInfoInHob[Index].InitialApicId;
+ if (CpuMpData->CpuData[Index].InitialApicId >= 255) {
+ CpuMpData->X2ApicEnable = TRUE;
+ }
+ CpuMpData->CpuData[Index].Health = CpuInfoInHob[Index].Health;
+ CpuMpData->CpuData[Index].CpuHealthy = (CpuMpData->CpuData[Index].Health == 0)? TRUE:FALSE;
+ CpuMpData->CpuData[Index].ApFunction = 0;
+ CopyMem (
+ &CpuMpData->CpuData[Index].VolatileRegisters,
+ &CpuMpData->CpuData[0].VolatileRegisters,
+ sizeof (CPU_VOLATILE_REGISTERS)
+ );
+ }
+ //
+ // Wakeup APs to do some AP initialize sync
+ //
+ WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData);
+ //
+ // Wait for all APs finished initialization
+ //
+ while (CpuMpData->FinishedCount < (CpuMpData->CpuCount - 1)) {
+ CpuPause ();
+ }
+ CpuMpData->InitFlag = ApInitDone;
+ for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
+ SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
+ }
+ }
//
- // Wakeup all APs and calculate the processor count in system
- //
- CollectProcessorCount (CpuMpData);
- //
// Initialize global data for MP support
//
InitMpGlobalData (CpuMpData);
@@ -941,6 +990,7 @@ MpInitLibGetNumberOfProcessors (
{
return EFI_UNSUPPORTED;
}
+
/**
Get pointer to CPU MP Data structure from GUIDed HOB.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 27/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetNumberOfProcessors()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (25 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 26/46] UefiCpuPkg/MpInitLib: Skip collect processor count if GUIDed HOB exist Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 28/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetProcessorInfo() Jeff Fan
` (18 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 39 +++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 775bbcf..5c5cb10 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -961,6 +961,7 @@ MpInitLibWhoAmI (
{
return EFI_UNSUPPORTED;
}
+
/**
Retrieves the number of logical processor in the platform and the number of
those logical processors that are enabled on this boot. This service may only
@@ -988,9 +989,45 @@ MpInitLibGetNumberOfProcessors (
OUT UINTN *NumberOfEnabledProcessors OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ CPU_MP_DATA *CpuMpData;
+ UINTN CallerNumber;
+ UINTN ProcessorNumber;
+ UINTN EnabledProcessorNumber;
+ UINTN Index;
+
+ CpuMpData = GetCpuMpData ();
+
+ if ((NumberOfProcessors == NULL) && (NumberOfEnabledProcessors == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ProcessorNumber = CpuMpData->CpuCount;
+ EnabledProcessorNumber = 0;
+ for (Index = 0; Index < ProcessorNumber; Index++) {
+ if (GetApState (&CpuMpData->CpuData[Index]) != CpuStateDisabled) {
+ EnabledProcessorNumber ++;
+ }
+ }
+
+ if (NumberOfProcessors != NULL) {
+ *NumberOfProcessors = ProcessorNumber;
+ }
+ if (NumberOfEnabledProcessors != NULL) {
+ *NumberOfEnabledProcessors = EnabledProcessorNumber;
+ }
+
+ return EFI_SUCCESS;
}
+
/**
Get pointer to CPU MP Data structure from GUIDed HOB.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 28/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetProcessorInfo()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (26 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 27/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetNumberOfProcessors() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 29/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibWhoAmI() Jeff Fan
` (17 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. Update HealthData type from UINT32 to EFI_HEALTH_FLAGS
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 174 ++++++++++++++++++++++++++++++++++-
1 file changed, 173 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 5c5cb10..58eb392 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -63,6 +63,132 @@ IsBspExecuteDisableEnabled (
}
/**
+ Get CPU Package/Core/Thread location information.
+
+ @param[in] InitialApicId CPU APIC ID
+ @param[out] Location Pointer to CPU location information
+**/
+VOID
+ExtractProcessorLocation (
+ IN UINT32 InitialApicId,
+ OUT EFI_CPU_PHYSICAL_LOCATION *Location
+ )
+{
+ BOOLEAN TopologyLeafSupported;
+ UINTN ThreadBits;
+ UINTN CoreBits;
+ CPUID_VERSION_INFO_EBX VersionInfoEbx;
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;
+ CPUID_CACHE_PARAMS_EAX CacheParamsEax;
+ CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
+ CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
+ CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
+ UINT32 MaxCpuIdIndex;
+ UINT32 SubIndex;
+ UINTN LevelType;
+ UINT32 MaxLogicProcessorsPerPackage;
+ UINT32 MaxCoresPerPackage;
+
+ //
+ // Check if the processor is capable of supporting more than one logical processor.
+ //
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
+ if (VersionInfoEdx.Bits.HTT == 0) {
+ Location->Thread = 0;
+ Location->Core = 0;
+ Location->Package = 0;
+ return;
+ }
+
+ ThreadBits = 0;
+ CoreBits = 0;
+
+ //
+ // Assume three-level mapping of APIC ID: Package:Core:SMT.
+ //
+
+ TopologyLeafSupported = FALSE;
+ //
+ // Get the max index of basic CPUID
+ //
+ AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
+
+ //
+ // If the extended topology enumeration leaf is available, it
+ // is the preferred mechanism for enumerating topology.
+ //
+ if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
+ AsmCpuidEx (
+ CPUID_EXTENDED_TOPOLOGY,
+ 0,
+ &ExtendedTopologyEax.Uint32,
+ &ExtendedTopologyEbx.Uint32,
+ &ExtendedTopologyEcx.Uint32,
+ NULL
+ );
+ //
+ // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
+ // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
+ // supported on that processor.
+ //
+ if (ExtendedTopologyEbx.Uint32 != 0) {
+ TopologyLeafSupported = TRUE;
+
+ //
+ // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
+ // the SMT sub-field of x2APIC ID.
+ //
+ LevelType = ExtendedTopologyEcx.Bits.LevelType;
+ ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
+ ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
+
+ //
+ // Software must not assume any "level type" encoding
+ // value to be related to any sub-leaf index, except sub-leaf 0.
+ //
+ SubIndex = 1;
+ do {
+ AsmCpuidEx (
+ CPUID_EXTENDED_TOPOLOGY,
+ SubIndex,
+ &ExtendedTopologyEax.Uint32,
+ NULL,
+ &ExtendedTopologyEcx.Uint32,
+ NULL
+ );
+ LevelType = ExtendedTopologyEcx.Bits.LevelType;
+ if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
+ CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
+ break;
+ }
+ SubIndex++;
+ } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
+ }
+ }
+
+ if (!TopologyLeafSupported) {
+ AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
+ MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
+ if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
+ AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
+ MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
+ } else {
+ //
+ // Must be a single-core processor.
+ //
+ MaxCoresPerPackage = 1;
+ }
+
+ ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
+ CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
+ }
+
+ Location->Thread = InitialApicId & ~((-1) << ThreadBits);
+ Location->Core = (InitialApicId >> ThreadBits) & ~((-1) << CoreBits);
+ Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
+}
+
+/**
Get the Application Processors state.
@param[in] CpuData The pointer to CPU_AP_DATA of specified AP
@@ -935,8 +1061,54 @@ MpInitLibGetProcessorInfo (
OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ CPU_MP_DATA *CpuMpData;
+ UINTN CallerNumber;
+
+ CpuMpData = GetCpuMpData ();
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorInfoBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= CpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ ProcessorInfoBuffer->ProcessorId = (UINT64) CpuMpData->CpuData[ProcessorNumber].ApicId;
+ ProcessorInfoBuffer->StatusFlag = 0;
+ if (ProcessorNumber == CpuMpData->BspNumber) {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
+ }
+ if (CpuMpData->CpuData[ProcessorNumber].CpuHealthy) {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT;
+ }
+ if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateDisabled) {
+ ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT;
+ } else {
+ ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;
+ }
+
+ //
+ // Get processor location information
+ //
+ ExtractProcessorLocation (CpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);
+
+ if (HealthData != NULL) {
+ HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health;
+ }
+
+ return EFI_SUCCESS;
}
+
+
/**
This return the handle number for the calling processor. This service may be
called from the BSP and APs.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 29/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibWhoAmI()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (27 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 28/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetProcessorInfo() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 30/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibSwitchBSP() Jeff Fan
` (16 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/Library/MpInitLib/MpLib.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 58eb392..225f172 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1131,7 +1131,15 @@ MpInitLibWhoAmI (
OUT UINTN *ProcessorNumber
)
{
- return EFI_UNSUPPORTED;
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = GetCpuMpData ();
+
+ if (ProcessorNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return GetProcessorNumber (CpuMpData, ProcessorNumber);
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 30/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibSwitchBSP()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (28 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 29/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibWhoAmI() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 31/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibEnableDisableAP() Jeff Fan
` (15 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. Simply the internal function SwitchBSPWorker()'s comment header
due to it is duplicated with MpInitLibSwitchBSP().
v3:
1. Rename MpInitLibSwitchBsp to MpInitLibSwitchBSP.
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 26 +++++-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 144 ++++++++++++++++++++++++++++++--
UefiCpuPkg/Library/MpInitLib/MpLib.h | 53 ++++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 2 +-
4 files changed, 218 insertions(+), 7 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index ce7a554..3e2b299 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -386,7 +386,31 @@ MpInitLibSwitchBSP (
IN BOOLEAN EnableOldBSP
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ BOOLEAN OldInterruptState;
+
+ //
+ // Before send both BSP and AP to a procedure to exchange their roles,
+ // interrupt must be disabled. This is because during the exchange role
+ // process, 2 CPU may use 1 stack. If interrupt happens, the stack will
+ // be corrupted, since interrupt return address will be pushed to stack
+ // by hardware.
+ //
+ OldInterruptState = SaveAndDisableInterrupts ();
+
+ //
+ // Mask LINT0 & LINT1 for the old BSP
+ //
+ DisableLvtInterrupts ();
+
+ Status = SwitchBSPWorker (ProcessorNumber, EnableOldBSP);
+
+ //
+ // Restore interrupt state.
+ //
+ SetInterruptState (OldInterruptState);
+
+ return Status;
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 225f172..bf17149 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -189,6 +189,26 @@ ExtractProcessorLocation (
}
/**
+ Worker function for SwitchBSP().
+
+ Worker function for SwitchBSP(), assigned to the AP which is intended
+ to become BSP.
+
+ @param[in] Buffer Pointer to CPU MP Data
+**/
+VOID
+EFIAPI
+FutureBSPProc (
+ IN VOID *Buffer
+ )
+{
+ CPU_MP_DATA *DataInHob;
+
+ DataInHob = (CPU_MP_DATA *) Buffer;
+ AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
+}
+
+/**
Get the Application Processors state.
@param[in] CpuData The pointer to CPU_AP_DATA of specified AP
@@ -651,11 +671,20 @@ ApCFunction (
// Invoke AP function here
//
Procedure (Parameter);
- //
- // Re-get the CPU APICID and Initial APICID
- //
- CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
- CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ if (CpuMpData->SwitchBspFlag) {
+ //
+ // Re-get the processor number due to BSP/AP maybe exchange in AP function
+ //
+ GetProcessorNumber (CpuMpData, &ProcessorNumber);
+ CpuMpData->CpuData[ProcessorNumber].ApFunction = 0;
+ CpuMpData->CpuData[ProcessorNumber].ApFunctionArgument = 0;
+ } else {
+ //
+ // Re-get the CPU APICID and Initial APICID
+ //
+ CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();
+ CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();
+ }
}
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateFinished);
}
@@ -946,6 +975,7 @@ MpInitLibInitialize (
CpuMpData->CpuCount = 1;
CpuMpData->BspNumber = 0;
CpuMpData->WaitEvent = NULL;
+ CpuMpData->SwitchBspFlag = FALSE;
CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock(&CpuMpData->MpLock);
@@ -1108,6 +1138,110 @@ MpInitLibGetProcessorInfo (
return EFI_SUCCESS;
}
+/**
+ Worker function to switch the requested AP to be the BSP from that point onward.
+
+ @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval others Failed to switch BSP.
+
+**/
+EFI_STATUS
+SwitchBSPWorker (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ UINTN CallerNumber;
+ CPU_STATE State;
+ MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
+
+ CpuMpData = GetCpuMpData ();
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_SUCCESS;
+ }
+
+ if (ProcessorNumber >= CpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether specified AP is disabled
+ //
+ State = GetApState (&CpuMpData->CpuData[ProcessorNumber]);
+ if (State == CpuStateDisabled) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether ProcessorNumber specifies the current BSP
+ //
+ if (ProcessorNumber == CpuMpData->BspNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether specified AP is busy
+ //
+ if (State == CpuStateBusy) {
+ return EFI_NOT_READY;
+ }
+
+ CpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
+ CpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE;
+ CpuMpData->SwitchBspFlag = TRUE;
+
+ //
+ // Clear the BSP bit of MSR_IA32_APIC_BASE
+ //
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.BSP = 0;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
+
+ //
+ // Need to wakeUp AP (future BSP).
+ //
+ WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData);
+
+ AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);
+
+ //
+ // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
+ //
+ ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
+ ApicBaseMsr.Bits.BSP = 1;
+ AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
+
+ //
+ // Wait for old BSP finished AP task
+ //
+ while (GetApState (&CpuMpData->CpuData[CallerNumber]) != CpuStateFinished) {
+ CpuPause ();
+ }
+
+ CpuMpData->SwitchBspFlag = FALSE;
+ //
+ // Set old BSP enable state
+ //
+ if (!EnableOldBSP) {
+ SetApState (&CpuMpData->CpuData[CallerNumber], CpuStateDisabled);
+ }
+ //
+ // Save new BSP number
+ //
+ CpuMpData->BspNumber = (UINT32) ProcessorNumber;
+
+ return EFI_SUCCESS;
+}
/**
This return the handle number for the calling processor. This service may be
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index aa81d0a..83aec83 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -37,6 +37,23 @@
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
+//
+// The MP data for switch BSP
+//
+#define CPU_SWITCH_STATE_IDLE 0
+#define CPU_SWITCH_STATE_STORED 1
+#define CPU_SWITCH_STATE_LOADED 2
+
+//
+// CPU exchange information for switch BSP
+//
+typedef struct {
+ UINT8 State; // offset 0
+ UINTN StackPointer; // offset 4 / 8
+ IA32_DESCRIPTOR Gdtr; // offset 8 / 16
+ IA32_DESCRIPTOR Idtr; // offset 14 / 26
+} CPU_EXCHANGE_ROLE_INFO;
+
typedef enum {
ApInHltLoop = 1,
ApInMwaitLoop = 2,
@@ -173,6 +190,9 @@ struct _CPU_MP_DATA {
AP_INIT_STATE InitFlag;
BOOLEAN X2ApicEnable;
+ BOOLEAN SwitchBspFlag;
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;
+ CPU_EXCHANGE_ROLE_INFO APInfo;
MTRR_SETTINGS MtrrTable;
UINT8 ApLoopMode;
UINT8 ApTargetCState;
@@ -218,6 +238,22 @@ AsmGetAddressMap (
);
/**
+ This function is called by both the BSP and the AP which is to become the BSP to
+ Exchange execution context including stack between them. After return from this
+ function, the BSP becomes AP and the AP becomes the BSP.
+
+ @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor.
+ @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer.
+
+**/
+VOID
+EFIAPI
+AsmExchangeRole (
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
+ );
+
+/**
Get the pointer to CPU MP Data structure.
@return The pointer to CPU MP Data structure.
@@ -287,6 +323,23 @@ InitMpGlobalData (
);
/**
+ Worker function to switch the requested AP to be the BSP from that point onward.
+
+ @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval others Failed to switch BSP.
+
+**/
+EFI_STATUS
+SwitchBSPWorker (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
Get pointer to CPU MP Data structure from GUIDed HOB.
@return The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 2e021c9..03ba08e 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -560,7 +560,7 @@ MpInitLibSwitchBSP (
IN BOOLEAN EnableOldBSP
)
{
- return EFI_UNSUPPORTED;
+ return SwitchBSPWorker (ProcessorNumber, EnableOldBSP);
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 31/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibEnableDisableAP()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (29 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 30/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibSwitchBSP() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 32/46] UefiCpuPkg/MpInitLib: Check APs Status and update APs status Jeff Fan
` (14 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. Simply the internal function MpInitLibEnableDisableAP()'s function
header due to it is duplicated with MpInitLibEnableDisableAP().
v3:
1. Use CamelCase for mCheckAllAPsEvent, mStopCheckAllApsStatus.
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 20 +++++++++++-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 56 +++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 21 +++++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 2 +-
4 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 3e2b299..dd7bc9d 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -451,5 +451,23 @@ MpInitLibEnableDisableAP (
IN UINT32 *HealthFlag OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ BOOLEAN TempStopCheckState;
+
+ TempStopCheckState = FALSE;
+ //
+ // temporarily stop checkAllAPsStatus for initialize parameters.
+ //
+ if (!mStopCheckAllApsStatus) {
+ mStopCheckAllApsStatus = TRUE;
+ TempStopCheckState = TRUE;
+ }
+
+ Status = EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);
+
+ if (TempStopCheckState) {
+ mStopCheckAllApsStatus = FALSE;
+ }
+
+ return Status;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index bf17149..d8ef19f 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1244,6 +1244,62 @@ SwitchBSPWorker (
}
/**
+ Worker function to let the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ @param[in] ProcessorNumber The handle number of AP.
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval others Failed to Enable/Disable AP.
+
+**/
+EFI_STATUS
+EnableDisableApWorker (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ UINTN CallerNumber;
+
+ CpuMpData = GetCpuMpData ();
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber == CpuMpData->BspNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= CpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!EnableAP) {
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateDisabled);
+ } else {
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
+ }
+
+ if (HealthFlag != NULL) {
+ CpuMpData->CpuData[ProcessorNumber].CpuHealthy =
+ (BOOLEAN) ((*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT) != 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
This return the handle number for the calling processor. This service may be
called from the BSP and APs.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 83aec83..a5a3732 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -340,6 +340,27 @@ SwitchBSPWorker (
);
/**
+ Worker function to let the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ @param[in] ProcessorNumber The handle number of AP.
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval others Failed to Enable/Disable AP.
+
+**/
+EFI_STATUS
+EnableDisableApWorker (
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
Get pointer to CPU MP Data structure from GUIDed HOB.
@return The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 03ba08e..e066e42 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -601,7 +601,7 @@ MpInitLibEnableDisableAP (
IN UINT32 *HealthFlag OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);
}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 32/46] UefiCpuPkg/MpInitLib: Check APs Status and update APs status
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (30 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 31/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibEnableDisableAP() Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:14 ` [Patch v4 33/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupThisAP() Jeff Fan
` (13 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v3:
1. Use CamelCase for CheckAndUpdateApsStatus().
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 37 ++++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 326 ++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 42 +++-
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 11 ++
4 files changed, 415 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index dd7bc9d..ce45249 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -117,6 +117,43 @@ CheckAndUpdateApsStatus (
VOID
)
{
+ UINTN ProcessorNumber;
+ EFI_STATUS Status;
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = GetCpuMpData ();
+
+ //
+ // First, check whether pending StartupAllAPs() exists.
+ //
+ if (CpuMpData->WaitEvent != NULL) {
+
+ Status = CheckAllAPs ();
+ //
+ // If all APs finish for StartupAllAPs(), signal the WaitEvent for it.
+ //
+ if (Status != EFI_NOT_READY) {
+ Status = gBS->SignalEvent (CpuMpData->WaitEvent);
+ CpuMpData->WaitEvent = NULL;
+ }
+ }
+
+ //
+ // Second, check whether pending StartupThisAPs() callings exist.
+ //
+ for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {
+
+ if (CpuMpData->CpuData[ProcessorNumber].WaitEvent == NULL) {
+ continue;
+ }
+
+ Status = CheckThisAP (ProcessorNumber);
+
+ if (Status != EFI_NOT_READY) {
+ gBS->SignalEvent (CpuMpData->CpuData[ProcessorNumber].WaitEvent);
+ CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL;
+ }
+ }
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index d8ef19f..f6e15e8 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -907,6 +907,332 @@ WakeUpAP (
}
/**
+ Calculate timeout value and return the current performance counter value.
+
+ Calculate the number of performance counter ticks required for a timeout.
+ If TimeoutInMicroseconds is 0, return value is also 0, which is recognized
+ as infinity.
+
+ @param[in] TimeoutInMicroseconds Timeout value in microseconds.
+ @param[out] CurrentTime Returns the current value of the performance counter.
+
+ @return Expected time stamp counter for timeout.
+ If TimeoutInMicroseconds is 0, return value is also 0, which is recognized
+ as infinity.
+
+**/
+UINT64
+CalculateTimeout (
+ IN UINTN TimeoutInMicroseconds,
+ OUT UINT64 *CurrentTime
+ )
+{
+ //
+ // Read the current value of the performance counter
+ //
+ *CurrentTime = GetPerformanceCounter ();
+
+ //
+ // If TimeoutInMicroseconds is 0, return value is also 0, which is recognized
+ // as infinity.
+ //
+ if (TimeoutInMicroseconds == 0) {
+ return 0;
+ }
+
+ //
+ // GetPerformanceCounterProperties () returns the timestamp counter's frequency
+ // in Hz. So multiply the return value with TimeoutInMicroseconds and then divide
+ // it by 1,000,000, to get the number of ticks for the timeout value.
+ //
+ return DivU64x32 (
+ MultU64x64 (
+ GetPerformanceCounterProperties (NULL, NULL),
+ TimeoutInMicroseconds
+ ),
+ 1000000
+ );
+}
+
+/**
+ Checks whether timeout expires.
+
+ Check whether the number of elapsed performance counter ticks required for
+ a timeout condition has been reached.
+ If Timeout is zero, which means infinity, return value is always FALSE.
+
+ @param[in, out] PreviousTime On input, the value of the performance counter
+ when it was last read.
+ On output, the current value of the performance
+ counter
+ @param[in] TotalTime The total amount of elapsed time in performance
+ counter ticks.
+ @param[in] Timeout The number of performance counter ticks required
+ to reach a timeout condition.
+
+ @retval TRUE A timeout condition has been reached.
+ @retval FALSE A timeout condition has not been reached.
+
+**/
+BOOLEAN
+CheckTimeout (
+ IN OUT UINT64 *PreviousTime,
+ IN UINT64 *TotalTime,
+ IN UINT64 Timeout
+ )
+{
+ UINT64 Start;
+ UINT64 End;
+ UINT64 CurrentTime;
+ INT64 Delta;
+ INT64 Cycle;
+
+ if (Timeout == 0) {
+ return FALSE;
+ }
+ GetPerformanceCounterProperties (&Start, &End);
+ Cycle = End - Start;
+ if (Cycle < 0) {
+ Cycle = -Cycle;
+ }
+ Cycle++;
+ CurrentTime = GetPerformanceCounter();
+ Delta = (INT64) (CurrentTime - *PreviousTime);
+ if (Start > End) {
+ Delta = -Delta;
+ }
+ if (Delta < 0) {
+ Delta += Cycle;
+ }
+ *TotalTime += Delta;
+ *PreviousTime = CurrentTime;
+ if (*TotalTime > Timeout) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ Reset an AP to Idle state.
+
+ Any task being executed by the AP will be aborted and the AP
+ will be waiting for a new task in Wait-For-SIPI state.
+
+ @param[in] ProcessorNumber The handle number of processor.
+**/
+VOID
+ResetProcessorToIdleState (
+ IN UINTN ProcessorNumber
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = GetCpuMpData ();
+
+ WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL);
+
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
+}
+
+/**
+ Searches for the next waiting AP.
+
+ Search for the next AP that is put in waiting state by single-threaded StartupAllAPs().
+
+ @param[out] NextProcessorNumber Pointer to the processor number of the next waiting AP.
+
+ @retval EFI_SUCCESS The next waiting AP has been found.
+ @retval EFI_NOT_FOUND No waiting AP exists.
+
+**/
+EFI_STATUS
+GetNextWaitingProcessorNumber (
+ OUT UINTN *NextProcessorNumber
+ )
+{
+ UINTN ProcessorNumber;
+ CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = GetCpuMpData ();
+
+ for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {
+ if (CpuMpData->CpuData[ProcessorNumber].Waiting) {
+ *NextProcessorNumber = ProcessorNumber;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/** Checks status of specified AP.
+
+ This function checks whether the specified AP has finished the task assigned
+ by StartupThisAP(), and whether timeout expires.
+
+ @param[in] ProcessorNumber The handle number of processor.
+
+ @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
+ @retval EFI_TIMEOUT The timeout expires.
+ @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
+**/
+EFI_STATUS
+CheckThisAP (
+ IN UINTN ProcessorNumber
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ CPU_AP_DATA *CpuData;
+
+ CpuMpData = GetCpuMpData ();
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+
+ //
+ // Check the CPU state of AP. If it is CpuStateFinished, then the AP has finished its task.
+ // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the
+ // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.
+ //
+ //
+ // If the AP finishes for StartupThisAP(), return EFI_SUCCESS.
+ //
+ if (GetApState(CpuData) == CpuStateFinished) {
+ if (CpuData->Finished != NULL) {
+ *(CpuData->Finished) = TRUE;
+ }
+ SetApState (CpuData, CpuStateIdle);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // If timeout expires for StartupThisAP(), report timeout.
+ //
+ if (CheckTimeout (&CpuData->CurrentTime, &CpuData->TotalTime, CpuData->ExpectedTime)) {
+ if (CpuData->Finished != NULL) {
+ *(CpuData->Finished) = FALSE;
+ }
+ //
+ // Reset failed AP to idle state
+ //
+ ResetProcessorToIdleState (ProcessorNumber);
+
+ return EFI_TIMEOUT;
+ }
+ }
+ return EFI_NOT_READY;
+}
+
+/**
+ Checks status of all APs.
+
+ This function checks whether all APs have finished task assigned by StartupAllAPs(),
+ and whether timeout expires.
+
+ @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().
+ @retval EFI_TIMEOUT The timeout expires.
+ @retval EFI_NOT_READY APs have not finished task and timeout has not expired.
+**/
+EFI_STATUS
+CheckAllAPs (
+ VOID
+ )
+{
+ UINTN ProcessorNumber;
+ UINTN NextProcessorNumber;
+ UINTN ListIndex;
+ EFI_STATUS Status;
+ CPU_MP_DATA *CpuMpData;
+ CPU_AP_DATA *CpuData;
+
+ CpuMpData = GetCpuMpData ();
+
+ NextProcessorNumber = 0;
+
+ //
+ // Go through all APs that are responsible for the StartupAllAPs().
+ //
+ for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {
+ if (!CpuMpData->CpuData[ProcessorNumber].Waiting) {
+ continue;
+ }
+
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+ //
+ // Check the CPU state of AP. If it is CpuStateFinished, then the AP has finished its task.
+ // Only BSP and corresponding AP access this unit of CPU Data. This means the AP will not modify the
+ // value of state after setting the it to CpuStateFinished, so BSP can safely make use of its value.
+ //
+ if (GetApState(CpuData) == CpuStateFinished) {
+ CpuMpData->RunningCount ++;
+ CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
+ SetApState(CpuData, CpuStateIdle);
+
+ //
+ // If in Single Thread mode, then search for the next waiting AP for execution.
+ //
+ if (CpuMpData->SingleThread) {
+ Status = GetNextWaitingProcessorNumber (&NextProcessorNumber);
+
+ if (!EFI_ERROR (Status)) {
+ WakeUpAP (
+ CpuMpData,
+ FALSE,
+ (UINT32) NextProcessorNumber,
+ CpuMpData->Procedure,
+ CpuMpData->ProcArguments
+ );
+ }
+ }
+ }
+ }
+
+ //
+ // If all APs finish, return EFI_SUCCESS.
+ //
+ if (CpuMpData->RunningCount == CpuMpData->StartCount) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If timeout expires, report timeout.
+ //
+ if (CheckTimeout (
+ &CpuMpData->CurrentTime,
+ &CpuMpData->TotalTime,
+ CpuMpData->ExpectedTime)
+ ) {
+ //
+ // If FailedCpuList is not NULL, record all failed APs in it.
+ //
+ if (CpuMpData->FailedCpuList != NULL) {
+ *CpuMpData->FailedCpuList =
+ AllocatePool ((CpuMpData->StartCount - CpuMpData->FinishedCount + 1) * sizeof (UINTN));
+ ASSERT (*CpuMpData->FailedCpuList != NULL);
+ }
+ ListIndex = 0;
+
+ for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {
+ //
+ // Check whether this processor is responsible for StartupAllAPs().
+ //
+ if (CpuMpData->CpuData[ProcessorNumber].Waiting) {
+ //
+ // Reset failed APs to idle state
+ //
+ ResetProcessorToIdleState (ProcessorNumber);
+ CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;
+ if (CpuMpData->FailedCpuList != NULL) {
+ (*CpuMpData->FailedCpuList)[ListIndex++] = ProcessorNumber;
+ }
+ }
+ }
+ if (CpuMpData->FailedCpuList != NULL) {
+ (*CpuMpData->FailedCpuList)[ListIndex] = END_OF_CPU_LIST;
+ }
+ return EFI_TIMEOUT;
+ }
+ return EFI_NOT_READY;
+}
+
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a5a3732..17ebbcf 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -369,7 +369,47 @@ CPU_MP_DATA *
GetCpuMpDataFromGuidedHob (
VOID
);
-
+
+/** Checks status of specified AP.
+
+ This function checks whether the specified AP has finished the task assigned
+ by StartupThisAP(), and whether timeout expires.
+
+ @param[in] ProcessorNumber The handle number of processor.
+
+ @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
+ @retval EFI_TIMEOUT The timeout expires.
+ @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
+**/
+EFI_STATUS
+CheckThisAP (
+ IN UINTN ProcessorNumber
+ );
+
+/**
+ Checks status of all APs.
+
+ This function checks whether all APs have finished task assigned by StartupAllAPs(),
+ and whether timeout expires.
+
+ @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().
+ @retval EFI_TIMEOUT The timeout expires.
+ @retval EFI_NOT_READY APs have not finished task and timeout has not expired.
+**/
+EFI_STATUS
+CheckAllAPs (
+ VOID
+ );
+
+/**
+ Checks APs status and updates APs status if needed.
+
+**/
+VOID
+CheckAndUpdateApsStatus (
+ VOID
+ );
+
/**
Detect whether specified processor can find matching microcode patch and load it.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index e066e42..3a8a4d1 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -334,6 +334,17 @@ FreeResetVector (
}
/**
+ Checks APs status and updates APs status if needed.
+
+**/
+VOID
+CheckAndUpdateApsStatus (
+ VOID
+ )
+{
+}
+
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 33/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupThisAP()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (31 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 32/46] UefiCpuPkg/MpInitLib: Check APs Status and update APs status Jeff Fan
@ 2016-07-29 18:14 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 34/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupAllAPs() Jeff Fan
` (12 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:14 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. Simply the internal function StartupThisAPWorker()'s comment
header due to it is duplicated with MpInitLibStartupThisAP().
v3:
1. Use CamelCase for mStopCheckAllApsStatus and
CheckAndUpdateApsStatus().
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 20 +++++-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 112 ++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 33 ++++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 13 +++-
4 files changed, 176 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index ce45249..11676a6 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -387,7 +387,25 @@ MpInitLibStartupThisAP (
OUT BOOLEAN *Finished OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+
+ //
+ // temporarily stop checkAllApsStatus for avoid resource dead-lock.
+ //
+ mStopCheckAllApsStatus = TRUE;
+
+ Status = StartupThisAPWorker (
+ Procedure,
+ ProcessorNumber,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ Finished
+ );
+
+ mStopCheckAllApsStatus = FALSE;
+
+ return Status;
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index f6e15e8..6e800a7 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1725,6 +1725,118 @@ MpInitLibGetNumberOfProcessors (
/**
+ Worker function to let the caller get one enabled AP to execute a caller-provided
+ function.
+
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system.
+ @param[in] ProcessorNumber The handle number of the AP.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode.
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If AP returns from Procedure before the
+ timeout expires, its content is set to TRUE.
+ Otherwise, the value is set to FALSE.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval others Failed to Startup AP.
+
+**/
+EFI_STATUS
+StartupThisAPWorker (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CPU_MP_DATA *CpuMpData;
+ CPU_AP_DATA *CpuData;
+ UINTN CallerNumber;
+
+ CpuMpData = GetCpuMpData ();
+
+ if (Finished != NULL) {
+ *Finished = FALSE;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check whether processor with the handle specified by ProcessorNumber exists
+ //
+ if (ProcessorNumber >= CpuMpData->CpuCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check whether specified processor is BSP
+ //
+ if (ProcessorNumber == CpuMpData->BspNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check parameter Procedure
+ //
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Update AP state
+ //
+ CheckAndUpdateApsStatus ();
+
+ //
+ // Check whether specified AP is disabled
+ //
+ if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateDisabled) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If WaitEvent is not NULL, execute in non-blocking mode.
+ // BSP saves data for CheckAPsStatus(), and returns EFI_SUCCESS.
+ // CheckAPsStatus() will check completion and timeout periodically.
+ //
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+ CpuData->WaitEvent = WaitEvent;
+ CpuData->Finished = Finished;
+ CpuData->ExpectedTime = CalculateTimeout (TimeoutInMicroseconds, &CpuData->CurrentTime);
+ CpuData->TotalTime = 0;
+
+ WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);
+
+ //
+ // If WaitEvent is NULL, execute in blocking mode.
+ // BSP checks AP's state until it finishes or TimeoutInMicrosecsond expires.
+ //
+ Status = EFI_SUCCESS;
+ if (WaitEvent == NULL) {
+ do {
+ Status = CheckThisAP (ProcessorNumber);
+ } while (Status == EFI_NOT_READY);
+ }
+
+ return Status;
+}
+
+/**
Get pointer to CPU MP Data structure from GUIDed HOB.
@return The pointer to CPU MP Data structure.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 17ebbcf..96ce1fc 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -323,6 +323,39 @@ InitMpGlobalData (
);
/**
+ Worker function to let the caller get one enabled AP to execute a caller-provided
+ function.
+
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system.
+ @param[in] ProcessorNumber The handle number of the AP.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode.
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If AP returns from Procedure before the
+ timeout expires, its content is set to TRUE.
+ Otherwise, the value is set to FALSE.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval others Failed to Startup AP.
+
+**/
+EFI_STATUS
+StartupThisAPWorker (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ );
+
+/**
Worker function to switch the requested AP to be the BSP from that point onward.
@param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 3a8a4d1..141697d 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -535,7 +535,18 @@ MpInitLibStartupThisAP (
OUT BOOLEAN *Finished OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ if (WaitEvent != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return StartupThisAPWorker (
+ Procedure,
+ ProcessorNumber,
+ NULL,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ Finished
+ );
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 34/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupAllAPs()
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (32 preceding siblings ...)
2016-07-29 18:14 ` [Patch v4 33/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupThisAP() Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 35/46] UefiCpuPkg/MpInitLib: Place APs in safe loop before hand-off to OS Jeff Fan
` (11 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
v4:
1. Simply the internal function StartupAllAPsWorker()'s function
header due to it is duplicated with MpInitLibStartupAllAPs().
v3:
1. Use CamelCase for mStopCheckAllApsStatus and
CheckAndUpdateApsStatus()
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 23 ++++-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 158 ++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 41 +++++++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 13 ++-
4 files changed, 233 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 11676a6..8d1854c 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -302,7 +302,28 @@ MpInitLibStartupAllAPs (
OUT UINTN **FailedCpuList OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+
+ //
+ // Temporarily stop checkAllApsStatus for avoid resource dead-lock.
+ //
+ mStopCheckAllApsStatus = TRUE;
+
+ Status = StartupAllAPsWorker (
+ Procedure,
+ SingleThread,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ FailedCpuList
+ );
+
+ //
+ // Start checkAllApsStatus
+ //
+ mStopCheckAllApsStatus = FALSE;
+
+ return Status;
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 6e800a7..a90fd97 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1725,6 +1725,164 @@ MpInitLibGetNumberOfProcessors (
/**
+ Worker function to execute a caller provided function on all enabled APs.
+
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode.
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval others Failed to Startup all APs.
+
+**/
+EFI_STATUS
+StartupAllAPsWorker (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CPU_MP_DATA *CpuMpData;
+ UINTN ProcessorCount;
+ UINTN ProcessorNumber;
+ UINTN CallerNumber;
+ CPU_AP_DATA *CpuData;
+ BOOLEAN HasEnabledAp;
+ CPU_STATE ApState;
+
+ CpuMpData = GetCpuMpData ();
+
+ if (FailedCpuList != NULL) {
+ *FailedCpuList = NULL;
+ }
+
+ if (CpuMpData->CpuCount == 1) {
+ return EFI_NOT_STARTED;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether caller processor is BSP
+ //
+ MpInitLibWhoAmI (&CallerNumber);
+ if (CallerNumber != CpuMpData->BspNumber) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Update AP state
+ //
+ CheckAndUpdateApsStatus ();
+
+ ProcessorCount = CpuMpData->CpuCount;
+ HasEnabledAp = FALSE;
+ //
+ // Check whether all enabled APs are idle.
+ // If any enabled AP is not idle, return EFI_NOT_READY.
+ //
+ for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+ if (ProcessorNumber != CpuMpData->BspNumber) {
+ ApState = GetApState (CpuData);
+ if (ApState != CpuStateDisabled) {
+ HasEnabledAp = TRUE;
+ if (ApState != CpuStateIdle) {
+ //
+ // If any enabled APs are busy, return EFI_NOT_READY.
+ //
+ return EFI_NOT_READY;
+ }
+ }
+ }
+ }
+
+ if (!HasEnabledAp) {
+ //
+ // If no enabled AP exists, return EFI_NOT_STARTED.
+ //
+ return EFI_NOT_STARTED;
+ }
+
+ CpuMpData->StartCount = 0;
+ for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {
+ CpuData = &CpuMpData->CpuData[ProcessorNumber];
+ CpuData->Waiting = FALSE;
+ if (ProcessorNumber != CpuMpData->BspNumber) {
+ if (CpuData->State == CpuStateIdle) {
+ //
+ // Mark this processor as responsible for current calling.
+ //
+ CpuData->Waiting = TRUE;
+ CpuMpData->StartCount++;
+ }
+ }
+ }
+
+ CpuMpData->Procedure = Procedure;
+ CpuMpData->ProcArguments = ProcedureArgument;
+ CpuMpData->SingleThread = SingleThread;
+ CpuMpData->FinishedCount = 0;
+ CpuMpData->RunningCount = 0;
+ CpuMpData->FailedCpuList = FailedCpuList;
+ CpuMpData->ExpectedTime = CalculateTimeout (
+ TimeoutInMicroseconds,
+ &CpuMpData->CurrentTime
+ );
+ CpuMpData->TotalTime = 0;
+ CpuMpData->WaitEvent = WaitEvent;
+
+ if (!SingleThread) {
+ WakeUpAP (CpuMpData, TRUE, 0, Procedure, ProcedureArgument);
+ } else {
+ for (ProcessorNumber = 0; ProcessorNumber < ProcessorCount; ProcessorNumber++) {
+ if (ProcessorNumber == CallerNumber) {
+ continue;
+ }
+ if (CpuMpData->CpuData[ProcessorNumber].Waiting) {
+ WakeUpAP (CpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);
+ break;
+ }
+ }
+ }
+
+ Status = EFI_SUCCESS;
+ if (WaitEvent == NULL) {
+ do {
+ Status = CheckAllAPs ();
+ } while (Status == EFI_NOT_READY);
+ }
+
+ return Status;
+}
+
+/**
Worker function to let the caller get one enabled AP to execute a caller-provided
function.
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 96ce1fc..47b8b54 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -323,6 +323,47 @@ InitMpGlobalData (
);
/**
+ Worker function to execute a caller provided function on all enabled APs.
+
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode.
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval others Failed to Startup all APs.
+
+**/
+EFI_STATUS
+StartupAllAPsWorker (
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ );
+
+/**
Worker function to let the caller get one enabled AP to execute a caller-provided
function.
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index 141697d..b227e04 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -450,7 +450,18 @@ MpInitLibStartupAllAPs (
OUT UINTN **FailedCpuList OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ if (WaitEvent != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return StartupAllAPsWorker (
+ Procedure,
+ SingleThread,
+ NULL,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ FailedCpuList
+ );
}
/**
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 35/46] UefiCpuPkg/MpInitLib: Place APs in safe loop before hand-off to OS
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (33 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 34/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupAllAPs() Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 36/46] OvmfPkg: Add MpInitLib reference in DSC files Jeff Fan
` (10 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Register Exit Boot Service callback function MpInitExitBootServicesCallback() to
place AP one safe loop before hand-off to OS.
Allocated one reserved memory and copy the AsmRellocateApLoop() code into it. It
could avoid the CPU Dxe driver (located in Boot Service data range) crashed
after Exit Boot Service event.
Place AP into the target Cx-State (specified by PcdCpuApTargetCstate) could save
power if Monitor-mwait feature supported.
In long mode, switch AP into protected mode could let AP not require page table
when executing this safe loop. Page Table (located in Boot Service data range)
may crashed after Exit Boot Service event.
v3:
1. Rename *RellocateAp* to *RelocateAp*
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>
---
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 97 +++++++++++++++++++++++++++++++++
UefiCpuPkg/Library/MpInitLib/MpLib.h | 11 ++++
2 files changed, 108 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 8d1854c..d34eb14 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -19,6 +19,7 @@
CPU_MP_DATA *mCpuMpData = NULL;
EFI_EVENT mCheckAllApsEvent = NULL;
+EFI_EVENT mMpInitExitBootServicesEvent = NULL;
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
/**
@@ -183,6 +184,94 @@ CheckApsStatus (
}
/**
+ Get Protected mode code segment from current GDT table.
+
+ @returen Protected mode code segment value.
+**/
+UINT16
+GetProtectedModeCS (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtrDesc;
+ IA32_SEGMENT_DESCRIPTOR *GdtEntry;
+ UINTN GdtEntryCount;
+ UINT16 Index;
+
+ Index = (UINT16) -1;
+ AsmReadGdtr (&GdtrDesc);
+ GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+ GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
+ for (Index = 0; Index < GdtEntryCount; Index++) {
+ if (GdtEntry->Bits.L == 0) {
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) {
+ break;
+ }
+ }
+ GdtEntry++;
+ }
+ ASSERT (Index != -1);
+ return Index * 8;
+}
+
+/**
+ Do sync on APs.
+
+ @param[in, out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+RelocateApLoop (
+ IN OUT VOID *Buffer
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ BOOLEAN MwaitSupport;
+ ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;
+
+ CpuMpData = GetCpuMpData ();
+ MwaitSupport = IsMwaitSupport ();
+ AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) Buffer;
+ AsmRelocateApLoopFunc (MwaitSupport, CpuMpData->ApTargetCState, CpuMpData->PmCodeSegment);
+ //
+ // It should never reach here
+ //
+ ASSERT (FALSE);
+}
+
+/**
+ Callback function for ExitBootServices.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+MpInitExitBootServicesCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CPU_MP_DATA *CpuMpData;
+ VOID *ReservedApLoopFunc;
+ //
+ // Avoid APs access invalid buff data which allocated by BootServices,
+ // so we will allocate reserved data for AP loop code.
+ //
+ CpuMpData = GetCpuMpData ();
+ CpuMpData->PmCodeSegment = GetProtectedModeCS ();
+ CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+ ReservedApLoopFunc = AllocateReservedCopyPool (
+ CpuMpData->AddressMap.RelocateApLoopFuncSize,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress
+ );
+ WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, ReservedApLoopFunc);
+ DEBUG ((DEBUG_INFO, "MpInitExitBootServicesCallback() done!\n"));
+}
+
+/**
Initialize global data for MP support.
@param[in] CpuMpData The pointer to CPU MP Data structure.
@@ -214,6 +303,14 @@ InitMpGlobalData (
EFI_TIMER_PERIOD_MILLISECONDS (100)
);
ASSERT_EFI_ERROR (Status);
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ MpInitExitBootServicesCallback,
+ NULL,
+ &mMpInitExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 47b8b54..9ba3f8b 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -495,6 +495,17 @@ MicrocodeDetect (
);
/**
+ Detect whether Mwait-monitor feature is supported.
+
+ @retval TRUE Mwait-monitor feature is supported.
+ @retval FALSE Mwait-monitor feature is not supported.
+**/
+BOOLEAN
+IsMwaitSupport (
+ VOID
+ );
+
+/**
Notify function on End Of PEI PPI.
On S3 boot, this function will restore wakeup buffer data.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 36/46] OvmfPkg: Add MpInitLib reference in DSC files.
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (34 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 35/46] UefiCpuPkg/MpInitLib: Place APs in safe loop before hand-off to OS Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 37/46] QuarkPlatformPkg: " Jeff Fan
` (9 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Jordan Justen, Laszlo Ersek
This update is for CpuMpPei&CpuDxe consuming MP Initialize library.
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
3 files changed, 6 insertions(+)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 8af3267..5ed39f7 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -213,6 +213,7 @@ [LibraryClasses.common.PEIM]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -292,6 +293,7 @@ [LibraryClasses.common.DXE_DRIVER]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 4bb38d0..a1fae56 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -218,6 +218,7 @@ [LibraryClasses.common.PEIM]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -297,6 +298,7 @@ [LibraryClasses.common.DXE_DRIVER]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index be3aa1f..2ec8e8c 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -218,6 +218,7 @@ [LibraryClasses.common.PEIM]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -297,6 +298,7 @@ [LibraryClasses.common.DXE_DRIVER]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 37/46] QuarkPlatformPkg: Add MpInitLib reference in DSC files.
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (35 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 36/46] OvmfPkg: Add MpInitLib reference in DSC files Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 38/46] UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services Jeff Fan
` (8 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Kelly Steele
This update is for CpuDxe consuming MP Initialize library.
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Kelly Steele <kelly.steele@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
QuarkPlatformPkg/Quark.dsc | 1 +
QuarkPlatformPkg/QuarkMin.dsc | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/QuarkPlatformPkg/Quark.dsc b/QuarkPlatformPkg/Quark.dsc
index c87bb17..4770789 100644
--- a/QuarkPlatformPkg/Quark.dsc
+++ b/QuarkPlatformPkg/Quark.dsc
@@ -196,6 +196,7 @@ [LibraryClasses]
#
MtrrLib|QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
#
# Quark North Cluster
diff --git a/QuarkPlatformPkg/QuarkMin.dsc b/QuarkPlatformPkg/QuarkMin.dsc
index f8a656e..59bf607 100644
--- a/QuarkPlatformPkg/QuarkMin.dsc
+++ b/QuarkPlatformPkg/QuarkMin.dsc
@@ -2,7 +2,7 @@
# Clanton Peak CRB platform with 32-bit DXE for 4MB/8MB flash devices.
#
# This package provides Clanton Peak CRB platform specific modules.
-# Copyright (c) 2013 - 2014 Intel Corporation.
+# Copyright (c) 2013 - 2016 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -165,6 +165,7 @@ [LibraryClasses]
#
MtrrLib|QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
#
# Quark North Cluster
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 38/46] UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (36 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 37/46] QuarkPlatformPkg: " Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 39/46] UefiCpuPkg/CpuMpPei: Remove unused files and codes Jeff Fan
` (7 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Consume MP initialize library to produce CPU MP PPI, it could simply the code.
Add STATIC for some internal functions to avoid build issue with the same
functions name in PeiMpInit instance. They will be removed by the next patch.
v4:
1. Update BistData type from UINT32 to EFI_HEALTH_FLAGS.
v3:
1. Rename MpInitLibSwitchBSP to MpInitLibSwitchBSP
2. Add PeiMpInitLib.inf in DSC file
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>
---
UefiCpuPkg/CpuMpPei/CpuBist.c | 53 ++--
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 70 ++++--
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 10 +-
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 +
UefiCpuPkg/CpuMpPei/PeiMpServices.c | 469 +++---------------------------------
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
6 files changed, 113 insertions(+), 491 deletions(-)
diff --git a/UefiCpuPkg/CpuMpPei/CpuBist.c b/UefiCpuPkg/CpuMpPei/CpuBist.c
index 5629245..641eb10 100644
--- a/UefiCpuPkg/CpuMpPei/CpuBist.c
+++ b/UefiCpuPkg/CpuMpPei/CpuBist.c
@@ -44,15 +44,18 @@ SecPlatformInformation2 (
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
UINTN BistInformationSize;
UINTN CpuIndex;
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
+ EFI_PROCESSOR_INFORMATION ProcessorInfo;
+ EFI_HEALTH_FLAGS BistData;
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
- PeiCpuMpData = GetMpHobData ();
+ MpInitLibGetNumberOfProcessors(&NumberOfProcessors, &NumberOfEnabledProcessors);
BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
- sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount;
+ sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors;
//
// return the information size if input buffer size is too small
//
@@ -61,11 +64,12 @@ SecPlatformInformation2 (
return EFI_BUFFER_TOO_SMALL;
}
- PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount;
+ PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors;
CpuInstance = PlatformInformationRecord2->CpuInstance;
- for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) {
- CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId;
- CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health;
+ for (CpuIndex = 0; CpuIndex < NumberOfProcessors; CpuIndex ++) {
+ MpInitLibGetProcessorInfo (CpuIndex, &ProcessorInfo, &BistData);
+ CpuInstance[CpuIndex].CpuLocation = (UINT32) ProcessorInfo.ProcessorId;
+ CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = BistData;
}
return EFI_SUCCESS;
@@ -152,13 +156,11 @@ GetBistInfoFromPpi (
or SEC Platform Information PPI.
@param PeiServices Pointer to PEI Services Table
- @param PeiCpuMpData Pointer to PEI CPU MP Data
**/
VOID
CollectBistDataFromPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN PEI_CPU_MP_DATA *PeiCpuMpData
+ IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
@@ -170,7 +172,12 @@ CollectBistDataFromPpi (
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
UINTN ProcessorNumber;
UINTN CpuIndex;
- PEI_CPU_DATA *CpuData;
+ EFI_PROCESSOR_INFORMATION ProcessorInfo;
+ EFI_HEALTH_FLAGS BistData;
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
+
+ MpInitLibGetNumberOfProcessors(&NumberOfProcessors, &NumberOfEnabledProcessors);
SecPlatformInformation2 = NULL;
SecPlatformInformation = NULL;
@@ -215,21 +222,18 @@ CollectBistDataFromPpi (
DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
}
}
- for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) {
- CpuData = &PeiCpuMpData->CpuData[ProcessorNumber];
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber ++) {
+ MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
ASSERT (CpuInstance != NULL);
- if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) {
+ if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) {
//
// Update processor's BIST data if it is already stored before
//
- CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
+ BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
}
}
- if (CpuData->Health.Uint32 == 0) {
- CpuData->CpuHealthy = TRUE;
- } else {
- CpuData->CpuHealthy = FALSE;
+ if (BistData.Uint32 != 0) {
//
// Report Status Code that self test is failed
//
@@ -239,14 +243,14 @@ CollectBistDataFromPpi (
);
}
DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n",
- PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
- PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32
+ ProcessorInfo.ProcessorId,
+ BistData
));
}
- if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) {
+ if (SecPlatformInformation2 != NULL && NumberOfData < NumberOfProcessors) {
//
- // Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion
+ // Reinstall SecPlatformInformation2 PPI to include new BIST information
//
Status = PeiServicesReInstallPpi (
SecInformationDescriptor,
@@ -255,9 +259,10 @@ CollectBistDataFromPpi (
ASSERT_EFI_ERROR (Status);
} else {
//
- // Install SecPlatformInformation2 PPI to include new BIST inforamtion
+ // Install SecPlatformInformation2 PPI to include new BIST information
//
Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
ASSERT_EFI_ERROR(Status);
}
}
+
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index 4a453c6..b5f8887 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -28,6 +28,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/
+STATIC
VOID
SortApicId (
IN PEI_CPU_MP_DATA *PeiCpuMpData
@@ -84,6 +85,7 @@ SortApicId (
@param Buffer Pointer to private data buffer.
**/
+STATIC
VOID
EFIAPI
ApFuncEnableX2Apic (
@@ -100,6 +102,7 @@ ApFuncEnableX2Apic (
@return The AP loop mode.
**/
+STATIC
UINT8
GetApLoopMode (
OUT UINT16 *MonitorFilterSize
@@ -170,6 +173,7 @@ GetMpHobData (
@param VolatileRegisters Returns buffer saved the volatile resisters
**/
+STATIC
VOID
SaveVolatileRegisters (
OUT CPU_VOLATILE_REGISTERS *VolatileRegisters
@@ -203,6 +207,7 @@ SaveVolatileRegisters (
@param IsRestoreDr TRUE: Restore DRx if supported
FALSE: Do not restore DRx
**/
+STATIC
VOID
RestoreVolatileRegisters (
IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
@@ -233,11 +238,41 @@ RestoreVolatileRegisters (
}
/**
+ Find the current Processor number by APIC ID.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param ProcessorNumber Return the pocessor number found
+
+ @retval EFI_SUCCESS ProcessorNumber is found and returned.
+ @retval EFI_NOT_FOUND ProcessorNumber is not found.
+**/
+STATIC
+EFI_STATUS
+GetProcessorNumber (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ UINTN TotalProcessorNumber;
+ UINTN Index;
+
+ TotalProcessorNumber = PeiCpuMpData->CpuCount;
+ for (Index = 0; Index < TotalProcessorNumber; Index ++) {
+ if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
This function will be called from AP reset code if BSP uses WakeUpAP.
@param ExchangeInfo Pointer to the MP exchange info buffer
@param NumApsExecuting Number of current executing AP
**/
+STATIC
VOID
EFIAPI
ApCFunction (
@@ -407,6 +442,7 @@ WriteStartupSignal (
@param Procedure The function to be invoked by AP
@param ProcedureArgument The argument to be passed into AP function
**/
+STATIC
VOID
WakeUpAP (
IN PEI_CPU_MP_DATA *PeiCpuMpData,
@@ -487,6 +523,7 @@ WakeUpAP (
@retval other Return wakeup buffer address below 1MB.
@retval -1 Cannot find free memory below 1MB.
**/
+STATIC
UINTN
GetWakeupBuffer (
IN UINTN WakeupBufferSize
@@ -556,6 +593,7 @@ GetWakeupBuffer (
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/
+STATIC
VOID
BackupAndPrepareWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData
@@ -578,6 +616,7 @@ BackupAndPrepareWakeupBuffer(
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/
+STATIC
VOID
RestoreWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData
@@ -760,6 +799,7 @@ PrepareAPStartupVector (
@retval EFI_SUCCESS When everything is OK.
**/
+STATIC
EFI_STATUS
EFIAPI
CpuMpEndOfPeiCallback (
@@ -829,8 +869,7 @@ CpuMpPeimInit (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
- EFI_STATUS Status;
- PEI_CPU_MP_DATA *PeiCpuMpData;
+ EFI_STATUS Status;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
@@ -849,31 +888,18 @@ CpuMpPeimInit (
}
Status = InitializeCpuExceptionHandlers (VectorInfo);
ASSERT_EFI_ERROR (Status);
+
//
- // Get wakeup buffer and copy AP reset code in it
- //
- PeiCpuMpData = PrepareAPStartupVector ();
- //
- // Count processor number and collect processor information
- //
- CountProcessorNumber (PeiCpuMpData);
- //
- // Build location of PEI CPU MP DATA buffer in HOB
+ // Wakeup APs to do initialization
//
- BuildGuidDataHob (
- &gEfiCallerIdGuid,
- (VOID *)&PeiCpuMpData,
- sizeof(UINT64)
- );
+ Status = MpInitLibInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
//
// Update and publish CPU BIST information
//
- CollectBistDataFromPpi (PeiServices, PeiCpuMpData);
- //
- // register an event for EndOfPei
- //
- Status = PeiServicesNotifyPpi (&mNotifyList);
- ASSERT_EFI_ERROR (Status);
+ CollectBistDataFromPpi (PeiServices);
+
//
// Install CPU MP PPI
//
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 0d1a14a..fb57669 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -42,6 +42,7 @@
#include <Library/UefiCpuLib.h>
#include <Library/CpuLib.h>
#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/MpInitLib.h>
#include "Microcode.h"
@@ -187,6 +188,7 @@ AsmInitializeGdt (
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/
+STATIC
VOID
BackupAndPrepareWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData
@@ -197,6 +199,7 @@ BackupAndPrepareWakeupBuffer(
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/
+STATIC
VOID
RestoreWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData
@@ -215,6 +218,7 @@ RestoreWakeupBuffer(
@retval EFI_SUCCESS When everything is OK.
**/
+STATIC
EFI_STATUS
EFIAPI
CpuMpEndOfPeiCallback (
@@ -233,6 +237,7 @@ CpuMpEndOfPeiCallback (
@param Procedure The function to be invoked by AP
@param ProcedureArgument The argument to be passed into AP function
**/
+STATIC
VOID
WakeUpAP (
IN PEI_CPU_MP_DATA *PeiCpuMpData,
@@ -261,6 +266,7 @@ GetMpHobData (
@retval EFI_SUCCESS ProcessorNumber is found and returned.
@retval EFI_NOT_FOUND ProcessorNumber is not found.
**/
+STATIC
EFI_STATUS
GetProcessorNumber (
IN PEI_CPU_MP_DATA *PeiCpuMpData,
@@ -274,13 +280,11 @@ GetProcessorNumber (
or SEC Platform Information PPI.
@param PeiServices Pointer to PEI Services Table
- @param PeiCpuMpData Pointer to PEI CPU MP Data
**/
VOID
CollectBistDataFromPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN PEI_CPU_MP_DATA *PeiCpuMpData
+ IN CONST EFI_PEI_SERVICES **PeiServices
);
/**
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 5f45662..532e8a7 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -67,6 +67,7 @@ [LibraryClasses]
UefiCpuLib
CpuLib
CpuExceptionHandlerLib
+ MpInitLib
[Ppis]
gEfiPeiMpServicesPpiGuid ## PRODUCES
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
index e06fdf1..44e8f21 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -33,12 +33,14 @@ EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
&mMpServicesPpi
};
+
/**
Get CPU Package/Core/Thread location information.
@param InitialApicId CPU APIC ID
@param Location Pointer to CPU location information
**/
+STATIC
VOID
ExtractProcessorLocation (
IN UINT32 InitialApicId,
@@ -144,40 +146,13 @@ ExtractProcessorLocation (
}
/**
- Find the current Processor number by APIC ID.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
- @param ProcessorNumber Return the pocessor number found
-
- @retval EFI_SUCCESS ProcessorNumber is found and returned.
- @retval EFI_NOT_FOUND ProcessorNumber is not found.
-**/
-EFI_STATUS
-GetProcessorNumber (
- IN PEI_CPU_MP_DATA *PeiCpuMpData,
- OUT UINTN *ProcessorNumber
- )
-{
- UINTN TotalProcessorNumber;
- UINTN Index;
-
- TotalProcessorNumber = PeiCpuMpData->CpuCount;
- for (Index = 0; Index < TotalProcessorNumber; Index ++) {
- if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
- *ProcessorNumber = Index;
- return EFI_SUCCESS;
- }
- }
- return EFI_NOT_FOUND;
-}
-
-/**
Worker function for SwitchBSP().
Worker function for SwitchBSP(), assigned to the AP which is intended to become BSP.
@param Buffer Pointer to CPU MP Data
**/
+STATIC
VOID
EFIAPI
FutureBSPProc (
@@ -233,41 +208,14 @@ PeiGetNumberOfProcessors (
OUT UINTN *NumberOfEnabledProcessors
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
- UINTN ProcessorNumber;
- UINTN EnabledProcessorNumber;
- UINTN Index;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
return EFI_INVALID_PARAMETER;
}
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_DEVICE_ERROR;
- }
-
- ProcessorNumber = PeiCpuMpData->CpuCount;
- EnabledProcessorNumber = 0;
- for (Index = 0; Index < ProcessorNumber; Index++) {
- if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
- EnabledProcessorNumber ++;
- }
- }
-
- *NumberOfProcessors = ProcessorNumber;
- *NumberOfEnabledProcessors = EnabledProcessorNumber;
-
- return EFI_SUCCESS;
+ return MpInitLibGetNumberOfProcessors (
+ NumberOfProcessors,
+ NumberOfEnabledProcessors
+ );
}
/**
@@ -305,50 +253,7 @@ PeiGetProcessorInfo (
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_DEVICE_ERROR;
- }
-
- if (ProcessorInfoBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
- return EFI_NOT_FOUND;
- }
-
- ProcessorInfoBuffer->ProcessorId = (UINT64) PeiCpuMpData->CpuData[ProcessorNumber].ApicId;
- ProcessorInfoBuffer->StatusFlag = 0;
- if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId == GetInitialApicId()) {
- ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
- }
- if (PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy) {
- ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT;
- }
- if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
- ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT;
- } else {
- ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;
- }
-
- //
- // Get processor location information
- //
- ExtractProcessorLocation (PeiCpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);
-
- return EFI_SUCCESS;
+ return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
}
/**
@@ -425,131 +330,14 @@ PeiStartupAllAPs (
IN VOID *ProcedureArgument OPTIONAL
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN ProcessorNumber;
- UINTN Index;
- UINTN CallerNumber;
- BOOLEAN HasEnabledAp;
- BOOLEAN HasEnabledIdleAp;
- volatile UINT32 *FinishedCount;
- EFI_STATUS Status;
- UINTN WaitCountIndex;
- UINTN WaitCountNumber;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- if (Procedure == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_DEVICE_ERROR;
- }
-
- ProcessorNumber = PeiCpuMpData->CpuCount;
-
- HasEnabledAp = FALSE;
- HasEnabledIdleAp = FALSE;
- for (Index = 0; Index < ProcessorNumber; Index ++) {
- if (Index == CallerNumber) {
- //
- // Skip BSP
- //
- continue;
- }
- if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
- HasEnabledAp = TRUE;
- if (PeiCpuMpData->CpuData[Index].State != CpuStateBusy) {
- HasEnabledIdleAp = TRUE;
- }
- }
- }
- if (!HasEnabledAp) {
- //
- // If no enabled AP exists, return EFI_NOT_STARTED.
- //
- return EFI_NOT_STARTED;
- }
- if (!HasEnabledIdleAp) {
- //
- // If any enabled APs are busy, return EFI_NOT_READY.
- //
- return EFI_NOT_READY;
- }
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Backup original data and copy AP reset vector in it
- //
- BackupAndPrepareWakeupBuffer(PeiCpuMpData);
- }
-
- WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1;
- WaitCountIndex = 0;
- FinishedCount = &PeiCpuMpData->FinishedCount;
- if (!SingleThread) {
- WakeUpAP (PeiCpuMpData, TRUE, 0, Procedure, ProcedureArgument);
- //
- // Wait to finish
- //
- if (TimeoutInMicroSeconds == 0) {
- while (*FinishedCount < ProcessorNumber - 1) {
- CpuPause ();
- }
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_TIMEOUT;
- for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
- MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
- if (*FinishedCount >= ProcessorNumber - 1) {
- Status = EFI_SUCCESS;
- break;
- }
- }
- }
- } else {
- Status = EFI_SUCCESS;
- for (Index = 0; Index < ProcessorNumber; Index++) {
- if (Index == CallerNumber) {
- continue;
- }
- WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument);
- //
- // Wait to finish
- //
- if (TimeoutInMicroSeconds == 0) {
- while (*FinishedCount < 1) {
- CpuPause ();
- }
- } else {
- for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
- MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
- if (*FinishedCount >= 1) {
- break;
- }
- }
- if (WaitCountIndex == WaitCountNumber) {
- Status = EFI_TIMEOUT;
- }
- }
- }
- }
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Restore original data
- //
- RestoreWakeupBuffer(PeiCpuMpData);
- }
-
- return Status;
+ return MpInitLibStartupAllAPs (
+ Procedure,
+ SingleThread,
+ NULL,
+ TimeoutInMicroSeconds,
+ ProcedureArgument,
+ NULL
+ );
}
/**
@@ -609,81 +397,14 @@ PeiStartupThisAP (
IN VOID *ProcedureArgument OPTIONAL
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
- volatile UINT32 *FinishedCount;
- EFI_STATUS Status;
- UINTN WaitCountIndex;
- UINTN WaitCountNumber;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_DEVICE_ERROR;
- }
-
- if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
- return EFI_NOT_FOUND;
- }
-
- if (ProcessorNumber == PeiCpuMpData->BspNumber || Procedure == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether specified AP is disabled
- //
- if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Backup original data and copy AP reset vector in it
- //
- BackupAndPrepareWakeupBuffer(PeiCpuMpData);
- }
-
- WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;
- WaitCountIndex = 0;
- FinishedCount = &PeiCpuMpData->FinishedCount;
-
- WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);
-
- //
- // Wait to finish
- //
- if (TimeoutInMicroseconds == 0) {
- while (*FinishedCount < 1) {
- CpuPause() ;
- }
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_TIMEOUT;
- for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
- MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
- if (*FinishedCount >= 1) {
- Status = EFI_SUCCESS;
- break;
- }
- }
- }
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Backup original data and copy AP reset vector in it
- //
- RestoreWakeupBuffer(PeiCpuMpData);
- }
-
- return Status;
+ return MpInitLibStartupThisAP (
+ Procedure,
+ ProcessorNumber,
+ NULL,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ NULL
+ );
}
/**
@@ -729,97 +450,7 @@ PeiSwitchBSP (
IN BOOLEAN EnableOldBSP
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
- MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_SUCCESS;
- }
-
- if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether specified AP is disabled
- //
- if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether ProcessorNumber specifies the current BSP
- //
- if (ProcessorNumber == PeiCpuMpData->BspNumber) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether specified AP is busy
- //
- if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateBusy) {
- return EFI_NOT_READY;
- }
-
- //
- // Clear the BSP bit of MSR_IA32_APIC_BASE
- //
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- ApicBaseMsr.Bits.BSP = 0;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
-
- PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
- PeiCpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE;
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Backup original data and copy AP reset vector in it
- //
- BackupAndPrepareWakeupBuffer(PeiCpuMpData);
- }
-
- //
- // Need to wakeUp AP (future BSP).
- //
- WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData);
-
- AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);
-
- if (PeiCpuMpData->EndOfPeiFlag) {
- //
- // Backup original data and copy AP reset vector in it
- //
- RestoreWakeupBuffer(PeiCpuMpData);
- }
-
- //
- // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
- //
- ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
- ApicBaseMsr.Bits.BSP = 1;
- AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
- //
- // Set old BSP enable state
- //
- if (!EnableOldBSP) {
- PeiCpuMpData->CpuData[PeiCpuMpData->BspNumber].State = CpuStateDisabled;
- }
- //
- // Save new BSP number
- //
- PeiCpuMpData->BspNumber = (UINT32) ProcessorNumber;
-
- return EFI_SUCCESS;
+ return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
}
/**
@@ -871,41 +502,7 @@ PeiEnableDisableAP (
IN UINT32 *HealthFlag OPTIONAL
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN CallerNumber;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Check whether caller processor is BSP
- //
- PeiWhoAmI (PeiServices, This, &CallerNumber);
- if (CallerNumber != PeiCpuMpData->BspNumber) {
- return EFI_DEVICE_ERROR;
- }
-
- if (ProcessorNumber == PeiCpuMpData->BspNumber) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
- return EFI_NOT_FOUND;
- }
-
- if (!EnableAP) {
- PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateDisabled;
- } else {
- PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
- }
-
- if (HealthFlag != NULL) {
- PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy =
- (BOOLEAN) ((*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT) != 0);
- }
- return EFI_SUCCESS;
+ return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
}
/**
@@ -940,17 +537,5 @@ PeiWhoAmI (
OUT UINTN *ProcessorNumber
)
{
- PEI_CPU_MP_DATA *PeiCpuMpData;
-
- PeiCpuMpData = GetMpHobData ();
- if (PeiCpuMpData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- if (ProcessorNumber == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- return GetProcessorNumber (PeiCpuMpData, ProcessorNumber);
+ return MpInitLibWhoAmI (ProcessorNumber);
}
-
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 598c797..50f9af7 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -70,6 +70,7 @@ [LibraryClasses.common.PEIM]
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM]
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 39/46] UefiCpuPkg/CpuMpPei: Remove unused files and codes
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (37 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 38/46] UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 40/46] UefiCpuPkg/CpuMpPei: Delete PeiMpServices.c and PeiMpServices.h Jeff Fan
` (6 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 837 ----------------------------------
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 248 ----------
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 29 --
UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc | 39 --
UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm | 250 ----------
UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm | 229 ----------
UefiCpuPkg/CpuMpPei/Microcode.c | 213 ---------
UefiCpuPkg/CpuMpPei/Microcode.h | 58 ---
UefiCpuPkg/CpuMpPei/PeiMpServices.c | 131 ------
UefiCpuPkg/CpuMpPei/PeiMpServices.h | 23 -
UefiCpuPkg/CpuMpPei/X64/MpEqu.inc | 41 --
UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm | 290 ------------
UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm | 281 ------------
13 files changed, 2669 deletions(-)
delete mode 100644 UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
delete mode 100644 UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
delete mode 100644 UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
delete mode 100644 UefiCpuPkg/CpuMpPei/Microcode.c
delete mode 100644 UefiCpuPkg/CpuMpPei/Microcode.h
delete mode 100644 UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
delete mode 100644 UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
delete mode 100644 UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index b5f8887..a36adf6 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -13,843 +13,6 @@
**/
#include "CpuMpPei.h"
-
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiEndOfPeiSignalPpiGuid,
- CpuMpEndOfPeiCallback
-};
-
-/**
- Sort the APIC ID of all processors.
-
- This function sorts the APIC ID of all processors so that processor number is
- assigned in the ascending order of APIC ID which eases MP debugging.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-STATIC
-VOID
-SortApicId (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- )
-{
- UINTN Index1;
- UINTN Index2;
- UINTN Index3;
- UINT32 ApicId;
- PEI_CPU_DATA CpuData;
- UINT32 ApCount;
-
- ApCount = PeiCpuMpData->CpuCount - 1;
-
- if (ApCount != 0) {
- for (Index1 = 0; Index1 < ApCount; Index1++) {
- Index3 = Index1;
- //
- // Sort key is the hardware default APIC ID
- //
- ApicId = PeiCpuMpData->CpuData[Index1].ApicId;
- for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) {
- if (ApicId > PeiCpuMpData->CpuData[Index2].ApicId) {
- Index3 = Index2;
- ApicId = PeiCpuMpData->CpuData[Index2].ApicId;
- }
- }
- if (Index3 != Index1) {
- CopyMem (&CpuData, &PeiCpuMpData->CpuData[Index3], sizeof (PEI_CPU_DATA));
- CopyMem (
- &PeiCpuMpData->CpuData[Index3],
- &PeiCpuMpData->CpuData[Index1],
- sizeof (PEI_CPU_DATA)
- );
- CopyMem (&PeiCpuMpData->CpuData[Index1], &CpuData, sizeof (PEI_CPU_DATA));
- }
- }
-
- //
- // Get the processor number for the BSP
- //
- ApicId = GetInitialApicId ();
- for (Index1 = 0; Index1 < PeiCpuMpData->CpuCount; Index1++) {
- if (PeiCpuMpData->CpuData[Index1].ApicId == ApicId) {
- PeiCpuMpData->BspNumber = (UINT32) Index1;
- break;
- }
- }
- }
-}
-
-/**
- Enable x2APIC mode on APs.
-
- @param Buffer Pointer to private data buffer.
-**/
-STATIC
-VOID
-EFIAPI
-ApFuncEnableX2Apic (
- IN OUT VOID *Buffer
- )
-{
- SetApicMode (LOCAL_APIC_MODE_X2APIC);
-}
-
-/**
- Get AP loop mode.
-
- @param MonitorFilterSize Returns the largest monitor-line size in bytes.
-
- @return The AP loop mode.
-**/
-STATIC
-UINT8
-GetApLoopMode (
- OUT UINT16 *MonitorFilterSize
- )
-{
- UINT8 ApLoopMode;
- UINT32 RegEbx;
- UINT32 RegEcx;
- UINT32 RegEdx;
-
- ASSERT (MonitorFilterSize != NULL);
-
- ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
- ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);
- if (ApLoopMode == ApInMwaitLoop) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL);
- if ((RegEcx & BIT3) == 0) {
- //
- // If processor does not support MONITOR/MWAIT feature
- // by CPUID.[EAX=01H]:ECX.BIT3, force AP in Hlt-loop mode
- //
- ApLoopMode = ApInHltLoop;
- }
- }
-
- if (ApLoopMode == ApInHltLoop) {
- *MonitorFilterSize = 0;
- } else if (ApLoopMode == ApInRunLoop) {
- *MonitorFilterSize = sizeof (UINT32);
- } else if (ApLoopMode == ApInMwaitLoop) {
- //
- // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes
- // CPUID.[EAX=05H].EDX: C-states supported using MWAIT
- //
- AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &RegEbx, NULL, &RegEdx);
- *MonitorFilterSize = RegEbx & 0xFFFF;
- }
-
- return ApLoopMode;
-}
-
-/**
- Get CPU MP Data pointer from the Guided HOB.
-
- @return Pointer to Pointer to PEI CPU MP Data
-**/
-PEI_CPU_MP_DATA *
-GetMpHobData (
- VOID
- )
-{
- EFI_HOB_GUID_TYPE *GuidHob;
- VOID *DataInHob;
- PEI_CPU_MP_DATA *CpuMpData;
-
- CpuMpData = NULL;
- GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
- if (GuidHob != NULL) {
- DataInHob = GET_GUID_HOB_DATA (GuidHob);
- CpuMpData = (PEI_CPU_MP_DATA *)(*(UINTN *)DataInHob);
- }
- ASSERT (CpuMpData != NULL);
- return CpuMpData;
-}
-
-/**
- Save the volatile registers required to be restored following INIT IPI.
-
- @param VolatileRegisters Returns buffer saved the volatile resisters
-**/
-STATIC
-VOID
-SaveVolatileRegisters (
- OUT CPU_VOLATILE_REGISTERS *VolatileRegisters
- )
-{
- UINT32 RegEdx;
-
- VolatileRegisters->Cr0 = AsmReadCr0 ();
- VolatileRegisters->Cr3 = AsmReadCr3 ();
- VolatileRegisters->Cr4 = AsmReadCr4 ();
-
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT2) != 0) {
- //
- // If processor supports Debugging Extensions feature
- // by CPUID.[EAX=01H]:EDX.BIT2
- //
- VolatileRegisters->Dr0 = AsmReadDr0 ();
- VolatileRegisters->Dr1 = AsmReadDr1 ();
- VolatileRegisters->Dr2 = AsmReadDr2 ();
- VolatileRegisters->Dr3 = AsmReadDr3 ();
- VolatileRegisters->Dr6 = AsmReadDr6 ();
- VolatileRegisters->Dr7 = AsmReadDr7 ();
- }
-}
-
-/**
- Restore the volatile registers following INIT IPI.
-
- @param VolatileRegisters Pointer to volatile resisters
- @param IsRestoreDr TRUE: Restore DRx if supported
- FALSE: Do not restore DRx
-**/
-STATIC
-VOID
-RestoreVolatileRegisters (
- IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
- IN BOOLEAN IsRestoreDr
- )
-{
- UINT32 RegEdx;
-
- AsmWriteCr0 (VolatileRegisters->Cr0);
- AsmWriteCr3 (VolatileRegisters->Cr3);
- AsmWriteCr4 (VolatileRegisters->Cr4);
-
- if (IsRestoreDr) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT2) != 0) {
- //
- // If processor supports Debugging Extensions feature
- // by CPUID.[EAX=01H]:EDX.BIT2
- //
- AsmWriteDr0 (VolatileRegisters->Dr0);
- AsmWriteDr1 (VolatileRegisters->Dr1);
- AsmWriteDr2 (VolatileRegisters->Dr2);
- AsmWriteDr3 (VolatileRegisters->Dr3);
- AsmWriteDr6 (VolatileRegisters->Dr6);
- AsmWriteDr7 (VolatileRegisters->Dr7);
- }
- }
-}
-
-/**
- Find the current Processor number by APIC ID.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
- @param ProcessorNumber Return the pocessor number found
-
- @retval EFI_SUCCESS ProcessorNumber is found and returned.
- @retval EFI_NOT_FOUND ProcessorNumber is not found.
-**/
-STATIC
-EFI_STATUS
-GetProcessorNumber (
- IN PEI_CPU_MP_DATA *PeiCpuMpData,
- OUT UINTN *ProcessorNumber
- )
-{
- UINTN TotalProcessorNumber;
- UINTN Index;
-
- TotalProcessorNumber = PeiCpuMpData->CpuCount;
- for (Index = 0; Index < TotalProcessorNumber; Index ++) {
- if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
- *ProcessorNumber = Index;
- return EFI_SUCCESS;
- }
- }
- return EFI_NOT_FOUND;
-}
-
-/**
- This function will be called from AP reset code if BSP uses WakeUpAP.
-
- @param ExchangeInfo Pointer to the MP exchange info buffer
- @param NumApsExecuting Number of current executing AP
-**/
-STATIC
-VOID
-EFIAPI
-ApCFunction (
- IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
- IN UINTN NumApsExecuting
- )
-{
- PEI_CPU_MP_DATA *PeiCpuMpData;
- UINTN ProcessorNumber;
- EFI_AP_PROCEDURE Procedure;
- UINTN BistData;
- volatile UINT32 *ApStartupSignalBuffer;
-
- PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
- while (TRUE) {
- if (PeiCpuMpData->InitFlag) {
- ProcessorNumber = NumApsExecuting;
- //
- // Sync BSP's Control registers to APs
- //
- RestoreVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters, FALSE);
- //
- // This is first time AP wakeup, get BIST information from AP stack
- //
- BistData = *(UINTN *) (PeiCpuMpData->Buffer + ProcessorNumber * PeiCpuMpData->CpuApStackSize - sizeof (UINTN));
- PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 = (UINT32) BistData;
- PeiCpuMpData->CpuData[ProcessorNumber].ApicId = GetInitialApicId ();
- if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId >= 0xFF) {
- //
- // Set x2APIC mode if there are any logical processor reporting
- // an APIC ID of 255 or greater.
- //
- AcquireSpinLock(&PeiCpuMpData->MpLock);
- PeiCpuMpData->X2ApicEnable = TRUE;
- ReleaseSpinLock(&PeiCpuMpData->MpLock);
- }
- //
- // Sync BSP's Mtrr table to all wakeup APs and load microcode on APs.
- //
- MtrrSetAllMtrrs (&PeiCpuMpData->MtrrTable);
- MicrocodeDetect (PeiCpuMpData);
- PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
- } else {
- //
- // Execute AP function if AP is not disabled
- //
- GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
- if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Restore AP's volatile registers saved
- //
- RestoreVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
- }
-
- if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) &&
- (PeiCpuMpData->ApFunction != 0)) {
- PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateBusy;
- Procedure = (EFI_AP_PROCEDURE)(UINTN)PeiCpuMpData->ApFunction;
- //
- // Invoke AP function here
- //
- Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument);
- //
- // Re-get the processor number due to BSP/AP maybe exchange in AP function
- //
- GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
- PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
- }
- }
-
- //
- // AP finished executing C code
- //
- InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount);
-
- //
- // Place AP is specified loop mode
- //
- if (PeiCpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Save AP volatile registers
- //
- SaveVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
- //
- // Place AP in Hlt-loop
- //
- while (TRUE) {
- DisableInterrupts ();
- CpuSleep ();
- CpuPause ();
- }
- }
- ApStartupSignalBuffer = PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal;
- while (TRUE) {
- DisableInterrupts ();
- if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
- //
- // Place AP in Mwait-loop
- //
- AsmMonitor ((UINTN)ApStartupSignalBuffer, 0, 0);
- if (*ApStartupSignalBuffer != WAKEUP_AP_SIGNAL) {
- //
- // If AP start-up signal is not set, place AP into
- // the maximum C-state
- //
- AsmMwait (PeiCpuMpData->ApTargetCState << 4, 0);
- }
- } else if (PeiCpuMpData->ApLoopMode == ApInRunLoop) {
- //
- // Place AP in Run-loop
- //
- CpuPause ();
- } else {
- ASSERT (FALSE);
- }
-
- //
- // If AP start-up signal is written, AP is waken up
- // otherwise place AP in loop again
- //
- if (*ApStartupSignalBuffer == WAKEUP_AP_SIGNAL) {
- //
- // Clear AP start-up signal when AP waken up
- //
- InterlockedCompareExchange32 (
- (UINT32 *)ApStartupSignalBuffer,
- WAKEUP_AP_SIGNAL,
- 0
- );
- break;
- }
- }
- }
-}
-
-/**
- Write AP start-up signal to wakeup AP.
-
- @param ApStartupSignalBuffer Pointer to AP wakeup signal
-**/
-VOID
-WriteStartupSignal (
- IN volatile UINT32 *ApStartupSignalBuffer
- )
-{
- *ApStartupSignalBuffer = WAKEUP_AP_SIGNAL;
- //
- // If AP is waken up, StartupApSignal should be cleared.
- // Otherwise, write StartupApSignal again till AP waken up.
- //
- while (InterlockedCompareExchange32 (
- (UINT32 *)ApStartupSignalBuffer,
- WAKEUP_AP_SIGNAL,
- WAKEUP_AP_SIGNAL
- ) != 0) {
- CpuPause ();
- }
-}
-
-/**
- This function will be called by BSP to wakeup AP.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
- @param Broadcast TRUE: Send broadcast IPI to all APs
- FALSE: Send IPI to AP by ApicId
- @param ProcessorNumber The handle number of specified processor
- @param Procedure The function to be invoked by AP
- @param ProcedureArgument The argument to be passed into AP function
-**/
-STATIC
-VOID
-WakeUpAP (
- IN PEI_CPU_MP_DATA *PeiCpuMpData,
- IN BOOLEAN Broadcast,
- IN UINTN ProcessorNumber,
- IN EFI_AP_PROCEDURE Procedure, OPTIONAL
- IN VOID *ProcedureArgument OPTIONAL
- )
-{
- volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
- UINTN Index;
-
- PeiCpuMpData->ApFunction = (UINTN) Procedure;
- PeiCpuMpData->ApFunctionArgument = (UINTN) ProcedureArgument;
- PeiCpuMpData->FinishedCount = 0;
-
- ExchangeInfo = PeiCpuMpData->MpCpuExchangeInfo;
- ExchangeInfo->Lock = 0;
- ExchangeInfo->StackStart = PeiCpuMpData->Buffer;
- ExchangeInfo->StackSize = PeiCpuMpData->CpuApStackSize;
- ExchangeInfo->BufferStart = PeiCpuMpData->WakeupBuffer;
- ExchangeInfo->ModeOffset = PeiCpuMpData->AddressMap.ModeEntryOffset;
- ExchangeInfo->Cr3 = AsmReadCr3 ();
- ExchangeInfo->CodeSegment = AsmReadCs ();
- ExchangeInfo->DataSegment = AsmReadDs ();
- ExchangeInfo->CFunction = (UINTN) ApCFunction;
- ExchangeInfo->NumApsExecuting = 0;
- ExchangeInfo->PeiCpuMpData = PeiCpuMpData;
-
- //
- // Get the BSP's data of GDT and IDT
- //
- AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile);
- AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);
-
- if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
- //
- // Get AP target C-state each time when waking up AP,
- // for it maybe updated by platform again
- //
- PeiCpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate);
- }
-
- //
- // Wakeup APs per AP loop state
- //
- if (PeiCpuMpData->ApLoopMode == ApInHltLoop || PeiCpuMpData->InitFlag) {
- if (Broadcast) {
- SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
- } else {
- SendInitSipiSipi (
- PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
- (UINT32) ExchangeInfo->BufferStart
- );
- }
- } else if ((PeiCpuMpData->ApLoopMode == ApInMwaitLoop) ||
- (PeiCpuMpData->ApLoopMode == ApInRunLoop)) {
- if (Broadcast) {
- for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) {
- if (Index != PeiCpuMpData->BspNumber) {
- WriteStartupSignal (PeiCpuMpData->CpuData[Index].StartupApSignal);
- }
- }
- } else {
- WriteStartupSignal (PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal);
- }
- } else {
- ASSERT (FALSE);
- }
- return ;
-}
-
-/**
- Get available system memory below 1MB by specified size.
-
- @param WakeupBufferSize Wakeup buffer size required
-
- @retval other Return wakeup buffer address below 1MB.
- @retval -1 Cannot find free memory below 1MB.
-**/
-STATIC
-UINTN
-GetWakeupBuffer (
- IN UINTN WakeupBufferSize
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
- UINTN WakeupBufferStart;
- UINTN WakeupBufferEnd;
-
- //
- // Get the HOB list for processing
- //
- Hob.Raw = GetHobList ();
-
- //
- // Collect memory ranges
- //
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- if ((Hob.ResourceDescriptor->PhysicalStart < BASE_1MB) &&
- (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
- ((Hob.ResourceDescriptor->ResourceAttribute &
- (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
- EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED
- )) == 0)
- ) {
- //
- // Need memory under 1MB to be collected here
- //
- WakeupBufferEnd = (UINTN) (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength);
- if (WakeupBufferEnd > BASE_1MB) {
- //
- // Wakeup buffer should be under 1MB
- //
- WakeupBufferEnd = BASE_1MB;
- }
- //
- // Wakeup buffer should be aligned on 4KB
- //
- WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1);
- if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {
- continue;
- }
- //
- // Create a memory allocation HOB.
- //
- BuildMemoryAllocationHob (
- WakeupBufferStart,
- WakeupBufferSize,
- EfiBootServicesData
- );
- return WakeupBufferStart;
- }
- }
- //
- // Find the next HOB
- //
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
-
- return (UINTN) -1;
-}
-
-/**
- Get available system memory below 1MB by specified size.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-STATIC
-VOID
-BackupAndPrepareWakeupBuffer(
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- )
-{
- CopyMem (
- (VOID *) PeiCpuMpData->BackupBuffer,
- (VOID *) PeiCpuMpData->WakeupBuffer,
- PeiCpuMpData->BackupBufferSize
- );
- CopyMem (
- (VOID *) PeiCpuMpData->WakeupBuffer,
- (VOID *) PeiCpuMpData->AddressMap.RendezvousFunnelAddress,
- PeiCpuMpData->AddressMap.RendezvousFunnelSize
- );
-}
-
-/**
- Restore wakeup buffer data.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-STATIC
-VOID
-RestoreWakeupBuffer(
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- )
-{
- CopyMem ((VOID *) PeiCpuMpData->WakeupBuffer, (VOID *) PeiCpuMpData->BackupBuffer, PeiCpuMpData->BackupBufferSize);
-}
-
-/**
- This function will get CPU count in the system.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-
- @return AP processor count
-**/
-UINT32
-CountProcessorNumber (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- )
-{
- //
- // Load Microcode on BSP
- //
- MicrocodeDetect (PeiCpuMpData);
- //
- // Store BSP's MTRR setting
- //
- MtrrGetAllMtrrs (&PeiCpuMpData->MtrrTable);
-
- //
- // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
- //
- if (PcdGet32 (PcdCpuMaxLogicalProcessorNumber) > 1) {
- //
- // Send 1st broadcast IPI to APs to wakeup APs
- //
- PeiCpuMpData->InitFlag = TRUE;
- PeiCpuMpData->X2ApicEnable = FALSE;
- WakeUpAP (PeiCpuMpData, TRUE, 0, NULL, NULL);
- //
- // Wait for AP task to complete and then exit.
- //
- MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
- PeiCpuMpData->InitFlag = FALSE;
- PeiCpuMpData->CpuCount += (UINT32)PeiCpuMpData->MpCpuExchangeInfo->NumApsExecuting;
- ASSERT (PeiCpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- //
- // Wait for all APs finished the initialization
- //
- while (PeiCpuMpData->FinishedCount < (PeiCpuMpData->CpuCount - 1)) {
- CpuPause ();
- }
-
- if (PeiCpuMpData->X2ApicEnable) {
- DEBUG ((EFI_D_INFO, "Force x2APIC mode!\n"));
- //
- // Wakeup all APs to enable x2APIC mode
- //
- WakeUpAP (PeiCpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL);
- //
- // Wait for all known APs finished
- //
- while (PeiCpuMpData->FinishedCount < (PeiCpuMpData->CpuCount - 1)) {
- CpuPause ();
- }
- //
- // Enable x2APIC on BSP
- //
- SetApicMode (LOCAL_APIC_MODE_X2APIC);
- }
- DEBUG ((EFI_D_INFO, "APIC MODE is %d\n", GetApicMode ()));
- //
- // Sort BSP/Aps by CPU APIC ID in ascending order
- //
- SortApicId (PeiCpuMpData);
- }
-
- DEBUG ((EFI_D_INFO, "CpuMpPei: Find %d processors in system.\n", PeiCpuMpData->CpuCount));
- return PeiCpuMpData->CpuCount;
-}
-
-/**
- Prepare for AP wakeup buffer and copy AP reset code into it.
-
- Get wakeup buffer below 1MB. Allocate memory for CPU MP Data and APs Stack.
-
- @return Pointer to PEI CPU MP Data
-**/
-PEI_CPU_MP_DATA *
-PrepareAPStartupVector (
- VOID
- )
-{
- EFI_STATUS Status;
- UINT32 MaxCpuCount;
- PEI_CPU_MP_DATA *PeiCpuMpData;
- EFI_PHYSICAL_ADDRESS Buffer;
- UINTN BufferSize;
- UINTN WakeupBuffer;
- UINTN WakeupBufferSize;
- MP_ASSEMBLY_ADDRESS_MAP AddressMap;
- UINT8 ApLoopMode;
- UINT16 MonitorFilterSize;
- UINT8 *MonitorBuffer;
- UINTN Index;
-
- AsmGetAddressMap (&AddressMap);
- WakeupBufferSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
- WakeupBuffer = GetWakeupBuffer ((WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1));
- ASSERT (WakeupBuffer != (UINTN) -1);
- DEBUG ((EFI_D_INFO, "CpuMpPei: WakeupBuffer = 0x%x\n", WakeupBuffer));
-
- //
- // Allocate Pages for APs stack, CPU MP Data, backup buffer for wakeup buffer,
- // and monitor buffer if required.
- //
- MaxCpuCount = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
- BufferSize = PcdGet32 (PcdCpuApStackSize) * MaxCpuCount + sizeof (PEI_CPU_MP_DATA)
- + WakeupBufferSize + sizeof (PEI_CPU_DATA) * MaxCpuCount;
- ApLoopMode = GetApLoopMode (&MonitorFilterSize);
- BufferSize += MonitorFilterSize * MaxCpuCount;
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- ASSERT_EFI_ERROR (Status);
-
- PeiCpuMpData = (PEI_CPU_MP_DATA *) (UINTN) (Buffer + PcdGet32 (PcdCpuApStackSize) * MaxCpuCount);
- PeiCpuMpData->Buffer = (UINTN) Buffer;
- PeiCpuMpData->CpuApStackSize = PcdGet32 (PcdCpuApStackSize);
- PeiCpuMpData->WakeupBuffer = WakeupBuffer;
- PeiCpuMpData->BackupBuffer = (UINTN)PeiCpuMpData + sizeof (PEI_CPU_MP_DATA);
- PeiCpuMpData->BackupBufferSize = WakeupBufferSize;
- PeiCpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (WakeupBuffer + AddressMap.RendezvousFunnelSize);
-
- PeiCpuMpData->CpuCount = 1;
- PeiCpuMpData->BspNumber = 0;
- PeiCpuMpData->CpuData = (PEI_CPU_DATA *) (PeiCpuMpData->BackupBuffer +
- PeiCpuMpData->BackupBufferSize);
- PeiCpuMpData->CpuData[0].ApicId = GetInitialApicId ();
- PeiCpuMpData->CpuData[0].Health.Uint32 = 0;
- PeiCpuMpData->EndOfPeiFlag = FALSE;
- InitializeSpinLock(&PeiCpuMpData->MpLock);
- SaveVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters);
- CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));
- //
- // Initialize AP loop mode
- //
- PeiCpuMpData->ApLoopMode = ApLoopMode;
- DEBUG ((EFI_D_INFO, "AP Loop Mode is %d\n", PeiCpuMpData->ApLoopMode));
- MonitorBuffer = (UINT8 *)(PeiCpuMpData->CpuData + MaxCpuCount);
- if (PeiCpuMpData->ApLoopMode != ApInHltLoop) {
- //
- // Set up APs wakeup signal buffer
- //
- for (Index = 0; Index < MaxCpuCount; Index++) {
- PeiCpuMpData->CpuData[Index].StartupApSignal =
- (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);
- }
- }
- //
- // Backup original data and copy AP reset code in it
- //
- BackupAndPrepareWakeupBuffer(PeiCpuMpData);
-
- return PeiCpuMpData;
-}
-
-/**
- Notify function on End Of Pei PPI.
-
- On S3 boot, this function will restore wakeup buffer data.
- On normal boot, this function will flag wakeup buffer to be un-used type.
-
- @param PeiServices The pointer to the PEI Services Table.
- @param NotifyDescriptor Address of the notification descriptor data structure.
- @param Ppi Address of the PPI that was installed.
-
- @retval EFI_SUCCESS When everything is OK.
-
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CpuMpEndOfPeiCallback (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- )
-{
- EFI_STATUS Status;
- EFI_BOOT_MODE BootMode;
- PEI_CPU_MP_DATA *PeiCpuMpData;
- EFI_PEI_HOB_POINTERS Hob;
- EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
-
- DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invoked\n"));
-
- Status = PeiServicesGetBootMode (&BootMode);
- ASSERT_EFI_ERROR (Status);
-
- PeiCpuMpData = GetMpHobData ();
- ASSERT (PeiCpuMpData != NULL);
-
- if (BootMode != BOOT_ON_S3_RESUME) {
- //
- // Get the HOB list for processing
- //
- Hob.Raw = GetHobList ();
- //
- // Collect memory ranges
- //
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
- MemoryHob = Hob.MemoryAllocation;
- if(MemoryHob->AllocDescriptor.MemoryBaseAddress == PeiCpuMpData->WakeupBuffer) {
- //
- // Flag this HOB type to un-used
- //
- GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
- break;
- }
- }
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
- } else {
- RestoreWakeupBuffer (PeiCpuMpData);
- PeiCpuMpData->EndOfPeiFlag = TRUE;
- }
- return EFI_SUCCESS;
-}
-
/**
The Entry point of the MP CPU PEIM.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index fb57669..5a422b2 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -21,259 +21,21 @@
#include <Ppi/SecPlatformInformation.h>
#include <Ppi/SecPlatformInformation2.h>
#include <Ppi/EndOfPeiPhase.h>
-#include <Ppi/VectorHandoffInfo.h>
-
-#include <Register/Cpuid.h>
-#include <Register/LocalApic.h>
-#include <Register/Msr.h>
#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/LocalApicLib.h>
-#include <Library/MtrrLib.h>
-#include <Library/PcdLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/ReportStatusCodeLib.h>
-#include <Library/SynchronizationLib.h>
-#include <Library/TimerLib.h>
-#include <Library/UefiCpuLib.h>
-#include <Library/CpuLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/MpInitLib.h>
-#include "Microcode.h"
-
-//
-// AP state
-//
-typedef enum {
- CpuStateIdle,
- CpuStateBusy,
- CpuStateDisabled
-} CPU_STATE;
-
-#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
-
-typedef enum {
- ApInHltLoop = 1,
- ApInMwaitLoop = 2,
- ApInRunLoop = 3
-} AP_LOOP_MODE;
-
-//
-// AP reset code information
-//
-typedef struct {
- UINT8 *RendezvousFunnelAddress;
- UINTN ModeEntryOffset;
- UINTN RendezvousFunnelSize;
-} MP_ASSEMBLY_ADDRESS_MAP;
-
-//
-// CPU exchange information for switch BSP
-//
-typedef struct {
- UINT8 State; // offset 0
- UINTN StackPointer; // offset 4 / 8
- IA32_DESCRIPTOR Gdtr; // offset 8 / 16
- IA32_DESCRIPTOR Idtr; // offset 14 / 26
-} CPU_EXCHANGE_ROLE_INFO;
-
-typedef struct _PEI_CPU_MP_DATA PEI_CPU_MP_DATA;
-
-#pragma pack(1)
-
-//
-// MP CPU exchange information for AP reset code
-// This structure is required to be packed because fixed field offsets
-// into this structure are used in assembly code in this module
-//
-typedef struct {
- UINTN Lock;
- UINTN StackStart;
- UINTN StackSize;
- UINTN CFunction;
- IA32_DESCRIPTOR GdtrProfile;
- IA32_DESCRIPTOR IdtrProfile;
- UINTN BufferStart;
- UINTN ModeOffset;
- UINTN NumApsExecuting;
- UINTN CodeSegment;
- UINTN DataSegment;
- UINTN Cr3;
- PEI_CPU_MP_DATA *PeiCpuMpData;
-} MP_CPU_EXCHANGE_INFO;
-
-#pragma pack()
-
-typedef struct {
- UINTN Cr0;
- UINTN Cr3;
- UINTN Cr4;
- UINTN Dr0;
- UINTN Dr1;
- UINTN Dr2;
- UINTN Dr3;
- UINTN Dr6;
- UINTN Dr7;
-} CPU_VOLATILE_REGISTERS;
-
-typedef struct {
- volatile UINT32 *StartupApSignal;
- UINT32 ApicId;
- EFI_HEALTH_FLAGS Health;
- CPU_STATE State;
- BOOLEAN CpuHealthy;
- CPU_VOLATILE_REGISTERS VolatileRegisters;
-} PEI_CPU_DATA;
-
-//
-// PEI CPU MP Data save in memory
-//
-struct _PEI_CPU_MP_DATA {
- SPIN_LOCK MpLock;
- UINT32 CpuCount;
- UINT32 BspNumber;
- UINTN Buffer;
- UINTN CpuApStackSize;
- MP_ASSEMBLY_ADDRESS_MAP AddressMap;
- UINTN WakeupBuffer;
- UINTN BackupBuffer;
- UINTN BackupBufferSize;
- UINTN ApFunction;
- UINTN ApFunctionArgument;
- volatile UINT32 FinishedCount;
- BOOLEAN EndOfPeiFlag;
- BOOLEAN InitFlag;
- BOOLEAN X2ApicEnable;
- CPU_EXCHANGE_ROLE_INFO BSPInfo;
- CPU_EXCHANGE_ROLE_INFO APInfo;
- MTRR_SETTINGS MtrrTable;
- UINT8 ApLoopMode;
- UINT8 ApTargetCState;
- PEI_CPU_DATA *CpuData;
- volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
-};
extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
/**
- Assembly code to get starting address and size of the rendezvous entry for APs.
- Information for fixing a jump instruction in the code is also returned.
-
- @param AddressMap Output buffer for address map information.
-**/
-VOID
-EFIAPI
-AsmGetAddressMap (
- OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
- );
-
-/**
- Assembly code to load GDT table and update segment accordingly.
-
- @param Gdtr Pointer to GDT descriptor
-**/
-VOID
-EFIAPI
-AsmInitializeGdt (
- IN IA32_DESCRIPTOR *Gdtr
- );
-
-/**
- Get available system memory below 1MB by specified size.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-STATIC
-VOID
-BackupAndPrepareWakeupBuffer(
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- );
-
-/**
- Restore wakeup buffer data.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-STATIC
-VOID
-RestoreWakeupBuffer(
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- );
-
-/**
- Notify function on End Of Pei PPI.
-
- On S3 boot, this function will restore wakeup buffer data.
- On normal boot, this function will flag wakeup buffer to be un-used type.
-
- @param PeiServices The pointer to the PEI Services Table.
- @param NotifyDescriptor Address of the notification descriptor data structure.
- @param Ppi Address of the PPI that was installed.
-
- @retval EFI_SUCCESS When everything is OK.
-
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CpuMpEndOfPeiCallback (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- );
-
-/**
- This function will be called by BSP to wakeup AP.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
- @param Broadcast TRUE: Send broadcast IPI to all APs
- FALSE: Send IPI to AP by ApicId
- @param ProcessorNumber The handle number of specified processor
- @param Procedure The function to be invoked by AP
- @param ProcedureArgument The argument to be passed into AP function
-**/
-STATIC
-VOID
-WakeUpAP (
- IN PEI_CPU_MP_DATA *PeiCpuMpData,
- IN BOOLEAN Broadcast,
- IN UINTN ProcessorNumber,
- IN EFI_AP_PROCEDURE Procedure, OPTIONAL
- IN VOID *ProcedureArgument OPTIONAL
- );
-
-/**
- Get CPU MP Data pointer from the Guided HOB.
-
- @return Pointer to Pointer to PEI CPU MP Data
-**/
-PEI_CPU_MP_DATA *
-GetMpHobData (
- VOID
- );
-
-/**
- Find the current Processor number by APIC ID.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
- @param ProcessorNumber Return the pocessor number found
-
- @retval EFI_SUCCESS ProcessorNumber is found and returned.
- @retval EFI_NOT_FOUND ProcessorNumber is not found.
-**/
-STATIC
-EFI_STATUS
-GetProcessorNumber (
- IN PEI_CPU_MP_DATA *PeiCpuMpData,
- OUT UINTN *ProcessorNumber
- );
-
-/**
Collects BIST data from PPI.
This function collects BIST data from Sec Platform Information2 PPI
@@ -307,14 +69,4 @@ SecPlatformInformation2 (
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
);
-/**
- Detect whether specified processor can find matching microcode patch and load it.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-VOID
-MicrocodeDetect (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- );
-
#endif
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 532e8a7..3bf9a8b 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -31,21 +31,9 @@ [Sources]
CpuMpPei.h
CpuMpPei.c
CpuBist.c
- Microcode.h
- Microcode.c
PeiMpServices.h
PeiMpServices.c
-[Sources.IA32]
- Ia32/MpEqu.inc
- Ia32/MpFuncs.asm
- Ia32/MpFuncs.nasm
-
-[Sources.X64]
- X64/MpEqu.inc
- X64/MpFuncs.asm
- X64/MpFuncs.nasm
-
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -53,40 +41,23 @@ [Packages]
[LibraryClasses]
BaseLib
- BaseMemoryLib
DebugLib
HobLib
LocalApicLib
- MtrrLib
- PcdLib
PeimEntryPoint
PeiServicesLib
ReportStatusCodeLib
- SynchronizationLib
- TimerLib
- UefiCpuLib
- CpuLib
CpuExceptionHandlerLib
MpInitLib
[Ppis]
gEfiPeiMpServicesPpiGuid ## PRODUCES
- gEfiEndOfPeiSignalPpiGuid ## NOTIFY
gEfiSecPlatformInformationPpiGuid ## SOMETIMES_CONSUMES
## SOMETIMES_CONSUMES
## SOMETIMES_PRODUCES
gEfiSecPlatformInformation2PpiGuid
gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES
-[Pcd]
- gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
-
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc b/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
deleted file mode 100644
index 773eab3..0000000
--- a/UefiCpuPkg/CpuMpPei/Ia32/MpEqu.inc
+++ /dev/null
@@ -1,39 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpEqu.inc
-;
-; Abstract:
-;
-; This is the equates file for Multiple Processor support
-;
-;-------------------------------------------------------------------------------
-
-VacantFlag equ 00h
-NotVacantFlag equ 0ffh
-
-CPU_SWITCH_STATE_IDLE equ 0
-CPU_SWITCH_STATE_STORED equ 1
-CPU_SWITCH_STATE_LOADED equ 2
-
-LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
-StackStartAddressLocation equ LockLocation + 04h
-StackSizeLocation equ LockLocation + 08h
-ApProcedureLocation equ LockLocation + 0Ch
-GdtrLocation equ LockLocation + 10h
-IdtrLocation equ LockLocation + 16h
-BufferStartLocation equ LockLocation + 1Ch
-ModeOffsetLocation equ LockLocation + 20h
-NumApsExecutingLoction equ LockLocation + 24h
-CodeSegmentLocation equ LockLocation + 28h
-DataSegmentLocation equ LockLocation + 2Ch
-
diff --git a/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm b/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
deleted file mode 100644
index 27e16c6..0000000
--- a/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
+++ /dev/null
@@ -1,250 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpFuncs32.asm
-;
-; Abstract:
-;
-; This is the assembly code for MP support
-;
-;-------------------------------------------------------------------------------
-
-.686p
-.model flat
-
-include MpEqu.inc
-InitializeFloatingPointUnits PROTO C
-
-.code
-
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-RendezvousFunnelProc PROC PUBLIC
-RendezvousFunnelProcStart::
-; At this point CS = 0x(vv00) and ip= 0x0.
-; Save BIST information to ebp firstly
- db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
-
- db 8ch,0c8h ; mov ax, cs
- db 8eh,0d8h ; mov ds, ax
- db 8eh,0c0h ; mov es, ax
- db 8eh,0d0h ; mov ss, ax
- db 33h,0c0h ; xor ax, ax
- db 8eh,0e0h ; mov fs, ax
- db 8eh,0e8h ; mov gs, ax
-
- db 0BEh ; opcode of mov si, mem16
- dw BufferStartLocation ; mov si, BufferStartLocation
- db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]
-
- db 0BEh ; opcode of mov si, mem16
- dw ModeOffsetLocation ; mov si, ModeOffsetLocation
- db 66h, 8Bh, 04h ; mov eax, [si]
- db 0BEh ; opcode of mov si, mem16
- dw CodeSegmentLocation ; mov si, CodeSegmentLocation
- db 66h, 8Bh, 14h ; mov edx, [si]
- db 89h, 0C7h ; mov di, ax
- db 83h, 0EFh, 02h ; sub di, 02h
- db 89h, 15h ; mov [di], dx
- db 83h, 0EFh, 04h ; sub di, 04h
- db 66h, 01h, 0D8h ; add eax, ebx
- db 66h, 89h, 05h ; mov [di], eax
-
- db 0BEh ; opcode of mov si, mem16
- dw DataSegmentLocation ; mov si, DataSegmentLocation
- db 66h, 8Bh, 14h ; mov edx, [si]
-
- db 0BEh ; opcode of mov si, mem16
- dw GdtrLocation ; mov si, GdtrLocation
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
-
- db 0BEh
- dw IdtrLocation ; mov si, IdtrLocation
- db 66h ; db 66h
- db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
-
- db 33h, 0C0h ; xor ax, ax
- db 8Eh, 0D8h ; mov ds, ax
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
- db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
- db 0Fh, 22h, 0C0h ; mov cr0, eax
-
- db 66h, 67h, 0EAh ; far jump
- dd 0h ; 32-bit offset
- dw 0h ; 16-bit selector
-
-Flat32Start:: ; protected mode entry point
- mov ds, dx
- mov es, dx
- mov fs, dx
- mov gs, dx
- mov ss, dx
-
- mov esi, ebx
- mov edi, esi
- add edi, LockLocation
- mov eax, NotVacantFlag
-
-TestLock:
- xchg dword ptr [edi], eax
- cmp eax, NotVacantFlag
- jz TestLock
-
- mov edi, esi
- add edi, NumApsExecutingLoction
- inc dword ptr [edi]
- mov ebx, dword ptr [edi]
-
-ProgramStack:
- mov edi, esi
- add edi, StackSizeLocation
- mov eax, dword ptr [edi]
- mov edi, esi
- add edi, StackStartAddressLocation
- add eax, dword ptr [edi]
- mov esp, eax
- mov dword ptr [edi], eax
-
-Releaselock:
- mov eax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg dword ptr [edi], eax
-
-CProcedureInvoke:
- push ebp ; push BIST data at top of AP stack
- xor ebp, ebp ; clear ebp for call stack trace
- push ebp
- mov ebp, esp
-
- mov eax, InitializeFloatingPointUnits
- call eax ; Call assembly function to initialize FPU per UEFI spec
-
- push ebx ; Push NumApsExecuting
- mov eax, esi
- add eax, LockLocation
- push eax ; push address of exchange info data buffer
-
- mov edi, esi
- add edi, ApProcedureLocation
- mov eax, dword ptr [edi]
-
- call eax ; invoke C function
-
- jmp $ ; never reach here
-
-RendezvousFunnelProc ENDP
-RendezvousFunnelProcEnd::
-
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-AsmGetAddressMap PROC near C PUBLIC
- pushad
- mov ebp,esp
-
- mov ebx, dword ptr [ebp+24h]
- mov dword ptr [ebx], RendezvousFunnelProcStart
- mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
- mov dword ptr [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-
- popad
- ret
-AsmGetAddressMap ENDP
-
-PAUSE32 MACRO
- DB 0F3h
- DB 090h
- ENDM
-
-;-------------------------------------------------------------------------------------
-;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
-;about to become an AP. It switches it'stack with the current AP.
-;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
-;-------------------------------------------------------------------------------------
-AsmExchangeRole PROC near C PUBLIC
- ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
- ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
- pushad
- mov ebp,esp
-
- ; esi contains MyInfo pointer
- mov esi, dword ptr [ebp+24h]
-
- ; edi contains OthersInfo pointer
- mov edi, dword ptr [ebp+28h]
-
- ;Store EFLAGS, GDTR and IDTR register to stack
- pushfd
- mov eax, cr4
- push eax ; push cr4 firstly
- mov eax, cr0
- push eax
-
- sgdt fword ptr [esi+8]
- sidt fword ptr [esi+14]
-
- ; Store the its StackPointer
- mov dword ptr [esi+4],esp
-
- ; update its switch state to STORED
- mov byte ptr [esi], CPU_SWITCH_STATE_STORED
-
-WaitForOtherStored:
- ; wait until the other CPU finish storing its state
- cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
- jz OtherStored
- PAUSE32
- jmp WaitForOtherStored
-
-OtherStored:
- ; Since another CPU already stored its state, load them
- ; load GDTR value
- lgdt fword ptr [edi+8]
-
- ; load IDTR value
- lidt fword ptr [edi+14]
-
- ; load its future StackPointer
- mov esp, dword ptr [edi+4]
-
- ; update the other CPU's switch state to LOADED
- mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
-
-WaitForOtherLoaded:
- ; wait until the other CPU finish loading new state,
- ; otherwise the data in stack may corrupt
- cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
- jz OtherLoaded
- PAUSE32
- jmp WaitForOtherLoaded
-
-OtherLoaded:
- ; since the other CPU already get the data it want, leave this procedure
- pop eax
- mov cr0, eax
- pop eax
- mov cr4, eax
- popfd
-
- popad
- ret
-AsmExchangeRole ENDP
-
-END
diff --git a/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm b/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
deleted file mode 100644
index 0852a5b..0000000
--- a/UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
+++ /dev/null
@@ -1,229 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpFuncs.nasm
-;
-; Abstract:
-;
-; This is the assembly code for MP support
-;
-;-------------------------------------------------------------------------------
-
-%include "MpEqu.inc"
-extern ASM_PFX(InitializeFloatingPointUnits)
-
-SECTION .text
-
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-global ASM_PFX(RendezvousFunnelProc)
-ASM_PFX(RendezvousFunnelProc):
-RendezvousFunnelProcStart:
-; At this point CS = 0x(vv00) and ip= 0x0.
-BITS 16
- mov ebp, eax ; save BIST information
-
- mov ax, cs
- mov ds, ax
- mov es, ax
- mov ss, ax
- xor ax, ax
- mov fs, ax
- mov gs, ax
-
- mov si, BufferStartLocation
- mov ebx, [si]
-
- mov si, ModeOffsetLocation
- mov eax, [si]
- mov si, CodeSegmentLocation
- mov edx, [si]
- mov di, ax
- sub di, 02h
- mov [di], dx
- sub di, 04h
- add eax, ebx
- mov [di],eax
-
- mov si, DataSegmentLocation
- mov edx, [si]
-
- mov si, GdtrLocation
-o32 lgdt [cs:si]
-
- mov si, IdtrLocation
-o32 lidt [cs:si]
-
- xor ax, ax
- mov ds, ax
-
- mov eax, cr0 ;Get control register 0
- or eax, 000000003h ;Set PE bit (bit #0) & MP
- mov cr0, eax
-
- jmp 0:strict dword 0 ; far jump to protected mode
-BITS 32
-Flat32Start: ; protected mode entry point
- mov ds, dx
- mov es, dx
- mov fs, dx
- mov gs, dx
- mov ss, dx
-
- mov esi, ebx
- mov edi, esi
- add edi, LockLocation
- mov eax, NotVacantFlag
-
-TestLock:
- xchg [edi], eax
- cmp eax, NotVacantFlag
- jz TestLock
-
- mov edi, esi
- add edi, NumApsExecutingLoction
- inc dword [edi]
- mov ebx, [edi]
-
-ProgramStack:
- mov edi, esi
- add edi, StackSizeLocation
- mov eax, [edi]
- mov edi, esi
- add edi, StackStartAddressLocation
- add eax, [edi]
- mov esp, eax
- mov [edi], eax
-
-Releaselock:
- mov eax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg [edi], eax
-
-CProcedureInvoke:
- push ebp ; push BIST data at top of AP stack
- xor ebp, ebp ; clear ebp for call stack trace
- push ebp
- mov ebp, esp
-
- mov eax, ASM_PFX(InitializeFloatingPointUnits)
- call eax ; Call assembly function to initialize FPU per UEFI spec
-
- push ebx ; Push NumApsExecuting
- mov eax, esi
- add eax, LockLocation
- push eax ; push address of exchange info data buffer
-
- mov edi, esi
- add edi, ApProcedureLocation
- mov eax, [edi]
-
- call eax ; invoke C function
-
- jmp $ ; never reach here
-RendezvousFunnelProcEnd:
-
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-global ASM_PFX(AsmGetAddressMap)
-ASM_PFX(AsmGetAddressMap):
- pushad
- mov ebp,esp
-
- mov ebx, [ebp + 24h]
- mov dword [ebx], RendezvousFunnelProcStart
- mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
- mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-
- popad
- ret
-
-;-------------------------------------------------------------------------------------
-;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
-;about to become an AP. It switches it'stack with the current AP.
-;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
-;-------------------------------------------------------------------------------------
-global ASM_PFX(AsmExchangeRole)
-ASM_PFX(AsmExchangeRole):
- ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
- ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
- pushad
- mov ebp,esp
-
- ; esi contains MyInfo pointer
- mov esi, [ebp + 24h]
-
- ; edi contains OthersInfo pointer
- mov edi, [ebp + 28h]
-
- ;Store EFLAGS, GDTR and IDTR register to stack
- pushfd
- mov eax, cr4
- push eax ; push cr4 firstly
- mov eax, cr0
- push eax
-
- sgdt [esi + 8]
- sidt [esi + 14]
-
- ; Store the its StackPointer
- mov [esi + 4],esp
-
- ; update its switch state to STORED
- mov byte [esi], CPU_SWITCH_STATE_STORED
-
-WaitForOtherStored:
- ; wait until the other CPU finish storing its state
- cmp byte [edi], CPU_SWITCH_STATE_STORED
- jz OtherStored
- pause
- jmp WaitForOtherStored
-
-OtherStored:
- ; Since another CPU already stored its state, load them
- ; load GDTR value
- lgdt [edi + 8]
-
- ; load IDTR value
- lidt [edi + 14]
-
- ; load its future StackPointer
- mov esp, [edi + 4]
-
- ; update the other CPU's switch state to LOADED
- mov byte [edi], CPU_SWITCH_STATE_LOADED
-
-WaitForOtherLoaded:
- ; wait until the other CPU finish loading new state,
- ; otherwise the data in stack may corrupt
- cmp byte [esi], CPU_SWITCH_STATE_LOADED
- jz OtherLoaded
- pause
- jmp WaitForOtherLoaded
-
-OtherLoaded:
- ; since the other CPU already get the data it want, leave this procedure
- pop eax
- mov cr0, eax
- pop eax
- mov cr4, eax
- popfd
-
- popad
- ret
diff --git a/UefiCpuPkg/CpuMpPei/Microcode.c b/UefiCpuPkg/CpuMpPei/Microcode.c
deleted file mode 100644
index 4fe6f2d..0000000
--- a/UefiCpuPkg/CpuMpPei/Microcode.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/** @file
- Implementation of loading microcode on processors.
-
- Copyright (c) 2015 - 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
- 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 "CpuMpPei.h"
-
-/**
- Get microcode update signature of currently loaded microcode update.
-
- @return Microcode signature.
-
-**/
-UINT32
-GetCurrentMicrocodeSignature (
- VOID
- )
-{
- UINT64 Signature;
-
- AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
- Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
- return (UINT32) RShiftU64 (Signature, 32);
-}
-
-/**
- Detect whether specified processor can find matching microcode patch and load it.
-
- @param PeiCpuMpData Pointer to PEI CPU MP Data
-**/
-VOID
-MicrocodeDetect (
- IN PEI_CPU_MP_DATA *PeiCpuMpData
- )
-{
- UINT64 MicrocodePatchAddress;
- UINT64 MicrocodePatchRegionSize;
- UINT32 ExtendedTableLength;
- UINT32 ExtendedTableCount;
- EFI_CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
- EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
- EFI_CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
- UINTN MicrocodeEnd;
- UINTN Index;
- UINT8 PlatformId;
- UINT32 RegEax;
- UINT32 CurrentRevision;
- UINT32 LatestRevision;
- UINTN TotalSize;
- UINT32 CheckSum32;
- BOOLEAN CorrectMicrocode;
- MICROCODE_INFO MicrocodeInfo;
-
- ZeroMem (&MicrocodeInfo, sizeof (MICROCODE_INFO));
- MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
- MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
- if (MicrocodePatchRegionSize == 0) {
- //
- // There is no microcode patches
- //
- return;
- }
-
- CurrentRevision = GetCurrentMicrocodeSignature ();
- if (CurrentRevision != 0) {
- //
- // Skip loading microcode if it has been loaded successfully
- //
- return;
- }
-
- ExtendedTableLength = 0;
- //
- // Here data of CPUID leafs have not been collected into context buffer, so
- // GetProcessorCpuid() cannot be used here to retrieve CPUID data.
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
-
- //
- // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID
- //
- PlatformId = (UINT8) AsmMsrBitFieldRead64 (EFI_MSR_IA32_PLATFORM_ID, 50, 52);
-
- LatestRevision = 0;
- MicrocodeEnd = (UINTN) (MicrocodePatchAddress + MicrocodePatchRegionSize);
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress;
- do {
- //
- // Check if the microcode is for the Cpu and the version is newer
- // and the update can be processed on the platform
- //
- CorrectMicrocode = FALSE;
- if (MicrocodeEntryPoint->HeaderVersion == 0x1) {
- //
- // It is the microcode header. It is not the padding data between microcode patches
- // because the padding data should not include 0x00000001 and it should be the repeated
- // byte format (like 0xXYXYXYXY....).
- //
- if (MicrocodeEntryPoint->ProcessorId == RegEax &&
- MicrocodeEntryPoint->UpdateRevision > LatestRevision &&
- (MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId))
- ) {
- if (MicrocodeEntryPoint->DataSize == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, 2048);
- } else {
- CheckSum32 = CalculateSum32 ((UINT32 *)MicrocodeEntryPoint, MicrocodeEntryPoint->DataSize + sizeof(EFI_CPU_MICROCODE_HEADER));
- }
- if (CheckSum32 == 0) {
- CorrectMicrocode = TRUE;
- }
- } else if ((MicrocodeEntryPoint->DataSize != 0) &&
- (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) {
- ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
- if (ExtendedTableLength != 0) {
- //
- // Extended Table exist, check if the CPU in support list
- //
- ExtendedTableHeader = (EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + sizeof (EFI_CPU_MICROCODE_HEADER));
- //
- // Calculate Extended Checksum
- //
- if ((ExtendedTableLength % 4) == 0) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength);
- if (CheckSum32 == 0) {
- //
- // Checksum correct
- //
- ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
- ExtendedTable = (EFI_CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
- for (Index = 0; Index < ExtendedTableCount; Index ++) {
- CheckSum32 = CalculateSum32 ((UINT32 *)ExtendedTable, sizeof(EFI_CPU_MICROCODE_EXTENDED_TABLE));
- if (CheckSum32 == 0) {
- //
- // Verify Header
- //
- if ((ExtendedTable->ProcessorSignature == RegEax) &&
- (ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) {
- //
- // Find one
- //
- CorrectMicrocode = TRUE;
- break;
- }
- }
- ExtendedTable ++;
- }
- }
- }
- }
- }
- } else {
- //
- // It is the padding data between the microcode patches for microcode patches alignment.
- // Because the microcode patch is the multiple of 1-KByte, the padding data should not
- // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode
- // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
- // find the next possible microcode patch header.
- //
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB);
- continue;
- }
- //
- // Get the next patch.
- //
- if (MicrocodeEntryPoint->DataSize == 0) {
- TotalSize = 2048;
- } else {
- TotalSize = MicrocodeEntryPoint->TotalSize;
- }
-
- if (CorrectMicrocode) {
- LatestRevision = MicrocodeEntryPoint->UpdateRevision;
- MicrocodeInfo.MicrocodeData = (VOID *)((UINTN)MicrocodeEntryPoint + sizeof (EFI_CPU_MICROCODE_HEADER));
- MicrocodeInfo.MicrocodeSize = TotalSize;
- MicrocodeInfo.ProcessorId = RegEax;
- }
-
- MicrocodeEntryPoint = (EFI_CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize);
- } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd));
-
- if (LatestRevision > CurrentRevision) {
- //
- // BIOS only authenticate updates that contain a numerically larger revision
- // than the currently loaded revision, where Current Signature < New Update
- // Revision. A processor with no loaded update is considered to have a
- // revision equal to zero.
- //
- AsmWriteMsr64 (
- EFI_MSR_IA32_BIOS_UPDT_TRIG,
- (UINT64) (UINTN) MicrocodeInfo.MicrocodeData
- );
- //
- // Get and check new microcode signature
- //
- CurrentRevision = GetCurrentMicrocodeSignature ();
- if (CurrentRevision != LatestRevision) {
- AcquireSpinLock(&PeiCpuMpData->MpLock);
- DEBUG ((EFI_D_ERROR, "Updated microcode signature [0x%08x] does not match \
- loaded microcode signature [0x%08x]\n", CurrentRevision, LatestRevision));
- ReleaseSpinLock(&PeiCpuMpData->MpLock);
- }
- }
-}
diff --git a/UefiCpuPkg/CpuMpPei/Microcode.h b/UefiCpuPkg/CpuMpPei/Microcode.h
deleted file mode 100644
index 9656045..0000000
--- a/UefiCpuPkg/CpuMpPei/Microcode.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/** @file
- Definitions for loading microcode on processors.
-
- Copyright (c) 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.
-
-**/
-
-#ifndef _CPU_MICROCODE_H_
-#define _CPU_MICROCODE_H_
-
-#define EFI_MSR_IA32_PLATFORM_ID 0x17
-#define EFI_MSR_IA32_BIOS_UPDT_TRIG 0x79
-#define EFI_MSR_IA32_BIOS_SIGN_ID 0x8b
-
-#define MAX_MICROCODE_DESCRIPTOR_LENGTH 100
-
-typedef struct {
- VOID *MicrocodeData;
- UINTN MicrocodeSize;
- UINT32 ProcessorId;
-} MICROCODE_INFO;
-
-//
-// Definition for IA32 microcode format
-//
-typedef struct {
- UINT32 HeaderVersion;
- UINT32 UpdateRevision;
- UINT32 Date;
- UINT32 ProcessorId;
- UINT32 Checksum;
- UINT32 LoaderRevision;
- UINT32 ProcessorFlags;
- UINT32 DataSize;
- UINT32 TotalSize;
- UINT8 Reserved[12];
-} EFI_CPU_MICROCODE_HEADER;
-
-typedef struct {
- UINT32 ExtendedSignatureCount;
- UINT32 ExtendedTableChecksum;
- UINT8 Reserved[12];
-} EFI_CPU_MICROCODE_EXTENDED_TABLE_HEADER;
-
-typedef struct {
- UINT32 ProcessorSignature;
- UINT32 ProcessorFlag;
- UINT32 ProcessorChecksum;
-} EFI_CPU_MICROCODE_EXTENDED_TABLE;
-
-#endif
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
index 44e8f21..c9b2ad4 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -35,137 +35,6 @@ EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
/**
- Get CPU Package/Core/Thread location information.
-
- @param InitialApicId CPU APIC ID
- @param Location Pointer to CPU location information
-**/
-STATIC
-VOID
-ExtractProcessorLocation (
- IN UINT32 InitialApicId,
- OUT EFI_CPU_PHYSICAL_LOCATION *Location
- )
-{
- BOOLEAN TopologyLeafSupported;
- UINTN ThreadBits;
- UINTN CoreBits;
- UINT32 RegEax;
- UINT32 RegEbx;
- UINT32 RegEcx;
- UINT32 RegEdx;
- UINT32 MaxCpuIdIndex;
- UINT32 SubIndex;
- UINTN LevelType;
- UINT32 MaxLogicProcessorsPerPackage;
- UINT32 MaxCoresPerPackage;
-
- //
- // Check if the processor is capable of supporting more than one logical processor.
- //
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT28) == 0) {
- Location->Thread = 0;
- Location->Core = 0;
- Location->Package = 0;
- return;
- }
-
- ThreadBits = 0;
- CoreBits = 0;
-
- //
- // Assume three-level mapping of APIC ID: Package:Core:SMT.
- //
-
- TopologyLeafSupported = FALSE;
- //
- // Get the max index of basic CPUID
- //
- AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
-
- //
- // If the extended topology enumeration leaf is available, it
- // is the preferred mechanism for enumerating topology.
- //
- if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
- AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, NULL);
- //
- // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
- // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
- // supported on that processor.
- //
- if (RegEbx != 0) {
- TopologyLeafSupported = TRUE;
-
- //
- // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
- // the SMT sub-field of x2APIC ID.
- //
- LevelType = (RegEcx >> 8) & 0xff;
- ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
- ThreadBits = RegEax & 0x1f;
-
- //
- // Software must not assume any "level type" encoding
- // value to be related to any sub-leaf index, except sub-leaf 0.
- //
- SubIndex = 1;
- do {
- AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, SubIndex, &RegEax, NULL, &RegEcx, NULL);
- LevelType = (RegEcx >> 8) & 0xff;
- if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
- CoreBits = (RegEax & 0x1f) - ThreadBits;
- break;
- }
- SubIndex++;
- } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
- }
- }
-
- if (!TopologyLeafSupported) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
- MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff;
- if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
- AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL);
- MaxCoresPerPackage = (RegEax >> 26) + 1;
- } else {
- //
- // Must be a single-core processor.
- //
- MaxCoresPerPackage = 1;
- }
-
- ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
- CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
- }
-
- Location->Thread = InitialApicId & ~((-1) << ThreadBits);
- Location->Core = (InitialApicId >> ThreadBits) & ~((-1) << CoreBits);
- Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
-}
-
-/**
- Worker function for SwitchBSP().
-
- Worker function for SwitchBSP(), assigned to the AP which is intended to become BSP.
-
- @param Buffer Pointer to CPU MP Data
-**/
-STATIC
-VOID
-EFIAPI
-FutureBSPProc (
- IN VOID *Buffer
- )
-{
- PEI_CPU_MP_DATA *DataInHob;
-
- DataInHob = (PEI_CPU_MP_DATA *) Buffer;
- AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
-}
-
-/**
This service retrieves the number of logical processor in the platform
and the number of those logical processors that are enabled on this boot.
This service may only be called from the BSP.
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.h b/UefiCpuPkg/CpuMpPei/PeiMpServices.h
index 57f7691..036d12e 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.h
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.h
@@ -17,29 +17,6 @@
#include "CpuMpPei.h"
-//
-// The MP data for switch BSP
-//
-#define CPU_SWITCH_STATE_IDLE 0
-#define CPU_SWITCH_STATE_STORED 1
-#define CPU_SWITCH_STATE_LOADED 2
-
-#define CPU_CHECK_AP_INTERVAL 0x100 // 100 microseconds
-
-/**
- This function is called by both the BSP and the AP which is to become the BSP to
- Exchange execution context including stack between them. After return from this
- function, the BSP becomes AP and the AP becomes the BSP.
-
- @param MyInfo Pointer to buffer holding the exchanging information for the executing processor.
- @param OthersInfo Pointer to buffer holding the exchanging information for the peer.
-**/
-VOID
-EFIAPI
-AsmExchangeRole (
- IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
- IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
- );
/**
This service retrieves the number of logical processor in the platform
diff --git a/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc b/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
deleted file mode 100644
index 00f57ce..0000000
--- a/UefiCpuPkg/CpuMpPei/X64/MpEqu.inc
+++ /dev/null
@@ -1,41 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpEqu.inc
-;
-; Abstract:
-;
-; This is the equates file for Multiple Processor support
-;
-;-------------------------------------------------------------------------------
-
-VacantFlag equ 00h
-NotVacantFlag equ 0ffh
-
-CPU_SWITCH_STATE_IDLE equ 0
-CPU_SWITCH_STATE_STORED equ 1
-CPU_SWITCH_STATE_LOADED equ 2
-
-LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
-StackStartAddressLocation equ LockLocation + 08h
-StackSizeLocation equ LockLocation + 10h
-ApProcedureLocation equ LockLocation + 18h
-GdtrLocation equ LockLocation + 20h
-IdtrLocation equ LockLocation + 2Ah
-BufferStartLocation equ LockLocation + 34h
-ModeOffsetLocation equ LockLocation + 3Ch
-NumApsExecutingLoction equ LockLocation + 44h
-CodeSegmentLocation equ LockLocation + 4Ch
-DataSegmentLocation equ LockLocation + 54h
-Cr3Location equ LockLocation + 5Ch
-
-;-------------------------------------------------------------------------------
diff --git a/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm b/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
deleted file mode 100644
index 4adfff3..0000000
--- a/UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
+++ /dev/null
@@ -1,290 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpFuncs32.asm
-;
-; Abstract:
-;
-; This is the assembly code for MP support
-;
-;-------------------------------------------------------------------------------
-
-include MpEqu.inc
-extern InitializeFloatingPointUnits:PROC
-
-.code
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-RendezvousFunnelProc PROC PUBLIC
-RendezvousFunnelProcStart::
-; At this point CS = 0x(vv00) and ip= 0x0.
-; Save BIST information to ebp firstly
- db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
-
- db 8ch,0c8h ; mov ax, cs
- db 8eh,0d8h ; mov ds, ax
- db 8eh,0c0h ; mov es, ax
- db 8eh,0d0h ; mov ss, ax
- db 33h,0c0h ; xor ax, ax
- db 8eh,0e0h ; mov fs, ax
- db 8eh,0e8h ; mov gs, ax
-
- db 0BEh ; opcode of mov si, mem16
- dw BufferStartLocation ; mov si, BufferStartLocation
- db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]
-
- db 0BFh ; opcode of mov di, mem16
- dw ModeOffsetLocation ; mov di, ModeOffsetLocation
- db 66h, 8Bh, 05h ; mov eax, [di]
- db 0BFh ; opcode of mov di, mem16
- dw CodeSegmentLocation ; mov di, CodeSegmentLocation
- db 66h, 8Bh, 15h ; mov edx, [di]
- db 89h, 0C7h ; mov di, ax
- db 83h, 0EFh, 02h ; sub di, 02h
- db 89h, 15h ; mov [di], dx ; Patch long mode CS
- db 83h, 0EFh, 04h ; sub di, 04h
- db 66h, 01h, 0D8h ; add eax, ebx
- db 66h, 89h, 05h ; mov [di], eax ; Patch address
-
- db 0BEh ; opcode of mov si, mem16
- dw GdtrLocation ; mov si, GdtrLocation
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
-
- db 0BEh
- dw IdtrLocation ; mov si, IdtrLocation
- db 66h ; db 66h
- db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
-
- db 0BFh ; opcode of mov di, mem16
- dw DataSegmentLocation ; mov di, DataSegmentLocation
- db 66h, 8Bh, 3Dh ; mov edi, [di] ; Save long mode DS in edi
-
- db 0BEh
- dw Cr3Location ; mov si, Cr3Location
- db 66h, 8Bh, 0Ch ; mov ecx, dword ptr [si] ; ECX is keeping the value of CR3
-
- db 31h, 0C0h ; xor ax, ax
- db 8Eh, 0D8h ; mov ds, ax ; Clear data segment
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
- db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ; Set PE bit (bit #0) & MP
- db 0Fh, 22h, 0C0h ; mov cr0, eax
-
- db 0Fh, 20h, 0E0h ; mov eax, cr4
- db 66h, 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
- db 0Fh, 22h, 0E0h ; mov cr4, eax
-
- db 0Fh, 22h, 0D9h ; mov cr3, ecx
-
- db 66h, 0B9h
- dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
- db 0Fh, 32h ; rdmsr ; Read EFER.
- db 66h, 0Fh, 0BAh, 0E8h, 08h; bts eax, 8 ; Set LME=1.
- db 0Fh, 30h ; wrmsr ; Write EFER.
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
- db 66h, 0Fh, 0BAh, 0E8h, 1Fh; bts eax, 31 ; Set PG=1.
- db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
-
-LONG_JUMP:
- db 66h, 0EAh ; far jump
- dd 0h ; 32-bit offset
- dw 0h ; 16-bit selector
-
-LongModeStart::
- mov eax, edi
- mov ds, ax
- mov es, ax
- mov ss, ax
-
- mov esi, ebx
- mov edi, esi
- add edi, LockLocation
- mov rax, NotVacantFlag
-
-TestLock:
- xchg qword ptr [edi], rax
- cmp rax, NotVacantFlag
- jz TestLock
-
- mov edi, esi
- add edi, NumApsExecutingLoction
- inc dword ptr [edi]
- mov ebx, dword ptr [edi]
-
-ProgramStack:
- mov edi, esi
- add edi, StackSizeLocation
- mov rax, qword ptr [edi]
- mov edi, esi
- add edi, StackStartAddressLocation
- add rax, qword ptr [edi]
- mov rsp, rax
- mov qword ptr [edi], rax
-
-Releaselock:
- mov rax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg qword ptr [edi], rax
-
-CProcedureInvoke:
- push rbp ; push BIST data
- xor rbp, rbp ; clear ebp for call stack trace
- push rbp
- mov rbp, rsp
-
- mov rax, InitializeFloatingPointUnits
- sub rsp, 20h
- call rax ; Call assembly function to initialize FPU per UEFI spec
- add rsp, 20h
-
- mov edx, ebx ; edx is NumApsExecuting
- mov ecx, esi
- add ecx, LockLocation ; rcx is address of exchange info data buffer
-
- mov edi, esi
- add edi, ApProcedureLocation
- mov rax, qword ptr [edi]
-
- sub rsp, 20h
- call rax ; invoke C function
- add rsp, 20h
- jmp $
-
-RendezvousFunnelProc ENDP
-RendezvousFunnelProcEnd::
-
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-AsmGetAddressMap PROC
- mov rax, offset RendezvousFunnelProcStart
- mov qword ptr [rcx], rax
- mov qword ptr [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
- mov qword ptr [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
- ret
-AsmGetAddressMap ENDP
-
-;-------------------------------------------------------------------------------------
-;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
-;about to become an AP. It switches it'stack with the current AP.
-;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
-;-------------------------------------------------------------------------------------
-AsmExchangeRole PROC
- ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
- ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
-
- push rax
- push rbx
- push rcx
- push rdx
- push rsi
- push rdi
- push rbp
- push r8
- push r9
- push r10
- push r11
- push r12
- push r13
- push r14
- push r15
-
- mov rax, cr0
- push rax
-
- mov rax, cr4
- push rax
-
- ; rsi contains MyInfo pointer
- mov rsi, rcx
-
- ; rdi contains OthersInfo pointer
- mov rdi, rdx
-
- ;Store EFLAGS, GDTR and IDTR regiter to stack
- pushfq
- sgdt fword ptr [rsi + 16]
- sidt fword ptr [rsi + 26]
-
- ; Store the its StackPointer
- mov qword ptr [rsi + 8], rsp
-
- ; update its switch state to STORED
- mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
-
-WaitForOtherStored:
- ; wait until the other CPU finish storing its state
- cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
- jz OtherStored
- pause
- jmp WaitForOtherStored
-
-OtherStored:
- ; Since another CPU already stored its state, load them
- ; load GDTR value
- lgdt fword ptr [rdi + 16]
-
- ; load IDTR value
- lidt fword ptr [rdi + 26]
-
- ; load its future StackPointer
- mov rsp, qword ptr [rdi + 8]
-
- ; update the other CPU's switch state to LOADED
- mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
-
-WaitForOtherLoaded:
- ; wait until the other CPU finish loading new state,
- ; otherwise the data in stack may corrupt
- cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
- jz OtherLoaded
- pause
- jmp WaitForOtherLoaded
-
-OtherLoaded:
- ; since the other CPU already get the data it want, leave this procedure
- popfq
-
- pop rax
- mov cr4, rax
-
- pop rax
- mov cr0, rax
-
- pop r15
- pop r14
- pop r13
- pop r12
- pop r11
- pop r10
- pop r9
- pop r8
- pop rbp
- pop rdi
- pop rsi
- pop rdx
- pop rcx
- pop rbx
- pop rax
-
- ret
-AsmExchangeRole ENDP
-
-END
diff --git a/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm b/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
deleted file mode 100644
index f19c75f..0000000
--- a/UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
+++ /dev/null
@@ -1,281 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2015 - 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
-; 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.
-;
-; Module Name:
-;
-; MpFuncs.nasm
-;
-; Abstract:
-;
-; This is the assembly code for MP support
-;
-;-------------------------------------------------------------------------------
-
-%include "MpEqu.inc"
-extern ASM_PFX(InitializeFloatingPointUnits)
-
-DEFAULT REL
-
-SECTION .text
-
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-global ASM_PFX(RendezvousFunnelProc)
-ASM_PFX(RendezvousFunnelProc):
-RendezvousFunnelProcStart:
-; At this point CS = 0x(vv00) and ip= 0x0.
-; Save BIST information to ebp firstly
-
-BITS 16
- mov ebp, eax ; Save BIST information
-
- mov ax, cs
- mov ds, ax
- mov es, ax
- mov ss, ax
- xor ax, ax
- mov fs, ax
- mov gs, ax
-
- mov si, BufferStartLocation
- mov ebx, [si]
-
- mov di, ModeOffsetLocation
- mov eax, [di]
- mov di, CodeSegmentLocation
- mov edx, [di]
- mov di, ax
- sub di, 02h
- mov [di],dx ; Patch long mode CS
- sub di, 04h
- add eax, ebx
- mov [di],eax ; Patch address
-
- mov si, GdtrLocation
-o32 lgdt [cs:si]
-
- mov si, IdtrLocation
-o32 lidt [cs:si]
-
-
- mov di, DataSegmentLocation
- mov edi, [di] ; Save long mode DS in edi
-
- mov si, Cr3Location ; Save CR3 in ecx
- mov ecx, [si]
-
- xor ax, ax
- mov ds, ax ; Clear data segment
-
- mov eax, cr0 ; Get control register 0
- or eax, 000000003h ; Set PE bit (bit #0) & MP
- mov cr0, eax
-
- mov eax, cr4
- bts eax, 5
- mov cr4, eax
-
- mov cr3, ecx ; Load CR3
-
- mov ecx, 0c0000080h ; EFER MSR number
- rdmsr ; Read EFER
- bts eax, 8 ; Set LME=1
- wrmsr ; Write EFER
-
- mov eax, cr0 ; Read CR0
- bts eax, 31 ; Set PG=1
- mov cr0, eax ; Write CR0
-
- jmp 0:strict dword 0 ; far jump to long mode
-BITS 64
-LongModeStart:
- mov eax, edi
- mov ds, ax
- mov es, ax
- mov ss, ax
-
- mov esi, ebx
- mov edi, esi
- add edi, LockLocation
- mov rax, NotVacantFlag
-
-TestLock:
- xchg qword [edi], rax
- cmp rax, NotVacantFlag
- jz TestLock
-
- mov edi, esi
- add edi, NumApsExecutingLoction
- inc dword [edi]
- mov ebx, [edi]
-
-ProgramStack:
- mov edi, esi
- add edi, StackSizeLocation
- mov rax, qword [edi]
- mov edi, esi
- add edi, StackStartAddressLocation
- add rax, qword [edi]
- mov rsp, rax
- mov qword [edi], rax
-
-Releaselock:
- mov rax, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg qword [edi], rax
-
-CProcedureInvoke:
- push rbp ; push BIST data at top of AP stack
- xor rbp, rbp ; clear ebp for call stack trace
- push rbp
- mov rbp, rsp
-
- mov rax, ASM_PFX(InitializeFloatingPointUnits)
- sub rsp, 20h
- call rax ; Call assembly function to initialize FPU per UEFI spec
- add rsp, 20h
-
- mov edx, ebx ; edx is NumApsExecuting
- mov ecx, esi
- add ecx, LockLocation ; rcx is address of exchange info data buffer
-
- mov edi, esi
- add edi, ApProcedureLocation
- mov rax, qword [edi]
-
- sub rsp, 20h
- call rax ; invoke C function
- add rsp, 20h
- jmp $
-
-RendezvousFunnelProcEnd:
-
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-global ASM_PFX(AsmGetAddressMap)
-ASM_PFX(AsmGetAddressMap):
- mov rax, ASM_PFX(RendezvousFunnelProc)
- mov qword [rcx], rax
- mov qword [rcx + 8h], LongModeStart - RendezvousFunnelProcStart
- mov qword [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
- ret
-
-;-------------------------------------------------------------------------------------
-;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
-;about to become an AP. It switches it'stack with the current AP.
-;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
-;-------------------------------------------------------------------------------------
-global ASM_PFX(AsmExchangeRole)
-ASM_PFX(AsmExchangeRole):
- ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
- ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
-
- push rax
- push rbx
- push rcx
- push rdx
- push rsi
- push rdi
- push rbp
- push r8
- push r9
- push r10
- push r11
- push r12
- push r13
- push r14
- push r15
-
- mov rax, cr0
- push rax
-
- mov rax, cr4
- push rax
-
- ; rsi contains MyInfo pointer
- mov rsi, rcx
-
- ; rdi contains OthersInfo pointer
- mov rdi, rdx
-
- ;Store EFLAGS, GDTR and IDTR regiter to stack
- pushfq
- sgdt [rsi + 16]
- sidt [rsi + 26]
-
- ; Store the its StackPointer
- mov [rsi + 8], rsp
-
- ; update its switch state to STORED
- mov byte [rsi], CPU_SWITCH_STATE_STORED
-
-WaitForOtherStored:
- ; wait until the other CPU finish storing its state
- cmp byte [rdi], CPU_SWITCH_STATE_STORED
- jz OtherStored
- pause
- jmp WaitForOtherStored
-
-OtherStored:
- ; Since another CPU already stored its state, load them
- ; load GDTR value
- lgdt [rdi + 16]
-
- ; load IDTR value
- lidt [rdi + 26]
-
- ; load its future StackPointer
- mov rsp, [rdi + 8]
-
- ; update the other CPU's switch state to LOADED
- mov byte [rdi], CPU_SWITCH_STATE_LOADED
-
-WaitForOtherLoaded:
- ; wait until the other CPU finish loading new state,
- ; otherwise the data in stack may corrupt
- cmp byte [rsi], CPU_SWITCH_STATE_LOADED
- jz OtherLoaded
- pause
- jmp WaitForOtherLoaded
-
-OtherLoaded:
- ; since the other CPU already get the data it want, leave this procedure
- popfq
-
- pop rax
- mov cr4, rax
-
- pop rax
- mov cr0, rax
-
- pop r15
- pop r14
- pop r13
- pop r12
- pop r11
- pop r10
- pop r9
- pop r8
- pop rbp
- pop rdi
- pop rsi
- pop rdx
- pop rcx
- pop rbx
- pop rax
-
- ret
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 40/46] UefiCpuPkg/CpuMpPei: Delete PeiMpServices.c and PeiMpServices.h
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (38 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 39/46] UefiCpuPkg/CpuMpPei: Remove unused files and codes Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 41/46] UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services Jeff Fan
` (5 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Move the code in PeiMpServices.c & PeiMpServices.h to CpuMpPei.c & CpuMpPei.h.
v3:
1. Rename MpInitLibSwitchBSP to MpInitLibSwitchBSP
2. Add PeiMpInitLib.inf in DSC file
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>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 395 ++++++++++++++++++++++++++++++++++
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 332 +++++++++++++++++++++++++++++
UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 2 -
UefiCpuPkg/CpuMpPei/PeiMpServices.c | 410 ------------------------------------
UefiCpuPkg/CpuMpPei/PeiMpServices.h | 354 -------------------------------
5 files changed, 727 insertions(+), 766 deletions(-)
delete mode 100644 UefiCpuPkg/CpuMpPei/PeiMpServices.c
delete mode 100644 UefiCpuPkg/CpuMpPei/PeiMpServices.h
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index a36adf6..eaf99c7 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -13,6 +13,401 @@
**/
#include "CpuMpPei.h"
+
+//
+// CPU MP PPI to be installed
+//
+EFI_PEI_MP_SERVICES_PPI mMpServicesPpi = {
+ PeiGetNumberOfProcessors,
+ PeiGetProcessorInfo,
+ PeiStartupAllAPs,
+ PeiStartupThisAP,
+ PeiSwitchBSP,
+ PeiEnableDisableAP,
+ PeiWhoAmI,
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMpServicesPpiGuid,
+ &mMpServicesPpi
+};
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Ppi provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This Pointer to this instance of the PPI.
+ @param[out] NumberOfProcessors Pointer to the total number of logical processors in
+ the system, including the BSP and disabled APs.
+ @param[out] NumberOfEnabledProcessors
+ Number of processors in the system that are enabled.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ NumberOfEnabledProcessors is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetNumberOfProcessors (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ )
+{
+ if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return MpInitLibGetNumberOfProcessors (
+ NumberOfProcessors,
+ NumberOfEnabledProcessors
+ );
+}
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This Pointer to this instance of the PPI.
+ @param[in] ProcessorNumber Pointer to the total number of logical processors in
+ the system, including the BSP and disabled APs.
+ @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetProcessorInfo (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ )
+{
+ return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
+}
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking requests only. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If the timeout specified by TimeoutInMicroSeconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Ppi does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. PEI services and Ppis may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroSeconds expires.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] Procedure A pointer to the function to be run on enabled APs of
+ the system.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute the function
+ specified by Procedure one by one, in ascending order
+ of processor handle number. If FALSE, then all the
+ enabled APs execute the function specified by Procedure
+ simultaneously.
+ @param[in] TimeoutInMicroSeconds
+ Indicates the time limit in microseconds for APs to
+ return from Procedure, for blocking mode only. Zero
+ means infinity. If the timeout expires before all APs
+ return from Procedure, then Procedure on the failed APs
+ is terminated. All enabled APs are available for next
+ function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
+ timeout expires in blocking mode, BSP returns
+ EFI_TIMEOUT.
+ @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before the
+ timeout expired.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before all
+ enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupAllAPs (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN UINTN TimeoutInMicroSeconds,
+ IN VOID *ProcedureArgument OPTIONAL
+ )
+{
+ return MpInitLibStartupAllAPs (
+ Procedure,
+ SingleThread,
+ NULL,
+ TimeoutInMicroSeconds,
+ ProcedureArgument,
+ NULL
+ );
+}
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to wait for the completion
+ of the AP. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument.
+ The execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
+ EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] Procedure A pointer to the function to be run on enabled APs of
+ the system.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] TimeoutInMicroseconds
+ Indicates the time limit in microseconds for APs to
+ return from Procedure, for blocking mode only. Zero
+ means infinity. If the timeout expires before all APs
+ return from Procedure, then Procedure on the failed APs
+ is terminated. All enabled APs are available for next
+ function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
+ timeout expires in blocking mode, BSP returns
+ EFI_TIMEOUT.
+ @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before the
+ timeout expires.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before the
+ specified AP has finished.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupThisAP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL
+ )
+{
+ return MpInitLibStartupThisAP (
+ Procedure,
+ ProcessorNumber,
+ NULL,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ NULL
+ );
+}
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
+ AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
+ service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
+ AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+**/
+EFI_STATUS
+EFIAPI
+PeiSwitchBSP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
+}
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for enabled,
+ FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies the
+ new health status of the AP. This flag corresponds to
+ StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
+ Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter is
+ ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
+ to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+**/
+EFI_STATUS
+EFIAPI
+PeiEnableDisableAP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ )
+{
+ return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
+}
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned in
+ ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiWhoAmI (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ return MpInitLibWhoAmI (ProcessorNumber);
+}
+
/**
The Entry point of the MP CPU PEIM.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 5a422b2..24931c9 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -34,6 +34,338 @@
extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc;
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Ppi provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This Pointer to this instance of the PPI.
+ @param[out] NumberOfProcessors Pointer to the total number of logical processors in
+ the system, including the BSP and disabled APs.
+ @param[out] NumberOfEnabledProcessors
+ Number of processors in the system that are enabled.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ NumberOfEnabledProcessors is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetNumberOfProcessors (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ );
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This Pointer to this instance of the PPI.
+ @param[in] ProcessorNumber Pointer to the total number of logical processors in
+ the system, including the BSP and disabled APs.
+ @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetProcessorInfo (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ );
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking requests only. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If the timeout specified by TimeoutInMicroSeconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Ppi does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. PEI services and Ppis may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroSeconds expires.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] Procedure A pointer to the function to be run on enabled APs of
+ the system.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute the function
+ specified by Procedure one by one, in ascending order
+ of processor handle number. If FALSE, then all the
+ enabled APs execute the function specified by Procedure
+ simultaneously.
+ @param[in] TimeoutInMicroSeconds
+ Indicates the time limit in microseconds for APs to
+ return from Procedure, for blocking mode only. Zero
+ means infinity. If the timeout expires before all APs
+ return from Procedure, then Procedure on the failed APs
+ is terminated. All enabled APs are available for next
+ function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
+ timeout expires in blocking mode, BSP returns
+ EFI_TIMEOUT.
+ @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before the
+ timeout expired.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before all
+ enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupAllAPs (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN UINTN TimeoutInMicroSeconds,
+ IN VOID *ProcedureArgument OPTIONAL
+ );
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to wait for the completion
+ of the AP. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument.
+ The execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
+ EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] Procedure A pointer to the function to be run on enabled APs of
+ the system.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] TimeoutInMicroseconds
+ Indicates the time limit in microseconds for APs to
+ return from Procedure, for blocking mode only. Zero
+ means infinity. If the timeout expires before all APs
+ return from Procedure, then Procedure on the failed APs
+ is terminated. All enabled APs are available for next
+ function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+ or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
+ timeout expires in blocking mode, BSP returns
+ EFI_TIMEOUT.
+ @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before the
+ timeout expires.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before the
+ specified AP has finished.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupThisAP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL
+ );
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
+ AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
+ service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
+ AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+**/
+EFI_STATUS
+EFIAPI
+PeiSwitchBSP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for enabled,
+ FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies the
+ new health status of the AP. This flag corresponds to
+ StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
+ Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter is
+ ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
+ to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+**/
+EFI_STATUS
+EFIAPI
+PeiEnableDisableAP (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
+ @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
+ total number of logical processors minus 1. The total
+ number of logical processors can be retrieved by
+ EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned in
+ ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PeiWhoAmI (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_MP_SERVICES_PPI *This,
+ OUT UINTN *ProcessorNumber
+ );
/**
Collects BIST data from PPI.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 3bf9a8b..c8461a2 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -31,8 +31,6 @@ [Sources]
CpuMpPei.h
CpuMpPei.c
CpuBist.c
- PeiMpServices.h
- PeiMpServices.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
deleted file mode 100644
index c9b2ad4..0000000
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/** @file
- Implementation of Multiple Processor PPI services.
-
- Copyright (c) 2015 - 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
- 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 "PeiMpServices.h"
-
-//
-// CPU MP PPI to be installed
-//
-EFI_PEI_MP_SERVICES_PPI mMpServicesPpi = {
- PeiGetNumberOfProcessors,
- PeiGetProcessorInfo,
- PeiStartupAllAPs,
- PeiStartupThisAP,
- PeiSwitchBSP,
- PeiEnableDisableAP,
- PeiWhoAmI,
-};
-
-EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiPeiMpServicesPpiGuid,
- &mMpServicesPpi
-};
-
-
-/**
- This service retrieves the number of logical processor in the platform
- and the number of those logical processors that are enabled on this boot.
- This service may only be called from the BSP.
-
- This function is used to retrieve the following information:
- - The number of logical processors that are present in the system.
- - The number of enabled logical processors in the system at the instant
- this call is made.
-
- Because MP Service Ppi provides services to enable and disable processors
- dynamically, the number of enabled logical processors may vary during the
- course of a boot session.
-
- If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
- If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
- EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
- is returned in NumberOfProcessors, the number of currently enabled processor
- is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This Pointer to this instance of the PPI.
- @param[out] NumberOfProcessors Pointer to the total number of logical processors in
- the system, including the BSP and disabled APs.
- @param[out] NumberOfEnabledProcessors
- Number of processors in the system that are enabled.
-
- @retval EFI_SUCCESS The number of logical processors and enabled
- logical processors was retrieved.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
- NumberOfEnabledProcessors is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiGetNumberOfProcessors (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- OUT UINTN *NumberOfProcessors,
- OUT UINTN *NumberOfEnabledProcessors
- )
-{
- if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- return MpInitLibGetNumberOfProcessors (
- NumberOfProcessors,
- NumberOfEnabledProcessors
- );
-}
-
-/**
- Gets detailed MP-related information on the requested processor at the
- instant this call is made. This service may only be called from the BSP.
-
- This service retrieves detailed MP-related information about any processor
- on the platform. Note the following:
- - The processor information may change during the course of a boot session.
- - The information presented here is entirely MP related.
-
- Information regarding the number of caches and their sizes, frequency of operation,
- slot numbers is all considered platform-related information and is not provided
- by this service.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This Pointer to this instance of the PPI.
- @param[in] ProcessorNumber Pointer to the total number of logical processors in
- the system, including the BSP and disabled APs.
- @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
-**/
-EFI_STATUS
-EFIAPI
-PeiGetProcessorInfo (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
- )
-{
- return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
-}
-
-/**
- This service executes a caller provided function on all enabled APs. APs can
- run either simultaneously or one at a time in sequence. This service supports
- both blocking requests only. This service may only
- be called from the BSP.
-
- This function is used to dispatch all the enabled APs to the function specified
- by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
- immediately and Procedure is not started on any AP.
-
- If SingleThread is TRUE, all the enabled APs execute the function specified by
- Procedure one by one, in ascending order of processor handle number. Otherwise,
- all the enabled APs execute the function specified by Procedure simultaneously.
-
- If the timeout specified by TimeoutInMicroSeconds expires before all APs return
- from Procedure, then Procedure on the failed APs is terminated. All enabled APs
- are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
- content points to the list of processor handle numbers in which Procedure was
- terminated.
-
- Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- to make sure that the nature of the code that is executed on the BSP and the
- dispatched APs is well controlled. The MP Services Ppi does not guarantee
- that the Procedure function is MP-safe. Hence, the tasks that can be run in
- parallel are limited to certain independent tasks and well-controlled exclusive
- code. PEI services and Ppis may not be called by APs unless otherwise
- specified.
-
- In blocking execution mode, BSP waits until all APs finish or
- TimeoutInMicroSeconds expires.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] Procedure A pointer to the function to be run on enabled APs of
- the system.
- @param[in] SingleThread If TRUE, then all the enabled APs execute the function
- specified by Procedure one by one, in ascending order
- of processor handle number. If FALSE, then all the
- enabled APs execute the function specified by Procedure
- simultaneously.
- @param[in] TimeoutInMicroSeconds
- Indicates the time limit in microseconds for APs to
- return from Procedure, for blocking mode only. Zero
- means infinity. If the timeout expires before all APs
- return from Procedure, then Procedure on the failed APs
- is terminated. All enabled APs are available for next
- function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
- timeout expires in blocking mode, BSP returns
- EFI_TIMEOUT.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
-
- @retval EFI_SUCCESS In blocking mode, all APs have finished before the
- timeout expired.
- @retval EFI_DEVICE_ERROR Caller processor is AP.
- @retval EFI_NOT_STARTED No enabled APs exist in the system.
- @retval EFI_NOT_READY Any enabled APs are busy.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before all
- enabled APs have finished.
- @retval EFI_INVALID_PARAMETER Procedure is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiStartupAllAPs (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN EFI_AP_PROCEDURE Procedure,
- IN BOOLEAN SingleThread,
- IN UINTN TimeoutInMicroSeconds,
- IN VOID *ProcedureArgument OPTIONAL
- )
-{
- return MpInitLibStartupAllAPs (
- Procedure,
- SingleThread,
- NULL,
- TimeoutInMicroSeconds,
- ProcedureArgument,
- NULL
- );
-}
-
-/**
- This service lets the caller get one enabled AP to execute a caller-provided
- function. The caller can request the BSP to wait for the completion
- of the AP. This service may only be called from the BSP.
-
- This function is used to dispatch one enabled AP to the function specified by
- Procedure passing in the argument specified by ProcedureArgument.
- The execution is in blocking mode. The BSP waits until the AP finishes or
- TimeoutInMicroSecondss expires.
-
- If the timeout specified by TimeoutInMicroseconds expires before the AP returns
- from Procedure, then execution of Procedure by the AP is terminated. The AP is
- available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
- EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] Procedure A pointer to the function to be run on enabled APs of
- the system.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] TimeoutInMicroseconds
- Indicates the time limit in microseconds for APs to
- return from Procedure, for blocking mode only. Zero
- means infinity. If the timeout expires before all APs
- return from Procedure, then Procedure on the failed APs
- is terminated. All enabled APs are available for next
- function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
- timeout expires in blocking mode, BSP returns
- EFI_TIMEOUT.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
-
- @retval EFI_SUCCESS In blocking mode, specified AP finished before the
- timeout expires.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before the
- specified AP has finished.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
- @retval EFI_INVALID_PARAMETER Procedure is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiStartupThisAP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN ProcessorNumber,
- IN UINTN TimeoutInMicroseconds,
- IN VOID *ProcedureArgument OPTIONAL
- )
-{
- return MpInitLibStartupThisAP (
- Procedure,
- ProcessorNumber,
- NULL,
- TimeoutInMicroseconds,
- ProcedureArgument,
- NULL
- );
-}
-
-/**
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. This call can only be performed
- by the current BSP.
-
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. The new BSP can take over the
- execution of the old BSP and continue seamlessly from where the old one left
- off.
-
- If the BSP cannot be switched prior to the return from this service, then
- EFI_UNSUPPORTED must be returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
- AP. Otherwise, it will be disabled.
-
- @retval EFI_SUCCESS BSP successfully switched.
- @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
- service returning.
- @retval EFI_UNSUPPORTED Switching the BSP is not supported.
- @retval EFI_SUCCESS The calling processor is an AP.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
- AP.
- @retval EFI_NOT_READY The specified AP is busy.
-**/
-EFI_STATUS
-EFIAPI
-PeiSwitchBSP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableOldBSP
- )
-{
- return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
-}
-
-/**
- This service lets the caller enable or disable an AP from this point onward.
- This service may only be called from the BSP.
-
- This service allows the caller enable or disable an AP from this point onward.
- The caller can optionally specify the health status of the AP by Health. If
- an AP is being disabled, then the state of the disabled AP is implementation
- dependent. If an AP is enabled, then the implementation must guarantee that a
- complete initialization sequence is performed on the AP, so the AP is in a state
- that is compatible with an MP operating system.
-
- If the enable or disable AP operation cannot be completed prior to the return
- from this service, then EFI_UNSUPPORTED must be returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] EnableAP Specifies the new state for the processor for enabled,
- FALSE for disabled.
- @param[in] HealthFlag If not NULL, a pointer to a value that specifies the
- new health status of the AP. This flag corresponds to
- StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
- Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
- bits are ignored. If it is NULL, this parameter is
- ignored.
-
- @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
- @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
- to this service returning.
- @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
- does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
-**/
-EFI_STATUS
-EFIAPI
-PeiEnableDisableAP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableAP,
- IN UINT32 *HealthFlag OPTIONAL
- )
-{
- return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
-}
-
-/**
- This return the handle number for the calling processor. This service may be
- called from the BSP and APs.
-
- This service returns the processor handle number for the calling processor.
- The returned value is in the range from 0 to the total number of logical
- processors minus 1. The total number of logical processors can be retrieved
- with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
- called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
- is returned. Otherwise, the current processors handle number is returned in
- ProcessorNumber, and EFI_SUCCESS is returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
-
- @retval EFI_SUCCESS The current processor handle number was returned in
- ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiWhoAmI (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- OUT UINTN *ProcessorNumber
- )
-{
- return MpInitLibWhoAmI (ProcessorNumber);
-}
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.h b/UefiCpuPkg/CpuMpPei/PeiMpServices.h
deleted file mode 100644
index 036d12e..0000000
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/** @file
- Functions prototype of Multiple Processor PPI services.
-
- Copyright (c) 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.
-
-**/
-
-#ifndef _PEI_MP_SERVICES_H_
-#define _PEI_MP_SERVICES_H_
-
-#include "CpuMpPei.h"
-
-
-/**
- This service retrieves the number of logical processor in the platform
- and the number of those logical processors that are enabled on this boot.
- This service may only be called from the BSP.
-
- This function is used to retrieve the following information:
- - The number of logical processors that are present in the system.
- - The number of enabled logical processors in the system at the instant
- this call is made.
-
- Because MP Service Ppi provides services to enable and disable processors
- dynamically, the number of enabled logical processors may vary during the
- course of a boot session.
-
- If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
- If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
- EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
- is returned in NumberOfProcessors, the number of currently enabled processor
- is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This Pointer to this instance of the PPI.
- @param[out] NumberOfProcessors Pointer to the total number of logical processors in
- the system, including the BSP and disabled APs.
- @param[out] NumberOfEnabledProcessors
- Number of processors in the system that are enabled.
-
- @retval EFI_SUCCESS The number of logical processors and enabled
- logical processors was retrieved.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
- NumberOfEnabledProcessors is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiGetNumberOfProcessors (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- OUT UINTN *NumberOfProcessors,
- OUT UINTN *NumberOfEnabledProcessors
- );
-
-/**
- Gets detailed MP-related information on the requested processor at the
- instant this call is made. This service may only be called from the BSP.
-
- This service retrieves detailed MP-related information about any processor
- on the platform. Note the following:
- - The processor information may change during the course of a boot session.
- - The information presented here is entirely MP related.
-
- Information regarding the number of caches and their sizes, frequency of operation,
- slot numbers is all considered platform-related information and is not provided
- by this service.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This Pointer to this instance of the PPI.
- @param[in] ProcessorNumber Pointer to the total number of logical processors in
- the system, including the BSP and disabled APs.
- @param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
-**/
-EFI_STATUS
-EFIAPI
-PeiGetProcessorInfo (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
- );
-
-/**
- This service executes a caller provided function on all enabled APs. APs can
- run either simultaneously or one at a time in sequence. This service supports
- both blocking requests only. This service may only
- be called from the BSP.
-
- This function is used to dispatch all the enabled APs to the function specified
- by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
- immediately and Procedure is not started on any AP.
-
- If SingleThread is TRUE, all the enabled APs execute the function specified by
- Procedure one by one, in ascending order of processor handle number. Otherwise,
- all the enabled APs execute the function specified by Procedure simultaneously.
-
- If the timeout specified by TimeoutInMicroSeconds expires before all APs return
- from Procedure, then Procedure on the failed APs is terminated. All enabled APs
- are always available for further calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- and EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If FailedCpuList is not NULL, its
- content points to the list of processor handle numbers in which Procedure was
- terminated.
-
- Note: It is the responsibility of the consumer of the EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- to make sure that the nature of the code that is executed on the BSP and the
- dispatched APs is well controlled. The MP Services Ppi does not guarantee
- that the Procedure function is MP-safe. Hence, the tasks that can be run in
- parallel are limited to certain independent tasks and well-controlled exclusive
- code. PEI services and Ppis may not be called by APs unless otherwise
- specified.
-
- In blocking execution mode, BSP waits until all APs finish or
- TimeoutInMicroSeconds expires.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] Procedure A pointer to the function to be run on enabled APs of
- the system.
- @param[in] SingleThread If TRUE, then all the enabled APs execute the function
- specified by Procedure one by one, in ascending order
- of processor handle number. If FALSE, then all the
- enabled APs execute the function specified by Procedure
- simultaneously.
- @param[in] TimeoutInMicroSeconds
- Indicates the time limit in microseconds for APs to
- return from Procedure, for blocking mode only. Zero
- means infinity. If the timeout expires before all APs
- return from Procedure, then Procedure on the failed APs
- is terminated. All enabled APs are available for next
- function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
- timeout expires in blocking mode, BSP returns
- EFI_TIMEOUT.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
-
- @retval EFI_SUCCESS In blocking mode, all APs have finished before the
- timeout expired.
- @retval EFI_DEVICE_ERROR Caller processor is AP.
- @retval EFI_NOT_STARTED No enabled APs exist in the system.
- @retval EFI_NOT_READY Any enabled APs are busy.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before all
- enabled APs have finished.
- @retval EFI_INVALID_PARAMETER Procedure is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiStartupAllAPs (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN EFI_AP_PROCEDURE Procedure,
- IN BOOLEAN SingleThread,
- IN UINTN TimeoutInMicroSeconds,
- IN VOID *ProcedureArgument OPTIONAL
- );
-
-/**
- This service lets the caller get one enabled AP to execute a caller-provided
- function. The caller can request the BSP to wait for the completion
- of the AP. This service may only be called from the BSP.
-
- This function is used to dispatch one enabled AP to the function specified by
- Procedure passing in the argument specified by ProcedureArgument.
- The execution is in blocking mode. The BSP waits until the AP finishes or
- TimeoutInMicroSecondss expires.
-
- If the timeout specified by TimeoutInMicroseconds expires before the AP returns
- from Procedure, then execution of Procedure by the AP is terminated. The AP is
- available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
- EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] Procedure A pointer to the function to be run on enabled APs of
- the system.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] TimeoutInMicroseconds
- Indicates the time limit in microseconds for APs to
- return from Procedure, for blocking mode only. Zero
- means infinity. If the timeout expires before all APs
- return from Procedure, then Procedure on the failed APs
- is terminated. All enabled APs are available for next
- function assigned by EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
- or EFI_PEI_MP_SERVICES_PPI.StartupThisAP(). If the
- timeout expires in blocking mode, BSP returns
- EFI_TIMEOUT.
- @param[in] ProcedureArgument The parameter passed into Procedure for all APs.
-
- @retval EFI_SUCCESS In blocking mode, specified AP finished before the
- timeout expires.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before the
- specified AP has finished.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
- @retval EFI_INVALID_PARAMETER Procedure is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiStartupThisAP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN ProcessorNumber,
- IN UINTN TimeoutInMicroseconds,
- IN VOID *ProcedureArgument OPTIONAL
- );
-
-/**
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. This call can only be performed
- by the current BSP.
-
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. The new BSP can take over the
- execution of the old BSP and continue seamlessly from where the old one left
- off.
-
- If the BSP cannot be switched prior to the return from this service, then
- EFI_UNSUPPORTED must be returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an enabled
- AP. Otherwise, it will be disabled.
-
- @retval EFI_SUCCESS BSP successfully switched.
- @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to this
- service returning.
- @retval EFI_UNSUPPORTED Switching the BSP is not supported.
- @retval EFI_SUCCESS The calling processor is an AP.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or a disabled
- AP.
- @retval EFI_NOT_READY The specified AP is busy.
-**/
-EFI_STATUS
-EFIAPI
-PeiSwitchBSP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableOldBSP
- );
-
-/**
- This service lets the caller enable or disable an AP from this point onward.
- This service may only be called from the BSP.
-
- This service allows the caller enable or disable an AP from this point onward.
- The caller can optionally specify the health status of the AP by Health. If
- an AP is being disabled, then the state of the disabled AP is implementation
- dependent. If an AP is enabled, then the implementation must guarantee that a
- complete initialization sequence is performed on the AP, so the AP is in a state
- that is compatible with an MP operating system.
-
- If the enable or disable AP operation cannot be completed prior to the return
- from this service, then EFI_UNSUPPORTED must be returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
- @param[in] EnableAP Specifies the new state for the processor for enabled,
- FALSE for disabled.
- @param[in] HealthFlag If not NULL, a pointer to a value that specifies the
- new health status of the AP. This flag corresponds to
- StatusFlag defined in EFI_PEI_MP_SERVICES_PPI.GetProcessorInfo().
- Only the PROCESSOR_HEALTH_STATUS_BIT is used. All other
- bits are ignored. If it is NULL, this parameter is
- ignored.
-
- @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
- @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed prior
- to this service returning.
- @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
- @retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
- does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
-**/
-EFI_STATUS
-EFIAPI
-PeiEnableDisableAP (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- IN UINTN ProcessorNumber,
- IN BOOLEAN EnableAP,
- IN UINT32 *HealthFlag OPTIONAL
- );
-
-/**
- This return the handle number for the calling processor. This service may be
- called from the BSP and APs.
-
- This service returns the processor handle number for the calling processor.
- The returned value is in the range from 0 to the total number of logical
- processors minus 1. The total number of logical processors can be retrieved
- with EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors(). This service may be
- called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
- is returned. Otherwise, the current processors handle number is returned in
- ProcessorNumber, and EFI_SUCCESS is returned.
-
- @param[in] PeiServices An indirect pointer to the PEI Services Table
- published by the PEI Foundation.
- @param[in] This A pointer to the EFI_PEI_MP_SERVICES_PPI instance.
- @param[out] ProcessorNumber The handle number of the AP. The range is from 0 to the
- total number of logical processors minus 1. The total
- number of logical processors can be retrieved by
- EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
-
- @retval EFI_SUCCESS The current processor handle number was returned in
- ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
-**/
-EFI_STATUS
-EFIAPI
-PeiWhoAmI (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_MP_SERVICES_PPI *This,
- OUT UINTN *ProcessorNumber
- );
-
-#endif
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 41/46] UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (39 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 40/46] UefiCpuPkg/CpuMpPei: Delete PeiMpServices.c and PeiMpServices.h Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 42/46] UefiCpuPkg/CpuDxe: Move SetMtrrsFromBuffer() location Jeff Fan
` (4 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
Consume MP Initialize library to produce CPU MP Protocol services to simply the
code.
v4:
1. Update CpuDxe.c file header to mention it produces CPU Arch protocol.
2. Update BistData type from UINT32 to EFI_HEALTH_FLAG.
3. Move some header location from CpuMp.h to CpuDxe.h.
v3:
1. Move the code Consume MpInitLib APIs to produce CPU MP Protocol from patch
#40 to this patch.
2. Add DxeMpInitLib.inf in DSC file
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>
---
UefiCpuPkg/CpuDxe/CpuDxe.c | 2 +-
UefiCpuPkg/CpuDxe/CpuDxe.h | 12 +-
UefiCpuPkg/CpuDxe/CpuDxe.inf | 7 +-
UefiCpuPkg/CpuDxe/CpuDxe.uni | 10 +-
| 4 +-
UefiCpuPkg/CpuDxe/CpuMp.c | 854 +++-----------------------------------
UefiCpuPkg/CpuDxe/CpuMp.h | 2 -
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
8 files changed, 77 insertions(+), 815 deletions(-)
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index 78b2c88..1b94290 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -1,5 +1,5 @@
/** @file
- CPU DXE Module.
+ CPU DXE Module to produce CPU ARCH Protocol.
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h
index 2aef626..00d1a8f 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.h
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -1,7 +1,7 @@
/** @file
- CPU DXE Module.
+ CPU DXE Module to produce CPU ARCH Protocol and CPU MP Protocol.
- Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2008 - 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
@@ -18,6 +18,10 @@
#include <PiDxe.h>
#include <Protocol/Cpu.h>
+#include <Protocol/MpService.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
@@ -33,6 +37,10 @@
#include <Library/UefiLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/TimerLib.h>
+#include <Library/HobLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/MpInitLib.h>
+
#include <Guid/IdleLoopEvent.h>
#include <Guid/VectorHandoffTable.h>
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index bdff548..0643bec 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -1,5 +1,5 @@
## @file
-# Simple CPU driver installs CPU Architecture Protocol.
+# CPU driver installs CPU Architecture Protocol and CPU MP protocol.
#
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
@@ -41,10 +41,9 @@ [LibraryClasses]
UefiCpuLib
UefiLib
CpuExceptionHandlerLib
- TimerLib
- SynchronizationLib
HobLib
ReportStatusCodeLib
+ MpInitLib
[Sources]
ApStartup.c
@@ -71,7 +70,7 @@ [Sources.X64]
[Protocols]
gEfiCpuArchProtocolGuid ## PRODUCES
- gEfiMpServiceProtocolGuid ## SOMETIMES_PRODUCES
+ gEfiMpServiceProtocolGuid ## PRODUCES
[Guids]
gIdleLoopEventGuid ## CONSUMES ## Event
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.uni b/UefiCpuPkg/CpuDxe/CpuDxe.uni
index 5ac7810..caf01dc 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.uni
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.uni
@@ -1,9 +1,9 @@
// /** @file
-// Simple CPU driver installs CPU Architecture Protocol.
+// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.
//
-// Simple CPU driver installs CPU Architecture Protocol.
+// CPU driver installs CPU Architecture Protocol and CPU MP Protocol.
//
-// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2008 - 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
@@ -16,7 +16,7 @@
// **/
-#string STR_MODULE_ABSTRACT #language en-US "Installs CPU Architecture Protocol"
+#string STR_MODULE_ABSTRACT #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."
-#string STR_MODULE_DESCRIPTION #language en-US "Simple CPU driver installs CPU Architecture Protocol."
+#string STR_MODULE_DESCRIPTION #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol."
--git a/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni b/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
index fbfc2e1..c1d2019 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
+++ b/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni
@@ -1,7 +1,7 @@
// /** @file
// CpuDxe Localized Strings and Content
//
-// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2013 - 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
@@ -15,6 +15,6 @@
#string STR_PROPERTIES_MODULE_NAME
#language en-US
-"CPU Architectural DXE Driver"
+"CPU Architectural and CPU Multi-processor DXE Driver"
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 98fdfdf..38603f9 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1,7 +1,7 @@
/** @file
- CPU DXE Module.
+ CPU DXE Module to produce CPU MP Protocol.
- Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2008 - 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
@@ -21,6 +21,7 @@ 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;
@@ -28,7 +29,6 @@ VOID *mTopOfApCommonStack = 0;
VOID *mApStackStart = 0;
volatile BOOLEAN mAPsAlreadyInitFinished = FALSE;
-volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;
EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
GetNumberOfProcessors,
@@ -102,6 +102,7 @@ IsBSP (
@retval CPU_STATE the AP status
**/
+STATIC
CPU_STATE
GetApState (
IN CPU_DATA_BLOCK *CpuData
@@ -123,6 +124,7 @@ GetApState (
@param State The AP status
**/
+STATIC
VOID
SetApState (
IN CPU_DATA_BLOCK *CpuData,
@@ -452,13 +454,10 @@ GetNumberOfProcessors (
return EFI_INVALID_PARAMETER;
}
- if (!IsBSP ()) {
- return EFI_DEVICE_ERROR;
- }
-
- *NumberOfProcessors = mMpSystemData.NumberOfProcessors;
- *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;
- return EFI_SUCCESS;
+ return MpInitLibGetNumberOfProcessors (
+ NumberOfProcessors,
+ NumberOfEnabledProcessors
+ );
}
/**
@@ -495,20 +494,7 @@ GetProcessorInfo (
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
)
{
- if (ProcessorInfoBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (!IsBSP ()) {
- return EFI_DEVICE_ERROR;
- }
-
- if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
- return EFI_NOT_FOUND;
- }
-
- CopyMem (ProcessorInfoBuffer, &mMpSystemData.CpuDatas[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
- return EFI_SUCCESS;
+ return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
}
/**
@@ -659,155 +645,14 @@ StartupAllAPs (
OUT UINTN **FailedCpuList OPTIONAL
)
{
- EFI_STATUS Status;
- CPU_DATA_BLOCK *CpuData;
- UINTN Number;
- CPU_STATE APInitialState;
- CPU_STATE CpuState;
-
- CpuData = NULL;
-
- if (FailedCpuList != NULL) {
- *FailedCpuList = NULL;
- }
-
- if (!IsBSP ()) {
- return EFI_DEVICE_ERROR;
- }
-
- if (mMpSystemData.NumberOfProcessors == 1) {
- return EFI_NOT_STARTED;
- }
-
- if (Procedure == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // temporarily stop checkAllAPsStatus for avoid resource dead-lock.
- //
- mStopCheckAllAPsStatus = TRUE;
-
- 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) {
- return EFI_NOT_READY;
- }
- }
-
- mMpSystemData.Procedure = Procedure;
- mMpSystemData.ProcedureArgument = ProcedureArgument;
- mMpSystemData.WaitEvent = WaitEvent;
- mMpSystemData.Timeout = TimeoutInMicroseconds;
- mMpSystemData.TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
- mMpSystemData.FinishCount = 0;
- mMpSystemData.StartCount = 0;
- mMpSystemData.SingleThread = SingleThread;
- mMpSystemData.FailedList = FailedCpuList;
- mMpSystemData.FailedListIndex = 0;
- APInitialState = CpuStateReady;
-
- 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;
- }
-
- //
- // Get APs prepared, and put failing APs into FailedCpuList
- // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready
- // state 1 by 1, until the previous 1 finished its task
- // if not "SingleThread", all APs are put to ready state from the beginning
- //
- CpuState = GetApState (CpuData);
- if (CpuState == CpuStateIdle ||
- CpuState == CpuStateSleeping) {
- mMpSystemData.StartCount++;
-
- SetApState (CpuData, APInitialState);
-
- if (APInitialState == CpuStateReady) {
- SetApProcedure (CpuData, Procedure, ProcedureArgument);
- //
- // If this AP previous state is Sleeping, we should
- // wake up this AP by sent a SIPI. and avoid
- // re-involve the sleeping state. we must call
- // SetApProcedure() first.
- //
- if (CpuState == CpuStateSleeping) {
- ResetProcessorToIdleState (CpuData);
- }
- }
-
- if (SingleThread) {
- APInitialState = CpuStateBlocked;
- }
- }
- }
-
- mStopCheckAllAPsStatus = FALSE;
-
- if (WaitEvent != NULL) {
- //
- // non blocking
- //
- return EFI_SUCCESS;
- }
-
- //
- // Blocking temporarily stop CheckAllAPsStatus()
- //
- mStopCheckAllAPsStatus = TRUE;
-
- while (TRUE) {
- CheckAndUpdateAllAPsToIdleState ();
- if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {
- Status = EFI_SUCCESS;
- goto Done;
- }
-
- //
- // task timeout
- //
- if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
- ResetAllFailedAPs();
- Status = EFI_TIMEOUT;
- goto Done;
- }
-
- MicroSecondDelay (gPollInterval);
- mMpSystemData.Timeout -= gPollInterval;
- }
-
-Done:
-
- return Status;
+ return MpInitLibStartupAllAPs (
+ Procedure,
+ SingleThread,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ FailedCpuList
+ );
}
/**
@@ -908,90 +753,14 @@ StartupThisAP (
OUT BOOLEAN *Finished OPTIONAL
)
{
- CPU_DATA_BLOCK *CpuData;
- CPU_STATE CpuState;
-
- CpuData = NULL;
-
- if (Finished != NULL) {
- *Finished = FALSE;
- }
-
- if (!IsBSP ()) {
- return EFI_DEVICE_ERROR;
- }
-
- if (Procedure == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
- return EFI_NOT_FOUND;
- }
-
- //
- // temporarily stop checkAllAPsStatus for avoid resource dead-lock.
- //
- mStopCheckAllAPsStatus = TRUE;
-
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
- if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) ||
- !TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
- return EFI_INVALID_PARAMETER;
- }
-
- CpuState = GetApState (CpuData);
- if (CpuState != CpuStateIdle &&
- CpuState != CpuStateSleeping) {
- return EFI_NOT_READY;
- }
-
- SetApState (CpuData, CpuStateReady);
-
- SetApProcedure (CpuData, Procedure, ProcedureArgument);
- //
- // If this AP previous state is Sleeping, we should
- // wake up this AP by sent a SIPI. and avoid
- // re-involve the sleeping state. we must call
- // SetApProcedure() first.
- //
- if (CpuState == CpuStateSleeping) {
- ResetProcessorToIdleState (CpuData);
- }
-
- CpuData->Timeout = TimeoutInMicroseconds;
- CpuData->WaitEvent = WaitEvent;
- CpuData->TimeoutActive = (BOOLEAN) (TimeoutInMicroseconds != 0);
- CpuData->Finished = Finished;
-
- mStopCheckAllAPsStatus = FALSE;
-
- if (WaitEvent != NULL) {
- //
- // Non Blocking
- //
- return EFI_SUCCESS;
- }
-
- //
- // Blocking
- //
- while (TRUE) {
- if (GetApState (CpuData) == CpuStateFinished) {
- SetApState (CpuData, CpuStateIdle);
- break;
- }
-
- if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
- ResetProcessorToIdleState (CpuData);
- return EFI_TIMEOUT;
- }
-
- MicroSecondDelay (gPollInterval);
- CpuData->Timeout -= gPollInterval;
- }
-
- return EFI_SUCCESS;
+ return MpInitLibStartupThisAP (
+ Procedure,
+ ProcessorNumber,
+ WaitEvent,
+ TimeoutInMicroseconds,
+ ProcedureArgument,
+ Finished
+ );
}
/**
@@ -1037,10 +806,7 @@ SwitchBSP (
IN BOOLEAN EnableOldBSP
)
{
- //
- // Current always return unsupported.
- //
- return EFI_UNSUPPORTED;
+ return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
}
/**
@@ -1093,62 +859,7 @@ EnableDisableAP (
IN UINT32 *HealthFlag OPTIONAL
)
{
- CPU_DATA_BLOCK *CpuData;
- BOOLEAN TempStopCheckState;
- CPU_STATE CpuState;
-
- CpuData = NULL;
- TempStopCheckState = FALSE;
-
- if (!IsBSP ()) {
- return EFI_DEVICE_ERROR;
- }
-
- if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) {
- return EFI_NOT_FOUND;
- }
-
- //
- // temporarily stop checkAllAPsStatus for initialize parameters.
- //
- if (!mStopCheckAllAPsStatus) {
- mStopCheckAllAPsStatus = TRUE;
- TempStopCheckState = TRUE;
- }
-
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
- if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
- return EFI_INVALID_PARAMETER;
- }
-
- CpuState = GetApState (CpuData);
- if (CpuState != CpuStateIdle &&
- CpuState != CpuStateSleeping) {
- return EFI_UNSUPPORTED;
- }
-
- if (EnableAP) {
- if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) {
- mMpSystemData.NumberOfEnabledProcessors++;
- }
- CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT);
- } else {
- if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {
- mMpSystemData.NumberOfEnabledProcessors--;
- }
- CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT);
- }
-
- if (HealthFlag != NULL) {
- CpuStatusFlagAndNot (CpuData, (UINT32)~PROCESSOR_HEALTH_STATUS_BIT);
- CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));
- }
-
- if (TempStopCheckState) {
- mStopCheckAllAPsStatus = FALSE;
- }
-
- return EFI_SUCCESS;
+ return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
}
/**
@@ -1182,383 +893,7 @@ WhoAmI (
OUT UINTN *ProcessorNumber
)
{
- UINTN Index;
- UINT32 ProcessorId;
-
- if (ProcessorNumber == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ProcessorId = GetApicId ();
- for (Index = 0; Index < mMpSystemData.NumberOfProcessors; Index++) {
- if (mMpSystemData.CpuDatas[Index].Info.ProcessorId == ProcessorId) {
- break;
- }
- }
-
- *ProcessorNumber = Index;
- return EFI_SUCCESS;
-}
-
-/**
- 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
- )
-{
- ResetApStackless ((UINT32)CpuData->Info.ProcessorId);
-}
-
-/**
- Application Processors do loop routine
- after switch to its own stack.
-
- @param Context1 A pointer to the context to pass into the function.
- @param Context2 A pointer to the context to pass into the function.
-
-**/
-VOID
-ProcessorToIdleState (
- IN VOID *Context1, OPTIONAL
- IN VOID *Context2 OPTIONAL
- )
-{
- UINTN ProcessorNumber;
- CPU_DATA_BLOCK *CpuData;
- EFI_AP_PROCEDURE Procedure;
- volatile VOID *ProcedureArgument;
-
- AsmApDoneWithCommonStack ();
-
- while (!mAPsAlreadyInitFinished) {
- CpuPause ();
- }
-
- WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
-
- //
- // Avoid forcibly reset AP caused the AP got lock not release.
- //
- if (CpuData->LockSelf == (INTN) GetApicId ()) {
- ReleaseSpinLock (&CpuData->CpuDataLock);
- }
-
- //
- // Avoid forcibly reset AP caused the timeout AP State is not
- // updated.
- //
- GetMpSpinLock (CpuData);
- if (CpuData->State == CpuStateBusy) {
- CpuData->Procedure = NULL;
- }
- CpuData->State = CpuStateIdle;
- ReleaseMpSpinLock (CpuData);
-
- while (TRUE) {
- GetMpSpinLock (CpuData);
- ProcedureArgument = CpuData->Parameter;
- Procedure = CpuData->Procedure;
- ReleaseMpSpinLock (CpuData);
-
- if (Procedure != NULL) {
- SetApState (CpuData, CpuStateBusy);
-
- Procedure ((VOID*) ProcedureArgument);
-
- GetMpSpinLock (CpuData);
- CpuData->Procedure = NULL;
- CpuData->State = CpuStateFinished;
- ReleaseMpSpinLock (CpuData);
- } else {
- //
- // if no procedure to execution, we simply put AP
- // into sleeping state, and waiting BSP sent SIPI.
- //
- GetMpSpinLock (CpuData);
- if (CpuData->State == CpuStateIdle) {
- CpuData->State = CpuStateSleeping;
- }
- ReleaseMpSpinLock (CpuData);
- }
-
- if (GetApState (CpuData) == CpuStateSleeping) {
- CpuSleep ();
- }
-
- CpuPause ();
- }
-
- CpuSleep ();
- CpuDeadLoop ();
-}
-
-/**
- Checks AP' status periodically.
-
- This function is triggerred by timer perodically to check the
- state of AP forStartupThisAP() executed in non-blocking mode.
-
- @param Event Event triggered.
- @param Context Parameter passed with the event.
-
-**/
-VOID
-EFIAPI
-CheckThisAPStatus (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- CPU_DATA_BLOCK *CpuData;
- CPU_STATE CpuState;
-
- CpuData = (CPU_DATA_BLOCK *) Context;
- if (CpuData->TimeoutActive) {
- CpuData->Timeout -= gPollInterval;
- }
-
- CpuState = GetApState (CpuData);
-
- if (CpuState == CpuStateFinished) {
- if (CpuData->Finished) {
- *CpuData->Finished = TRUE;
- }
- SetApState (CpuData, CpuStateIdle);
- goto out;
- }
-
- if (CpuData->TimeoutActive && CpuData->Timeout < 0) {
- if (CpuState != CpuStateIdle &&
- CpuData->Finished) {
- *CpuData->Finished = FALSE;
- }
- ResetProcessorToIdleState (CpuData);
- goto out;
- }
-
- return;
-
-out:
- CpuData->TimeoutActive = FALSE;
- gBS->SignalEvent (CpuData->WaitEvent);
- CpuData->WaitEvent = NULL;
-}
-
-/**
- Checks APs' status periodically.
-
- This function is triggerred by timer perodically to check the
- state of APs for StartupAllAPs() executed in non-blocking mode.
-
- @param Event Event triggered.
- @param Context Parameter passed with the event.
-
-**/
-VOID
-EFIAPI
-CheckAllAPsStatus (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- CPU_DATA_BLOCK *CpuData;
- UINTN Number;
- EFI_STATUS Status;
-
- if (mMpSystemData.TimeoutActive) {
- mMpSystemData.Timeout -= gPollInterval;
- }
-
- if (mStopCheckAllAPsStatus) {
- return;
- }
-
- //
- // avoid next timer enter.
- //
- Status = gBS->SetTimer (
- mMpSystemData.CheckAllAPsEvent,
- TimerCancel,
- 0
- );
- ASSERT_EFI_ERROR (Status);
-
- if (mMpSystemData.WaitEvent != NULL) {
- CheckAndUpdateAllAPsToIdleState ();
- //
- // task timeout
- //
- if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
- ResetAllFailedAPs();
- //
- // force exit
- //
- mMpSystemData.FinishCount = mMpSystemData.StartCount;
- }
-
- if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
- goto EXIT;
- }
-
- mMpSystemData.TimeoutActive = FALSE;
- gBS->SignalEvent (mMpSystemData.WaitEvent);
- mMpSystemData.WaitEvent = NULL;
- mStopCheckAllAPsStatus = TRUE;
-
- goto EXIT;
- }
-
- //
- // check each AP status for StartupThisAP
- //
- for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {
- CpuData = &mMpSystemData.CpuDatas[Number];
- if (CpuData->WaitEvent) {
- CheckThisAPStatus (NULL, (VOID *)CpuData);
- }
- }
-
-EXIT:
- Status = gBS->SetTimer (
- mMpSystemData.CheckAllAPsEvent,
- TimerPeriodic,
- EFI_TIMER_PERIOD_MICROSECONDS (100)
- );
- ASSERT_EFI_ERROR (Status);
-}
-
-/**
- Application Processor C code entry point.
-
-**/
-VOID
-EFIAPI
-ApEntryPointInC (
- VOID
- )
-{
- VOID* TopOfApStack;
- UINTN ProcessorNumber;
-
- if (!mAPsAlreadyInitFinished) {
- FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
- TopOfApStack = (UINT8*)mApStackStart + gApStackSize;
- mApStackStart = TopOfApStack;
-
- //
- // Store the Stack address, when reset the AP, We can found the original address.
- //
- mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack;
- mMpSystemData.NumberOfProcessors++;
- mMpSystemData.NumberOfEnabledProcessors++;
- } else {
- WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
- //
- // Get the original stack address.
- //
- TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack;
- }
-
- SwitchStack (
- (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
- NULL,
- NULL,
- TopOfApStack);
-}
-
-/**
- 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
- )
-{
- CPU_DATA_BLOCK *CpuData;
- UINT32 ProcessorId;
-
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
- ProcessorId = GetApicId ();
- CpuData->Info.ProcessorId = ProcessorId;
- CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
- if (Bsp) {
- CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
- }
- CpuData->Info.Location.Package = ProcessorId;
- CpuData->Info.Location.Core = 0;
- CpuData->Info.Location.Thread = 0;
- CpuData->State = Bsp ? CpuStateBusy : CpuStateIdle;
-
- CpuData->Procedure = NULL;
- CpuData->Parameter = NULL;
- InitializeSpinLock (&CpuData->CpuDataLock);
- CpuData->LockSelf = -1;
-
- return EFI_SUCCESS;
-}
-
-/**
- Prepare the System Data.
-
- @retval EFI_SUCCESS the System Data finished initilization.
-
-**/
-EFI_STATUS
-InitMpSystemData (
- VOID
- )
-{
- EFI_STATUS Status;
-
- ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));
-
- mMpSystemData.NumberOfProcessors = 1;
- mMpSystemData.NumberOfEnabledProcessors = 1;
-
- mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber);
- ASSERT(mMpSystemData.CpuDatas != NULL);
-
- Status = gBS->CreateEvent (
- EVT_TIMER | EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- CheckAllAPsStatus,
- NULL,
- &mMpSystemData.CheckAllAPsEvent
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Set timer to check all APs status.
- //
- Status = gBS->SetTimer (
- mMpSystemData.CheckAllAPsEvent,
- TimerPeriodic,
- EFI_TIMER_PERIOD_MICROSECONDS (100)
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // BSP
- //
- FillInProcessorInformation (TRUE, 0);
-
- return EFI_SUCCESS;
+ return MpInitLibWhoAmI (ProcessorNumber);;
}
/**
@@ -1580,8 +915,8 @@ CollectBistDataFromHob (
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
UINTN ProcessorNumber;
- UINT32 InitialLocalApicId;
- CPU_DATA_BLOCK *CpuData;
+ EFI_PROCESSOR_INFORMATION ProcessorInfo;
+ EFI_HEALTH_FLAGS BistData;
SecPlatformInformation2 = NULL;
SecPlatformInformation = NULL;
@@ -1622,23 +957,22 @@ CollectBistDataFromHob (
}
while ((NumberOfData--) > 0) {
- for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
- InitialLocalApicId = (UINT32) CpuData->Info.ProcessorId;
- if (InitialLocalApicId == CpuInstance[NumberOfData].CpuLocation) {
+ for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) {
+ MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
+ if (ProcessorInfo.ProcessorId == CpuInstance[NumberOfData].CpuLocation) {
//
// Update CPU health status for MP Services Protocol according to BIST data.
//
- if (CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags.Uint32 != 0) {
- CpuData->Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
- //
- // Report Status Code that self test is failed
- //
- REPORT_STATUS_CODE (
- EFI_ERROR_CODE | EFI_ERROR_MAJOR,
- (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
- );
- }
+ BistData = CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags;
+ }
+ if (BistData.Uint32 != 0) {
+ //
+ // Report Status Code that self test is failed
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
+ );
}
}
}
@@ -1692,115 +1026,37 @@ InitializeMpSupport (
)
{
EFI_STATUS Status;
- MTRR_SETTINGS MtrrSettings;
- UINTN Timeout;
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
- gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
- if (gMaxLogicalProcessorNumber < 1) {
+ NumberOfProcessors = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ if (NumberOfProcessors < 1) {
DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
return;
}
-
-
- InitMpSystemData ();
-
//
// Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
//
- if (gMaxLogicalProcessorNumber > 1) {
-
- gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
- ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0);
-
- mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
- ASSERT (mApStackStart != NULL);
-
- //
- // the first buffer of stack size used for common stack, when the amount of AP
- // more than 1, we should never free the common stack which maybe used for AP reset.
- //
- mCommonStack = mApStackStart;
- mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize;
- mApStackStart = mTopOfApCommonStack;
-
- PrepareAPStartupCode ();
+ if (NumberOfProcessors > 1) {
+ Status = MpInitLibInitialize ();
+ ASSERT_EFI_ERROR (Status);
- StartApsStackless ();
- }
-
- DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors));
- if (mMpSystemData.NumberOfProcessors == 1) {
- FreeApStartupCode ();
- if (mCommonStack != NULL) {
- FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));
- }
+ MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);
+ mNumberOfProcessors = NumberOfProcessors;
}
-
- mMpSystemData.CpuDatas = ReallocatePool (
- sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber,
- sizeof (CPU_DATA_BLOCK) * mMpSystemData.NumberOfProcessors,
- mMpSystemData.CpuDatas);
-
- //
- // Release all APs to complete initialization and enter idle loop
- //
- mAPsAlreadyInitFinished = TRUE;
-
- //
- // Wait for all APs to enter idle loop.
- //
- Timeout = 0;
- do {
- if (CheckAllAPsSleeping ()) {
- break;
- }
- MicroSecondDelay (gPollInterval);
- Timeout += gPollInterval;
- } while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
- ASSERT (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+ DEBUG ((EFI_D_ERROR, "Detect CPU count: %d\n", mNumberOfProcessors));
//
// Update CPU healthy information from Guided HOB
//
CollectBistDataFromHob ();
- //
- // Synchronize MTRR settings to APs.
- //
- MtrrGetAllMtrrs (&MtrrSettings);
- Status = mMpServicesTemplate.StartupAllAPs (
- &mMpServicesTemplate, // This
- SetMtrrsFromBuffer, // Procedure
- TRUE, // SingleThread
- NULL, // WaitEvent
- 0, // TimeoutInMicrosecsond
- &MtrrSettings, // ProcedureArgument
- NULL // FailedCpuList
- );
- ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_STARTED);
-
Status = gBS->InstallMultipleProtocolInterfaces (
&mMpServiceHandle,
&gEfiMpServiceProtocolGuid, &mMpServicesTemplate,
NULL
);
ASSERT_EFI_ERROR (Status);
-
- if (mMpSystemData.NumberOfProcessors > 1 && mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
- if (mApStackStart != NULL) {
- FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
- (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *
- gApStackSize));
- }
- }
-
- Status = gBS->CreateEvent (
- EVT_SIGNAL_EXIT_BOOT_SERVICES,
- TPL_CALLBACK,
- ExitBootServicesCallback,
- NULL,
- &mExitBootServicesEvent
- );
- ASSERT_EFI_ERROR (Status);
}
+
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 503f3ae..1e204f3 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -19,8 +19,6 @@
#include <Ppi/SecPlatformInformation2.h>
#include <Protocol/MpService.h>
#include <Library/SynchronizationLib.h>
-#include <Library/HobLib.h>
-#include <Library/ReportStatusCodeLib.h>
/**
Initialize Multi-processor support.
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 50f9af7..268b3f4 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -83,6 +83,7 @@ [LibraryClasses.common.DXE_DRIVER]
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 42/46] UefiCpuPkg/CpuDxe: Move SetMtrrsFromBuffer() location.
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (40 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 41/46] UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 43/46] UefiCpuPkg/CpuDxe: Remove unused codes and files Jeff Fan
` (3 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/CpuDxe/CpuDxe.c | 15 +++++++++++++++
UefiCpuPkg/CpuDxe/CpuMp.c | 16 ----------------
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index 1b94290..f6d0a67 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -313,6 +313,21 @@ CpuGetTimerValue (
return EFI_SUCCESS;
}
+/**
+ 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
+ )
+{
+ MtrrSetAllMtrrs (Buffer);
+}
/**
Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 38603f9..8f7a56c 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1001,22 +1001,6 @@ ExitBootServicesCallback (
}
/**
- 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
- )
-{
- MtrrSetAllMtrrs (Buffer);
-}
-
-/**
Initialize Multi-processor support.
**/
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 43/46] UefiCpuPkg/CpuDxe: Remove unused codes and files
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (41 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 42/46] UefiCpuPkg/CpuDxe: Move SetMtrrsFromBuffer() location Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 44/46] MdePkg/MpService.h: Fixed typo in function header to match PI spec Jeff Fan
` (2 subsequent siblings)
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel; +Cc: Michael Kinney, Feng Tian, Giri P Mudusuru, Laszlo Ersek
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>
---
UefiCpuPkg/CpuDxe/ApStartup.c | 478 --------------------------------------
UefiCpuPkg/CpuDxe/CpuDxe.h | 1 -
UefiCpuPkg/CpuDxe/CpuDxe.inf | 5 -
UefiCpuPkg/CpuDxe/CpuMp.c | 400 -------------------------------
UefiCpuPkg/CpuDxe/CpuMp.h | 184 +--------------
UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm | 76 ------
UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm | 68 ------
UefiCpuPkg/CpuDxe/X64/MpAsm.asm | 76 ------
UefiCpuPkg/CpuDxe/X64/MpAsm.nasm | 70 ------
9 files changed, 1 insertion(+), 1357 deletions(-)
delete mode 100644 UefiCpuPkg/CpuDxe/ApStartup.c
delete mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
delete mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
delete mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.asm
delete mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c
deleted file mode 100644
index 78fb26f..0000000
--- a/UefiCpuPkg/CpuDxe/ApStartup.c
+++ /dev/null
@@ -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);
-}
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h
index 00d1a8f..6dd0ad3 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.h
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -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>
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 0643bec..ac87c9e 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -46,7 +46,6 @@ [LibraryClasses]
MpInitLib
[Sources]
- ApStartup.c
CpuDxe.c
CpuDxe.h
CpuGdt.c
@@ -58,15 +57,11 @@ [Sources.IA32]
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
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 8f7a56c..efab78c 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -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,
@@ -41,372 +29,6 @@ EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
};
/**
- 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.
This service may only be called from the BSP.
@@ -979,28 +601,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.
**/
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 1e204f3..43ec3bd 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -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_
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
deleted file mode 100644
index 09579f2..0000000
--- a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
+++ /dev/null
@@ -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
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
deleted file mode 100644
index c47cdce..0000000
--- a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
+++ /dev/null
@@ -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
-
diff --git a/UefiCpuPkg/CpuDxe/X64/MpAsm.asm b/UefiCpuPkg/CpuDxe/X64/MpAsm.asm
deleted file mode 100644
index 308de51..0000000
--- a/UefiCpuPkg/CpuDxe/X64/MpAsm.asm
+++ /dev/null
@@ -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
-
diff --git a/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm b/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
deleted file mode 100644
index e3dc248..0000000
--- a/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
+++ /dev/null
@@ -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
-
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 44/46] MdePkg/MpService.h: Fixed typo in function header to match PI spec
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (42 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 43/46] UefiCpuPkg/CpuDxe: Remove unused codes and files Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 45/46] MdePkg/MpService.h: Trim whitespace at end of line Jeff Fan
2016-07-29 18:15 ` [Patch v4 46/46] UefiCpuPkg/CpuDxe: Fixed typo in function header to match PI spec Jeff Fan
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel
Cc: Liming Gao, Michael Kinney, Feng Tian, Giri P Mudusuru,
Laszlo Ersek
Cc: Liming Gao <liming.gao@intel.com>
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
MdePkg/Include/Protocol/MpService.h | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/MdePkg/Include/Protocol/MpService.h b/MdePkg/Include/Protocol/MpService.h
index 5934727..043a10a 100644
--- a/MdePkg/Include/Protocol/MpService.h
+++ b/MdePkg/Include/Protocol/MpService.h
@@ -27,7 +27,7 @@
APs to help test system memory in parallel with other device initialization.
Diagnostics applications may also use this protocol for multi-processor.
-Copyright (c) 2006 - 2010, 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 that accompanies this distribution.
The full text of the license may be found at
@@ -388,8 +388,8 @@ EFI_STATUS
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
instance.
- @param[in] Procedure A pointer to the function to be run on
- enabled APs of the system. See type
+ @param[in] Procedure A pointer to the function to be run on the
+ designated AP of the system. See type
EFI_AP_PROCEDURE.
@param[in] ProcessorNumber The handle number of the AP. The range is
from 0 to the total number of logical
@@ -398,13 +398,13 @@ EFI_STATUS
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
@param[in] WaitEvent The event created by the caller with CreateEvent()
service. If it is NULL, then execute in
- blocking mode. BSP waits until all APs finish
+ blocking mode. BSP waits until this AP finish
or TimeoutInMicroSeconds expires. If it's
not NULL, then execute in non-blocking mode.
BSP requests the function specified by
- Procedure to be started on all the enabled
- APs, and go on executing immediately. If
- all return from Procedure or TimeoutInMicroSeconds
+ Procedure to be started on this AP,
+ and go on executing immediately. If this AP
+ return from Procedure or TimeoutInMicroSeconds
expires, this event is signaled. The BSP
can use the CheckEvent() or WaitForEvent()
services to check the state of event. Type
@@ -412,20 +412,20 @@ EFI_STATUS
the Unified Extensible Firmware Interface
Specification.
@param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
- APs to return from Procedure, either for
+ this AP to finish this Procedure, either for
blocking or non-blocking mode. Zero means
infinity. If the timeout expires before
- all APs return from Procedure, then Procedure
- on the failed APs is terminated. All enabled
- APs are available for next function assigned
+ this AP returns from Procedure, then Procedure
+ on the AP is terminated. The
+ AP is available for next function assigned
by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
If the timeout expires in blocking mode,
BSP returns EFI_TIMEOUT. If the timeout
expires in non-blocking mode, WaitEvent
is signaled with SignalEvent().
- @param[in] ProcedureArgument The parameter passed into Procedure for
- all APs.
+ @param[in] ProcedureArgument The parameter passed into Procedure on the
+ specified AP.
@param[out] Finished If NULL, this parameter is ignored. In
blocking mode, this parameter is ignored.
In non-blocking mode, if AP returns from
@@ -523,8 +523,8 @@ EFI_STATUS
from this service, then EFI_UNSUPPORTED must be returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new
- BSP. The range is from 0 to the total number of
+ @param[in] ProcessorNumber The handle number of AP.
+ The range is from 0 to the total number of
logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
@@ -570,8 +570,8 @@ EFI_STATUS
ProcessorNumber, and EFI_SUCCESS is returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new
- BSP. The range is from 0 to the total number of
+ @param[in] ProcessorNumber Pointer to the handle number of AP.
+ The range is from 0 to the total number of
logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 45/46] MdePkg/MpService.h: Trim whitespace at end of line
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (43 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 44/46] MdePkg/MpService.h: Fixed typo in function header to match PI spec Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
2016-07-29 18:15 ` [Patch v4 46/46] UefiCpuPkg/CpuDxe: Fixed typo in function header to match PI spec Jeff Fan
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel
Cc: Liming Gao, Michael Kinney, Feng Tian, Giri P Mudusuru,
Laszlo Ersek
Cc: Liming Gao <liming.gao@intel.com>
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
MdePkg/Include/Protocol/MpService.h | 470 ++++++++++++++++++------------------
1 file changed, 235 insertions(+), 235 deletions(-)
diff --git a/MdePkg/Include/Protocol/MpService.h b/MdePkg/Include/Protocol/MpService.h
index 043a10a..0dbd150 100644
--- a/MdePkg/Include/Protocol/MpService.h
+++ b/MdePkg/Include/Protocol/MpService.h
@@ -1,5 +1,5 @@
/** @file
- When installed, the MP Services Protocol produces a collection of services
+ When installed, the MP Services Protocol produces a collection of services
that are needed for MP management.
The MP Services Protocol provides a generalized way of performing following tasks:
@@ -14,32 +14,32 @@
The Protocol is available only during boot time.
MP Services Protocol is hardware-independent. Most of the logic of this protocol
- is architecturally neutral. It abstracts the multi-processor environment and
- status of processors, and provides interfaces to retrieve information, maintain,
+ is architecturally neutral. It abstracts the multi-processor environment and
+ status of processors, and provides interfaces to retrieve information, maintain,
and dispatch.
- MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
+ MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
protocol to retrieve data that are needed for an MP platform and report them to OS.
- MP Services Protocol may also be used to program and configure processors, such
+ MP Services Protocol may also be used to program and configure processors, such
as MTRR synchronization for memory space attributes setting in DXE Services.
- MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
- by taking advantage of the processing capabilities of the APs, for example, using
+ MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
+ by taking advantage of the processing capabilities of the APs, for example, using
APs to help test system memory in parallel with other device initialization.
Diagnostics applications may also use this protocol for multi-processor.
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 that accompanies this distribution.
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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,
+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.
@par Revision Reference:
- This Protocol is defined in the UEFI Platform Initialization Specification 1.2,
+ This Protocol is defined in the UEFI Platform Initialization Specification 1.2,
Volume 2:Driver Execution Environment Core Interface.
-
+
**/
#ifndef _MP_SERVICE_PROTOCOL_H_
@@ -64,22 +64,22 @@ typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL;
#define END_OF_CPU_LIST 0xffffffff
///
-/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
/// indicates whether the processor is playing the role of BSP. If the bit is 1,
/// then the processor is BSP. Otherwise, it is AP.
///
#define PROCESSOR_AS_BSP_BIT 0x00000001
///
-/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
-/// indicates whether the processor is enabled. If the bit is 1, then the
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// indicates whether the processor is enabled. If the bit is 1, then the
/// processor is enabled. Otherwise, it is disabled.
///
#define PROCESSOR_ENABLED_BIT 0x00000002
///
-/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
-/// indicates whether the processor is healthy. If the bit is 1, then the
+/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
+/// indicates whether the processor is healthy. If the bit is 1, then the
/// processor is healthy. Otherwise, some fault has been detected for the processor.
///
#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
@@ -107,17 +107,17 @@ typedef struct {
///
typedef struct {
///
- /// The unique processor ID determined by system hardware. For IA32 and X64,
- /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits
+ /// The unique processor ID determined by system hardware. For IA32 and X64,
+ /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits
/// are used, and higher bits are reserved. For IPF, the lower 16 bits contains
/// id/eid, and higher bits are reserved.
///
- UINT64 ProcessorId;
+ UINT64 ProcessorId;
+ ///
+ /// Flags indicating if the processor is BSP or AP, if the processor is enabled
+ /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and
+ /// must be 0.
///
- /// Flags indicating if the processor is BSP or AP, if the processor is enabled
- /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and
- /// must be 0.
- ///
/// <pre>
/// BSP ENABLED HEALTH Description
/// === ======= ====== ===================================================
@@ -134,7 +134,7 @@ typedef struct {
UINT32 StatusFlag;
///
/// The physical location of the processor, including the physical package number
- /// that identifies the cartridge, the physical core number within package, and
+ /// that identifies the cartridge, the physical core number within package, and
/// logical thread number within core.
///
EFI_CPU_PHYSICAL_LOCATION Location;
@@ -147,17 +147,17 @@ typedef struct {
This function is used to retrieve the following information:
- The number of logical processors that are present in the system.
- - The number of enabled logical processors in the system at the instant
+ - The number of enabled logical processors in the system at the instant
this call is made.
- Because MP Service Protocol provides services to enable and disable processors
- dynamically, the number of enabled logical processors may vary during the
+ Because MP Service Protocol provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
course of a boot session.
-
- If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
- If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
- EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
- is returned in NumberOfProcessors, the number of currently enabled processor
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
@@ -169,7 +169,7 @@ typedef struct {
processors that exist in system, including
the BSP.
- @retval EFI_SUCCESS The number of logical processors and enabled
+ @retval EFI_SUCCESS The number of logical processors and enabled
logical processors was retrieved.
@retval EFI_DEVICE_ERROR The calling processor is an AP.
@retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
@@ -188,13 +188,13 @@ EFI_STATUS
Gets detailed MP-related information on the requested processor at the
instant this call is made. This service may only be called from the BSP.
- This service retrieves detailed MP-related information about any processor
+ This service retrieves detailed MP-related information about any processor
on the platform. Note the following:
- The processor information may change during the course of a boot session.
- The information presented here is entirely MP related.
-
+
Information regarding the number of caches and their sizes, frequency of operation,
- slot numbers is all considered platform-related information and is not provided
+ slot numbers is all considered platform-related information and is not provided
by this service.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
@@ -219,137 +219,137 @@ EFI_STATUS
);
/**
- This service executes a caller provided function on all enabled APs. APs can
- run either simultaneously or one at a time in sequence. This service supports
- both blocking and non-blocking requests. The non-blocking requests use EFI
- events so the BSP can detect when the APs have finished. This service may only
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
be called from the BSP.
- This function is used to dispatch all the enabled APs to the function specified
- by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
immediately and Procedure is not started on any AP.
- If SingleThread is TRUE, all the enabled APs execute the function specified by
- Procedure one by one, in ascending order of processor handle number. Otherwise,
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
all the enabled APs execute the function specified by Procedure simultaneously.
- If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
- APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking
- mode, and the BSP returns from this service without waiting for APs. If a
- non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking
+ mode, and the BSP returns from this service without waiting for APs. If a
+ non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
is signaled, then EFI_UNSUPPORTED must be returned.
- If the timeout specified by TimeoutInMicroseconds expires before all APs return
- from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ If the timeout specified by TimeoutInMicroseconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
- and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
- content points to the list of processor handle numbers in which Procedure was
+ and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
terminated.
- Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
- to make sure that the nature of the code that is executed on the BSP and the
- dispatched APs is well controlled. The MP Services Protocol does not guarantee
- that the Procedure function is MP-safe. Hence, the tasks that can be run in
- parallel are limited to certain independent tasks and well-controlled exclusive
- code. EFI services and protocols may not be called by APs unless otherwise
+ Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Protocol does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. EFI services and protocols may not be called by APs unless otherwise
specified.
- In blocking execution mode, BSP waits until all APs finish or
+ In blocking execution mode, BSP waits until all APs finish or
TimeoutInMicroSeconds expires.
- In non-blocking execution mode, BSP is freed to return to the caller and then
- proceed to the next task without having to wait for APs. The following
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
sequence needs to occur in a non-blocking execution mode:
- -# The caller that intends to use this MP Services Protocol in non-blocking
- mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
- invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
- is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
- the function specified by Procedure to be started on all the enabled APs,
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
+ invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
+ is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
+ the function specified by Procedure to be started on all the enabled APs,
and releases the BSP to continue with other tasks.
- -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
the state of the WaitEvent created in step 1.
- -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
- Service signals WaitEvent by calling the EFI SignalEvent() function. If
- FailedCpuList is not NULL, its content is available when WaitEvent is
- signaled. If all APs returned from Procedure prior to the timeout, then
- FailedCpuList is set to NULL. If not all APs return from Procedure before
- the timeout, then FailedCpuList is filled in with the list of the failed
- APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
It is the caller's responsibility to free the buffer with FreePool() service.
-# This invocation of SignalEvent() function informs the caller that invoked
EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
- the specified task or a timeout occurred. The contents of FailedCpuList
- can be examined to determine which APs did not complete the specified task
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
prior to the timeout.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
instance.
- @param[in] Procedure A pointer to the function to be run on
+ @param[in] Procedure A pointer to the function to be run on
enabled APs of the system. See type
EFI_AP_PROCEDURE.
- @param[in] SingleThread If TRUE, then all the enabled APs execute
- the function specified by Procedure one by
- one, in ascending order of processor handle
- number. If FALSE, then all the enabled APs
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
execute the function specified by Procedure
simultaneously.
@param[in] WaitEvent The event created by the caller with CreateEvent()
- service. If it is NULL, then execute in
- blocking mode. BSP waits until all APs finish
- or TimeoutInMicroSeconds expires. If it's
- not NULL, then execute in non-blocking mode.
- BSP requests the function specified by
- Procedure to be started on all the enabled
- APs, and go on executing immediately. If
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
all return from Procedure, or TimeoutInMicroSeconds
- expires, this event is signaled. The BSP
- can use the CheckEvent() or WaitForEvent()
- services to check the state of event. Type
- EFI_EVENT is defined in CreateEvent() in
- the Unified Extensible Firmware Interface
- Specification.
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
- APs to return from Procedure, either for
- blocking or non-blocking mode. Zero means
- infinity. If the timeout expires before
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
all APs return from Procedure, then Procedure
- on the failed APs is terminated. All enabled
- APs are available for next function assigned
- by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
- If the timeout expires in blocking mode,
- BSP returns EFI_TIMEOUT. If the timeout
- expires in non-blocking mode, WaitEvent
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
is signaled with SignalEvent().
- @param[in] ProcedureArgument The parameter passed into Procedure for
+ @param[in] ProcedureArgument The parameter passed into Procedure for
all APs.
- @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
- if all APs finish successfully, then its
- content is set to NULL. If not all APs
- finish before timeout expires, then its
- content is set to address of the buffer
- holding handle numbers of the failed APs.
- The buffer is allocated by MP Service Protocol,
- and it's the caller's responsibility to
+ @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
+ if all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+ The buffer is allocated by MP Service Protocol,
+ and it's the caller's responsibility to
free the buffer with FreePool() service.
- In blocking mode, it is ready for consumption
- when the call returns. In non-blocking mode,
- it is ready when WaitEvent is signaled. The
- list of failed CPU is terminated by
+ In blocking mode, it is ready for consumption
+ when the call returns. In non-blocking mode,
+ it is ready when WaitEvent is signaled. The
+ list of failed CPU is terminated by
END_OF_CPU_LIST.
- @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
the timeout expired.
- @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
to all enabled APs.
- @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
- UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
signaled.
@retval EFI_DEVICE_ERROR Caller processor is AP.
@retval EFI_NOT_STARTED No enabled APs exist in the system.
@retval EFI_NOT_READY Any enabled APs are busy.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
all enabled APs have finished.
@retval EFI_INVALID_PARAMETER Procedure is NULL.
@@ -367,23 +367,23 @@ EFI_STATUS
);
/**
- This service lets the caller get one enabled AP to execute a caller-provided
- function. The caller can request the BSP to either wait for the completion
- of the AP or just proceed with the next task by using the EFI event mechanism.
- See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
execution support. This service may only be called from the BSP.
- This function is used to dispatch one enabled AP to the function specified by
- Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
- is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
- TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
- BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
- is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
then EFI_UNSUPPORTED must be returned.
-
- If the timeout specified by TimeoutInMicroseconds expires before the AP returns
- from Procedure, then execution of Procedure by the AP is terminated. The AP is
- available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
@@ -391,62 +391,62 @@ EFI_STATUS
@param[in] Procedure A pointer to the function to be run on the
designated AP of the system. See type
EFI_AP_PROCEDURE.
- @param[in] ProcessorNumber The handle number of the AP. The range is
+ @param[in] ProcessorNumber The handle number of the AP. The range is
from 0 to the total number of logical
- processors minus 1. The total number of
+ processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
@param[in] WaitEvent The event created by the caller with CreateEvent()
- service. If it is NULL, then execute in
- blocking mode. BSP waits until this AP finish
- or TimeoutInMicroSeconds expires. If it's
- not NULL, then execute in non-blocking mode.
- BSP requests the function specified by
- Procedure to be started on this AP,
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until this AP finish
+ or TimeoutInMicroSeconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on this AP,
and go on executing immediately. If this AP
return from Procedure or TimeoutInMicroSeconds
- expires, this event is signaled. The BSP
- can use the CheckEvent() or WaitForEvent()
- services to check the state of event. Type
- EFI_EVENT is defined in CreateEvent() in
- the Unified Extensible Firmware Interface
- Specification.
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
- this AP to finish this Procedure, either for
- blocking or non-blocking mode. Zero means
- infinity. If the timeout expires before
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ this AP to finish this Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
this AP returns from Procedure, then Procedure
- on the AP is terminated. The
- AP is available for next function assigned
- by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ on the AP is terminated. The
+ AP is available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
- If the timeout expires in blocking mode,
- BSP returns EFI_TIMEOUT. If the timeout
- expires in non-blocking mode, WaitEvent
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
is signaled with SignalEvent().
@param[in] ProcedureArgument The parameter passed into Procedure on the
specified AP.
- @param[out] Finished If NULL, this parameter is ignored. In
+ @param[out] Finished If NULL, this parameter is ignored. In
blocking mode, this parameter is ignored.
- In non-blocking mode, if AP returns from
+ In non-blocking mode, if AP returns from
Procedure before the timeout expires, its
- content is set to TRUE. Otherwise, the
+ content is set to TRUE. Otherwise, the
value is set to FALSE. The caller can
- determine if the AP returned from Procedure
+ determine if the AP returned from Procedure
by evaluating this value.
- @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
the timeout expires.
- @retval EFI_SUCCESS In non-blocking mode, the function has been
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
dispatched to specified AP.
- @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
- UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
signaled.
@retval EFI_DEVICE_ERROR The calling processor is an AP.
- @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
the specified AP has finished.
@retval EFI_NOT_READY The specified AP is busy.
- @retval EFI_NOT_FOUND The processor with the handle specified by
+ @retval EFI_NOT_FOUND The processor with the handle specified by
ProcessorNumber does not exist.
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
@retval EFI_INVALID_PARAMETER Procedure is NULL.
@@ -465,36 +465,36 @@ EFI_STATUS
);
/**
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. This call can only be performed
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
by the current BSP.
- This service switches the requested AP to be the BSP from that point onward.
- This service changes the BSP for all purposes. The new BSP can take over the
- execution of the old BSP and continue seamlessly from where the old one left
- off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
is signaled.
- If the BSP cannot be switched prior to the return from this service, then
+ If the BSP cannot be switched prior to the return from this service, then
EFI_UNSUPPORTED must be returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new
- BSP. The range is from 0 to the total number of
- logical processors minus 1. The total number of
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
- @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
enabled AP. Otherwise, it will be disabled.
@retval EFI_SUCCESS BSP successfully switched.
- @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
this service returning.
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
@retval EFI_SUCCESS The calling processor is an AP.
@retval EFI_NOT_FOUND The processor with the handle specified by
ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
a disabled AP.
@retval EFI_NOT_READY The specified AP is busy.
@@ -508,38 +508,38 @@ EFI_STATUS
);
/**
- This service lets the caller enable or disable an AP from this point onward.
+ This service lets the caller enable or disable an AP from this point onward.
This service may only be called from the BSP.
- This service allows the caller enable or disable an AP from this point onward.
- The caller can optionally specify the health status of the AP by Health. If
- an AP is being disabled, then the state of the disabled AP is implementation
- dependent. If an AP is enabled, then the implementation must guarantee that a
- complete initialization sequence is performed on the AP, so the AP is in a state
- that is compatible with an MP operating system. This service may not be supported
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system. This service may not be supported
after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
- If the enable or disable AP operation cannot be completed prior to the return
+ If the enable or disable AP operation cannot be completed prior to the return
from this service, then EFI_UNSUPPORTED must be returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
@param[in] ProcessorNumber The handle number of AP.
- The range is from 0 to the total number of
- logical processors minus 1. The total number of
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
- @param[in] EnableAP Specifies the new state for the processor for
+ @param[in] EnableAP Specifies the new state for the processor for
enabled, FALSE for disabled.
- @param[in] HealthFlag If not NULL, a pointer to a value that specifies
- the new health status of the AP. This flag
- corresponds to StatusFlag defined in
- EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
- the PROCESSOR_HEALTH_STATUS_BIT is used. All other
- bits are ignored. If it is NULL, this parameter
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
is ignored.
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
- @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
prior to this service returning.
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
@retval EFI_DEVICE_ERROR The calling processor is an AP.
@@ -558,25 +558,25 @@ EFI_STATUS
);
/**
- This return the handle number for the calling processor. This service may be
+ This return the handle number for the calling processor. This service may be
called from the BSP and APs.
- This service returns the processor handle number for the calling processor.
- The returned value is in the range from 0 to the total number of logical
- processors minus 1. The total number of logical processors can be retrieved
- with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
- called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
- is returned. Otherwise, the current processors handle number is returned in
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
ProcessorNumber, and EFI_SUCCESS is returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
@param[in] ProcessorNumber Pointer to the handle number of AP.
- The range is from 0 to the total number of
- logical processors minus 1. The total number of
+ The range is from 0 to the total number of
+ logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
- @retval EFI_SUCCESS The current processor handle number was returned
+ @retval EFI_SUCCESS The current processor handle number was returned
in ProcessorNumber.
@retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
@@ -589,34 +589,34 @@ EFI_STATUS
);
///
-/// When installed, the MP Services Protocol produces a collection of services
+/// When installed, the MP Services Protocol produces a collection of services
/// that are needed for MP management.
///
-/// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module
-/// that produces this protocol is required to place all APs into an idle state
-/// whenever the APs are disabled or the APs are not executing code as requested
-/// through the StartupAllAPs() or StartupThisAP() services. The idle state of
-/// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is
+/// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module
+/// that produces this protocol is required to place all APs into an idle state
+/// whenever the APs are disabled or the APs are not executing code as requested
+/// through the StartupAllAPs() or StartupThisAP() services. The idle state of
+/// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is
/// implementation dependent.
///
-/// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs
-/// must be placed in the OS compatible CPU state as defined by the UEFI
-/// Specification. Implementations of this protocol may use the UEFI event
-/// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as
-/// defined by the UEFI Specification. Modules that use this protocol must
-/// guarantee that all non-blocking mode requests on all APs have been completed
-/// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the
-/// order that event notification functions in the same event group are executed
-/// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot
+/// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs
+/// must be placed in the OS compatible CPU state as defined by the UEFI
+/// Specification. Implementations of this protocol may use the UEFI event
+/// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as
+/// defined by the UEFI Specification. Modules that use this protocol must
+/// guarantee that all non-blocking mode requests on all APs have been completed
+/// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the
+/// order that event notification functions in the same event group are executed
+/// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot
/// be used to guarantee that APs have completed their non-blocking mode requests.
///
-/// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs()
-/// and StartupThisAp() services must no longer support non-blocking mode requests.
-/// The support for SwitchBSP() and EnableDisableAP() may no longer be supported
-/// after this event is signaled. Since UEFI Applications and UEFI OS Loaders
-/// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these
+/// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs()
+/// and StartupThisAp() services must no longer support non-blocking mode requests.
+/// The support for SwitchBSP() and EnableDisableAP() may no longer be supported
+/// after this event is signaled. Since UEFI Applications and UEFI OS Loaders
+/// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these
/// UEFI images must be aware that the functionality of this protocol may be reduced.
-///
+///
struct _EFI_MP_SERVICES_PROTOCOL {
EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;
EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [Patch v4 46/46] UefiCpuPkg/CpuDxe: Fixed typo in function header to match PI spec
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
` (44 preceding siblings ...)
2016-07-29 18:15 ` [Patch v4 45/46] MdePkg/MpService.h: Trim whitespace at end of line Jeff Fan
@ 2016-07-29 18:15 ` Jeff Fan
45 siblings, 0 replies; 47+ messages in thread
From: Jeff Fan @ 2016-07-29 18:15 UTC (permalink / raw)
To: edk2-devel
Cc: Liming Gao, Michael Kinney, Feng Tian, Giri P Mudusuru,
Laszlo Ersek
Cc: Liming Gao <liming.gao@intel.com>
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: Giri P Mudusuru <giri.p.mudusuru@intel.com>
---
UefiCpuPkg/CpuDxe/CpuMp.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index efab78c..889edc8 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -299,8 +299,8 @@ StartupAllAPs (
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
instance.
- @param[in] Procedure A pointer to the function to be run on
- enabled APs of the system. See type
+ @param[in] Procedure A pointer to the function to be run on the
+ designated AP of the system. See type
EFI_AP_PROCEDURE.
@param[in] ProcessorNumber The handle number of the AP. The range is
from 0 to the total number of logical
@@ -309,34 +309,34 @@ StartupAllAPs (
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
@param[in] WaitEvent The event created by the caller with CreateEvent()
service. If it is NULL, then execute in
- blocking mode. BSP waits until all APs finish
- or TimeoutInMicroseconds expires. If it's
+ blocking mode. BSP waits until this AP finish
+ or TimeoutInMicroSeconds expires. If it's
not NULL, then execute in non-blocking mode.
BSP requests the function specified by
- Procedure to be started on all the enabled
- APs, and go on executing immediately. If
- all return from Procedure or TimeoutInMicroseconds
+ Procedure to be started on this AP,
+ and go on executing immediately. If this AP
+ return from Procedure or TimeoutInMicroSeconds
expires, this event is signaled. The BSP
can use the CheckEvent() or WaitForEvent()
services to check the state of event. Type
EFI_EVENT is defined in CreateEvent() in
the Unified Extensible Firmware Interface
Specification.
- @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
- APs to return from Procedure, either for
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ this AP to finish this Procedure, either for
blocking or non-blocking mode. Zero means
infinity. If the timeout expires before
- all APs return from Procedure, then Procedure
- on the failed APs is terminated. All enabled
- APs are available for next function assigned
+ this AP returns from Procedure, then Procedure
+ on the AP is terminated. The
+ AP is available for next function assigned
by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
If the timeout expires in blocking mode,
BSP returns EFI_TIMEOUT. If the timeout
expires in non-blocking mode, WaitEvent
is signaled with SignalEvent().
- @param[in] ProcedureArgument The parameter passed into Procedure for
- all APs.
+ @param[in] ProcedureArgument The parameter passed into Procedure on the
+ specified AP.
@param[out] Finished If NULL, this parameter is ignored. In
blocking mode, this parameter is ignored.
In non-blocking mode, if AP returns from
@@ -447,8 +447,8 @@ SwitchBSP (
from this service, then EFI_UNSUPPORTED must be returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new
- BSP. The range is from 0 to the total number of
+ @param[in] ProcessorNumber The handle number of AP.
+ The range is from 0 to the total number of
logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
@@ -497,8 +497,8 @@ EnableDisableAP (
ProcessorNumber, and EFI_SUCCESS is returned.
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
- @param[out] ProcessorNumber The handle number of AP that is to become the new
- BSP. The range is from 0 to the total number of
+ @param[out] ProcessorNumber Pointer to the handle number of AP.
+ The range is from 0 to the total number of
logical processors minus 1. The total number of
logical processors can be retrieved by
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 47+ messages in thread
end of thread, other threads:[~2016-07-29 18:16 UTC | newest]
Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-29 18:14 [Patch v4 00/46] MP Initialize Library Jeff Fan
2016-07-29 18:14 ` [Patch v4 01/46] UefiCpuPkg/LocalApic.h: Remove duplicated/conflicted definitions Jeff Fan
2016-07-29 18:14 ` [Patch v4 02/46] UefiCpuPkg/MpInitLib: Add microcode definitions defined in IA32 SDM Jeff Fan
2016-07-29 18:14 ` [Patch v4 03/46] UefiCpuPkg/CpuS3DataDxe: Move StartupVector allocation to EndOfDxe() Jeff Fan
2016-07-29 18:14 ` [Patch v4 04/46] UefiCpuPkg/MpInitLib: Add MP Initialize library class definition Jeff Fan
2016-07-29 18:14 ` [Patch v4 05/46] UefiCpuPkg/MpInitLib: Add two instances PeiMpInitLib and DxeMpInitLib Jeff Fan
2016-07-29 18:14 ` [Patch v4 06/46] UefiCpuPkg/MpInitLib: Add AP assembly code and MP_CPU_EXCHANGE_INFO Jeff Fan
2016-07-29 18:14 ` [Patch v4 07/46] UefiCpuPkg/MpInitLib: Fix typo and clean up the code Jeff Fan
2016-07-29 18:14 ` [Patch v4 08/46] UefiCpuPkg/MpInitLib: Add EnableExecuteDisable in MP_CPU_EXCHANGE_INFO Jeff Fan
2016-07-29 18:14 ` [Patch v4 09/46] UefiCpuPkg/MpInitLib: Add AsmRelocateApLoop() assembly code Jeff Fan
2016-07-29 18:14 ` [Patch v4 10/46] UefiCpuPkg/MpInitLib: Add MP_ASSEMBLY_ADDRESS_MAP Jeff Fan
2016-07-29 18:14 ` [Patch v4 11/46] UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size Jeff Fan
2016-07-29 18:14 ` [Patch v4 12/46] UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer Jeff Fan
2016-07-29 18:14 ` [Patch v4 13/46] UefiCpuPkg/MpInitLib: Initialize CPU_AP_DATA for CPU APs Jeff Fan
2016-07-29 18:14 ` [Patch v4 14/46] UefiCpuPkg/MpInitLib: Add CPU_VOLATILE_REGISTERS & worker functions Jeff Fan
2016-07-29 18:14 ` [Patch v4 15/46] UefiCpuPkg/MpInitLib: Add MicrocodeDetect() and load microcode on BSP Jeff Fan
2016-07-29 18:14 ` [Patch v4 16/46] UefiCpuPkg/MpInitLib: Save CPU MP Data pointer Jeff Fan
2016-07-29 18:14 ` [Patch v4 17/46] UefiCpuPkg/MpInitLib: Register one End of PEI callback function Jeff Fan
2016-07-29 18:14 ` [Patch v4 18/46] UefiCpuPkg/MpInitLib: Register one period event to check APs status Jeff Fan
2016-07-29 18:14 ` [Patch v4 19/46] UefiCpuPkg/MpInitLib: Allocate AP reset vector buffer under 1MB Jeff Fan
2016-07-29 18:14 ` [Patch v4 20/46] UefiCpuPkg/MpInitLib: Add ApCFunction() executed by assembly code Jeff Fan
2016-07-29 18:14 ` [Patch v4 21/46] UefiCpuPkg/MpInitLib: Fill MP_CPU_EXCHANGE_INFO fields Jeff Fan
2016-07-29 18:14 ` [Patch v4 22/46] UefiCpuPkg/MpInitLib: Add WakeUpAP() Jeff Fan
2016-07-29 18:14 ` [Patch v4 23/46] UefiCpuPkg/MpInitLib: Send INIT-SIPI-SIPI to get processor count Jeff Fan
2016-07-29 18:14 ` [Patch v4 24/46] UefiCpuPkg/MpInitLib: Enable x2APIC mode on BSP/APs Jeff Fan
2016-07-29 18:14 ` [Patch v4 25/46] UefiCpuPkg/MpInitLib: Sort processor by ascending order of APIC ID Jeff Fan
2016-07-29 18:14 ` [Patch v4 26/46] UefiCpuPkg/MpInitLib: Skip collect processor count if GUIDed HOB exist Jeff Fan
2016-07-29 18:14 ` [Patch v4 27/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetNumberOfProcessors() Jeff Fan
2016-07-29 18:14 ` [Patch v4 28/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibGetProcessorInfo() Jeff Fan
2016-07-29 18:14 ` [Patch v4 29/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibWhoAmI() Jeff Fan
2016-07-29 18:14 ` [Patch v4 30/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibSwitchBSP() Jeff Fan
2016-07-29 18:14 ` [Patch v4 31/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibEnableDisableAP() Jeff Fan
2016-07-29 18:14 ` [Patch v4 32/46] UefiCpuPkg/MpInitLib: Check APs Status and update APs status Jeff Fan
2016-07-29 18:14 ` [Patch v4 33/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupThisAP() Jeff Fan
2016-07-29 18:15 ` [Patch v4 34/46] UefiCpuPkg/MpInitLib: Implementation of MpInitLibStartupAllAPs() Jeff Fan
2016-07-29 18:15 ` [Patch v4 35/46] UefiCpuPkg/MpInitLib: Place APs in safe loop before hand-off to OS Jeff Fan
2016-07-29 18:15 ` [Patch v4 36/46] OvmfPkg: Add MpInitLib reference in DSC files Jeff Fan
2016-07-29 18:15 ` [Patch v4 37/46] QuarkPlatformPkg: " Jeff Fan
2016-07-29 18:15 ` [Patch v4 38/46] UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services Jeff Fan
2016-07-29 18:15 ` [Patch v4 39/46] UefiCpuPkg/CpuMpPei: Remove unused files and codes Jeff Fan
2016-07-29 18:15 ` [Patch v4 40/46] UefiCpuPkg/CpuMpPei: Delete PeiMpServices.c and PeiMpServices.h Jeff Fan
2016-07-29 18:15 ` [Patch v4 41/46] UefiCpuPkg/CpuDxe: Consume MpInitLib to produce CPU MP Protocol services Jeff Fan
2016-07-29 18:15 ` [Patch v4 42/46] UefiCpuPkg/CpuDxe: Move SetMtrrsFromBuffer() location Jeff Fan
2016-07-29 18:15 ` [Patch v4 43/46] UefiCpuPkg/CpuDxe: Remove unused codes and files Jeff Fan
2016-07-29 18:15 ` [Patch v4 44/46] MdePkg/MpService.h: Fixed typo in function header to match PI spec Jeff Fan
2016-07-29 18:15 ` [Patch v4 45/46] MdePkg/MpService.h: Trim whitespace at end of line Jeff Fan
2016-07-29 18:15 ` [Patch v4 46/46] UefiCpuPkg/CpuDxe: Fixed typo in function header to match PI spec Jeff Fan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox