Re: [edk2] question about setuping IDT in UEFI boot procedure

2014-10-27 Thread Fan, Jeff
For the case 32bit PEI + 64Bit DXE, we need to load 64bit IDT table to capture 
exceptions happened in long mode because 32bit IDT table cannot work in long 
mode.
For the case 32bit PEI + 32bit DXE, we could use the 32bit IDT table setup in 
SEC/PEI and needn't to load new 32bit IDT table.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:56 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your quick reply!
Another question:
1. MdeModulePkg\Core\DxeIplPeim\Ia32\DxeLoadFunc.c will reconstruct IDT before 
handing off to DXE.
   if (FeaturePcdGet(PcdDxeIplSwitchToLongMode))
  {
   Why it need to reconstruct IDT when trying to switch to Long-mode?
  }
  Else
  {
  Why does it not need to reconstruct IDT in this case?
  }

Best wishes,

- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月27日 14:33
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Exaclty.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:17 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your reply!
S3ResumeExecuteBootScript() (in 
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c) will call AsmReadIdtr 
(&PeiS3ResumeState->Idtr) to save IDT.
And S3ResumeBootOs()(in UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c)  
will call AsmWriteIdtr (&PeiS3ResumeState->Idtr) to restore IDT.

Why need to save and restore IDT in S3Resume PEIM?
Because of BootScriptExecutorDxe driver will call SetIdtEntry() to change IDT?

Best wishes,
- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月24日 16:48
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

On S3 path, S3NvsPageTableAddress () (in UefiCpuPkg/Universal/Acpi/S3Resume.c) 
will re-create Page Table since we cannot trust the original Page Table saved 
in ACPINvs memory more.
Moreover, we only create page table for < 4G address is due to performance 
concern.

When programming boot script entries, we may access  > 4 G MMIO or memory 
address.  Thus, One Page Fault exception handler is required to build Page 
entry in case > 4G address accessed.

Jeff
-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Thursday, October 23, 2014 5:55 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
MdeModulePkg\Universal\Acpi\BootScriptExecutorDxe\X64\SetIdtEntry.c will hook 
page fault handler.
So, is there any story about adding this hook function?
I want to understand why adding this code.

Thanks a lot!

Best wishes,

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] question about setuping IDT in UEFI boot procedure

2014-10-27 Thread TigerLiu
Hi, Jeff:
Got it!
Thanks a lot!
For creating IDT in SEC/PEI phase, is it just for source level debug purpose?
Usually, PEI should turn off interrupt, right?

Best wishes,

- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月27日 15:04
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

For the case 32bit PEI + 64Bit DXE, we need to load 64bit IDT table to capture 
exceptions happened in long mode because 32bit IDT table cannot work in long 
mode.
For the case 32bit PEI + 32bit DXE, we could use the 32bit IDT table setup in 
SEC/PEI and needn't to load new 32bit IDT table.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:56 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your quick reply!
Another question:
1. MdeModulePkg\Core\DxeIplPeim\Ia32\DxeLoadFunc.c will reconstruct IDT before 
handing off to DXE.
   if (FeaturePcdGet(PcdDxeIplSwitchToLongMode))
  {
   Why it need to reconstruct IDT when trying to switch to Long-mode?
  }
  Else
  {
  Why does it not need to reconstruct IDT in this case?
  }

Best wishes,

- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月27日 14:33
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Exaclty.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:17 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your reply!
S3ResumeExecuteBootScript() (in 
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c) will call AsmReadIdtr 
(&PeiS3ResumeState->Idtr) to save IDT.
And S3ResumeBootOs()(in UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c)  
will call AsmWriteIdtr (&PeiS3ResumeState->Idtr) to restore IDT.

Why need to save and restore IDT in S3Resume PEIM?
Because of BootScriptExecutorDxe driver will call SetIdtEntry() to change IDT?

Best wishes,
- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月24日 16:48
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

On S3 path, S3NvsPageTableAddress () (in UefiCpuPkg/Universal/Acpi/S3Resume.c) 
will re-create Page Table since we cannot trust the original Page Table saved 
in ACPINvs memory more.
Moreover, we only create page table for < 4G address is due to performance 
concern.

When programming boot script entries, we may access  > 4 G MMIO or memory 
address.  Thus, One Page Fault exception handler is required to build Page 
entry in case > 4G address accessed.

Jeff
-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Thursday, October 23, 2014 5:55 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
MdeModulePkg\Universal\Acpi\BootScriptExecutorDxe\X64\SetIdtEntry.c will hook 
page fault handler.
So, is there any story about adding this hook function?
I want to understand why adding this code.

Thanks a lot!

Best wishes,

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourc

Re: [edk2] question about setuping IDT in UEFI boot procedure

2014-10-27 Thread Fan, Jeff
No.  It’s SEC's responsibility to setup IDT table to capture CPU exceptions in 
SEC/PEI phases. Please refer to AsmWriteIdtr() in OvmfPkg\Sec\SecMain.c.

Debug Agent Lib in Source Level Debug Package is just to overwrite original IDT 
entries to provide source debugging feature.

Jeff
-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 3:32 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Got it!
Thanks a lot!
For creating IDT in SEC/PEI phase, is it just for source level debug purpose?
Usually, PEI should turn off interrupt, right?

Best wishes,

- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月27日 15:04
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

For the case 32bit PEI + 64Bit DXE, we need to load 64bit IDT table to capture 
exceptions happened in long mode because 32bit IDT table cannot work in long 
mode.
For the case 32bit PEI + 32bit DXE, we could use the 32bit IDT table setup in 
SEC/PEI and needn't to load new 32bit IDT table.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:56 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your quick reply!
Another question:
1. MdeModulePkg\Core\DxeIplPeim\Ia32\DxeLoadFunc.c will reconstruct IDT before 
handing off to DXE.
   if (FeaturePcdGet(PcdDxeIplSwitchToLongMode))
  {
   Why it need to reconstruct IDT when trying to switch to Long-mode?
  }
  Else
  {
  Why does it not need to reconstruct IDT in this case?
  }

Best wishes,

- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月27日 14:33
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Exaclty.

-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Monday, October 27, 2014 2:17 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
Thanks for your reply!
S3ResumeExecuteBootScript() (in 
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c) will call AsmReadIdtr 
(&PeiS3ResumeState->Idtr) to save IDT.
And S3ResumeBootOs()(in UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c)  
will call AsmWriteIdtr (&PeiS3ResumeState->Idtr) to restore IDT.

Why need to save and restore IDT in S3Resume PEIM?
Because of BootScriptExecutorDxe driver will call SetIdtEntry() to change IDT?

Best wishes,
- Original Message -
From: Fan, Jeff [mailto:jeff@intel.com] 
Sent: 2014年10月24日 16:48
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

On S3 path, S3NvsPageTableAddress () (in UefiCpuPkg/Universal/Acpi/S3Resume.c) 
will re-create Page Table since we cannot trust the original Page Table saved 
in ACPINvs memory more.
Moreover, we only create page table for < 4G address is due to performance 
concern.

When programming boot script entries, we may access  > 4 G MMIO or memory 
address.  Thus, One Page Fault exception handler is required to build Page 
entry in case > 4G address accessed.

Jeff
-Original Message-
From: tiger...@via-alliance.com [mailto:tiger...@via-alliance.com] 
Sent: Thursday, October 23, 2014 5:55 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] question about setuping IDT in UEFI boot procedure

Hi, Jeff:
MdeModulePkg\Universal\Acpi\BootScriptExecutorDxe\X64\SetIdtEntry.c will hook 
page fault handler.
So, is there any story about adding this hook function?
I want to understand why adding this code.

Thanks a lot!

Best wishes,

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___

[edk2] [RFC PATCH v6 10/27] UefiCpuPkg/CpuDxe: implement Mp Protocol: WhoAmI()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 51 ++-
 UefiCpuPkg/CpuDxe/CpuMp.h | 31 
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 20433b9..ae1488d 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -31,10 +31,59 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   NULL, // StartupThisAP,
   NULL, // SwitchBSP,
   NULL, // EnableDisableAP,
-  NULL  // WhoAmI
+  WhoAmI
 };
 
 /**
+  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
+  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
+   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
+  in ProcessorNumber.
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+WhoAmI (
+  IN EFI_MP_SERVICES_PROTOCOL  *This,
+  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;
+}
+
+/**
   Application Processors do loop routine
   after switch to its own stack.
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index b8771f7..63e288e 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -123,5 +123,36 @@ FillInProcessorInformation (
   IN UINTNProcessorNumber
   );
 
+/**
+  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
+  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
+   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
+  in ProcessorNumber.
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+WhoAmI (
+  IN EFI_MP_SERVICES_PROTOCOL  *This,
+  OUT UINTN*ProcessorNumber
+  );
+
 #endif // _CPU_MP_H_
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 23/27] UefiCpuPkg/MpService: avoid reset AP still hold a lock

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 9 +
 UefiCpuPkg/CpuDxe/CpuMp.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index b718465..6fcafc2 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -52,6 +52,7 @@ GetMpSpinLock (
   while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
 CpuPause ();
   }
+  CpuData->LockSelf = GetApicId ();
 }
 
 /**
@@ -1137,6 +1138,13 @@ ProcessorToIdleState (
   AsmApDoneWithCommonStack ();
 
   //
+  // Avoid forcibly reset AP caused the AP got lock not release.
+  //
+  if (CpuData->LockSelf == GetApicId ()) {
+ReleaseSpinLock (&CpuData->CpuDataLock);
+  }
+
+  //
   // Avoid forcibly reset AP caused the AP State is not updated.
   //
   GetMpSpinLock (CpuData);
@@ -1385,6 +1393,7 @@ FillInProcessorInformation (
   CpuData->Procedure= NULL;
   CpuData->Parameter= NULL;
   InitializeSpinLock (&CpuData->CpuDataLock);
+  CpuData->LockSelf = -1;
 
   return EFI_SUCCESS;
 }
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index d812561..10c67b8 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -89,6 +89,7 @@ typedef enum {
 typedef struct {
   EFI_PROCESSOR_INFORMATION  Info;
   SPIN_LOCK  CpuDataLock;
+  INTN   LockSelf;
   volatile CPU_STATE State;
 
   EFI_AP_PROCEDURE   Procedure;
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 11/27] UefiCpuPkg/CpuDxe: implement Mp Protocol:GetNumberOfProcessors()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 82 ++-
 UefiCpuPkg/CpuDxe/CpuMp.h | 44 +
 2 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index ae1488d..4c104ec 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -25,7 +25,7 @@ VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;
 
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
-  NULL, // GetNumberOfProcessors,
+  GetNumberOfProcessors,
   NULL, // GetProcessorInfo,
   NULL, // StartupAllAPs,
   NULL, // StartupThisAP,
@@ -35,6 +35,86 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
 };
 
 /**
+  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;
+}
+
+/**
+  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 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
+  is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+  @param[in]  ThisA pointer to the 
EFI_MP_SERVICES_PROTOCOL
+  instance.
+  @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_ERRORThe calling processor is an AP.
+  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
+  @retval EFI_INVALID_PARAMETER   NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetNumberOfProcessors (
+  IN  EFI_MP_SERVICES_PROTOCOL  *This,
+  OUT UINTN *NumberOfProcessors,
+  OUT UINTN *NumberOfEnabledProcessors
+  )
+{
+  if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+return EFI_INVALID_PARAMETER;
+  }
+
+  if (!IsBSP ()) {
+return EFI_DEVICE_ERROR;
+  }
+
+  *NumberOfProcessors= mMpSystemData.NumberOfProcessors;
+  *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors;
+  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/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 63e288e..99cec31 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -124,6 +124,50 @@ FillInProcessorInformation (
   );
 
 /**
+  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 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 en

[edk2] [RFC PATCH v6 13/27] UefiCpuPkg/CpuDxe: implement Mp Protocol:EnableDisableAP()

2014-10-27 Thread Chen Fan
Due to the implementation of  AcquireSpinLock() is not MP safe,
so we should use AcquireSpinLockOrFail directly instead.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 186 +-
 UefiCpuPkg/CpuDxe/CpuMp.h |  50 +
 2 files changed, 235 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index db863f3..c25157a 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -30,7 +30,7 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   NULL, // StartupAllAPs,
   NULL, // StartupThisAP,
   NULL, // SwitchBSP,
-  NULL, // EnableDisableAP,
+  EnableDisableAP,
   WhoAmI
 };
 
@@ -58,6 +58,101 @@ IsBSP (
 }
 
 /**
+  Get the Application Processors state.
+
+  @param   CpuDatathe pointer to CPU_DATA_BLOCK of specified AP
+
+  @retval  CPU_STATE  the AP status
+
+**/
+CPU_STATE
+GetApState (
+  IN  CPU_DATA_BLOCK  *CpuData
+  )
+{
+  CPU_STATE State;
+
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  State = CpuData->State;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+
+  return State;
+}
+
+/**
+  Check the Application Processors Status whether contains the Flags.
+
+  @param CpuData  the pointer to CPU_DATA_BLOCK of specified AP
+  @param Flagsthe StatusFlag describing in EFI_PROCESSOR_INFORMATION 
+
+  @retvalTRUE the AP status includes the StatusFlag
+  @retvalFALSEthe AP status excludes the StatusFlag
+
+**/
+BOOLEAN
+TestCpuStatusFlag (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32  Flags
+  )
+{
+  UINT32 Ret;
+
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  Ret = CpuData->Info.StatusFlag & Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+
+  return !!(Ret);
+}
+
+/**
+  Bitwise-Or of the Application Processors Status with the Flags.
+
+  @param CpuData  the pointer to CPU_DATA_BLOCK of specified AP
+  @param Flagsthe StatusFlag describing in EFI_PROCESSOR_INFORMATION
+
+**/
+VOID
+CpuStatusFlagOr (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32  Flags
+  )
+{
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  CpuData->Info.StatusFlag |= Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+/**
+  Bitwise-AndNot of the Application Processors Status with the Flags.
+
+  @param CpuData  the pointer to CPU_DATA_BLOCK of specified AP
+  @param Flagsthe StatusFlag describing in EFI_PROCESSOR_INFORMATION
+
+**/
+VOID
+CpuStatusFlagAndNot (
+  IN  CPU_DATA_BLOCK  *CpuData,
+  IN  UINT32  Flags
+  )
+{
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  CpuData->Info.StatusFlag &= ~Flags;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+/**
   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.
@@ -165,6 +260,95 @@ GetProcessorInfo (
 }
 
 /**
+  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
+  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
+  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
+   logical processors can be retrieved by
+   
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+  @param[in] EnableAP  Specifies the new state for the processor for
+   enabled, FALSE for disabled.
+  @param[in] HealthFlagIf 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
+ 

[edk2] [RFC PATCH v6 18/27] UefiCpuPkg/MpService: move settimer out to InitMpSystemData

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 128 --
 1 file changed, 78 insertions(+), 50 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 8482cdf..e97fb5c 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -25,6 +25,8 @@ VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;
 
+volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;
+
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetNumberOfProcessors,
   GetProcessorInfo,
@@ -637,6 +639,11 @@ StartupAllAPs (
 }
   }
 
+  //
+  // temporarily stop checkAllAPsStatus for initialize parameters.
+  //
+  mStopCheckAllAPsStatus = TRUE;
+
   mMpSystemData.Procedure = Procedure;
   mMpSystemData.ProcedureArgument = ProcedureArgument;
   mMpSystemData.WaitEvent = WaitEvent;
@@ -686,13 +693,13 @@ StartupAllAPs (
 }
   }
 
+  mStopCheckAllAPsStatus = FALSE;
+
   if (WaitEvent != NULL) {
-Status = gBS->SetTimer (
-mMpSystemData.CheckAllAPsEvent,
-TimerPeriodic,
-EFI_TIMER_PERIOD_MICROSECONDS (100)
-);
-return Status;
+//
+// non blocking
+//
+return EFI_SUCCESS;
   }
 
   while (TRUE) {
@@ -819,7 +826,6 @@ StartupThisAP (
   )
 {
   CPU_DATA_BLOCK*CpuData;
-  EFI_STATUSStatus;
 
   CpuData = NULL;
 
@@ -848,6 +854,11 @@ StartupThisAP (
 return EFI_NOT_READY;
   }
 
+  //
+  // temporarily stop checkAllAPsStatus for initialize parameters.
+  //
+  mStopCheckAllAPsStatus = TRUE;
+
   SetApState (CpuData, CpuStateReady);
 
   SetApProcedure (CpuData, Procedure, ProcedureArgument);
@@ -857,16 +868,13 @@ StartupThisAP (
   CpuData->TimeoutActive = !!(TimeoutInMicroseconds);
   CpuData->Finished = Finished;
 
+  mStopCheckAllAPsStatus = FALSE;
+
   if (WaitEvent != NULL) {
 //
 // Non Blocking
 //
-Status = gBS->SetTimer (
-CpuData->CheckThisAPEvent,
-TimerPeriodic,
-EFI_TIMER_PERIOD_MICROSECONDS (100)
-);
-return Status;
+return EFI_SUCCESS;
   }
 
   //
@@ -1190,11 +1198,9 @@ CheckThisAPStatus (
   return;
 
 out:
-  gBS->SetTimer (CpuData->CheckThisAPEvent, TimerCancel, 0);
-  if (CpuData->WaitEvent) {
-gBS->SignalEvent (CpuData->WaitEvent);
-CpuData->WaitEvent = NULL;
-  }
+  CpuData->TimeoutActive = FALSE;
+  gBS->SignalEvent (CpuData->WaitEvent);
+  CpuData->WaitEvent = NULL;
 }
 
 /**
@@ -1214,36 +1220,62 @@ CheckAllAPsStatus (
   IN  VOID *Context
   )
 {
+  CPU_DATA_BLOCK *CpuData;
+  UINTN  Number;
+
   if (mMpSystemData.TimeoutActive) {
 mMpSystemData.Timeout -= gPollInterval;
   }
 
-  CheckAndUpdateAllAPsToIdleState ();
+  if (mStopCheckAllAPsStatus) {
+return;
+  }
 
-  //
-  // task timeout
-  //
-  if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
-ResetAllFailedAPs();
+  if (mMpSystemData.WaitEvent != NULL) {
+CheckAndUpdateAllAPsToIdleState ();
 //
-// force exit
+// task timeout
 //
-mMpSystemData.FinishCount = mMpSystemData.StartCount;
-  }
-
-  if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
-return;
-  }
+if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) {
+  ResetAllFailedAPs();
+  //
+  // force exit
+  //
+  mMpSystemData.FinishCount = mMpSystemData.StartCount;
+}
 
-  gBS->SetTimer (
- mMpSystemData.CheckAllAPsEvent,
- TimerCancel,
- 0
- );
+if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
+  return;
+}
 
-  if (mMpSystemData.WaitEvent) {
+mMpSystemData.TimeoutActive = FALSE;
 gBS->SignalEvent (mMpSystemData.WaitEvent);
 mMpSystemData.WaitEvent = NULL;
+mStopCheckAllAPsStatus = TRUE;
+  }
+
+  //
+  // check each AP status for StartupThisAP
+  //
+  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;
+}
+
+if (CpuData->WaitEvent) {
+  CheckThisAPStatus (NULL, (VOID *)CpuData);
+}
   }
 }
 
@@ -1318,8 +1350,6 @@ InitMpSystemData (
   VOID
   )
 {
-  UINTN  ProcessorNumber;
-  CPU_DATA_BLOCK *CpuData;
   EFI_STATUS Status;
 
   ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));
@@ -1339,17 +1369,15 @@ InitMpSystemData (
   );
   ASSERT_EFI_ERROR (Status);
 
-  for (ProcessorNumber = 0; ProcessorNumber < gMaxLogicalProcessorNumber; 
ProcessorNumber++) {
-CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
-Status = gBS->Cr

[edk2] [RFC PATCH v6 02/27] UefiCpuPkg/CpuDxe: Add ApEntryPointInC

2014-10-27 Thread Chen Fan
From: Jordan Justen 

This is the function the AP assembly code will expect to call after
getting a lock and setting up the stack.

Only one AP will enter this routine at a time.

If ApEntryPointInC exits, then the assembly code will loop around to
grab the lock, setup the stack, and call ApEntryPointInC again.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index c8189bc..aa564c1 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -16,6 +16,19 @@
 #include "CpuMp.h"
 
 /**
+  Application Processor C code entry point.
+
+**/
+VOID
+EFIAPI
+ApEntryPointInC (
+  VOID
+  )
+{
+}
+
+
+/**
   Initialize Multi-processor support.
 
 **/
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 09/27] UefiCpuPkg/CpuDxe: introduce MP_SYSTEM_DATA for Mp Service Protocol

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf |  1 +
 UefiCpuPkg/CpuDxe/CpuMp.c| 89 +++-
 UefiCpuPkg/CpuDxe/CpuMp.h| 47 +++
 UefiCpuPkg/UefiCpuPkg.dsc|  1 +
 4 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 4f8ccac..6761e91 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -42,6 +42,7 @@
   UefiLib
   CpuExceptionHandlerLib
   TimerLib
+  SynchronizationLib
 
 [Sources]
   ApStartup.c
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 61c3a23..20433b9 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -18,12 +18,12 @@
 UINTN gMaxLogicalProcessorNumber;
 UINTN gApStackSize;
 
+MP_SYSTEM_DATA mMpSystemData;
+
 VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;
 
-volatile UINTN mNumberOfProcessors;
-
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   NULL, // GetNumberOfProcessors,
   NULL, // GetProcessorInfo,
@@ -63,14 +63,81 @@ ApEntryPointInC (
   VOID
   )
 {
-  mNumberOfProcessors++;
-  mApStackStart = mApStackStart + gApStackSize;
+  VOID* TopOfApStack;
+
+  FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
+  TopOfApStack  = mApStackStart + gApStackSize;
+  mApStackStart = TopOfApStack;
+
+  mMpSystemData.NumberOfProcessors++;
 
   SwitchStack (
 (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
 NULL,
 NULL,
-mApStackStart);
+TopOfApStack);
+}
+
+/**
+  This function is called by all processors (both BSP and AP) once and 
collects MP related data
+
+  @param MPSystemDataPointer to the data structure containing MP related 
data
+  @param BSP TRUE if the CPU is BSP
+
+  @retval EFI_SUCCESSData for the processor collected and filled in
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+  IN BOOLEAN  BSP,
+  IN UINTNProcessorNumber
+  )
+{
+  CPU_DATA_BLOCK  *CpuData;
+
+  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
+  CpuData->Info.ProcessorId  = GetApicId ();
+  CpuData->Info.StatusFlag   = PROCESSOR_ENABLED_BIT | 
PROCESSOR_HEALTH_STATUS_BIT;
+  if (BSP) {
+CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
+  }
+  CpuData->Info.Location.Package = (UINT32) ProcessorNumber;
+  CpuData->Info.Location.Core= 0;
+  CpuData->Info.Location.Thread  = 0;
+  CpuData->State = BSP ? CpuStateBuzy : CpuStateIdle;
+
+  CpuData->Procedure= NULL;
+  CpuData->Parameter= NULL;
+  InitializeSpinLock (&CpuData->CpuDataLock);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Prepare the System Data.
+
+  @retval EFI_SUCCESS the System Data finished initilization.
+
+**/
+EFI_STATUS
+InitMpSystemData (
+  VOID
+  )
+{
+  ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA));
+
+  mMpSystemData.NumberOfProcessors = 1;
+  mMpSystemData.NumberOfEnabledProcessors = 1;
+
+  mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * 
gMaxLogicalProcessorNumber);
+  ASSERT(mMpSystemData.CpuDatas != NULL);
+
+  //
+  // BSP
+  //
+  FillInProcessorInformation (TRUE, 0);
+
+  return EFI_SUCCESS;
 }
 
 
@@ -106,15 +173,17 @@ InitializeMpSupport (
   mTopOfApCommonStack = mApStackStart + gApStackSize;
   mApStackStart = mTopOfApCommonStack;
 
-  mNumberOfProcessors = 1;
+  InitMpSystemData ();
 
-  if (mNumberOfProcessors == 1) {
+  if (mMpSystemData.NumberOfProcessors == 1) {
 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * 
gApStackSize));
 return;
   }
 
-  if (mNumberOfProcessors < gMaxLogicalProcessorNumber) {
-FreePages (mApStackStart, EFI_SIZE_TO_PAGES ((gMaxLogicalProcessorNumber - 
mNumberOfProcessors) *
- gApStackSize));
+
+  if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
+FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
+(gMaxLogicalProcessorNumber - 
mMpSystemData.NumberOfProcessors) *
+gApStackSize));
   }
 }
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index efdd948..b8771f7 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -16,6 +16,7 @@
 #define _CPU_MP_H_
 
 #include 
+#include 
 
 /**
   Initialize Multi-processor support.
@@ -76,5 +77,51 @@ AsmApDoneWithCommonStack (
   VOID
   );
 
+typedef enum {
+  CpuStateIdle,
+  CpuStateBlocked,
+  CpuStateReady,
+  CpuStateBuzy,
+  CpuStateFinished
+} CPU_STATE;
+
+/**
+  Define Individual Processor Data block.
+
+**/
+typedef struct {
+  EFI_PROCESSOR_INFORMATION  Info;
+  SPIN_LOCK  CpuDataLock;
+  volatile CPU_STATE State;
+
+  EFI_AP_PROCEDURE   Procedure;
+  VOID   *Parameter;
+} CPU_DATA_BLOCK;
+
+/**
+  Define MP data block which 

[edk2] [RFC PATCH v6 24/27] UefiCpuPkg/MpService: avoid dead lock caused by CheckAllAPsStatus

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 40 
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 6fcafc2..7f6312c 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -632,6 +632,11 @@ StartupAllAPs (
 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)) {
@@ -653,11 +658,6 @@ StartupAllAPs (
 }
   }
 
-  //
-  // temporarily stop checkAllAPsStatus for initialize parameters.
-  //
-  mStopCheckAllAPsStatus = TRUE;
-
   mMpSystemData.Procedure = Procedure;
   mMpSystemData.ProcedureArgument = ProcedureArgument;
   mMpSystemData.WaitEvent = WaitEvent;
@@ -716,6 +716,11 @@ StartupAllAPs (
 return EFI_SUCCESS;
   }
 
+  //
+  // Blocking temporarily stop CheckAllAPsStatus()
+  //
+  mStopCheckAllAPsStatus = TRUE;
+
   while (TRUE) {
 CheckAndUpdateAllAPsToIdleState ();
 if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {
@@ -859,6 +864,12 @@ StartupThisAP (
 return EFI_NOT_FOUND;
   }
 
+  //
+  // temporarily stop checkAllAPsStatus for avoiding resource dead-lock.
+  //
+  mStopCheckAllAPsStatus = TRUE;
+
+
   CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
   if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {
 return EFI_INVALID_PARAMETER;
@@ -868,11 +879,6 @@ StartupThisAP (
 return EFI_NOT_READY;
   }
 
-  //
-  // temporarily stop checkAllAPsStatus for initialize parameters.
-  //
-  mStopCheckAllAPsStatus = TRUE;
-
   SetApState (CpuData, CpuStateReady);
 
   SetApProcedure (CpuData, Procedure, ProcedureArgument);
@@ -1295,20 +1301,6 @@ CheckAllAPsStatus (
   //
   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;
-}
-
 if (CpuData->WaitEvent) {
   CheckThisAPStatus (NULL, (VOID *)CpuData);
 }
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 26/27] UefiCpuPkg/CpuDxe: install Mp Service protocol

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 3668f05..f950832 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -20,6 +20,7 @@ UINTN gApStackSize;
 UINTN gPollInterval = 100; // 100 microseconds
 
 MP_SYSTEM_DATA mMpSystemData;
+EFI_HANDLE mMpServiceHandle = NULL;
 
 VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
@@ -1448,6 +1449,8 @@ InitializeMpSupport (
   VOID
   )
 {
+  EFI_STATUS Status;
+
   gMaxLogicalProcessorNumber = (UINTN) PcdGet32 
(PcdCpuMaxLogicalProcessorNumber);
   if (gMaxLogicalProcessorNumber < 1) {
 DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be 
more than zero.\n"));
@@ -1486,6 +1489,13 @@ InitializeMpSupport (
 
   mAPsAlreadyInitFinished = TRUE;
 
+  Status = gBS->InstallMultipleProtocolInterfaces (
+  &mMpServiceHandle,
+  &gEfiMpServiceProtocolGuid,  &mMpServicesTemplate,
+  NULL
+  );
+  ASSERT_EFI_ERROR (Status);
+
   if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
 FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
 (gMaxLogicalProcessorNumber - 
mMpSystemData.NumberOfProcessors) *
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 25/27] UefiCpuPkg/CpuDxe: Startup APs

2014-10-27 Thread Chen Fan
This sequence should happen:
* CpuMp.c: Allocate a stack for the APs
* ApStartup.c: Send Start IPI to wake APs in 16-bit real mode
* MpAsm.S: AP enters CpuDxe driver code without stack
  - AP grabs a lock
  - AP sets up stack
  - AP calls CpuMp.c:ApEntryPointInC

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 7f6312c..3668f05 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1475,6 +1475,9 @@ InitializeMpSupport (
 
   PrepareAPStartupCode ();
 
+  StartApsStackless ();
+
+  DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", 
mMpSystemData.NumberOfProcessors));
   if (mMpSystemData.NumberOfProcessors == 1) {
 FreeApStartupCode ();
 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * 
gApStackSize));
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 08/27] UefiCpuPkg/CpuDxe: introduce EFI_MP_SERVICES_PROTOCOL

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf |  1 +
 UefiCpuPkg/CpuDxe/CpuMp.c| 10 ++
 UefiCpuPkg/CpuDxe/CpuMp.h|  2 ++
 3 files changed, 13 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 1837560..4f8ccac 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -70,6 +70,7 @@
 
 [Protocols]
   gEfiCpuArchProtocolGuid   ## PRODUCES
+  gEfiMpServiceProtocolGuid ## PRODUCES
 
 [Guids]
   gIdleLoopEventGuid## CONSUMES   ## Event
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 956acf4..61c3a23 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -24,6 +24,16 @@ VOID *mApStackStart = 0;
 
 volatile UINTN mNumberOfProcessors;
 
+EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
+  NULL, // GetNumberOfProcessors,
+  NULL, // GetProcessorInfo,
+  NULL, // StartupAllAPs,
+  NULL, // StartupThisAP,
+  NULL, // SwitchBSP,
+  NULL, // EnableDisableAP,
+  NULL  // WhoAmI
+};
+
 /**
   Application Processors do loop routine
   after switch to its own stack.
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 6f5e615..efdd948 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -15,6 +15,8 @@
 #ifndef _CPU_MP_H_
 #define _CPU_MP_H_
 
+#include 
+
 /**
   Initialize Multi-processor support.
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 03/27] UefiCpuPkg/CpuDxe: Add stackless assembly AP entry points

2014-10-27 Thread Chen Fan
From: Jordan Justen 

The AP startup code simply jumps into this code with the CpuDxe driver
without setting up a stack for the processor.

Therefore, this code must setup the stack before calling into C code.

This is the basic flow:
* AP enters CpuDxe driver code (AsmApEntryPoint) without stack
  - AP grabs a lock
  - AP sets up stack
  - AP calls CpuMp.c:ApEntryPointInC
  - If ApEntryPointInC returns, the lock is freed, and another AP may
run
  - The AP C code may call AsmApDoneWithCommonStack to indicate that
the AP is no longer using the stack, and another may therefore
proceed to use the stack and then call ApEntryPointInC

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf  |  6 
 UefiCpuPkg/CpuDxe/CpuMp.c |  4 +++
 UefiCpuPkg/CpuDxe/CpuMp.h | 27 ++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm  | 75 ++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm | 68 +++
 UefiCpuPkg/CpuDxe/X64/MpAsm.asm   | 76 +++
 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm  | 70 
 7 files changed, 326 insertions(+)
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.asm
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index e49548f..9952eb7 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -53,11 +53,17 @@
   Ia32/CpuAsm.asm | MSFT
   Ia32/CpuAsm.asm | INTEL
   Ia32/CpuAsm.S   | GCC
+  Ia32/MpAsm.asm  | MSFT
+  Ia32/MpAsm.asm  | INTEL
+  Ia32/MpAsm.nasm | GCC
 
 [Sources.X64]
   X64/CpuAsm.asm | MSFT
   X64/CpuAsm.asm | INTEL
   X64/CpuAsm.S   | GCC
+  X64/MpAsm.asm  | MSFT
+  X64/MpAsm.asm  | INTEL
+  X64/MpAsm.nasm | GCC
 
 [Protocols]
   gEfiCpuArchProtocolGuid   ## PRODUCES
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index aa564c1..ea403e8 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -15,6 +15,10 @@
 #include "CpuDxe.h"
 #include "CpuMp.h"
 
+VOID *mCommonStack = 0;
+VOID *mTopOfApCommonStack = 0;
+
+
 /**
   Application Processor C code entry point.
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 9468212..cdca152 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -23,5 +23,32 @@ VOID InitializeMpSupport (
   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
+  );
+
 #endif // _CPU_MP_H_
 
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
new file mode 100644
index 000..d476829
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
@@ -0,0 +1,75 @@
+;--
+;
+; Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+; 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.
+;
+;--
+
+.586p
+.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 btsdword ptr [ApStackLock], 0
+pause
+jc  AsmApEntryPointAcquireLock
+
+mov esp, [mTopOfApCommonStack]
+callApEntryPointInC
+
+cli
+
+lock btcdword ptr [ApStackLock], 0
+
+mov eax, 100h
+AsmApEntryPointShareLock:
+pause
+dec eax
+jnz AsmApEntryPointShareLock
+
+jmp AsmApEntryPoint
+
+AsmApEntryPoint ENDP
+
+;--
+; VOID
+; EFIAPI
+; A

[edk2] [RFC PATCH v6 19/27] UefiCpuPkg/MpService: Simply Lock usage

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 89 +--
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index e97fb5c..1759f16 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -38,6 +38,36 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
 };
 
 /**
+   Get Mp Service Lock
+
+  @param   CpuDatathe pointer to CPU_DATA_BLOCK of specified processor
+
+**/
+VOID
+GetMpSpinLock (
+  IN  CPU_DATA_BLOCK  *CpuData
+  )
+{
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+}
+
+/**
+   Release Mp Service Lock
+
+  @param   CpuDatathe 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
@@ -75,12 +105,9 @@ GetApState (
 {
   CPU_STATE State;
 
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   State = CpuData->State;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 
   return State;
 }
@@ -98,12 +125,9 @@ SetApState (
   IN  CPU_STATEState
   )
 {
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   CpuData->State = State;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 }
 
 /**
@@ -122,13 +146,10 @@ SetApProcedure (
   IN   VOID  *ProcedureArgument
   )
 {
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   CpuData->Parameter  = ProcedureArgument;
   CpuData->Procedure  = Procedure;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 }
 
 /**
@@ -149,12 +170,9 @@ TestCpuStatusFlag (
 {
   UINT32 Ret;
 
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   Ret = CpuData->Info.StatusFlag & Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 
   return !!(Ret);
 }
@@ -172,12 +190,9 @@ CpuStatusFlagOr (
   IN  UINT32  Flags
   )
 {
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   CpuData->Info.StatusFlag |= Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 }
 
 /**
@@ -193,12 +208,9 @@ CpuStatusFlagAndNot (
   IN  UINT32  Flags
   )
 {
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   CpuData->Info.StatusFlag &= ~Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  ReleaseMpSpinLock (CpuData);
 }
 
 /**
@@ -1123,25 +1135,18 @@ ProcessorToIdleState (
   AsmApDoneWithCommonStack ();
 
   while (TRUE) {
-while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-  CpuPause ();
-}
-
+GetMpSpinLock (CpuData);
 ProcedureArgument = CpuData->Parameter;
 Procedure = CpuData->Procedure;
-ReleaseSpinLock (&CpuData->CpuDataLock);
+ReleaseMpSpinLock (CpuData);
 
 if (Procedure != NULL) {
   Procedure (ProcedureArgument);
 
-  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
-CpuPause ();
-  }
-
+  GetMpSpinLock (CpuData);
   CpuData->Procedure = NULL;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
-
-  SetApState (CpuData, CpuStateFinished);
+  CpuData->State = CpuStateFinished;
+  ReleaseMpSpinLock (CpuData);
 }
 
 CpuPause ();
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 16/27] UefiCpuPkg/CpuDxe: implement Mp Services:SwitchBSP()

2014-10-27 Thread Chen Fan
by now, SwitchBSP() always return UNSUPPORTED

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 51 ++-
 UefiCpuPkg/CpuDxe/CpuMp.h | 43 +++
 2 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 2d305e9..3ea6ff0 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -30,7 +30,7 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetProcessorInfo,
   StartupAllAPs,
   StartupThisAP,
-  NULL, // SwitchBSP,
+  SwitchBSP,
   EnableDisableAP,
   WhoAmI
 };
@@ -891,6 +891,55 @@ StartupThisAP (
 }
 
 /**
+  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
+  is signaled.
+
+  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
+   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
+   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
+SwitchBSP (
+  IN EFI_MP_SERVICES_PROTOCOL  *This,
+  IN  UINTNProcessorNumber,
+  IN  BOOLEAN  EnableOldBSP
+  )
+{
+   //
+   // Current always return unsupported.
+   //
+   return EFI_UNSUPPORTED;
+}
+
+/**
   This service lets the caller enable or disable an AP from this point onward.
   This service may only be called from the BSP.
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index cacab87..7af822b 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -465,6 +465,49 @@ StartupThisAP (
   );
 
 /**
+  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
+  is signaled.
+
+  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
+   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
+   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 

[edk2] [RFC PATCH v6 01/27] UefiCpuPkg/CpuDxe: Add no-op InitializeMpSupport

2014-10-27 Thread Chen Fan
From: Jordan Justen 

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
---
 UefiCpuPkg/CpuDxe/CpuDxe.c   |  3 +++
 UefiCpuPkg/CpuDxe/CpuDxe.inf |  2 ++
 UefiCpuPkg/CpuDxe/CpuMp.c| 28 
 UefiCpuPkg/CpuDxe/CpuMp.h| 27 +++
 4 files changed, 60 insertions(+)
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMp.c
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMp.h

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index f165e17..c9df4e1 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -13,6 +13,7 @@
 **/
 
 #include "CpuDxe.h"
+#include "CpuMp.h"
 
 //
 // Global Variables
@@ -897,6 +898,8 @@ InitializeCpu (
   );
   ASSERT_EFI_ERROR (Status);
 
+  InitializeMpSupport ();
+
   return Status;
 }
 
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 152a091..e49548f 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -46,6 +46,8 @@
   CpuDxe.c
   CpuDxe.h
   CpuGdt.c
+  CpuMp.c
+  CpuMp.h
 
 [Sources.IA32]
   Ia32/CpuAsm.asm | MSFT
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
new file mode 100644
index 000..c8189bc
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -0,0 +1,28 @@
+/** @file
+  CPU DXE Module.
+
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+  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 "CpuMp.h"
+
+/**
+  Initialize Multi-processor support.
+
+**/
+VOID
+InitializeMpSupport (
+  VOID
+  )
+{
+}
+
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
new file mode 100644
index 000..9468212
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -0,0 +1,27 @@
+/** @file
+  CPU DXE MP support
+
+  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+  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_MP_H_
+#define _CPU_MP_H_
+
+/**
+  Initialize Multi-processor support.
+
+**/
+VOID InitializeMpSupport (
+  VOID
+  );
+
+#endif // _CPU_MP_H_
+
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 20/27] UefiCpuPkg/MpService: avoid next timer getting into CheckAllAPsStatus()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 1759f16..1ef1cf3 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1227,6 +1227,7 @@ CheckAllAPsStatus (
 {
   CPU_DATA_BLOCK *CpuData;
   UINTN  Number;
+  EFI_STATUS Status;
 
   if (mMpSystemData.TimeoutActive) {
 mMpSystemData.Timeout -= gPollInterval;
@@ -1236,6 +1237,16 @@ CheckAllAPsStatus (
 return;
   }
 
+  //
+  // avoid next timer enter.
+  //
+  Status = gBS->SetTimer (
+  mMpSystemData.CheckAllAPsEvent,
+  TimerCancel,
+  0
+  );
+  ASSERT_EFI_ERROR (Status);
+
   if (mMpSystemData.WaitEvent != NULL) {
 CheckAndUpdateAllAPsToIdleState ();
 //
@@ -1250,13 +1261,15 @@ CheckAllAPsStatus (
 }
 
 if (mMpSystemData.FinishCount != mMpSystemData.StartCount) {
-  return;
+  goto EXIT;
 }
 
 mMpSystemData.TimeoutActive = FALSE;
 gBS->SignalEvent (mMpSystemData.WaitEvent);
 mMpSystemData.WaitEvent = NULL;
 mStopCheckAllAPsStatus = TRUE;
+
+goto EXIT;
   }
 
   //
@@ -1282,6 +1295,14 @@ CheckAllAPsStatus (
   CheckThisAPStatus (NULL, (VOID *)CpuData);
 }
   }
+
+EXIT:
+  Status = gBS->SetTimer (
+  mMpSystemData.CheckAllAPsEvent,
+  TimerPeriodic,
+  EFI_TIMER_PERIOD_MICROSECONDS (100)
+  );
+  ASSERT_EFI_ERROR (Status);
 }
 
 /**
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 06/27] UefiCpuPkg/CpuDxe: introduce two PCD value

2014-10-27 Thread Chen Fan
introduce PCD value: PcdCpuMaxLogicalProcessorNumber and PcdCpuApStackSize,
used for initialize APs stacks.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf |  4 
 UefiCpuPkg/CpuDxe/CpuMp.c| 41 -
 UefiCpuPkg/UefiCpuPkg.dec|  6 ++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index c2f12b7..1837560 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -75,6 +75,10 @@
   gIdleLoopEventGuid## CONSUMES   ## Event
   gEfiVectorHandoffTableGuid## SOMETIMES_CONSUMES ## 
SystemTable
 
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+
 [Depex]
   TRUE
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index ea403e8..611e3d5 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -15,9 +15,14 @@
 #include "CpuDxe.h"
 #include "CpuMp.h"
 
+UINTN gMaxLogicalProcessorNumber;
+UINTN gApStackSize;
+
 VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
+VOID *mApStackStart = 0;
 
+volatile UINTN mNumberOfProcessors;
 
 /**
   Application Processor C code entry point.
@@ -29,6 +34,7 @@ ApEntryPointInC (
   VOID
   )
 {
+  mNumberOfProcessors++;
 }
 
 
@@ -41,5 +47,38 @@ InitializeMpSupport (
   VOID
   )
 {
-}
+  gMaxLogicalProcessorNumber = (UINTN) PcdGet32 
(PcdCpuMaxLogicalProcessorNumber);
+  if (gMaxLogicalProcessorNumber < 1) {
+DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be 
more than zero.\n"));
+return;
+  }
+
+  if (gMaxLogicalProcessorNumber == 1) {
+return;
+  }
+
+  gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize);
+
+  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 = mApStackStart + gApStackSize;
+  mApStackStart = mTopOfApCommonStack;
+
+  mNumberOfProcessors = 1;
+
+  if (mNumberOfProcessors == 1) {
+FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * 
gApStackSize));
+return;
+  }
+
+  if (mNumberOfProcessors < gMaxLogicalProcessorNumber) {
+FreePages (mApStackStart, EFI_SIZE_TO_PAGES ((gMaxLogicalProcessorNumber - 
mNumberOfProcessors) *
+ gApStackSize));
+  }
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index c6e73a9..67d7196 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -54,6 +54,12 @@
   ## Specifies delay value in microseconds after sending out an INIT IPI.
   # @Prompt Configure delay value after send an INIT IPI
   
gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|1|UINT32|0x3002
+  ## Specifies max supported number of Logical Processors.
+  # @Prompt Configure max supported number of Logical Processorss
+  
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64|UINT32|0x0002
+  ## This value specifies the Application Processor (AP) stack size, which 
used for Mp Service.
+  # @Prompt Configure stack size for Application Processor (AP)
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize|0x8000|UINT32|0x0003
 
 [UserExtensions.TianoCore."ExtraFiles"]
   UefiCpuPkgExtra.uni
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 00/27] Introduce Mp Service protocol to UefiCpuPkg

2014-10-27 Thread Chen Fan
This series patchset try to implement Mp Service protocol in UefiCpuPkg,
Jordan had implemented the startup APs code, and I try to add more
initialization code to let all APs work up, this Mp Service protocol's
implementation used EmulatorPkg/MpService for reference.
this patches works on my github:
  https://github.com/ChenFanFnst/edk2/tree/cpu-mp-service

and made StartCorePkg app for testing Mp Service Protocol on:
  https://github.com/ChenFanFnst/edk2/tree/startcore

I had test Mp protocol, all passed.

v5-v6:
  1. using only one timer to check all APs status instead of timers for each AP.
  2. cancel timer each time avoid timer handler reentrancy.
  2. some bug fix.

v4-v5:
  1. introduce PcdCpuMaxLogicalProcessorNumber to pre-allocate
 stack buffer before starting the APs.
  2. implement the function that if procedure routine timeout,
 reset AP by sending init ipi.
  3. some bug fix.

v3-v4:
  1. change the order of the patches.
  2. update some minor format suggested by Jeff.
  3. add a PCD value to configure StackSize.
  4. the last patch add assembly code for MSFT, but didn't
 test.

V3-V3.1:
  1. use AcquireSpinLockOrFail() intead of AcquireSpinLock()
 to avoid ASSERT sugguested by Jeff.

V2-V3:
  1. rebase codes due to Jordan'tree updated:
 https://github.com/jljusten/edk2/tree/ap-startup-example
  2. add supported on Ia32 arch
  3. add a new Lock to replace present SpinLock mechanisms in mutilple
 processors, maybe the SpinLock mechanisms is not MP safe.
  4. add function header
  5. add StartupAllAPs() supported
  6. add SwitchBSP() function, which is unsupported.

V1-V2:
  1. do not call anything EFI API from APs.
  2. add AP busy-wait for task assignment from BSP and get rid of
 IPI sent mechanism.


Chen Fan (22):
  UefiCpuPkg/CpuDxe: introduce two PCD value
  UefiCpuPkg/CpuDxe: Switch Ap Stack to NewStack
  UefiCpuPkg/CpuDxe: introduce EFI_MP_SERVICES_PROTOCOL
  UefiCpuPkg/CpuDxe: introduce MP_SYSTEM_DATA for Mp Service Protocol
  UefiCpuPkg/CpuDxe: implement Mp Protocol: WhoAmI()
  UefiCpuPkg/CpuDxe: implement Mp Protocol:GetNumberOfProcessors()
  UefiCpuPkg/CpuDxe: implement Mp Services:GetProcessorInfo()
  UefiCpuPkg/CpuDxe: implement Mp Protocol:EnableDisableAP()
  UefiCpuPkg/CpuDxe: implement Mp Protocol:StartupThisAP()
  UefiCpuPkg/CpuDxe: implement Mp Services:StartupAllAPs()
  UefiCpuPkg/CpuDxe: implement Mp Services:SwitchBSP()
  UefiCpuPkg/CpuDxe: Ap do loop routine to execute procedure
  UefiCpuPkg/MpService: move settimer out to InitMpSystemData
  UefiCpuPkg/MpService: Simply Lock usage
  UefiCpuPkg/MpService: avoid next timer getting into
CheckAllAPsStatus()
  UefiCpuPkg/CpuDxe: split out StartupCode from StartApsStackless()
  UefiCpuPkg/CpuDxe: introduce ResetApStackless()
  UefiCpuPkg/MpService: avoid reset AP still hold a lock
  UefiCpuPkg/MpService: avoid dead lock caused by CheckAllAPsStatus
  UefiCpuPkg/CpuDxe: Startup APs
  UefiCpuPkg/CpuDxe: install Mp Service protocol
  UefiCpuPkg/CpuDxe: add Mp Service TestCase (!upstream)

Jordan Justen (5):
  UefiCpuPkg/CpuDxe: Add no-op InitializeMpSupport
  UefiCpuPkg/CpuDxe: Add ApEntryPointInC
  UefiCpuPkg/CpuDxe: Add stackless assembly AP entry points
  UefiCpuPkg/CpuDxe: Move GDT structures into CpuGdt.h
  UefiCpuPkg/CpuDxe: Add StartApsStackless routine

 UefiCpuPkg/CpuDxe/ApStartup.asm   |  111 +++
 UefiCpuPkg/CpuDxe/ApStartup.c |  252 +++
 UefiCpuPkg/CpuDxe/CpuDxe.c|5 +
 UefiCpuPkg/CpuDxe/CpuDxe.h|1 +
 UefiCpuPkg/CpuDxe/CpuDxe.inf  |   18 +
 UefiCpuPkg/CpuDxe/CpuGdt.c|   52 +-
 UefiCpuPkg/CpuDxe/CpuGdt.h|   72 ++
 UefiCpuPkg/CpuDxe/CpuMp.c | 1504 +
 UefiCpuPkg/CpuDxe/CpuMp.h |  650 
 UefiCpuPkg/CpuDxe/CpuMpTest.c |   97 +++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm  |   75 ++
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm |   68 ++
 UefiCpuPkg/CpuDxe/X64/MpAsm.asm   |   76 ++
 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm  |   70 ++
 UefiCpuPkg/UefiCpuPkg.dec |6 +
 UefiCpuPkg/UefiCpuPkg.dsc |1 +
 16 files changed, 3007 insertions(+), 51 deletions(-)
 create mode 100644 UefiCpuPkg/CpuDxe/ApStartup.asm
 create mode 100644 UefiCpuPkg/CpuDxe/ApStartup.c
 create mode 100644 UefiCpuPkg/CpuDxe/CpuGdt.h
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMp.c
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMp.h
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMpTest.c
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.asm
 create mode 100644 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.asm
 create mode 100644 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm

-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 04/27] UefiCpuPkg/CpuDxe: Move GDT structures into CpuGdt.h

2014-10-27 Thread Chen Fan
From: Jordan Justen 

We'll want to use the structures for AP startup.

Note: It seems previously we were not using '#pragma pack ()' in
  CpuGdt.c.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
---
 UefiCpuPkg/CpuDxe/CpuGdt.c | 52 +
 UefiCpuPkg/CpuDxe/CpuGdt.h | 72 ++
 2 files changed, 73 insertions(+), 51 deletions(-)
 create mode 100644 UefiCpuPkg/CpuDxe/CpuGdt.h

diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.c b/UefiCpuPkg/CpuDxe/CpuGdt.c
index 32f45a5..35a87a6 100644
--- a/UefiCpuPkg/CpuDxe/CpuGdt.c
+++ b/UefiCpuPkg/CpuDxe/CpuGdt.c
@@ -14,57 +14,7 @@
 **/
 
 #include "CpuDxe.h"
-
-
-//
-// Local structure definitions
-//
-
-#pragma pack (1)
-
-//
-// Global Descriptor Entry structures
-//
-
-typedef struct _GDT_ENTRY {
-  UINT16 Limit15_0;
-  UINT16 Base15_0;
-  UINT8  Base23_16;
-  UINT8  Type;
-  UINT8  Limit19_16_and_flags;
-  UINT8  Base31_24;
-} GDT_ENTRY;
-
-typedef
-struct _GDT_ENTRIES {
-  GDT_ENTRY Null;
-  GDT_ENTRY Linear;
-  GDT_ENTRY LinearCode;
-  GDT_ENTRY SysData;
-  GDT_ENTRY SysCode;
-  GDT_ENTRY LinearCode64;
-  GDT_ENTRY Spare4;
-  GDT_ENTRY Spare5;
-} GDT_ENTRIES;
-
-#define NULL_SEL  OFFSET_OF (GDT_ENTRIES, Null)
-#define LINEAR_SELOFFSET_OF (GDT_ENTRIES, Linear)
-#define LINEAR_CODE_SEL   OFFSET_OF (GDT_ENTRIES, LinearCode)
-#define SYS_DATA_SEL  OFFSET_OF (GDT_ENTRIES, SysData)
-#define SYS_CODE_SEL  OFFSET_OF (GDT_ENTRIES, SysCode)
-#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)
-#define SPARE4_SELOFFSET_OF (GDT_ENTRIES, Spare4)
-#define SPARE5_SELOFFSET_OF (GDT_ENTRIES, Spare5)
-
-#if defined (MDE_CPU_IA32)
-#define CPU_CODE_SEL LINEAR_CODE_SEL
-#define CPU_DATA_SEL LINEAR_SEL
-#elif defined (MDE_CPU_X64)
-#define CPU_CODE_SEL LINEAR_CODE64_SEL
-#define CPU_DATA_SEL LINEAR_SEL
-#else
-#error CPU type not supported for CPU GDT initialization!
-#endif
+#include "CpuGdt.h"
 
 //
 // Global descriptor table (GDT) Template
diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.h b/UefiCpuPkg/CpuDxe/CpuGdt.h
new file mode 100644
index 000..7ecec5d
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuGdt.h
@@ -0,0 +1,72 @@
+/** @file
+  C based implemention of IA32 interrupt handling only
+  requiring a minimal assembly interrupt entry point.
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+  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_GDT_H_
+#define _CPU_GDT_H_
+
+//
+// Local structure definitions
+//
+
+#pragma pack (1)
+
+//
+// Global Descriptor Entry structures
+//
+
+typedef struct _GDT_ENTRY {
+  UINT16 Limit15_0;
+  UINT16 Base15_0;
+  UINT8  Base23_16;
+  UINT8  Type;
+  UINT8  Limit19_16_and_flags;
+  UINT8  Base31_24;
+} GDT_ENTRY;
+
+typedef
+struct _GDT_ENTRIES {
+  GDT_ENTRY Null;
+  GDT_ENTRY Linear;
+  GDT_ENTRY LinearCode;
+  GDT_ENTRY SysData;
+  GDT_ENTRY SysCode;
+  GDT_ENTRY LinearCode64;
+  GDT_ENTRY Spare4;
+  GDT_ENTRY Spare5;
+} GDT_ENTRIES;
+
+#pragma pack ()
+
+#define NULL_SEL  OFFSET_OF (GDT_ENTRIES, Null)
+#define LINEAR_SELOFFSET_OF (GDT_ENTRIES, Linear)
+#define LINEAR_CODE_SEL   OFFSET_OF (GDT_ENTRIES, LinearCode)
+#define SYS_DATA_SEL  OFFSET_OF (GDT_ENTRIES, SysData)
+#define SYS_CODE_SEL  OFFSET_OF (GDT_ENTRIES, SysCode)
+#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)
+#define SPARE4_SELOFFSET_OF (GDT_ENTRIES, Spare4)
+#define SPARE5_SELOFFSET_OF (GDT_ENTRIES, Spare5)
+
+#if defined (MDE_CPU_IA32)
+#define CPU_CODE_SEL LINEAR_CODE_SEL
+#define CPU_DATA_SEL LINEAR_SEL
+#elif defined (MDE_CPU_X64)
+#define CPU_CODE_SEL LINEAR_CODE64_SEL
+#define CPU_DATA_SEL LINEAR_SEL
+#else
+#error CPU type not supported for CPU GDT initialization!
+#endif
+
+#endif // _CPU_GDT_H_
+
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 27/27] UefiCpuPkg/CpuDxe: add Mp Service TestCase (!upstream)

2014-10-27 Thread Chen Fan
NOTE: this patches is for testing temporary.
  So it should be ignore when adding to main tree.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuDxe.c|  2 +
 UefiCpuPkg/CpuDxe/CpuDxe.inf  |  1 +
 UefiCpuPkg/CpuDxe/CpuMp.h |  9 
 UefiCpuPkg/CpuDxe/CpuMpTest.c | 97 +++
 4 files changed, 109 insertions(+)
 create mode 100644 UefiCpuPkg/CpuDxe/CpuMpTest.c

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index c9df4e1..16e6bcc 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -900,6 +900,8 @@ InitializeCpu (
 
   InitializeMpSupport ();
 
+  AddTestMpService ();
+
   return Status;
 }
 
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index 6761e91..6983e62 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -52,6 +52,7 @@
   CpuGdt.h
   CpuMp.c
   CpuMp.h
+  CpuMpTest.c
 
 [Sources.IA32]
   Ia32/CpuAsm.asm | MSFT
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 10c67b8..5bb7c31 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -637,5 +637,14 @@ ResetApStackless (
   IN UINT32 ProcessorId
   );
 
+/**
+  Initialize Mp Service Testing.
+
+**/
+VOID
+AddTestMpService (
+  VOID
+  );
+
 #endif // _CPU_MP_H_
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMpTest.c b/UefiCpuPkg/CpuDxe/CpuMpTest.c
new file mode 100644
index 000..9d65b1c
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/CpuMpTest.c
@@ -0,0 +1,97 @@
+#include "CpuDxe.h"
+#include "CpuMp.h"
+
+VOID
+EFIAPI
+CheckTaskComplete (
+  IN  EFI_EVENTEvent,
+  IN  VOID *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "All Client Task finished.\n"));
+}
+
+VOID
+EFIAPI
+ClientTask(
+  IN VOID* parameter
+  )
+{
+   DEBUG ((DEBUG_INFO, "I am Client Task!!!\n"));
+}
+
+VOID
+EFIAPI
+ClientTask1(
+  IN VOID* parameter
+  )
+{
+   DEBUG ((DEBUG_INFO, "I am Client Task with timeout!!!\n"));
+   while (1);
+}
+
+
+/**
+  Initialize Mp Service Testing
+
+**/
+VOID
+AddTestMpService (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  EFI_MP_SERVICES_PROTOCOL *MpService;
+  UINTN WhoAmI;
+  UINTN NumberOfProcessors;
+  UINTN NumberOfEnabledProcessors;
+  EFI_EVENT WaitEvent;
+
+  Status = gBS->LocateProtocol(&gEfiMpServiceProtocolGuid,
+   NULL,
+   (void **) &MpService);
+  if (EFI_ERROR(Status)) {
+DEBUG ((DEBUG_ERROR, "Install Mp Service fails\n"));
+return;
+  }
+
+  Status = MpService->WhoAmI(MpService, &WhoAmI);
+  if (!EFI_ERROR(Status)) {
+DEBUG ((DEBUG_INFO, "WhoAmI is : %d\n", WhoAmI));
+  }
+
+  Status = MpService->GetNumberOfProcessors (MpService,
+ &NumberOfProcessors,
+ &NumberOfEnabledProcessors
+ );
+  if (!EFI_ERROR(Status)) {
+DEBUG ((DEBUG_INFO, "GetNumberOfProcessors : %d enabled: %d\n",
+  NumberOfProcessors, NumberOfEnabledProcessors));
+  }
+
+  gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CheckTaskComplete,
+ NULL,
+ &WaitEvent
+ );
+
+  Status = MpService->StartupThisAP (MpService, ClientTask1, 1, NULL,
+ 100, NULL, NULL);
+  if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "FAILED: %r\n", Status));
+  }
+
+  /*
+  do {
+Status = gBS->CheckEvent(WaitEvent);
+  } while (EFI_ERROR(Status));
+
+  Status = MpService->StartupAllAPs (MpService, ClientTask, TRUE, WaitEvent,
+ 0, NULL, NULL);
+  if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "FAILED.\n"));
+  }*/
+
+}
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 07/27] UefiCpuPkg/CpuDxe: Switch Ap Stack to NewStack

2014-10-27 Thread Chen Fan
All APs use the same common stack to initialization. after
initialization, APs should switch to the stack of its own.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 611e3d5..956acf4 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -25,6 +25,25 @@ VOID *mApStackStart = 0;
 volatile UINTN mNumberOfProcessors;
 
 /**
+  Application Processors do loop routine
+  after switch to its own stack.
+
+**/
+VOID
+ProcessorToIdleState (
+  IN  VOID  *Context1,  OPTIONAL
+  IN  VOID  *Context2   OPTIONAL
+  )
+{
+  DEBUG ((DEBUG_INFO, "Ap apicid is %d\n", GetApicId ()));
+
+  AsmApDoneWithCommonStack ();
+
+  CpuSleep ();
+  CpuDeadLoop ();
+}
+
+/**
   Application Processor C code entry point.
 
 **/
@@ -35,6 +54,13 @@ ApEntryPointInC (
   )
 {
   mNumberOfProcessors++;
+  mApStackStart = mApStackStart + gApStackSize;
+
+  SwitchStack (
+(SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState,
+NULL,
+NULL,
+mApStackStart);
 }
 
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 05/27] UefiCpuPkg/CpuDxe: Add StartApsStackless routine

2014-10-27 Thread Chen Fan
From: Jordan Justen 

This routine starts the APs and directs them to run the specified
code.

The specified code is entered without a stack being available.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen 
---
 UefiCpuPkg/CpuDxe/ApStartup.asm | 111 +
 UefiCpuPkg/CpuDxe/ApStartup.c   | 209 
 UefiCpuPkg/CpuDxe/CpuDxe.h  |   1 +
 UefiCpuPkg/CpuDxe/CpuDxe.inf|   3 +
 UefiCpuPkg/CpuDxe/CpuMp.h   |  24 +
 5 files changed, 348 insertions(+)
 create mode 100644 UefiCpuPkg/CpuDxe/ApStartup.asm
 create mode 100644 UefiCpuPkg/CpuDxe/ApStartup.c

diff --git a/UefiCpuPkg/CpuDxe/ApStartup.asm b/UefiCpuPkg/CpuDxe/ApStartup.asm
new file mode 100644
index 000..049a45f
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/ApStartup.asm
@@ -0,0 +1,111 @@
+;--
+; @file
+; Transition from 16 bit real mode into 64 bit long mode
+;
+; Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+; 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.
+;
+;--
+
+;
+; NOTE: This file is *NOT USED* in the build. It was used to help create
+;   ApStartup.c.
+;
+;   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  0x0023
+%define DEFAULT_CR4  0x640
+
+BITS16
+
+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
+BITS32
+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, 0xc080
+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
+BITS64
+jumpTo64BitAndLandHere:
+mov rax, 0xcdcdcdcdcdcdcdcd
+jmp rax
+
diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c
new file mode 100644
index 000..7b6f5dd
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/ApStartup.c
@@ -0,0 +1,209 @@
+/** @file
+  CPU DXE AP Startup
+
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+  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  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];
+ 

[edk2] [RFC PATCH v6 14/27] UefiCpuPkg/CpuDxe: implement Mp Protocol:StartupThisAP()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 344 +-
 UefiCpuPkg/CpuDxe/CpuMp.h | 117 
 2 files changed, 460 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index c25157a..a6d70d5 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -17,6 +17,7 @@
 
 UINTN gMaxLogicalProcessorNumber;
 UINTN gApStackSize;
+UINTN gPollInterval = 100; // 100 microseconds
 
 MP_SYSTEM_DATA mMpSystemData;
 
@@ -28,7 +29,7 @@ EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetNumberOfProcessors,
   GetProcessorInfo,
   NULL, // StartupAllAPs,
-  NULL, // StartupThisAP,
+  StartupThisAP,
   NULL, // SwitchBSP,
   EnableDisableAP,
   WhoAmI
@@ -83,6 +84,52 @@ GetApState (
 }
 
 /**
+  Set the Application Processors state.
+
+  @param   CpuDataThe pointer to CPU_DATA_BLOCK of specified AP
+  @param   State  The AP status
+
+**/
+VOID
+SetApState (
+  IN  CPU_DATA_BLOCK   *CpuData,
+  IN  CPU_STATEState
+  )
+{
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  CpuData->State = State;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+/**
+  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
+  )
+{
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  CpuData->Parameter  = ProcedureArgument;
+  CpuData->Procedure  = Procedure;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+}
+
+/**
   Check the Application Processors Status whether contains the Flags.
 
   @param CpuData  the pointer to CPU_DATA_BLOCK of specified AP
@@ -153,6 +200,45 @@ CpuStatusFlagAndNot (
 }
 
 /**
+  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_FOUNDNo 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;
+}
+
+/**
   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.
@@ -260,6 +346,176 @@ GetProcessorInfo (
 }
 
 /**
+  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,
+  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
+  EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+  @param[in]  ThisA 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
+  EFI_AP_PROCEDURE.
+  @par

[edk2] [RFC PATCH v6 21/27] UefiCpuPkg/CpuDxe: split out StartupCode from StartApsStackless()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/ApStartup.c | 54 ---
 UefiCpuPkg/CpuDxe/CpuMp.c |  3 +++
 UefiCpuPkg/CpuDxe/CpuMp.h | 27 ++
 3 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c
index 7b6f5dd..f985a5c 100644
--- a/UefiCpuPkg/CpuDxe/ApStartup.c
+++ b/UefiCpuPkg/CpuDxe/ApStartup.c
@@ -143,27 +143,22 @@ STARTUP_CODE mStartupCodeTemplate = {
 
 };
 
+volatile STARTUP_CODE *StartupCode = NULL;
 
 /**
-  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.
-
-  @param ApEntryPointPointer to the Entry Point routine
+  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
-StartApsStackless (
-  IN STACKLESS_AP_ENTRY_POINT ApEntryPoint
+PrepareAPStartupCode (
+  VOID
   )
 {
   EFI_STATUSStatus;
-  volatile STARTUP_CODE *StartupCode;
   IA32_DESCRIPTOR   Gdtr;
   EFI_PHYSICAL_ADDRESS  StartAddress;
 
@@ -186,7 +181,7 @@ StartApsStackless (
   StartupCode->GdtLimit = Gdtr.Limit;
   StartupCode->GdtBase = (UINT32) Gdtr.Base;
 
-  StartupCode->CpuDxeEntryValue = (UINTN) ApEntryPoint;
+  StartupCode->CpuDxeEntryValue = (UINTN) AsmApEntryPoint;
 
   StartupCode->FlatJmpOffset += (UINT32) StartAddress;
 
@@ -195,15 +190,46 @@ StartApsStackless (
   StartupCode->LongJmpOffset += (UINT32) StartAddress;
 #endif
 
-  SendInitSipiSipiAllExcludingSelf ((UINT32)(UINTN)(VOID*) StartupCode);
+  return EFI_SUCCESS;
+}
+
+/**
+  Free the code buffer of startup AP.
+
+**/
+VOID
+FreeApStartupCode (
+  VOID
+  )
+{
+  if (StartupCode != NULL) {
+gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(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 100 milliseconds for APs to arrive at the ApEntryPoint routine
   //
   MicroSecondDelay (100 * 1000);
 
-  gBS->FreePages (StartAddress, EFI_SIZE_TO_PAGES (sizeof (*StartupCode)));
-
   return EFI_SUCCESS;
 }
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 1ef1cf3..25331c0 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1448,7 +1448,10 @@ InitializeMpSupport (
 
   InitMpSystemData ();
 
+  PrepareAPStartupCode ();
+
   if (mMpSystemData.NumberOfProcessors == 1) {
+FreeApStartupCode ();
 FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * 
gApStackSize));
 return;
   }
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 7af822b..0337327 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -39,15 +39,12 @@ VOID
   The processor jumps to this code in flat mode, but the processor's
   stack is not initialized.
 
-  @param ApEntryPointPointer to the Entry Point routine
-
   @retval EFI_SUCCESS   The APs were started
-  @retval EFI_OUT_OF_RESOURCES  Cannot allocate memory to start APs
 
 **/
 EFI_STATUS
 StartApsStackless (
-  IN STACKLESS_AP_ENTRY_POINT ApEntryPoint
+  VOID
   );
 
 /**
@@ -602,5 +599,27 @@ 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
+  );
+
 #endif // _CPU_MP_H_
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 12/27] UefiCpuPkg/CpuDxe: implement Mp Services:GetProcessorInfo()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 52 ++-
 UefiCpuPkg/CpuDxe/CpuMp.h | 34 +++
 2 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 4c104ec..db863f3 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -26,7 +26,7 @@ VOID *mApStackStart = 0;
 
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetNumberOfProcessors,
-  NULL, // GetProcessorInfo,
+  GetProcessorInfo,
   NULL, // StartupAllAPs,
   NULL, // StartupThisAP,
   NULL, // SwitchBSP,
@@ -115,6 +115,56 @@ GetNumberOfProcessors (
 }
 
 /**
+  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]  This  A pointer to the EFI_MP_SERVICES_PROTOCOL
+instance.
+  @param[in]  ProcessorNumber   The handle number of processor.
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information 
for
+the requested processor is deposited.
+
+  @retval EFI_SUCCESS Processor information was returned.
+  @retval EFI_DEVICE_ERRORThe 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
+GetProcessorInfo (
+  IN  EFI_MP_SERVICES_PROTOCOL   *This,
+  IN  UINTN  ProcessorNumber,
+  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;
+}
+
+/**
   This return the handle number for the calling processor.  This service may be
   called from the BSP and APs.
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 99cec31..7e0bdb6 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -168,6 +168,40 @@ GetNumberOfProcessors (
   );
 
 /**
+  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]  This  A pointer to the EFI_MP_SERVICES_PROTOCOL
+instance.
+  @param[in]  ProcessorNumber   The handle number of processor.
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information 
for
+the requested processor is deposited.
+
+  @retval EFI_SUCCESS Processor information was returned.
+  @retval EFI_DEVICE_ERRORThe 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
+GetProcessorInfo (
+  IN  EFI_MP_SERVICES_PROTOCOL   *This,
+  IN  UINTN  ProcessorNumber,
+  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
+  );
+
+/**
   This return the handle number for the calling processor.  This service may be
   called from the BSP and APs.
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 17/27] UefiCpuPkg/CpuDxe: Ap do loop routine to execute procedure

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 3ea6ff0..8482cdf 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1104,10 +1104,41 @@ ProcessorToIdleState (
   IN  VOID  *Context2   OPTIONAL
   )
 {
-  DEBUG ((DEBUG_INFO, "Ap apicid is %d\n", GetApicId ()));
+  UINTN ProcessorNumber;
+  CPU_DATA_BLOCK*CpuData;
+  EFI_AP_PROCEDURE  Procedure;
+  VOID  *ProcedureArgument;
+
+  WhoAmI (&mMpServicesTemplate, &ProcessorNumber);
+  CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];
 
   AsmApDoneWithCommonStack ();
 
+  while (TRUE) {
+while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+  CpuPause ();
+}
+
+ProcedureArgument = CpuData->Parameter;
+Procedure = CpuData->Procedure;
+ReleaseSpinLock (&CpuData->CpuDataLock);
+
+if (Procedure != NULL) {
+  Procedure (ProcedureArgument);
+
+  while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
+CpuPause ();
+  }
+
+  CpuData->Procedure = NULL;
+  ReleaseSpinLock (&CpuData->CpuDataLock);
+
+  SetApState (CpuData, CpuStateFinished);
+}
+
+CpuPause ();
+  }
+
   CpuSleep ();
   CpuDeadLoop ();
 }
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [RFC PATCH v6 15/27] UefiCpuPkg/CpuDxe: implement Mp Services:StartupAllAPs()

2014-10-27 Thread Chen Fan
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/CpuMp.c | 436 +-
 UefiCpuPkg/CpuDxe/CpuMp.h | 160 +
 2 files changed, 595 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index a6d70d5..2d305e9 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -28,7 +28,7 @@ VOID *mApStackStart = 0;
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetNumberOfProcessors,
   GetProcessorInfo,
-  NULL, // StartupAllAPs,
+  StartupAllAPs,
   StartupThisAP,
   NULL, // SwitchBSP,
   EnableDisableAP,
@@ -239,6 +239,106 @@ GetNextBlockedNumber (
 }
 
 /**
+  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_STATUSStatus;
+  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);
+}
+  }
+
+  SetApState (CpuData, CpuStateIdle);
+}
+  }
+}
+
+/**
+  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) {
+  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.
@@ -346,6 +446,281 @@ GetProcessorInfo (
 }
 
 /**
+  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
+  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 WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+  APs finish or TimeoutInMicroseconds 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 Procedu

[edk2] [RFC PATCH v6 22/27] UefiCpuPkg/CpuDxe: introduce ResetApStackless()

2014-10-27 Thread Chen Fan
If timeout expires before AP returns from Procedure, the AP should
be terminated, we introduce ResetApStackLess() to send init IPI
to let AP exit Procedurce and re-available.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
---
 UefiCpuPkg/CpuDxe/ApStartup.c | 19 ++-
 UefiCpuPkg/CpuDxe/CpuMp.c | 35 ++-
 UefiCpuPkg/CpuDxe/CpuMp.h | 15 +++
 3 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c
index f985a5c..860b7c3 100644
--- a/UefiCpuPkg/CpuDxe/ApStartup.c
+++ b/UefiCpuPkg/CpuDxe/ApStartup.c
@@ -203,7 +203,7 @@ FreeApStartupCode (
   )
 {
   if (StartupCode != NULL) {
-gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(VOID *) StartupCode,
+gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)(VOID*) StartupCode,
 EFI_SIZE_TO_PAGES (sizeof (*StartupCode)));
   }
 }
@@ -233,3 +233,20 @@ StartApsStackless (
   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/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 25331c0..b718465 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -25,6 +25,7 @@ VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;
 
+BOOLEAN mAPsAlreadyInitFinished = FALSE;
 volatile BOOLEAN mStopCheckAllAPsStatus = TRUE;
 
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
@@ -,6 +1112,7 @@ ResetProcessorToIdleState (
   IN CPU_DATA_BLOCK  *CpuData
   )
 {
+  ResetApStackless(CpuData->Info.ProcessorId);
 }
 
 /**
@@ -1134,6 +1136,14 @@ ProcessorToIdleState (
 
   AsmApDoneWithCommonStack ();
 
+  //
+  // Avoid forcibly reset AP caused the AP State is not updated.
+  //
+  GetMpSpinLock (CpuData);
+  CpuData->State = CpuStateIdle;
+  CpuData->Procedure = NULL;
+  ReleaseMpSpinLock (CpuData);
+
   while (TRUE) {
 GetMpSpinLock (CpuData);
 ProcedureArgument = CpuData->Parameter;
@@ -1315,13 +1325,27 @@ ApEntryPointInC (
   VOID
   )
 {
-  VOID* TopOfApStack;
+  VOID*   TopOfApStack;
+  UINTN   ProcessorNumber;
 
-  FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
-  TopOfApStack  = mApStackStart + gApStackSize;
-  mApStackStart = TopOfApStack;
+  if (!mAPsAlreadyInitFinished) {
+FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
+TopOfApStack  = mApStackStart + gApStackSize;
+mApStackStart = TopOfApStack;
 
-  mMpSystemData.NumberOfProcessors++;
+//
+// 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,
@@ -1456,6 +1480,7 @@ InitializeMpSupport (
 return;
   }
 
+  mAPsAlreadyInitFinished = TRUE;
 
   if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
 FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 0337327..d812561 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -98,6 +98,7 @@ typedef struct {
   EFI_EVENT  WaitEvent;
   BOOLEANTimeoutActive;
   EFI_EVENT  CheckThisAPEvent;
+  VOID   *TopOfStack;
 } CPU_DATA_BLOCK;
 
 /**
@@ -621,5 +622,19 @@ 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
+  );
+
 #endif // _CPU_MP_H_
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] Firmware Volume Block Protocol

2014-10-27 Thread Gao, Liming
Hi,

  DxeCore has FVB notify function to call FVB protocol to check whether a FV 
image is there. DxeCore will read FV header, then base on header length to read 
the whole FV header, last check FV header. If your FV is not PI FFS format, its 
FV header length field is invalid that causes DxeCore wrongly read data.  To 
avoid it, DxeCore could be enhanced to check FV header first, then read full 
header. Could you apply the attached patch to DxeCore module and check again?

Thanks
Liming
From: Narinder Dhillon [mailto:ndhillo...@gmail.com]
Sent: Monday, October 27, 2014 8:44 AM
To: edk2-devel@lists.sourceforge.net
Subject: [edk2] Firmware Volume Block Protocol

Hi All,

I am trying to implement a non-volatile variable storage on a small part of 
eMMC device. I have implemented the FVB protocol and the 'Read' function is 
being called with increasing 'Lba' during UEFI boot.

Where is the 'Read' function is being called from ? (some sort of 
initialization code)
Why will it not stop ?
The 'Read' function is being called with increasing Lba till my board hangs.

FvbRead Lba:2 Offset:0, Numbytes:512 0x200
FvbRead Lba:3 Offset:0, Numbytes:512 0x200
FvbRead Lba:4 Offset:0, Numbytes:512 0x200

Thanx.



FwVol.c.patch
Description: FwVol.c.patch
--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] Get BlockIo protocol from Ata Device based on Port and Multiplier Port

2014-10-27 Thread Rafael Machado
Hi everyone.

I have a system, that has a Storage device.
This device can be detected at Port 0, Multiplier 0 by the
EFI_ATA_PASS_THRU_PROTOCOL.GetNextDevice()

*typedef EFI_STATUS*
*(EFIAPI *EFI_ATA_PASS_THRU_GET_NEXT_DEVICE) (*
*IN EFI_ATA_PASS_THRU_PROTOCOL *This,*
*IN UINT16 Port,*
*IN OUT UINT16 *PortMultiplierPort*
*);*

Now I need to know the EFI_BLOCK_IO_PROTOCOL "instance" that I need to use
to access this device.
Is there a way to do this ?

Thanks and Regards
Rafael R. Machado
--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] EDK2: Add #ifndef/#endif and remove trailing white space

2014-10-27 Thread Bruce Cran
On 10/23/2014 12:59 PM, Leahy, Leroy P wrote:
> Attached is an updated patch without the comments.
>
> Attestation:
>
> I have made the following change to support Google.
>
> Submission:
>
> Code clean-up: Remove trailing spaces and add #ifndef/#endif around
> NULL, MAX and MIN.

There's an existing typo in lines you're changing that could be fixed at 
the same time:

"Microsoft C complier" - 'complier' should probably be 'compiler'.

-- 
Bruce


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] [Xen-devel] [PATCH v4 00/19] Introducing Xen PV block driver to OVMF

2014-10-27 Thread Anthony PERARD
On Fri, Oct 24, 2014 at 04:29:39PM -0700, Jordan Justen wrote:
> Can you make these changes:
> 
> OvmfPkg: Introduce XenBus Protocol.
> OvmfPkg/Include/Protocol/XenBus.h
> Use standard EDK II BSD license header.

Done.

> OvmfPkg/XenBusDxe: Add Grant Table functions.
> OvmfPkg/XenBusDxe/GrantTable.c
> Maybe use standard EDK II BSD license header? Except, based on the
> copyright messages, maybe you can't.

Yes, it's probably best to keep the original license.

> Can you post this in a pvdisk-v5 branch in your repo at:
> git://xenbits.xen.org/people/aperard/ovmf.git
> (I don't think another list posting is needed.)

Done.

> Follow up requests for this series:
> 
> Can you look into moving InterlockedCompareExchange16 to 
> BaseSynchronizationLib?

I will look into this.

> After I commit BaseTools/Scripts/ConvertMasmToNasm.py can you look at
> converting the assembly to NASM with that script?

Yes, that should not be a problem.

Thank you.

-- 
Anthony PERARD

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] Edk2Setup.bat doesn't inherit %PATH% from calling shell

2014-10-27 Thread Hauch, Larry
Hi,
Actually, ORIGINAL_PATH is not a local variable, but is used as a flag so that 
when Edk2Setup (or edksetup) is run multiple times in the same command prompt 
window, the EDK II BaseTools path does not get added more than one time, along 
with other changes to the PATH.
The design allowed for using Edk2Setup once with --nt32 for including visual 
studio tools, then run it a second time without the flag and the visual studio 
tools would be cleared from the PATH.
Cheers,
Larry

-Original Message-
From: Scott Duplichan [mailto:sc...@notabs.org] 
Sent: Friday, October 24, 2014 3:35 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] Edk2Setup.bat doesn't inherit %PATH% from calling shell

Bruce Cran [mailto:bruce.c...@gmail.com] wrote:

]It appears that Edk2Setup.bat from the latest code is ignoring the ]%PATH% 
variable from the current shell and resetting it to the ]system-wide setting:
]
]C:\UDK2014>svn
]Type 'svn help' for usage.
]
]C:\UDK2014>Edk2Setup.bat --pull
]
]WARNING : NASM_PREFIX environment variable is not set ]  Attempting to build 
modules that require NASM will fail.
]'svn' is not recognized as an internal or external command, ]operable program 
or batch file.
]ERROR : The command-line svn tool is not available and the Win32 ]binaries do 
not exist
]Python does not appear to be available either. This script
]cannot be used to
]build the Win32 binaries or to obtain them from this repository:
]   https://svn.code.sf.net/p/edk2-toolbinaries/code/trunk/Win32
]
]C:\UDK2014>svn
]'svn' is not recognized as an internal or external command, ]operable program 
or batch file.
]

I bet if you first clear environment variable "ORIGINAL_PATH", the problem will 
disappear:

C:\UDK2014>ORIGINAL_PATH=
C:\UDK2014>Edk2Setup.bat --pull

Probably Edk2Setup.bat was meant to clear ORIGINAL_PATH before exit, but it 
doesn't.
setlocal/endlocal is simpler way of saving/restoring the path, along with all 
the EVs.

Thanks,
Scott

]--
]Bruce



--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] Firmware Volume Block Protocol

2014-10-27 Thread Narinder Dhillon
Hi Liming,

Yes, the patch helped and now the initialization is not stuck in a loop.
When UEFI runs for the first time, eMMC flash device is blank and there
will not be any information or FVB header. Would UEFI create one ? Or do I
have to create a volume first before UEFI will start using it ?
Thanx.

On Mon, Oct 27, 2014 at 3:24 AM, Gao, Liming  wrote:

>  Hi,
>
>   DxeCore has FVB notify function to call FVB protocol to check whether a
> FV image is there. DxeCore will read FV header, then base on header length
> to read the whole FV header, last check FV header. If your FV is not PI FFS
> format, its FV header length field is invalid that causes DxeCore wrongly
> read data.  To avoid it, DxeCore could be enhanced to check FV header
> first, then read full header. Could you apply the attached patch to DxeCore
> module and check again?
>
>
>
> Thanks
>
> Liming
>
> *From:* Narinder Dhillon [mailto:ndhillo...@gmail.com]
> *Sent:* Monday, October 27, 2014 8:44 AM
> *To:* edk2-devel@lists.sourceforge.net
> *Subject:* [edk2] Firmware Volume Block Protocol
>
>
>
> Hi All,
>
>
>
> I am trying to implement a non-volatile variable storage on a small part
> of eMMC device. I have implemented the FVB protocol and the 'Read' function
> is being called with increasing 'Lba' during UEFI boot.
>
>
>
> Where is the 'Read' function is being called from ? (some sort of
> initialization code)
>
> Why will it not stop ?
>
> The 'Read' function is being called with increasing Lba till my board
> hangs.
>
>
>
> FvbRead Lba:2 Offset:0, Numbytes:512 0x200
>
> FvbRead Lba:3 Offset:0, Numbytes:512 0x200
>
> FvbRead Lba:4 Offset:0, Numbytes:512 0x200
>
>
>
> Thanx.
>
>
>
>
> --
>
> ___
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
>
>
--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] UDK2014.SP1: UefiHandleParsingLib now consumes gEfiShellDynamicCommandProtocolGuid?

2014-10-27 Thread Bruce Cran
I have code that uses UefiHandleParsingLib that builds using UDK2014
but not using the latest UDK2014.SP1 code: it appears that
UefiHandleParsingLib now depends on
gEfiShellDynamicCommandProtocolGuid.

Should it be listed as being consumed in UefiHandleParsingLib.inf, or
would I need to add it to mine?

-- 
Bruce

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] Firmware Volume Block Protocol

2014-10-27 Thread Andrew Fish

> On Oct 27, 2014, at 12:11 PM, Narinder Dhillon  wrote:
> 
> Hi Liming,
> 
> Yes, the patch helped and now the initialization is not stuck in a loop.
> When UEFI runs for the first time, eMMC flash device is blank and there will 
> not be any information or FVB header. Would UEFI create one ? Or do I have to 
> create a volume first before UEFI will start using it ?

The assumption is it is formatted, the DXE does not attempt to format the 
volume. 

Thanks,

Andrew Fish

> Thanx.
> 
> On Mon, Oct 27, 2014 at 3:24 AM, Gao, Liming  > wrote:
> Hi,
> 
>   DxeCore has FVB notify function to call FVB protocol to check whether a FV 
> image is there. DxeCore will read FV header, then base on header length to 
> read the whole FV header, last check FV header. If your FV is not PI FFS 
> format, its FV header length field is invalid that causes DxeCore wrongly 
> read data.  To avoid it, DxeCore could be enhanced to check FV header first, 
> then read full header. Could you apply the attached patch to DxeCore module 
> and check again?
> 
>  
> 
> Thanks
> 
> Liming
> 
> From: Narinder Dhillon [mailto:ndhillo...@gmail.com 
> ] 
> Sent: Monday, October 27, 2014 8:44 AM
> To: edk2-devel@lists.sourceforge.net 
> Subject: [edk2] Firmware Volume Block Protocol
> 
>  
> 
> Hi All,
> 
>  
> 
> I am trying to implement a non-volatile variable storage on a small part of 
> eMMC device. I have implemented the FVB protocol and the 'Read' function is 
> being called with increasing 'Lba' during UEFI boot.
> 
>  
> 
> Where is the 'Read' function is being called from ? (some sort of 
> initialization code)
> 
> Why will it not stop ?
> 
> The 'Read' function is being called with increasing Lba till my board hangs.
> 
>  
> 
> FvbRead Lba:2 Offset:0, Numbytes:512 0x200
> 
> FvbRead Lba:3 Offset:0, Numbytes:512 0x200
> 
> FvbRead Lba:4 Offset:0, Numbytes:512 0x200
> 
>  
> 
> Thanx.
> 
>  
> 
> 
> --
> 
> ___
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net 
> https://lists.sourceforge.net/lists/listinfo/edk2-devel 
> 
> 
> 
> --
> ___
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


Re: [edk2] Edk2Setup.bat doesn't inherit %PATH% from calling shell

2014-10-27 Thread Scott Duplichan
Hauch, Larry [mailto:larry.ha...@intel.com] wrote:

]Hi,
]Actually, ORIGINAL_PATH is not a local variable, but is used as a flag so that 
when Edk2Setup (or edksetup) is run multiple times ]in the same command prompt 
window, the EDK II BaseTools path does not get added more than one time, along 
with other changes to ]the PATH.
]The design allowed for using Edk2Setup once with --nt32 for including visual 
studio tools, then run it a second time without the ]flag and the visual studio 
tools would be cleared from the PATH.
]Cheers,
]Larry

Hello Larry,

Thanks for explaining. I kind of suspected there was a reason based on how the 
code is written.

Thanks,
Scott

-Original Message-
From: Scott Duplichan [mailto:sc...@notabs.org] 
Sent: Friday, October 24, 2014 3:35 PM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] Edk2Setup.bat doesn't inherit %PATH% from calling shell

Bruce Cran [mailto:bruce.c...@gmail.com] wrote:

]It appears that Edk2Setup.bat from the latest code is ignoring the ]%PATH% 
variable from the current shell and resetting it to the ]system-wide setting:
]
]C:\UDK2014>svn
]Type 'svn help' for usage.
]
]C:\UDK2014>Edk2Setup.bat --pull
]
]WARNING : NASM_PREFIX environment variable is not set ]  Attempting to build 
modules that require NASM will fail.
]'svn' is not recognized as an internal or external command, ]operable program 
or batch file.
]ERROR : The command-line svn tool is not available and the Win32 ]binaries do 
not exist
]Python does not appear to be available either. This script
]cannot be used to
]build the Win32 binaries or to obtain them from this repository:
]   https://svn.code.sf.net/p/edk2-toolbinaries/code/trunk/Win32
]
]C:\UDK2014>svn
]'svn' is not recognized as an internal or external command, ]operable program 
or batch file.
]

I bet if you first clear environment variable "ORIGINAL_PATH", the problem will 
disappear:

C:\UDK2014>ORIGINAL_PATH=
C:\UDK2014>Edk2Setup.bat --pull

Probably Edk2Setup.bat was meant to clear ORIGINAL_PATH before exit, but it 
doesn't.
setlocal/endlocal is simpler way of saving/restoring the path, along with all 
the EVs.

Thanks,
Scott

]--
]Bruce



--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [PATCH v3 0/6] OVMF: Adding support for Qemu Q35 machine type

2014-10-27 Thread Gabriel L. Somlo
New in version 3:

  - patches 6 and 7 from earlier v2 now merged into a single PCI/ACPI
initialization patch; PIIX4 initialization of PCI_INTERRUPT_LINE
register re-added (in cleaned up form) as per Paolo's recommendation,
with a "FIXME" comment stating we should look for a way to initialize
present devices programmatically rather than hard-code "typical"
devices we expect to see configured by QEMU

  - cloned edk2 with these patches on top available on github
https://github.com/gsomlo/edk2

Thanks,
  Gabriel

> This series removes hard-coded assumptions about the presence of a PIIX4
> chipset, and dynamically probes for the presence of either PIIX4 or Q35.
> 
> Patches 1-6 are candidates for upstream right now (modulo any feedback,
> of course). Patch 7, however, is just an RFC at this point, and I'm
> hoping there's a standard mechanism already present in edk2 and/or OvmfPkg
> to accomplish what I'm doing there for the general case.
> 
> 
> Patch 1/7 adds macros for probing the host bridge device ID, as well as
>   accessing ACPI power management devices and registers.
> 
> Patch 2/7 uses these macros to initialize ACPI power management during PEI
> 
> Patch 3/7 has PEI write a dynamic PCD containing the detected hostbridge
>   device ID, for use during later stages (e.g. dxe_driver, etc)
> 
> Patch 4/7 splits AcpiTimerLib into three instances: 1. BaseRom, which
>   contains no global variables and queries ACPI pmbase each time it
>   reads the timer tick counter; 2. Base, which stores the timer tick
>   counter address in a global after directly reading the host bridge DID
>   from its constructor; and 3. Dxe, same as Base, but uses PCD written
>   by PEI for host bridge DID.
> 
> Patch 5/7 reads the host bridge type PCD set by PEI to initialize the
>   legacy interrupt device number. NOTE: I have not actually tested this patch.
> 
> Patch 6/7 uses host bridge type PCD to initialize LNK IRQ routing, and
>   cleans up a few stale and non-functional bits of PIIX4 pci device
>   initialization.
> 
> Patch 7/7 is a proof of concept or RFC, and not meant to be applied
>   upstream in its current form. It replicates the side effects of
>   SeaBIOS pci_bios_init_devices() assuming the *default* set of PCI
>   devices included with the QEMU Q35 machine type.
>   I'm looking for ideas and advice on how I could take advantage of
>   OVMF's existing PCI bus enumeration logic, or how/where I could
>   enumerate the PCI bus on my own to essentially port pci_bios_init_devices()
>   from SeaBIOS, which configures the PCI_INTERRUPT_LINE (0x3c) registers
>   based on the contents of each device's PCI_INTERRUPT_PIN (0x3d) register.



Gabriel L. Somlo (6):
  OvmfPkg: Factor out platform detection (q35 vs. piix4)
  OvmfPkg: PlatformPei: Platform specific ACPI power management setup
  OvmfPkg: Add PCD for Host Bridge dev. ID (PcdOvmfHostBridgePciDevId)
  OvmfPkg: AcpiTimerLib: Split into multiple phase-specific instances
  OvmfPkg: CsmSupportLib: Set/use platform specific legacy interrupt
device
  OvmfPkg: PlatformBdsLib: Platform dependent PCI/IRQ initialization

 OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf|   3 +
 OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c|  27 -
 OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h|   6 +-
 OvmfPkg/Include/OvmfPlatforms.h|  49 
 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c| 130 +
 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf  |  44 ---
 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c|  97 +++
 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf  |  37 ++
 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.c | 128 
 .../Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf   |  39 +++
 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c |  98 
 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf   |  40 +++
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c   | 111 ++
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h   |   2 +
 OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf  |   1 +
 OvmfPkg/OvmfPkg.dec|   1 +
 OvmfPkg/OvmfPkgIa32.dsc|  21 ++--
 OvmfPkg/OvmfPkgIa32X64.dsc |  21 ++--
 OvmfPkg/OvmfPkgX64.dsc |  21 ++--
 OvmfPkg/PlatformPei/Platform.c |  43 +--
 OvmfPkg/PlatformPei/PlatformPei.inf|   1 +
 21 files changed, 655 insertions(+), 265 deletions(-)
 create mode 100644 OvmfPkg/Include/OvmfPlatforms.h
 delete mode 100644 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.c
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
 create mode 100

[edk2] [PATCH v3 2/6] OvmfPkg: PlatformPei: Platform specific ACPI power management setup

2014-10-27 Thread Gabriel L. Somlo
Set up ACPI power management using registers determined based on
the underlying (PIIX4 or Q35/MCH) platform type.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/PlatformPei/Platform.c | 42 +++---
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 11b4cb7..fd00ca5 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "Platform.h"
 #include "Cmos.h"
@@ -228,6 +229,11 @@ MiscInitialization (
   VOID
   )
 {
+  UINT16 HostBridgeDevId;
+  UINTN  PMCMD;
+  UINTN  PMBA;
+  UINTN  PMREGMISC;
+
   //
   // Disable A20 Mask
   //
@@ -239,33 +245,47 @@ MiscInitialization (
   BuildCpuHob (36, 16);
 
   //
+  // Query Host Bridge DID to determine platform type
+  //
+  HostBridgeDevId = OVMF_GET_HOSTBRIDGE_DID;
+  switch (HostBridgeDevId) {
+case INTEL_82441_DEVICE_ID:
+  PMCMD = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+  PMBA  = POWER_MGMT_REGISTER_PIIX4 (0x40);
+  PMREGMISC = POWER_MGMT_REGISTER_PIIX4 (0x80);
+  break;
+case INTEL_Q35_MCH_DEVICE_ID:
+  PMCMD = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
+  PMBA  = POWER_MGMT_REGISTER_Q35 (0x40);
+  PMREGMISC = POWER_MGMT_REGISTER_Q35 (0x80);
+  break;
+default:
+  DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+__FUNCTION__, HostBridgeDevId));
+  ASSERT (FALSE);
+  }
+
+  //
   // If PMREGMISC/PMIOSE is set, assume the ACPI PMBA has been configured (for
   // example by Xen) and skip the setup here. This matches the logic in
   // AcpiTimerLibConstructor ().
   //
-  if ((PciRead8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80)) & 0x01) == 0) {
+  if ((PciRead8 (PMREGMISC) & 0x01) == 0) {
 //
 // The PEI phase should be exited with fully accessibe PIIX4 IO space:
 // 1. set PMBA
 //
-PciAndThenOr32 (
-  PCI_LIB_ADDRESS (0, 1, 3, 0x40),
-  (UINT32) ~0xFFC0,
-  PcdGet16 (PcdAcpiPmBaseAddress)
-  );
+PciAndThenOr32 (PMBA, (UINT32) ~0xFFC0, PcdGet16 (PcdAcpiPmBaseAddress));
 
 //
 // 2. set PCICMD/IOSE
 //
-PciOr8 (
-  PCI_LIB_ADDRESS (0, 1, 3, PCI_COMMAND_OFFSET),
-  EFI_PCI_COMMAND_IO_SPACE
-  );
+PciOr8 (PMCMD, EFI_PCI_COMMAND_IO_SPACE);
 
 //
 // 3. set PMREGMISC/PMIOSE
 //
-PciOr8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80), 0x01);
+PciOr8 (PMREGMISC, 0x01);
   }
 }
 
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [PATCH v3 3/6] OvmfPkg: Add PCD for Host Bridge dev. ID (PcdOvmfHostBridgePciDevId)

2014-10-27 Thread Gabriel L. Somlo
Set from PEI, this PCD allows subsequent stages (specifically
DXE_DRIVER and DXE_RUNTIME_DRIVER) to infer the underlying platform
type (e.g. PIIX4 or Q35/MCH) without the need to further query the
Host Bridge for its Device ID.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/OvmfPkg.dec | 1 +
 OvmfPkg/OvmfPkgIa32.dsc | 1 +
 OvmfPkg/OvmfPkgIa32X64.dsc  | 1 +
 OvmfPkg/OvmfPkgX64.dsc  | 1 +
 OvmfPkg/PlatformPei/Platform.c  | 3 ++-
 OvmfPkg/PlatformPei/PlatformPei.inf | 1 +
 6 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index c10948d..623a285 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -93,6 +93,7 @@
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0|UINT16|0x1b
 
 [PcdsFeatureFlag]
   gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 8527ece..8317814 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -330,6 +330,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
 
 
 

diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 823f005..1af12c7 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -336,6 +336,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
 
 
 

diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 40c18de..ea08567 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -335,6 +335,7 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
   gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
 
 
 

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index fd00ca5..d759c5a 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -245,7 +245,7 @@ MiscInitialization (
   BuildCpuHob (36, 16);
 
   //
-  // Query Host Bridge DID to determine platform type
+  // Query Host Bridge DID to determine platform type and save to PCD
   //
   HostBridgeDevId = OVMF_GET_HOSTBRIDGE_DID;
   switch (HostBridgeDevId) {
@@ -264,6 +264,7 @@ MiscInitialization (
 __FUNCTION__, HostBridgeDevId));
   ASSERT (FALSE);
   }
+  PcdSet16 (PcdOvmfHostBridgePciDevId, HostBridgeDevId);
 
   //
   // If PMREGMISC/PMIOSE is set, assume the ACPI PMBA has been configured (for
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index a5fa9b5..0307bca 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -73,6 +73,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [PATCH v3 4/6] OvmfPkg: AcpiTimerLib: Split into multiple phase-specific instances

2014-10-27 Thread Gabriel L. Somlo
Remove local power management register access macros in favor of
factored-out ones in OvmfPkg/Include/OvmfPlatforms.h

Next, AcpiTimerLib is split out into three instances, for use during
various stages:

  - BaseRom: used during SEC, PEI_CORE, and PEIM;
  - Dxe: used during DXE_DRIVER and DXE_RUNTIME_DRIVER;
  - Base:used by default during all other stages.

Most of the code remains in AcpiTimerLib.c, to be shared by all
instances. The two platform-dependent methods (constructor and
InternalAcpiGetTimerTick) are provided separately by source files
specific to each instance, namely [BaseRom|Base|Dxe]AcpiTimerLib.c.

Since pre-DXE stages can't rely on storing data in global variables,
methods specific to the "BaseRom" instance will call platform
detection macros each time they're invoked.

The "Base" instance calls platform detection macros only from its
constructor, and caches the address required by InternalAcpiTimerTick
in a global variable.

The "Dxe" instance is very similar to "Base", except no platform
detection macros are called at all; instead, the platform type is
read via a dynamic PCD set from PlatformPei.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c| 130 +
 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf  |  44 ---
 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c|  97 +++
 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf  |  37 ++
 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.c | 128 
 .../Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf   |  39 +++
 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c |  98 
 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf   |  40 +++
 OvmfPkg/OvmfPkgIa32.dsc|  20 ++--
 OvmfPkg/OvmfPkgIa32X64.dsc |  20 ++--
 OvmfPkg/OvmfPkgX64.dsc |  20 ++--
 11 files changed, 469 insertions(+), 204 deletions(-)
 delete mode 100644 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.c
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c
 create mode 100644 OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf

diff --git a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c 
b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
index 7d324cb..1fb70d7 100644
--- a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
+++ b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -14,112 +14,19 @@
 
 **/
 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
+#include 
 #include 
 
 //
-// PCI Location of PIIX4 Power Management PCI Configuration Registers
-//
-#define PIIX4_POWER_MANAGEMENT_BUS   0x00
-#define PIIX4_POWER_MANAGEMENT_DEVICE0x01
-#define PIIX4_POWER_MANAGEMENT_FUNCTION  0x03
-
-//
-// Macro to access PIIX4 Power Management PCI Configuration Registers
-//
-#define PIIX4_PCI_POWER_MANAGEMENT_REGISTER(Register) \
-  PCI_LIB_ADDRESS (   \
-PIIX4_POWER_MANAGEMENT_BUS,   \
-PIIX4_POWER_MANAGEMENT_DEVICE,\
-PIIX4_POWER_MANAGEMENT_FUNCTION,  \
-Register  \
-)
-
-//
-// PCI Location of Q35 Power Management PCI Configuration Registers
-//
-#define Q35_POWER_MANAGEMENT_BUS   0x00
-#define Q35_POWER_MANAGEMENT_DEVICE0x1f
-#define Q35_POWER_MANAGEMENT_FUNCTION  0x00
-
-//
-// Macro to access Q35 Power Management PCI Configuration Registers
-//
-#define Q35_PCI_POWER_MANAGEMENT_REGISTER(Register) \
-  PCI_LIB_ADDRESS ( \
-Q35_POWER_MANAGEMENT_BUS,   \
-Q35_POWER_MANAGEMENT_DEVICE,\
-Q35_POWER_MANAGEMENT_FUNCTION,  \
-Register\
-)
-
-//
-// PCI Location of Host Bridge PCI Configuration Registers
-//
-#define HOST_BRIDGE_BUS   0x00
-#define HOST_BRIDGE_DEVICE0x00
-#define HOST_BRIDGE_FUNCTION  0x00
-
-//
-// Macro to access Host Bridge Configuration Registers
-//
-#define HOST_BRIDGE_REGISTER(Register) \
-  PCI_LIB_ADDRESS (\
-HOST_BRIDGE_BUS,   \
-HOST_BRIDGE_DEVICE,\
-HOST_BRIDGE_FUNCTION,  \
-Register   \
-)
-
-//
-// Host Bridge Device ID (DID) Register
-//
-#define HOST_BRIDGE_DID  HOST_BRIDGE_REGISTER (0x02)
-
-//
-// Host Bridge DID Register values
-//
-#define PCI_DEVICE_ID_INTEL_824410x1237  // DID value for PIIX4
-#define PCI_DEVICE_ID_INTEL_Q35_MCH  0x29C0  // DID value for Q35
-
-//
-// Access Po

[edk2] [PATCH v3 5/6] OvmfPkg: CsmSupportLib: Set/use platform specific legacy interrupt device

2014-10-27 Thread Gabriel L. Somlo
Use a PCD set from PEI to determine the legacy interrupt device
number appropriate for the underlying platform type during protocol
initialization.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf |  3 +++
 OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c | 27 +--
 OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h |  6 +-
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf 
b/OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
index 34cadb2..1f16646 100644
--- a/OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
+++ b/OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
@@ -38,6 +38,9 @@
   MdePkg/MdePkg.dec
   IntelFrameworkPkg/IntelFrameworkPkg.dec
 
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+
 [Protocols]
   gEfiDevicePathProtocolGuid# PROTOCOL ALWAYS_CONSUMED
   gEfiDiskInfoProtocolGuid  # PROTOCOL ALWAYS_CONSUMED
diff --git a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c 
b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
index cd98417..6ad6e31 100644
--- a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
+++ b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
@@ -21,6 +21,11 @@
 STATIC EFI_HANDLE mLegacyInterruptHandle = NULL;
 
 //
+// Legacy Interrupt Device number (0x01 on piix4, 0x1f on q35/mch)
+//
+STATIC UINT8  mLegacyInterruptDevice;
+
+//
 // The Legacy Interrupt Protocol instance produced by this driver
 //
 STATIC EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt = {
@@ -77,7 +82,7 @@ GetLocation (
   )
 {
   *Bus  = LEGACY_INT_BUS;
-  *Device   = LEGACY_INT_DEV;
+  *Device   = mLegacyInterruptDevice;
   *Function = LEGACY_INT_FUNC;
 
   return EFI_SUCCESS;
@@ -98,7 +103,7 @@ GetAddress (
 {
   return PCI_LIB_ADDRESS(
   LEGACY_INT_BUS,
-  LEGACY_INT_DEV,
+  mLegacyInterruptDevice,
   LEGACY_INT_FUNC,
   PirqReg[PirqNumber]
   );
@@ -173,6 +178,7 @@ LegacyInterruptInstall (
   VOID
   )
 {
+  UINT16  HostBridgeDevId;
   EFI_STATUS  Status;
 
   //
@@ -181,6 +187,23 @@ LegacyInterruptInstall (
   ASSERT_PROTOCOL_ALREADY_INSTALLED(NULL, &gEfiLegacyInterruptProtocolGuid);
 
   //
+  // Query Host Bridge DID to determine platform type, then set device number
+  //
+  HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+  switch (HostBridgeDevId) {
+case INTEL_82441_DEVICE_ID:
+  mLegacyInterruptDevice = LEGACY_INT_DEV_PIIX4;
+  break;
+case INTEL_Q35_MCH_DEVICE_ID:
+  mLegacyInterruptDevice = LEGACY_INT_DEV_Q35;
+  break;
+default:
+  DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+__FUNCTION__, HostBridgeDevId));
+  ASSERT (FALSE);
+  }
+
+  //
   // Make a new handle and install the protocol
   //
   Status = gBS->InstallMultipleProtocolInterfaces (
diff --git a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h 
b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
index 193e48b..eb1f583 100644
--- a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
+++ b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
@@ -20,12 +20,16 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
+#include 
+
 
 #define LEGACY_INT_BUS  0
-#define LEGACY_INT_DEV  1
+#define LEGACY_INT_DEV_PIIX4  0x01
+#define LEGACY_INT_DEV_Q350x1f
 #define LEGACY_INT_FUNC 0
 
 #define PIRQN   0x00  // PIRQ Null
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel


[edk2] [PATCH v3 6/6] OvmfPkg: PlatformBdsLib: Platform dependent PCI/IRQ initialization

2014-10-27 Thread Gabriel L. Somlo
Merge PciInitialization() and AcpiInitialization() into a single
function, PciAcpiInitialization(), and use a PCD set during PEI to
detect the underlying platform type (PIIX4 or Q35/MCH) and therefore
the addresses of the registers to be initialized.

Add LNK[A-H] routing target initialization for the Q35 platform.

Additionally, initialize PCI_INTERRUPT_LINE registers for the typical
set of PCI devices included by QEMU with the Q35 machine type. The
corresponding PIIX4 initialization of PCI_INTERRUPT_LINE registers is
cleaned up and the list of PIIX4 PCI devices updated to the list
typically included with QEMU.

NOTE: The initialization of PCI_INTERRUPT_LINE registers *should*
be accomplished programmatically by enumerating all PCI devices
present in the system and computing PCI_INTERRUPT_LINE from
PCI_INTERRUPT_PIN, the slot/position of the device, and the available
host IRQs (for an example, see SeaBIOS pci_bios_init_devices() in
src/fw/pciinit.c). At the time of this patch, the relevant bits of
OVMF PCI initialization are shown in the following call tree:

  PlatformBdsPolicyBehavior ()
  {
...
ConnectRootBridge ()
{
  ...
  gBS->ConnectController()  // PCI bus is enumerated from this call
  ...
}
...
PlatformBdsConnectSequence ()
{
  ...
  PciAcpiInitialization()   // PCI initialization affected by this patch
  ...
}
...
  }

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c  | 111 +-
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h  |   2 +
 OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf |   1 +
 3 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c 
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index 2a1ca88..02439a3 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -717,63 +717,81 @@ Returns:
 
 
 VOID
-PciInitialization (
+PciAcpiInitialization (
   )
 {
-  //
-  // Bus 0, Device 0, Function 0 - Host to PCI Bridge
-  //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
-
-  //
-  // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
-  //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target
-
-  //
-  // Bus 0, Device 1, Function 1 - IDE Controller
-  //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
+  UINT16 HostBridgeDevId;
+  UINTN  PMBA;
 
   //
-  // Bus 0, Device 1, Function 3 - Power Managment Controller
+  // Query Host Bridge DID to determine platform type
   //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);
-  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA
-
-  //
-  // Bus 0, Device 2, Function 0 - Video Controller
-  //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
+  HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+  switch (HostBridgeDevId) {
+case INTEL_82441_DEVICE_ID:
+  PMBA = POWER_MGMT_REGISTER_PIIX4 (0x40);
+  //
+  // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
+  //
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
+  break;
+case INTEL_Q35_MCH_DEVICE_ID:
+  PMBA = POWER_MGMT_REGISTER_Q35 (0x40);
+  //
+  // 00:1f.0 LPC Bridge (Q35) LNK routing targets
+  //
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
+  break;
+default:
+  DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+__FUNCTION__, HostBridgeDevId));
+  ASSERT (FALSE);
+  }
 
   //
-  // Bus 0, Device 3, Function 0 - Network Controller
+  // Set ACPI SCI_EN bit in PMCNTRL
   //
-  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);
-  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)
+  IoOr16 ((PciRead32 (PMBA) & ~BIT0) + 4, BIT0);
 
   //
-  // Bus 0, Device 5, Function 0 - RAM Memory
+  // Initialize PCI_INTERRUPT_LINE for most commonly encountered dev

[edk2] [PATCH v3 1/6] OvmfPkg: Factor out platform detection (q35 vs. piix4)

2014-10-27 Thread Gabriel L. Somlo
Introduce macros to detect the underlying platform and access its
ACPI power management registers, based on querying the host bridge
device ID.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo 
---
 OvmfPkg/Include/OvmfPlatforms.h | 49 +
 1 file changed, 49 insertions(+)
 create mode 100644 OvmfPkg/Include/OvmfPlatforms.h

diff --git a/OvmfPkg/Include/OvmfPlatforms.h b/OvmfPkg/Include/OvmfPlatforms.h
new file mode 100644
index 000..d9207a0
--- /dev/null
+++ b/OvmfPkg/Include/OvmfPlatforms.h
@@ -0,0 +1,49 @@
+/** @file
+  OVMF Platform (PIIX4 vs. Q35) dependent device access
+
+  Copyright (c) 2014, Gabriel L. Somlo 
+
+  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 __OVMF_PLATFORMS_H__
+#define __OVMF_PLATFORMS_H__
+
+#include 
+#include 
+
+//
+// Read OVMF Host Bridge DID
+//
+#define OVMF_GET_HOSTBRIDGE_DID \
+  PciRead16 (PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET))
+
+//
+// Host Bridge Device ID (DID) values for PIIX4 and Q35/MCH
+//
+#define INTEL_82441_DEVICE_ID 0x1237  // PIIX4
+#define INTEL_Q35_MCH_DEVICE_ID   0x29C0  // Q35
+
+//
+// Power Management Device and Function numbers for PIIX4 and Q35/MCH
+//
+#define OVMF_PM_DEVICE_PIIX4  0x01
+#define OVMF_PM_FUNC_PIIX40x03
+#define OVMF_PM_DEVICE_Q350x1f
+#define OVMF_PM_FUNC_Q35  0x00
+
+//
+// Power Management Register access for PIIX4 and Q35/MCH
+//
+#define POWER_MGMT_REGISTER_PIIX4(Offset) \
+  PCI_LIB_ADDRESS (0, OVMF_PM_DEVICE_PIIX4, OVMF_PM_FUNC_PIIX4, (Offset))
+#define POWER_MGMT_REGISTER_Q35(Offset) \
+  PCI_LIB_ADDRESS (0, OVMF_PM_DEVICE_Q35, OVMF_PM_FUNC_Q35, (Offset))
+
+#endif
-- 
1.9.3


--
___
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel