public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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 +-
 UefiCpuPkg/CpuDxe/CpuDxeExtra.uni |   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."
 
diff --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