UefiCpuPkg/CpuMpPei: Find available memory < 1MB for AP reset code
authorJeff Fan <jeff.fan@intel.com>
Wed, 15 Jul 2015 03:29:40 +0000 (03:29 +0000)
committervanjeff <vanjeff@Edk2>
Wed, 15 Jul 2015 03:29:40 +0000 (03:29 +0000)
Search memory resource HOB list to find one available system memory under 1MB
for AP reset code and exchange information between BSP and APs.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17989 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/CpuMpPei/CpuMpPei.c
UefiCpuPkg/CpuMpPei/CpuMpPei.h
UefiCpuPkg/CpuMpPei/CpuMpPei.inf

index 78299b3271d48698bb912c031f3ba4d93b60480a..0e34f26afc2e6d434c02ebbdf6a618b742eb2589 100644 (file)
@@ -38,6 +38,77 @@ GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {
   (UINTN) mGdtEntries
   };
 
+/**
+  Get available system memory below 1MB by specified size.
+
+  @param  WakeupBufferSize   Wakeup buffer size required
+
+  @retval other   Return wakeup buffer address below 1MB.
+  @retval -1      Cannot find free memory below 1MB.
+**/
+UINTN
+GetWakeupBuffer (
+  IN UINTN                WakeupBufferSize
+  )
+{
+  EFI_PEI_HOB_POINTERS    Hob;
+  UINTN                   WakeupBufferStart;
+  UINTN                   WakeupBufferEnd;
+
+  //
+  // Get the HOB list for processing
+  //
+  Hob.Raw = GetHobList ();
+
+  //
+  // Collect memory ranges
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+      if ((Hob.ResourceDescriptor->PhysicalStart < BASE_1MB) &&
+          (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+          ((Hob.ResourceDescriptor->ResourceAttribute &
+            (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
+             EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
+             EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED
+             )) == 0)
+           ) {
+        //
+        // Need memory under 1MB to be collected here
+        //
+        WakeupBufferEnd = (UINTN) (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength);
+        if (WakeupBufferEnd > BASE_1MB) {
+          //
+          // Wakeup buffer should be under 1MB
+          //
+          WakeupBufferEnd = BASE_1MB;
+        }
+        //
+        // Wakeup buffer should be aligned on 4KB
+        //
+        WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1);
+        if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {
+          continue;
+        }
+        //
+        // Create a memory allocation HOB.
+        //
+        BuildMemoryAllocationHob (
+          WakeupBufferStart,
+          WakeupBufferSize,
+          EfiBootServicesData
+          );
+        return WakeupBufferStart;
+      }
+    }
+    //
+    // Find the next HOB
+    //
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  return (UINTN) -1;
+}
 
 /**
   The Entry point of the MP CPU PEIM.
index 611a296dce6d7e7102e3e80c0fd692d9435ce997..da01fdac87a8347fd6a7851c368fdd0ef175cfbd 100644 (file)
@@ -19,6 +19,7 @@
 
 
 #include <Library/BaseLib.h>
+#include <Library/HobLib.h>
 #include <Library/PeimEntryPoint.h>
 
 #pragma pack(1)
index 1dfee4eac8603ba5dfd2ccc82a8805671879923c..7cf33d32496483d1f3a27ea03e3e973b73195214 100644 (file)
@@ -49,6 +49,7 @@
 
 [LibraryClasses]
   BaseLib
+  HobLib
   PeimEntryPoint