--- /dev/null
+/** @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