]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2Pkg/FspSecCore/SecMain.c
IntelFsp2Pkg: FSP can utilize bootloader stack
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / SecMain.c
index 5a43ba1967143e2fc8849424bf8af32deaef1eff..c7caa3e7f927d23fb0284eaad0c2c6a501d30e75 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-  Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -19,6 +19,11 @@ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
 };\r
 \r
 EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gFspInApiModePpiGuid,\r
+    NULL\r
+  },\r
   {\r
     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
     &gEfiTemporaryRamSupportPpiGuid,\r
@@ -65,6 +70,7 @@ SecStartup (
   UINT32                      Index;\r
   FSP_GLOBAL_DATA             PeiFspData;\r
   UINT64                      ExceptionHandler;\r
+  UINTN                       IdtSize;\r
 \r
   //\r
   // Process all libraries constructor function linked to SecCore.\r
@@ -77,7 +83,29 @@ SecStartup (
   //\r
   InitializeFloatingPointUnits ();\r
 \r
+  //\r
+  // Scenario 1 memory map when running on bootloader stack\r
+  //\r
+  // |-------------------|---->\r
+  // |Idt Table          |\r
+  // |-------------------|\r
+  // |PeiService Pointer |\r
+  // |-------------------|\r
+  // |                   |\r
+  // |                   |\r
+  // |      Heap         |\r
+  // |                   |\r
+  // |                   |\r
+  // |-------------------|---->  TempRamBase\r
+  //\r
+  //\r
+  // |-------------------|\r
+  // |Bootloader stack   |----> somewhere in memory, FSP will share this stack.\r
+  // |-------------------|\r
 \r
+  //\r
+  // Scenario 2 memory map when running FSP on a separate stack\r
+  //\r
   // |-------------------|---->\r
   // |Idt Table          |\r
   // |-------------------|\r
@@ -93,13 +121,26 @@ SecStartup (
   // |                   |\r
   // |-------------------|---->  TempRamBase\r
   IdtTableInStack.PeiService  = NULL;\r
-  ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);\r
-  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {\r
-    CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  if (IdtDescriptor.Base == 0) {\r
+    ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);\r
+    for (Index = 0; Index < FixedPcdGet8(PcdFspMaxInterruptSupported); Index ++) {\r
+      CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));\r
+    }\r
+    IdtSize = sizeof (IdtTableInStack.IdtTable);\r
+  } else {\r
+    IdtSize = IdtDescriptor.Limit + 1;\r
+    if (IdtSize > sizeof (IdtTableInStack.IdtTable)) {\r
+      //\r
+      // ERROR: IDT table size from boot loader is larger than FSP can support, DeadLoop here!\r
+      //\r
+      CpuDeadLoop();\r
+    } else {\r
+      CopyMem ((VOID *) (UINTN) &IdtTableInStack.IdtTable, (VOID *) IdtDescriptor.Base, IdtSize);\r
+    }\r
   }\r
-\r
   IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;\r
-  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
+  IdtDescriptor.Limit = (UINT16)(IdtSize - 1);\r
 \r
   AsmWriteIdtr (&IdtDescriptor);\r
 \r
@@ -116,11 +157,19 @@ SecStartup (
   SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;\r
 \r
   SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;\r
-  SecCoreData.TemporaryRamSize       = SizeOfRam;\r
-  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
-  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;\r
-  SecCoreData.StackBase              = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);\r
-  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;\r
+  if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {\r
+    SecCoreData.TemporaryRamSize       = SizeOfRam; // stack size that is going to be copied to the permanent memory\r
+    SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
+    SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize;\r
+    SecCoreData.StackBase              = (VOID *)GetFspEntryStack(); // Share the same boot loader stack\r
+    SecCoreData.StackSize              = 0;\r
+  } else {\r
+    SecCoreData.TemporaryRamSize       = SizeOfRam;\r
+    SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
+    SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;\r
+    SecCoreData.StackBase              = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);\r
+    SecCoreData.StackSize              = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;\r
+  }\r
 \r
   DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));\r
   DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));\r
@@ -175,15 +224,37 @@ SecTemporaryRamSupport (
   UINTN             HeapSize;\r
   UINTN             StackSize;\r
 \r
-  HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;\r
-  StackSize  = CopySize - HeapSize;\r
+  UINTN             CurrentStack;\r
+  UINTN             FspStackBase;\r
 \r
-  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
-  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);\r
+  if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {\r
 \r
-  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);\r
-  NewStack = (VOID*)(UINTN)PermanentMemoryBase;\r
+    CurrentStack = AsmReadEsp();\r
+    FspStackBase = (UINTN)GetFspEntryStack();\r
 \r
+    StackSize = FspStackBase - CurrentStack;\r
+    HeapSize  = CopySize;\r
+\r
+    OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
+    NewHeap = (VOID*)((UINTN)PermanentMemoryBase);\r
+\r
+    OldStack = (VOID*)CurrentStack;\r
+    //\r
+    //The old stack is copied at the end of the stack region because stack grows down.\r
+    //\r
+    NewStack = (VOID*)((UINTN)PermanentMemoryBase - StackSize);\r
+\r
+  } else {\r
+    HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;\r
+    StackSize  = CopySize - HeapSize;\r
+\r
+    OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
+    NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);\r
+\r
+    OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);\r
+    NewStack = (VOID*)(UINTN)PermanentMemoryBase;\r
+\r
+  }\r
   //\r
   // Migrate Heap\r
   //\r