--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ \r\r
+ This program and the accompanying materials are licensed and made available under\r\r
+ the terms and conditions of the BSD License that accompanies this distribution. \r\r
+ The full text of the license may be found at \r\r
+ http://opensource.org/licenses/bsd-license.php. \r\r
+ \r\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r
+ \r\r
+\r
+Module Name:\r
+\r
+ MemoryCallback.c\r
+\r
+Abstract:\r
+\r
+ EFI 2.0 PEIM to provide the platform support functionality on the Bridgeport.\r
+\r
+--*/\r
+\r
+#include "PlatformEarlyInit.h"\r
+\r
+\r
+VOID\r
+UpdateDefaultSetupValue (\r
+ IN EFI_PLATFORM_INFO_HOB *PlatformInfo\r
+ )\r
+{\r
+return;\r
+}\r
+\r
+/**\r
+ PEI termination callback.\r
+\r
+ @param PeiServices General purpose services available to every PEIM.\r
+ @param NotifyDescriptor Not uesed.\r
+ @param Ppi Not uesed.\r
+\r
+ @retval EFI_SUCCESS If the interface could be successfully\r
+ installed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+EndOfPeiPpiNotifyCallback (\r
+ IN CONST EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 MemoryTop;\r
+ UINT64 LowUncableBase;\r
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;\r
+ UINT32 HecBaseHigh;\r
+ EFI_BOOT_MODE BootMode;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+\r
+ Status = (*PeiServices)->GetBootMode(\r
+ PeiServices,\r
+ &BootMode\r
+ );\r
+\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Set the some PCI and chipset range as UC\r
+ // And align to 1M at leaset\r
+ //\r
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);\r
+ ASSERT (Hob.Raw != NULL);\r
+ PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);\r
+\r
+ UpdateDefaultSetupValue (PlatformInfo);\r
+\r
+ DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm));\r
+ DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase));\r
+ DEBUG (\r
+ (EFI_D_ERROR,\r
+ "PCIE BASE: %lX Size : %X\n",\r
+ PlatformInfo->PciData.PciExpressBase,\r
+ PlatformInfo->PciData.PciExpressSize)\r
+ );\r
+ DEBUG (\r
+ (EFI_D_ERROR,\r
+ "PCI32 BASE: %X Limit: %X\n",\r
+ PlatformInfo->PciData.PciResourceMem32Base,\r
+ PlatformInfo->PciData.PciResourceMem32Limit)\r
+ );\r
+ DEBUG (\r
+ (EFI_D_ERROR,\r
+ "PCI64 BASE: %lX Limit: %lX\n",\r
+ PlatformInfo->PciData.PciResourceMem64Base,\r
+ PlatformInfo->PciData.PciResourceMem64Limit)\r
+ );\r
+ DEBUG ((EFI_D_ERROR, "UC START: %lX End : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1));\r
+\r
+ LowUncableBase = PlatformInfo->MemData.MemMaxTolm;\r
+ LowUncableBase &= (0x0FFF00000);\r
+ MemoryTop = (0x100000000);\r
+\r
+ if (BootMode != BOOT_ON_S3_RESUME) {\r
+ //\r
+ // In BIOS, HECBASE will be always below 4GB\r
+ //\r
+ HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28);\r
+ ASSERT (HecBaseHigh < 16);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Install Firmware Volume Hob's once there is main memory\r
+\r
+ @param PeiServices General purpose services available to every PEIM.\r
+ @param NotifyDescriptor Notify that this module published.\r
+ @param Ppi PPI that was installed.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MemoryDiscoveredPpiNotifyCallback (\r
+ IN CONST 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
+ EFI_CPUID_REGISTER FeatureInfo;\r
+ UINT8 CpuAddressWidth;\r
+ UINT16 Pm1Cnt;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_PLATFORM_INFO_HOB *PlatformInfo;\r
+ UINT32 RootComplexBar;\r
+ UINT32 PmcBase;\r
+ UINT32 IoBase;\r
+ UINT32 IlbBase;\r
+ UINT32 SpiBase;\r
+ UINT32 MphyBase;\r
+\r
+ //\r
+ // Get Platform Info HOB\r
+ //\r
+ Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);\r
+ ASSERT (Hob.Raw != NULL);\r
+ PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);\r
+\r
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);\r
+\r
+ //\r
+ // Check if user wants to turn off in PEI phase\r
+ //\r
+ if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) {\r
+ CheckPowerOffNow();\r
+ } else {\r
+ Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);\r
+ Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;\r
+ IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);\r
+ }\r
+\r
+ #ifndef MINNOW2_FSP_BUILD\r
+ //\r
+ // Set PEI cache mode here\r
+ //\r
+ SetPeiCacheMode (PeiServices);\r
+ #endif\r
+\r
+ //\r
+ // Pulish memory tyoe info\r
+ //\r
+ PublishMemoryTypeInfo ();\r
+\r
+ //\r
+ // Work done if on a S3 resume\r
+ //\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
+ //\r
+ //Program the side band packet register to send a sideband message to Punit\r
+ //To indicate that DRAM has been initialized and PUNIT FW base address in memory.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) & B_PCH_LPC_RCBA_BAR;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ RootComplexBar,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "RootComplexBar : 0x%x\n", RootComplexBar));\r
+\r
+ 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;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ PmcBase,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PmcBase));\r
+\r
+ 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;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ IoBase,\r
+ 0x4000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "IoBase : 0x%x\n", IoBase));\r
+\r
+ 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;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ IlbBase,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "IlbBase : 0x%x\n", IlbBase));\r
+\r
+ 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;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ SpiBase,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SpiBase));\r
+\r
+ 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;\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ MphyBase,\r
+ 0x100000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "MphyBase : 0x%x\n", MphyBase));\r
+\r
+ //\r
+ // Local APIC\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ LOCAL_APIC_ADDRESS,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS));\r
+\r
+ //\r
+ // IO APIC\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ IO_APIC_ADDRESS,\r
+ 0x1000\r
+ );\r
+ DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_ADDRESS));\r
+\r
+ //\r
+ // Adding the PCIE Express area to the E820 memory table as type 2 memory.\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ PlatformInfo->PciData.PciExpressBase,\r
+ PlatformInfo->PciData.PciExpressSize\r
+ );\r
+ DEBUG ((EFI_D_INFO, "PciExpressBase : 0x%x\n", PlatformInfo->PciData.PciExpressBase));\r
+\r
+ //\r
+ // Adding the Flashpart to the E820 memory table as type 2 memory.\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_FIRMWARE_DEVICE,\r
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),\r
+ FixedPcdGet32 (PcdFlashAreaBaseAddress),\r
+ FixedPcdGet32 (PcdFlashAreaSize)\r
+ );\r
+ DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32 (PcdFlashAreaBaseAddress)));\r
+\r
+ //\r
+ // Create a CPU hand-off information\r
+ //\r
+ CpuAddressWidth = 32;\r
+ AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);\r
+ if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) {\r
+ AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);\r
+ CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);\r
+ }\r
+\r
+ BuildCpuHob(CpuAddressWidth, 16);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ValidateFvHeader (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
+ )\r
+{\r
+ UINT16 *Ptr;\r
+ UINT16 HeaderLength;\r
+ UINT16 Checksum;\r
+\r
+ //\r
+ // Verify the header revision, header signature, length\r
+ // Length of FvBlock cannot be 2**64-1\r
+ // HeaderLength cannot be an odd number\r
+ //\r
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
+ (FwVolHeader->FvLength == ((UINT64) -1)) ||\r
+ ((FwVolHeader->HeaderLength & 0x01) != 0)\r
+ ) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Verify the header checksum\r
+ //\r
+ HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);\r
+ Ptr = (UINT16 *) FwVolHeader;\r
+ Checksum = 0;\r
+ while (HeaderLength > 0) {\r
+ Checksum = *Ptr++;\r
+ HeaderLength--;\r
+ }\r
+\r
+ if (Checksum != 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r