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