1 /** @file 2 3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials are licensed and made available under 7 the terms and conditions of the BSD License that accompanies this distribution. 9 The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php. 13 15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 21 23 Module Name: 24 25 MemoryCallback.c 26 27 Abstract: 28 29 EFI 2.0 PEIM to provide the platform support functionality on the Bridgeport. 30 31 --*/ 32 33 #include "PlatformEarlyInit.h" 34 35 36 VOID 37 UpdateDefaultSetupValue ( 38 IN EFI_PLATFORM_INFO_HOB *PlatformInfo 39 ) 40 { 41 return; 42 } 43 44 /** 45 PEI termination callback. 46 47 @param PeiServices General purpose services available to every PEIM. 48 @param NotifyDescriptor Not uesed. 49 @param Ppi Not uesed. 50 51 @retval EFI_SUCCESS If the interface could be successfully 52 installed. 53 54 **/ 55 EFI_STATUS 56 EFIAPI 57 EndOfPeiPpiNotifyCallback ( 58 IN CONST EFI_PEI_SERVICES **PeiServices, 59 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 60 IN VOID *Ppi 61 ) 62 { 63 EFI_STATUS Status; 64 UINT64 LowUncableBase; 65 EFI_PLATFORM_INFO_HOB *PlatformInfo; 66 UINT32 HecBaseHigh; 67 EFI_BOOT_MODE BootMode; 68 EFI_PEI_HOB_POINTERS Hob; 69 70 Status = (*PeiServices)->GetBootMode( 71 PeiServices, 72 &BootMode 73 ); 74 75 ASSERT_EFI_ERROR (Status); 76 77 // 78 // Set the some PCI and chipset range as UC 79 // And align to 1M at leaset 80 // 81 Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid); 82 ASSERT (Hob.Raw != NULL); 83 PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw); 84 85 UpdateDefaultSetupValue (PlatformInfo); 86 87 DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm)); 88 DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase)); 89 DEBUG ( 90 (EFI_D_ERROR, 91 "PCIE BASE: %lX Size : %X\n", 92 PlatformInfo->PciData.PciExpressBase, 93 PlatformInfo->PciData.PciExpressSize) 94 ); 95 DEBUG ( 96 (EFI_D_ERROR, 97 "PCI32 BASE: %X Limit: %X\n", 98 PlatformInfo->PciData.PciResourceMem32Base, 99 PlatformInfo->PciData.PciResourceMem32Limit) 100 ); 101 DEBUG ( 102 (EFI_D_ERROR, 103 "PCI64 BASE: %lX Limit: %lX\n", 104 PlatformInfo->PciData.PciResourceMem64Base, 105 PlatformInfo->PciData.PciResourceMem64Limit) 106 ); 107 DEBUG ((EFI_D_ERROR, "UC START: %lX End : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1)); 108 109 LowUncableBase = PlatformInfo->MemData.MemMaxTolm; 110 LowUncableBase &= (0x0FFF00000); 111 112 if (BootMode != BOOT_ON_S3_RESUME) { 113 // 114 // In BIOS, HECBASE will be always below 4GB 115 // 116 HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28); 117 ASSERT (HecBaseHigh < 16); 118 } 119 120 return Status; 121 } 122 123 /** 124 Install Firmware Volume Hob's once there is main memory 125 126 @param PeiServices General purpose services available to every PEIM. 127 @param NotifyDescriptor Notify that this module published. 128 @param Ppi PPI that was installed. 129 130 @retval EFI_SUCCESS The function completed successfully. 131 132 **/ 133 EFI_STATUS 134 EFIAPI 135 MemoryDiscoveredPpiNotifyCallback ( 136 IN CONST EFI_PEI_SERVICES **PeiServices, 137 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 138 IN VOID *Ppi 139 ) 140 { 141 EFI_STATUS Status; 142 EFI_BOOT_MODE BootMode; 143 EFI_CPUID_REGISTER FeatureInfo; 144 UINT8 CpuAddressWidth; 145 UINT16 Pm1Cnt; 146 EFI_PEI_HOB_POINTERS Hob; 147 EFI_PLATFORM_INFO_HOB *PlatformInfo; 148 UINT32 RootComplexBar; 149 UINT32 PmcBase; 150 UINT32 IoBase; 151 UINT32 IlbBase; 152 UINT32 SpiBase; 153 UINT32 MphyBase; 154 155 // 156 // Get Platform Info HOB 157 // 158 Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid); 159 ASSERT (Hob.Raw != NULL); 160 PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw); 161 162 Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); 163 164 // 165 // Check if user wants to turn off in PEI phase 166 // 167 if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) { 168 CheckPowerOffNow(); 169 } else { 170 Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT); 171 Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP; 172 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt); 173 } 174 175 #ifndef MINNOW2_FSP_BUILD 176 // 177 // Set PEI cache mode here 178 // 179 SetPeiCacheMode (PeiServices); 180 #endif 181 182 // 183 // Pulish memory tyoe info 184 // 185 PublishMemoryTypeInfo (); 186 187 // 188 // Work done if on a S3 resume 189 // 190 if (BootMode == BOOT_ON_S3_RESUME) { 191 // 192 //Program the side band packet register to send a sideband message to Punit 193 //To indicate that DRAM has been initialized and PUNIT FW base address in memory. 194 // 195 return EFI_SUCCESS; 196 } 197 198 RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) & B_PCH_LPC_RCBA_BAR; 199 BuildResourceDescriptorHob ( 200 EFI_RESOURCE_MEMORY_MAPPED_IO, 201 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 202 RootComplexBar, 203 0x1000 204 ); 205 DEBUG ((EFI_D_INFO, "RootComplexBar : 0x%x\n", RootComplexBar)); 206 207 PmcBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE ) & B_PCH_LPC_PMC_BASE_BAR; 208 BuildResourceDescriptorHob ( 209 EFI_RESOURCE_MEMORY_MAPPED_IO, 210 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 211 PmcBase, 212 0x1000 213 ); 214 DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PmcBase)); 215 216 IoBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE ) & B_PCH_LPC_IO_BASE_BAR; 217 BuildResourceDescriptorHob ( 218 EFI_RESOURCE_MEMORY_MAPPED_IO, 219 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 220 IoBase, 221 0x4000 222 ); 223 DEBUG ((EFI_D_INFO, "IoBase : 0x%x\n", IoBase)); 224 225 IlbBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE ) & B_PCH_LPC_ILB_BASE_BAR; 226 BuildResourceDescriptorHob ( 227 EFI_RESOURCE_MEMORY_MAPPED_IO, 228 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 229 IlbBase, 230 0x1000 231 ); 232 DEBUG ((EFI_D_INFO, "IlbBase : 0x%x\n", IlbBase)); 233 234 SpiBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE ) & B_PCH_LPC_SPI_BASE_BAR; 235 BuildResourceDescriptorHob ( 236 EFI_RESOURCE_MEMORY_MAPPED_IO, 237 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 238 SpiBase, 239 0x1000 240 ); 241 DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SpiBase)); 242 243 MphyBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE ) & B_PCH_LPC_MPHY_BASE_BAR; 244 BuildResourceDescriptorHob ( 245 EFI_RESOURCE_MEMORY_MAPPED_IO, 246 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 247 MphyBase, 248 0x100000 249 ); 250 DEBUG ((EFI_D_INFO, "MphyBase : 0x%x\n", MphyBase)); 251 252 // 253 // Local APIC 254 // 255 BuildResourceDescriptorHob ( 256 EFI_RESOURCE_MEMORY_MAPPED_IO, 257 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 258 LOCAL_APIC_ADDRESS, 259 0x1000 260 ); 261 DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS)); 262 263 // 264 // IO APIC 265 // 266 BuildResourceDescriptorHob ( 267 EFI_RESOURCE_MEMORY_MAPPED_IO, 268 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 269 IO_APIC_ADDRESS, 270 0x1000 271 ); 272 DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_ADDRESS)); 273 274 // 275 // Adding the PCIE Express area to the E820 memory table as type 2 memory. 276 // 277 BuildResourceDescriptorHob ( 278 EFI_RESOURCE_MEMORY_MAPPED_IO, 279 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 280 PlatformInfo->PciData.PciExpressBase, 281 PlatformInfo->PciData.PciExpressSize 282 ); 283 DEBUG ((EFI_D_INFO, "PciExpressBase : 0x%x\n", PlatformInfo->PciData.PciExpressBase)); 284 285 // 286 // Adding the Flashpart to the E820 memory table as type 2 memory. 287 // 288 BuildResourceDescriptorHob ( 289 EFI_RESOURCE_FIRMWARE_DEVICE, 290 (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), 291 FixedPcdGet32 (PcdFlashAreaBaseAddress), 292 FixedPcdGet32 (PcdFlashAreaSize) 293 ); 294 DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32 (PcdFlashAreaBaseAddress))); 295 296 // 297 // Create a CPU hand-off information 298 // 299 CpuAddressWidth = 32; 300 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); 301 if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) { 302 AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); 303 CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF); 304 } 305 306 BuildCpuHob(CpuAddressWidth, 16); 307 ASSERT_EFI_ERROR (Status); 308 309 return Status; 310 311 } 312 313 314 EFI_STATUS 315 ValidateFvHeader ( 316 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader 317 ) 318 { 319 UINT16 *Ptr; 320 UINT16 HeaderLength; 321 UINT16 Checksum; 322 323 // 324 // Verify the header revision, header signature, length 325 // Length of FvBlock cannot be 2**64-1 326 // HeaderLength cannot be an odd number 327 // 328 if ((FwVolHeader->Revision != EFI_FVH_REVISION) || 329 (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || 330 (FwVolHeader->FvLength == ((UINT64) -1)) || 331 ((FwVolHeader->HeaderLength & 0x01) != 0) 332 ) { 333 return EFI_NOT_FOUND; 334 } 335 336 // 337 // Verify the header checksum 338 // 339 HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2); 340 Ptr = (UINT16 *) FwVolHeader; 341 Checksum = 0; 342 while (HeaderLength > 0) { 343 Checksum = *Ptr++; 344 HeaderLength--; 345 } 346 347 if (Checksum != 0) { 348 return EFI_NOT_FOUND; 349 } 350 351 return EFI_SUCCESS; 352 } 353