]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/SecCore/SecMain.c
StandaloneMmPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / SecCore / SecMain.c
index 077d0db49f53ecdd7536617cc49abc4fe6ac6238..14696c81a5486cee036153e176483416995e6043 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   C functions in SEC\r
 \r
-  Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 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
@@ -21,6 +21,14 @@ EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = {
 EFI_SEC_PLATFORM_INFORMATION_PPI  mSecPlatformInformationPpi = { SecPlatformInformation };\r
 \r
 EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {\r
+  {\r
+    //\r
+    // SecPerformance PPI notify descriptor.\r
+    //\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    &gPeiSecPerformancePpiGuid,\r
+    (VOID *) (UINTN) SecPerformancePpiCallBack\r
+  },\r
   {\r
     EFI_PEI_PPI_DESCRIPTOR_PPI,\r
     &gEfiTemporaryRamDonePpiGuid,\r
@@ -55,6 +63,44 @@ SecStartupPhase2(
   IN VOID                     *Context\r
   );\r
 \r
+/**\r
+  Entry point of the notification callback function itself within the PEIM.\r
+  It is to get SEC performance data and build HOB to convey the SEC performance\r
+  data to DXE phase.\r
+\r
+  @param  PeiServices      Indirect reference to the PEI Services Table.\r
+  @param  NotifyDescriptor Address of the notification descriptor data structure.\r
+  @param  Ppi              Address of the PPI that was installed.\r
+\r
+  @return Status of the notification.\r
+          The status code returned from this function is ignored.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SecPerformancePpiCallBack (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  PEI_SEC_PERFORMANCE_PPI       *SecPerf;\r
+  FIRMWARE_SEC_PERFORMANCE      Performance;\r
+\r
+  SecPerf = (PEI_SEC_PERFORMANCE_PPI *) Ppi;\r
+  Status = SecPerf->GetPerformance ((CONST EFI_PEI_SERVICES **) PeiServices, SecPerf, &Performance);\r
+  if (!EFI_ERROR (Status)) {\r
+    BuildGuidDataHob (\r
+      &gEfiFirmwarePerformanceGuid,\r
+      &Performance,\r
+      sizeof (FIRMWARE_SEC_PERFORMANCE)\r
+    );\r
+    DEBUG ((DEBUG_INFO, "FPDT: SEC Performance Hob ResetEnd = %ld\n", Performance.ResetEnd));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
 \r
   Entry point to the C language phase of SEC. After the SEC assembly\r
@@ -67,6 +113,7 @@ SecStartupPhase2(
   @param BootFirmwareVolume  Base address of the Boot Firmware Volume.\r
 **/\r
 VOID\r
+NORETURN\r
 EFIAPI\r
 SecStartup (\r
   IN UINT32                   SizeOfRam,\r
@@ -143,7 +190,7 @@ SecStartup (
   //\r
   SecCoreData.DataSize               = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);\r
   SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
-  SecCoreData.BootFirmwareVolumeSize = (UINTN)(0x100000000ULL - (UINTN) BootFirmwareVolume);\r
+  SecCoreData.BootFirmwareVolumeSize = (UINTN)((EFI_FIRMWARE_VOLUME_HEADER *) BootFirmwareVolume)->FvLength;\r
   SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;\r
   SecCoreData.TemporaryRamSize       = SizeOfRam;\r
   SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;\r
@@ -155,6 +202,11 @@ SecStartup (
   // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
   //\r
   InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
+\r
+  //\r
+  // Should not come here.\r
+  //\r
+  UNREACHABLE ();\r
 }\r
 \r
 /**\r
@@ -180,22 +232,61 @@ SecStartupPhase2(
   EFI_PEI_PPI_DESCRIPTOR      *AllSecPpiList;\r
   EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;\r
 \r
+  PeiCoreEntryPoint = NULL;\r
   SecCoreData   = (EFI_SEC_PEI_HAND_OFF *) Context;\r
   AllSecPpiList = (EFI_PEI_PPI_DESCRIPTOR *) SecCoreData->PeiTemporaryRamBase;\r
+\r
+  //\r
+  // Perform platform specific initialization before entering PeiCore.\r
+  //\r
+  PpiList = SecPlatformMain (SecCoreData);\r
   //\r
   // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug\r
   // is enabled.\r
   //\r
-  FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);\r
-  if (PeiCoreEntryPoint == NULL)\r
-  {\r
-    CpuDeadLoop ();\r
+  if (PpiList != NULL) {\r
+    for (Index = 0;\r
+      (PpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+      Index++) {\r
+      if (CompareGuid (PpiList[Index].Guid, &gEfiPeiCoreFvLocationPpiGuid) &&\r
+          (((EFI_PEI_CORE_FV_LOCATION_PPI *) PpiList[Index].Ppi)->PeiCoreFvLocation != 0)\r
+         ) {\r
+        //\r
+        // In this case, SecCore is in BFV but PeiCore is in another FV reported by PPI.\r
+        //\r
+        FindAndReportEntryPoints (\r
+          (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase,\r
+          (EFI_FIRMWARE_VOLUME_HEADER *) ((EFI_PEI_CORE_FV_LOCATION_PPI *) PpiList[Index].Ppi)->PeiCoreFvLocation,\r
+          &PeiCoreEntryPoint\r
+          );\r
+        if (PeiCoreEntryPoint != NULL) {\r
+          break;\r
+        } else {\r
+          //\r
+          // PeiCore not found\r
+          //\r
+          CpuDeadLoop ();\r
+        }\r
+      }\r
+    }\r
   }\r
-\r
   //\r
-  // Perform platform specific initialization before entering PeiCore.\r
+  // If EFI_PEI_CORE_FV_LOCATION_PPI not found, try to locate PeiCore from BFV.\r
   //\r
-  PpiList = SecPlatformMain (SecCoreData);\r
+  if (PeiCoreEntryPoint == NULL) {\r
+    //\r
+    // Both SecCore and PeiCore are in BFV.\r
+    //\r
+    FindAndReportEntryPoints (\r
+      (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase,\r
+      (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase,\r
+      &PeiCoreEntryPoint\r
+      );\r
+    if (PeiCoreEntryPoint == NULL) {\r
+      CpuDeadLoop ();\r
+    }\r
+  }\r
+\r
   if (PpiList != NULL) {\r
     //\r
     // Remove the terminal flag from the terminal PPI\r
@@ -230,6 +321,12 @@ SecStartupPhase2(
     ASSERT (SecCoreData->PeiTemporaryRamSize > Index * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
     SecCoreData->PeiTemporaryRamBase = (VOID *)((UINTN) SecCoreData->PeiTemporaryRamBase + Index * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
     SecCoreData->PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize - Index * sizeof (EFI_PEI_PPI_DESCRIPTOR);\r
+    //\r
+    // Adjust the Base and Size to be 8-byte aligned as HOB which has 8byte aligned requirement\r
+    // will be built based on them in PEI phase.\r
+    //\r
+    SecCoreData->PeiTemporaryRamBase = (VOID *)(((UINTN)SecCoreData->PeiTemporaryRamBase + 7) & ~0x07);\r
+    SecCoreData->PeiTemporaryRamSize &= ~(UINTN)0x07;\r
   } else {\r
     //\r
     // No addition PPI, PpiList directly point to the common PPI list.\r