1 /** @file 2 This file includes a memory call back function notified when MRC is done, 3 following action is performed in this file, 4 1. ICH initialization after MRC. 5 2. SIO initialization. 6 3. Install ResetSystem and FinvFv PPI. 7 4. Set MTRR for PEI 8 5. Create FV HOB and Flash HOB 9 10 Copyright (c) 2013 Intel Corporation. 11 12 This program and the accompanying materials 13 are licensed and made available under the terms and conditions of the BSD License 14 which accompanies this distribution. The full text of the license may be found at 15 http://opensource.org/licenses/bsd-license.php 16 17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 20 **/ 21 22 23 #include "CommonHeader.h" 24 25 #include "PlatformEarlyInit.h" 26 27 extern EFI_PEI_PPI_DESCRIPTOR mPpiStall[]; 28 29 EFI_PEI_RESET_PPI mResetPpi = { ResetSystem }; 30 31 EFI_PEI_PPI_DESCRIPTOR mPpiList[1] = { 32 { 33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 34 &gEfiPeiResetPpiGuid, 35 &mResetPpi 36 } 37 }; 38 39 /** 40 This function reset the entire platform, including all processor and devices, and 41 reboots the system. 42 43 @param PeiServices General purpose services available to every PEIM. 44 45 @retval EFI_SUCCESS if it completed successfully. 46 **/ 47 EFI_STATUS 48 EFIAPI 49 ResetSystem ( 50 IN CONST EFI_PEI_SERVICES **PeiServices 51 ) 52 { 53 ResetCold(); 54 return EFI_SUCCESS; 55 } 56 57 /** 58 This function provides a blocking stall for reset at least the given number of microseconds 59 stipulated in the final argument. 60 61 @param PeiServices General purpose services available to every PEIM. 62 63 @param this Pointer to the local data for the interface. 64 65 @param Microseconds number of microseconds for which to stall. 66 67 @retval EFI_SUCCESS the function provided at least the required stall. 68 **/ 69 EFI_STATUS 70 EFIAPI 71 Stall ( 72 IN CONST EFI_PEI_SERVICES **PeiServices, 73 IN CONST EFI_PEI_STALL_PPI *This, 74 IN UINTN Microseconds 75 ) 76 { 77 MicroSecondDelay (Microseconds); 78 return EFI_SUCCESS; 79 } 80 81 82 /** 83 This function will be called when MRC is done. 84 85 @param PeiServices General purpose services available to every PEIM. 86 87 @param NotifyDescriptor Information about the notify event.. 88 89 @param Ppi The notify context. 90 91 @retval EFI_SUCCESS If the function completed successfully. 92 **/ 93 EFI_STATUS 94 EFIAPI 95 MemoryDiscoveredPpiNotifyCallback ( 96 IN EFI_PEI_SERVICES **PeiServices, 97 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 98 IN VOID *Ppi 99 ) 100 { 101 EFI_STATUS Status; 102 EFI_BOOT_MODE BootMode; 103 UINT64 MemoryLength; 104 EFI_SMRAM_DESCRIPTOR *SmramDescriptor; 105 UINTN NumSmramRegions; 106 UINT32 RmuMainBaseAddress; 107 UINT32 RegData32; 108 UINT8 CpuAddressWidth; 109 UINT32 RegEax; 110 MTRR_SETTINGS MtrrSettings; 111 112 DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n")); 113 114 NumSmramRegions = 0; 115 SmramDescriptor = NULL; 116 RmuMainBaseAddress = 0; 117 118 PERF_START (NULL, "SetCache", NULL, 0); 119 120 InfoPostInstallMemory (&RmuMainBaseAddress, &SmramDescriptor, &NumSmramRegions); 121 ASSERT (SmramDescriptor != NULL); 122 ASSERT (RmuMainBaseAddress != 0); 123 124 MemoryLength = ((UINT64) RmuMainBaseAddress) + 0x10000; 125 126 Status = PeiServicesGetBootMode (&BootMode); 127 ASSERT_EFI_ERROR (Status); 128 129 // 130 // Get current MTRR settings 131 // 132 MtrrGetAllMtrrs (&MtrrSettings); 133 134 // 135 // Set all DRAM cachability to CacheWriteBack 136 // 137 Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0, MemoryLength, CacheWriteBack); 138 ASSERT_EFI_ERROR (Status); 139 140 // 141 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE 142 // Workaround to make default SMRAM UnCachable 143 // 144 Status = MtrrSetMemoryAttributeInMtrrSettings (&MtrrSettings, 0x30000, SIZE_64KB, CacheUncacheable); 145 ASSERT_EFI_ERROR (Status); 146 147 // 148 // Set new MTRR settings 149 // 150 MtrrSetAllMtrrs (&MtrrSettings); 151 152 PERF_END (NULL, "SetCache", NULL, 0); 153 154 // 155 // Install PeiReset for PeiResetSystem service 156 // 157 Status = PeiServicesInstallPpi (&mPpiList[0]); 158 ASSERT_EFI_ERROR (Status); 159 160 // 161 // Do QNC initialization after MRC 162 // 163 PeiQNCPostMemInit (); 164 165 Status = PeiServicesInstallPpi (&mPpiStall[0]); 166 ASSERT_EFI_ERROR (Status); 167 168 // 169 // Set E000/F000 Routing 170 // 171 RegData32 = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC); 172 RegData32 |= (BIT2|BIT1); 173 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, RegData32); 174 175 if (BootMode == BOOT_IN_RECOVERY_MODE) { 176 Status = PeimInitializeRecovery (PeiServices); 177 ASSERT_EFI_ERROR (Status); 178 } else if (BootMode == BOOT_ON_S3_RESUME) { 179 return EFI_SUCCESS; 180 } else { 181 PeiServicesInstallFvInfoPpi ( 182 NULL, 183 (VOID *) (UINTN) PcdGet32 (PcdFlashFvMainBase), 184 PcdGet32 (PcdFlashFvMainSize), 185 NULL, 186 NULL 187 ); 188 189 // 190 // Publish the FVMAIN FV so the DXE Phase can dispatch drivers from this FV 191 // and produce Load File Protocols for UEFI Applications in this FV. 192 // 193 BuildFvHob ( 194 PcdGet32 (PcdFlashFvMainBase), 195 PcdGet32 (PcdFlashFvMainSize) 196 ); 197 198 // 199 // Publish the Payload FV so the DXE Phase can dispatch drivers from this FV 200 // and produce Load File Protocols for UEFI Applications in this FV. 201 // 202 BuildFvHob ( 203 PcdGet32 (PcdFlashFvPayloadBase), 204 PcdGet32 (PcdFlashFvPayloadSize) 205 ); 206 } 207 208 // 209 // Build flash HOB, it's going to be used by GCD and E820 building 210 // Map full SPI flash decode range (regardless of smaller SPI flash parts installed) 211 // 212 BuildResourceDescriptorHob ( 213 EFI_RESOURCE_FIRMWARE_DEVICE, 214 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 215 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 216 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 217 (SIZE_4GB - SIZE_8MB), 218 SIZE_8MB 219 ); 220 221 // 222 // Create a CPU hand-off information 223 // 224 CpuAddressWidth = 32; 225 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); 226 if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) { 227 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL); 228 CpuAddressWidth = (UINT8) (RegEax & 0xFF); 229 } 230 DEBUG ((EFI_D_INFO, "CpuAddressWidth: %d\n", CpuAddressWidth)); 231 232 BuildCpuHob (CpuAddressWidth, 16); 233 234 ASSERT_EFI_ERROR (Status); 235 236 return Status; 237 } 238