]> git.proxmox.com Git - mirror_edk2.git/blobdiff - QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Pei / PlatformInit / MemoryCallback.c
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
new file mode 100644 (file)
index 0000000..728e2b1
--- /dev/null
@@ -0,0 +1,237 @@
+/** @file\r
+This file includes a memory call back function notified when MRC is done,\r
+following action is performed in this file,\r
+  1. ICH initialization after MRC.\r
+  2. SIO initialization.\r
+  3. Install ResetSystem and FinvFv PPI.\r
+  4. Set MTRR for PEI\r
+  5. Create FV HOB and Flash HOB\r
+\r
+Copyright (c) 2013 Intel Corporation.\r
+\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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include "CommonHeader.h"\r
+\r
+#include "PlatformEarlyInit.h"\r
+\r
+extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[];\r
+\r
+EFI_PEI_RESET_PPI mResetPpi = { ResetSystem };\r
+\r
+EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = {\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiResetPpiGuid,\r
+    &mResetPpi\r
+  }\r
+};\r
+\r
+/**\r
+  This function reset the entire platform, including all processor and devices, and\r
+  reboots the system.\r
+\r
+  @param  PeiServices General purpose services available to every PEIM.\r
+\r
+  @retval EFI_SUCCESS if it completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ResetSystem (\r
+  IN CONST EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+{\r
+  ResetCold();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function provides a blocking stall for reset at least the given number of microseconds\r
+  stipulated in the final argument.\r
+\r
+  @param  PeiServices General purpose services available to every PEIM.\r
+\r
+  @param  this Pointer to the local data for the interface.\r
+\r
+  @param  Microseconds number of microseconds for which to stall.\r
+\r
+  @retval EFI_SUCCESS the function provided at least the required stall.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Stall (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN CONST EFI_PEI_STALL_PPI  *This,\r
+  IN UINTN                    Microseconds\r
+  )\r
+{\r
+  MicroSecondDelay (Microseconds);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This function will be called when MRC is done.\r
+\r
+  @param  PeiServices General purpose services available to every PEIM.\r
+\r
+  @param  NotifyDescriptor Information about the notify event..\r
+\r
+  @param  Ppi The notify context.\r
+\r
+  @retval EFI_SUCCESS If the function completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MemoryDiscoveredPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_BOOT_MODE                         BootMode;\r
+  UINT64                                MemoryLength;\r
+  EFI_SMRAM_DESCRIPTOR                  *SmramDescriptor;\r
+  UINTN                                 NumSmramRegions;\r
+  UINT32                                RmuMainBaseAddress;\r
+  UINT32                                RegData32;\r
+  UINT8                                 CpuAddressWidth;\r
+  UINT32                                RegEax;\r
+  MTRR_SETTINGS                         MtrrSettings;\r
+\r
+  DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));\r
+\r
+  NumSmramRegions = 0;\r
+  SmramDescriptor = NULL;\r
+  RmuMainBaseAddress = 0;\r
+\r
+  PERF_START (NULL, "SetCache", NULL, 0);\r
+\r
+  InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions);\r
+  ASSERT (SmramDescriptor != NULL);\r
+  ASSERT (RmuMainBaseAddress != 0);\r
+\r
+  MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000;\r
+\r
+  Status = PeiServicesGetBootMode (&BootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Get current MTRR settings\r
+  //\r
+  MtrrGetAllMtrrs (&MtrrSettings);\r
+\r
+  //\r
+  // Set all DRAM cachability to CacheWriteBack\r
+  //\r
+  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE\r
+  //             Workaround to make default SMRAM UnCachable\r
+  //\r
+  Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Set new MTRR settings\r
+  //\r
+  MtrrSetAllMtrrs (&MtrrSettings);\r
+\r
+  PERF_END (NULL, "SetCache", NULL, 0);\r
+\r
+  //\r
+  // Install PeiReset for PeiResetSystem service\r
+  //\r
+  Status = PeiServicesInstallPpi (&mPpiList[0]);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Do QNC initialization after MRC\r
+  //\r
+  PeiQNCPostMemInit ();\r
+\r
+  Status = PeiServicesInstallPpi (&mPpiStall[0]);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Set E000/F000 Routing\r
+  //\r
+  RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);\r
+  RegData32 |= (BIT2|BIT1);\r
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32);\r
+\r
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
+    Status = PeimInitializeRecovery (PeiServices);\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else if (BootMode == BOOT_ON_S3_RESUME) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    PeiServicesInstallFvInfoPpi (\r
+      NULL,\r
+      (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase),\r
+      PcdGet32 (PcdFlashFvMainSize),\r
+      NULL,\r
+      NULL\r
+      );\r
+\r
+    //\r
+    // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV\r
+    // and produce Load File Protocols for UEFI Applications in this FV.\r
+    //\r
+    BuildFvHob (\r
+      PcdGet32 (PcdFlashFvMainBase),\r
+      PcdGet32 (PcdFlashFvMainSize)\r
+      );\r
+\r
+    //\r
+    // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV\r
+    // and produce Load File Protocols for UEFI Applications in this FV.\r
+    //\r
+    BuildFvHob (\r
+      PcdGet32 (PcdFlashFvPayloadBase),\r
+      PcdGet32 (PcdFlashFvPayloadSize)\r
+      );\r
+  }\r
+\r
+  //\r
+  // Build flash HOB, it's going to be used by GCD and E820 building\r
+  // Map full SPI flash decode range (regardless of smaller SPI flash parts installed)\r
+  //\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_FIRMWARE_DEVICE,\r
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |\r
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+    (SIZE_4GB - SIZE_8MB),\r
+    SIZE_8MB\r
+    );\r
+\r
+  //\r
+  // Create a CPU hand-off information\r
+  //\r
+  CpuAddressWidth = 32;\r
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
+  if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
+    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);\r
+    CpuAddressWidth = (UINT8) (RegEax & 0xFF);\r
+  }\r
+  DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth));\r
+\r
+  BuildCpuHob (CpuAddressWidth, 16);\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r