From 46e638b002b713e7bdc0d0087bd3d9336ee2ccc1 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 14:31:30 +0800 Subject: BroxtonPlatformPkg: Add PlatformPostMemPei Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../PlatformSettings/PlatformPostMemPei/BootMode.c | 450 ++++++++++ .../PlatformPostMemPei/MemoryCallback.h | 25 + .../PlatformPostMemPei/MemoryPeim.c | 180 ++++ .../PlatformPostMemPei/PeiSaPolicyUpdate.h | 29 + .../PlatformPostMemPei/PlatformInit.c | 981 +++++++++++++++++++++ .../PlatformPostMemPei/PlatformInit.h | 283 ++++++ .../PlatformPostMemPei/PlatformPostMemPei.inf | 130 +++ .../PlatformPostMemPei/PlatformScInitPeim.c | 322 +++++++ .../PlatformPostMemPei/PowerFailureHandle.c | 126 +++ 9 files changed, 2526 insertions(+) create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c create mode 100644 Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c new file mode 100644 index 0000000000..c113097e55 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/BootMode.c @@ -0,0 +1,450 @@ +/** @file + EFI PEIM to provide the platform support functionality. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformInit.h" + +#define NORMALMODE 0 +#define RECOVERYMODE 1 +#define SAFEMODE 2 +#define MANUFACTURINGMODE 3 + +EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiBootInRecoveryModePpiGuid, + NULL +}; + + +/** + Return the setting of the Bios configuration jumper + + @retval NORMALMODE jumper in normal mode + +**/ +UINTN +GetConfigJumper ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ) +{ + return NORMALMODE; +} + + +BOOLEAN +CheckIfRecoveryMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ) +{ + if (GetConfigJumper (PeiServices, PlatformInfoHob) == RECOVERYMODE) { + return TRUE; + } + return FALSE; +} + + +BOOLEAN +CheckIfSafeMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ) +{ + if (GetConfigJumper (PeiServices, PlatformInfoHob) == SAFEMODE) { + return TRUE; + } + return FALSE; +} + + +BOOLEAN +CheckIfManufacturingMode ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; + UINT32 Attributes; + UINTN DataSize; + CHAR16 VarName[] = MFGMODE_VARIABLE_NAME; + UINT8 MfgMode; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + (VOID **) &Variable + ); + ASSERT_EFI_ERROR (Status); + + // + // Check if SW MMJ mode + // + Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); + DataSize = sizeof (MFG_MODE_VAR); + + Status = Variable->GetVariable ( + Variable, + VarName, + &gMfgModeVariableGuid, + &Attributes, + &DataSize, + &MfgMode + ); + + if (!(EFI_ERROR (Status))) { + return TRUE; + } + return FALSE; +} + + +/** + Parse the status registers for figuring out the wake-up event and save it into + an GUID HOB which will be referenced later. However, modification is required + to meet the chipset register definition and the practical hardware design. Thus, + this is just an example. + + @param[in] PeiServices Pointer to the PEI Service Table. + + @retval EFI_SUCCESS Always return Success. + +**/ +EFI_STATUS +EFIAPI +GetWakeupEventAndSaveToHob ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINT16 AcpiBaseAddr; + UINT16 Pm1Sts; + UINTN Gpe0Sts; + UINTN WakeEventData; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Read the ACPI registers + // + Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS); + Gpe0Sts = IoRead32 (AcpiBaseAddr + R_ACPI_GPE0a_STS); + + // + // Figure out the wake-up event + // + if ((Pm1Sts & B_ACPI_PM1_STS_PWRBTN) != 0) { + WakeEventData = SMBIOS_WAKEUP_TYPE_POWER_SWITCH; + } else if (((Pm1Sts & B_ACPI_PM1_STS_WAK) != 0)) { + WakeEventData = SMBIOS_WAKEUP_TYPE_PCI_PME; + } else if (Gpe0Sts != 0) { + WakeEventData = SMBIOS_WAKEUP_TYPE_OTHERS; + } else { + WakeEventData = SMBIOS_WAKEUP_TYPE_UNKNOWN; + } + + DEBUG ((EFI_D_INFO, "ACPI Wake Status Register: %04x\n", Pm1Sts)); + + return EFI_SUCCESS; +} + + +EFI_STATUS +UpdateBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + UINT16 SleepType; + CHAR16 *strBootMode; + PEI_CAPSULE_PPI *Capsule; + SYSTEM_CONFIGURATION SystemConfiguration; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; + UINTN VariableSize; + + DEBUG ((EFI_D_INFO, "PEIM UpdateBootMode Enter: \n")); + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + ASSERT_EFI_ERROR (Status); + if (BootMode == BOOT_IN_RECOVERY_MODE) { + DEBUG ((EFI_D_INFO, "PEIM UpdateBootMode Enter: Set Recovery Mode \n")); + return Status; + } + DEBUG ((EFI_D_INFO, "GetWakeupEventAndSaveToHob \n")); + GetWakeupEventAndSaveToHob (PeiServices); + + // + // Let's assume things are OK if not told otherwise + // + BootMode = BOOT_WITH_FULL_CONFIGURATION; + + Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + VariableSize = sizeof (SYSTEM_CONFIGURATION); + Status = VariableServices->GetVariable ( + VariableServices, + PLATFORM_SETUP_VARIABLE_NAME, + &gEfiSetupVariableGuid, + NULL, + &VariableSize, + &SystemConfiguration + ); + if (!EFI_ERROR (Status)) { + if (SystemConfiguration.FastBoot == 1) { + BootMode = BOOT_WITH_MINIMAL_CONFIGURATION; + } + } + + // + // Check if we need to boot in forced recovery mode + // + if (CheckIfRecoveryMode (PeiServices, PlatformInfoHob)) { + DEBUG ((EFI_D_ERROR, "Set Boot mode in recovery mode \n")); + BootMode = BOOT_IN_RECOVERY_MODE; + } + + if (BootMode == BOOT_IN_RECOVERY_MODE) { + Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiListRecoveryBootMode); + ASSERT_EFI_ERROR (Status); + } else { + if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) { + switch (SleepType) { + case V_ACPI_PM1_CNT_S3: + BootMode = BOOT_ON_S3_RESUME; + // + // Determine if we're in capsule update mode + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gPeiCapsulePpiGuid, + 0, + NULL, + (VOID **) &Capsule + ); + + if (Status == EFI_SUCCESS) { + if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES **) PeiServices) == EFI_SUCCESS) { + BootMode = BOOT_ON_FLASH_UPDATE; + } + } + break; + + case V_ACPI_PM1_CNT_S4: + BootMode = BOOT_ON_S4_RESUME; + break; + + case V_ACPI_PM1_CNT_S5: + BootMode = BOOT_ON_S5_RESUME; + break; + } // switch (SleepType) + } + // Check for Safe Mode + } + + switch (BootMode) { + case BOOT_WITH_FULL_CONFIGURATION: + strBootMode = L"BOOT_WITH_FULL_CONFIGURATION"; + break; + + case BOOT_WITH_MINIMAL_CONFIGURATION: + strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION"; + break; + + case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES: + strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES"; + break; + + case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS: + strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS"; + break; + + case BOOT_WITH_DEFAULT_SETTINGS: + strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS"; + break; + + case BOOT_ON_S4_RESUME: + strBootMode = L"BOOT_ON_S4_RESUME"; + break; + + case BOOT_ON_S5_RESUME: + strBootMode = L"BOOT_ON_S5_RESUME"; + break; + + case BOOT_ON_S2_RESUME: + strBootMode = L"BOOT_ON_S2_RESUME"; + break; + + case BOOT_ON_S3_RESUME: + strBootMode = L"BOOT_ON_S3_RESUME"; + break; + + case BOOT_ON_FLASH_UPDATE: + strBootMode = L"BOOT_ON_FLASH_UPDATE"; + break; + + case BOOT_IN_RECOVERY_MODE: + strBootMode = L"BOOT_IN_RECOVERY_MODE"; + break; + + default: + strBootMode = L"Unknown boot mode"; + } // switch (BootMode) + + DEBUG ((EFI_D_INFO, "Setting BootMode to %s\n", strBootMode)); + Status = (*PeiServices)->SetBootMode (PeiServices, BootMode); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +/** + Get sleep type after wakeup. + + @param[in] PeiServices Pointer to the PEI Service Table. + @param[out] SleepType Sleep type to be returned. + + @retval TRUE A wake event occured without power failure. + @retval FALSE Power failure occured or not a wakeup. + +**/ +BOOLEAN +GetSleepTypeAfterWakeup ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT UINT16 *SleepType + ) +{ + UINT16 Pm1Sts; + UINT16 Pm1Cnt; + UINTN GenPmCon1; + UINT16 AcpiBaseAddr; + + // + // When the SUS_PWR_FLR bit is set, it indicates the SUS well power is lost. + // This bit is in the SUS Well and defaults to 1'b1 based on RSMRST# assertion (not cleared by any type of reset). + // System BIOS should follow cold boot path if SUS_PWR_FLR (PBASE + 0x20[14]), + // GEN_RST_STS (PBASE + 0x20[9]) or PWRBTNOR_STS (ABASE + 0x00[11]) is set to 1'b1 + // regardless of the value in the SLP_TYP (ABASE + 0x04[12:10]) field. + // + GenPmCon1 = MmioRead32 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1); + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Read the ACPI registers + // + Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS); + Pm1Cnt = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_CNT); + + DEBUG ((EFI_D_INFO, "ACPI Pm1Cnt Register: %04x\n", Pm1Cnt)); + DEBUG ((EFI_D_INFO, "ACPI Pm1Sts Register: %04x\n", Pm1Sts)); + DEBUG ((EFI_D_INFO, "PMC GenPmCon1 Register: %08x\n", GenPmCon1)); + + if (GenPmCon1 != 0xFFFF) { + if ((GenPmCon1 & (B_PMC_GEN_PMCON_COLD_BOOT_STS | B_PMC_GEN_PMCON_WARM_RST_STS)) ||\ + (Pm1Sts & B_ACPI_PM1_STS_PRBTNOR) || \ + (((Pm1Sts & B_ACPI_PM1_STS_WAK) == 0) && ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3))) { + // + // If power failure indicator, then don't attempt s3 resume. + // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has + // lost already. This is to make sure no one will use PM1_CNT to check for S3 after + // power failure. + // + if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3) { + Pm1Cnt = ((Pm1Cnt & ~B_ACPI_PM1_CNT_SLP_TYP) | V_ACPI_PM1_CNT_S5); + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt); + } + // + // Clear Wake Status (WAK_STS) + // + IoWrite16 ((AcpiBaseAddr + R_ACPI_PM1_STS), B_ACPI_PM1_STS_WAK); + } + } + + // + // Get sleep type if a wake event occurred and there is no power failure + // + if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S3) { + *SleepType = Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP; + return TRUE; + } else if ((Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP) == V_ACPI_PM1_CNT_S4) { + *SleepType = Pm1Cnt & B_ACPI_PM1_CNT_SLP_TYP; + return TRUE; + } + + return FALSE; +} + + +VOID +SetPlatformBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ) +{ + EFI_PLATFORM_SETUP_ID PlatformSetupId; + + ZeroMem (&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID)); + + CopyMem (&PlatformSetupId.SetupGuid, &gEfiNormalSetupGuid, sizeof (EFI_GUID)); + + if (CheckIfRecoveryMode (PeiServices, PlatformInfoHob)) { + // + // Recovery mode + // + CopyMem (&PlatformSetupId.SetupName, SAFE_SETUP_NAME, StrSize (SAFE_SETUP_NAME)); + PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE; + } else if (CheckIfSafeMode (PeiServices, PlatformInfoHob)) { + // + // Safe mode also called config mode or maintenace mode. + // + CopyMem (&PlatformSetupId.SetupName, SAFE_SETUP_NAME, StrSize (SAFE_SETUP_NAME)); + PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE; + + } else if (0) { + // + // Manufacturing mode + // + CopyMem (&PlatformSetupId.SetupName, MANUFACTURE_SETUP_NAME, StrSize (MANUFACTURE_SETUP_NAME)); + PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE; + + } else { + // + // Default to normal mode. + // + CopyMem (&PlatformSetupId.SetupName, &NORMAL_SETUP_NAME, StrSize (NORMAL_SETUP_NAME)); + PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE; + } + + BuildGuidDataHob ( + &gEfiPlatformBootModeGuid, + &PlatformSetupId, + sizeof (EFI_PLATFORM_SETUP_ID) + ); + + return; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h new file mode 100644 index 0000000000..49dd74ab33 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryCallback.h @@ -0,0 +1,25 @@ +/** @file + Common header file shared by all source files. + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __MEMORY_CALLBACK_H__ +#define __MEMORY_CALLBACK_H__ + +// +//Function Prototypes and Defines only - please do not add #includes here +// + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c new file mode 100644 index 0000000000..4566ebc2c7 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/MemoryPeim.c @@ -0,0 +1,180 @@ +/** @file + This file implements the Platform Memory Range PPI. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformInit.h" + +// +// Need min. of 48MB PEI phase +// +#define PEI_MIN_MEMORY_SIZE (6 * 0x800000) +#define PEI_RECOVERY_MIN_MEMORY_SIZE (6 * 0x800000) + +// +// This is the memory needed for PEI to start up DXE. +// +// Over-estimating this size will lead to higher fragmentation +// of main memory. Under-estimation of this will cause catastrophic +// failure of PEI to load DXE. Generally, the failure may only be +// realized during capsule updates. +// +#define PRERESERVED_PEI_MEMORY (EFI_SIZE_TO_PAGES (3 * 0x800000)) // PEI Core memory based stack + +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { +#if (ENBDT_PF_ENABLE == 1) + { EfiACPIReclaimMemory, 0x40 }, // 0x40 pages = 256k for ASL + { EfiACPIMemoryNVS, 0x60 }, // 0x100 pages = 1 MB for S3, SMM, HII, etc + { EfiReservedMemoryType, 0x1A80 }, // 48k for BIOS Reserved + { EfiRuntimeServicesCode, 0xF0 }, + { EfiRuntimeServicesData, 0x240 }, + { EfiMaxMemoryType, 0 } +#else + { EfiACPIReclaimMemory, 0x30 }, // 0x40 pages = 256k for ASL + { EfiACPIMemoryNVS, 0x60 }, // 0x100 pages = 1 MB for S3, SMM, HII, etc + { EfiReservedMemoryType, 0x10 }, // 48k for BIOS Reserved + { EfiMemoryMappedIO, 0 }, + { EfiMemoryMappedIOPortSpace, 0 }, + { EfiPalCode, 0 }, + { EfiRuntimeServicesCode, 0x50 }, + { EfiRuntimeServicesData, 0x13B }, + { EfiLoaderCode, 0x100 }, + { EfiLoaderData, 0x100 }, + { EfiBootServicesCode, 0x800 }, + { EfiBootServicesData, 0x2500}, + { EfiConventionalMemory, 0 }, + { EfiUnusableMemory, 0 }, + { EfiMaxMemoryType, 0 } +#endif +}; + +STATIC +EFI_STATUS +GetMemorySize ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT UINT64 *LowMemoryLength, + OUT UINT64 *HighMemoryLength + ); + +STATIC +EFI_STATUS +GetMemorySize ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT UINT64 *LowMemoryLength, + OUT UINT64 *HighMemoryLength + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + + *HighMemoryLength = 0; + *LowMemoryLength = 0x100000; + // + // Get the HOB list for processing + // + Status = (*PeiServices)->GetHobList (PeiServices, (VOID **) &Hob.Raw); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + // + // Need memory above 1MB to be collected here + // + if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 && + Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) { + *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); + } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) { + *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength); + } + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + + return EFI_SUCCESS; +} + + +/** + Publish Memory Type Information. + + @retval EFI_SUCCESS Success. + @retval Others Errors have occurred. + +**/ + +EFI_STATUS +EFIAPI +PublishMemoryTypeInfo ( + void + ) +{ + EFI_STATUS Status; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; + UINTN DataSize; + EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; + + Status = PeiServicesLocatePpi ( + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + (VOID **) &Variable + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status)); + DEBUG ((EFI_D_ERROR, "Build Hob from default\n")); + // + // Build the default GUID'd HOB for DXE + // + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); + + return Status; + } + + + DataSize = sizeof (MemoryData); + // + // This variable is saved in BDS stage. Now read it back + // + Status = Variable->GetVariable ( + Variable, + EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, + &gEfiMemoryTypeInformationGuid, + NULL, + &DataSize, + &MemoryData + ); + if (EFI_ERROR (Status)) { + // + // build default + // + DEBUG ((EFI_D_ERROR, "Build Hob from default\n")); + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); + + } else { + // + // Build the GUID'd HOB for DXE from variable + // + DEBUG ((EFI_D_INFO, "Build Hob from variable \n")); + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, MemoryData, DataSize); + } + + return Status; +} + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h new file mode 100644 index 0000000000..d9f5be520f --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PeiSaPolicyUpdate.h @@ -0,0 +1,29 @@ +/** @file + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_SA_POLICY_UPDATE_H_ +#define _PEI_SA_POLICY_UPDATE_H_ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c new file mode 100644 index 0000000000..84ff11700c --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.c @@ -0,0 +1,981 @@ +/** @file + Do platform specific PEI stage initializations. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformInit.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ + #pragma GCC push_options + #pragma GCC optimize ("O0") +#else + #pragma optimize ("", off) +#endif + +EFI_STATUS +CpuS3SmmAccessNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +static EFI_PEI_RESET_PPI mResetPpi = { IchReset }; + +static EFI_PEI_PPI_DESCRIPTOR mBoardPostMemInitStartPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gBoardPostMemInitStartGuid, + NULL + } +}; + +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { + { + // + // This PPI is hard coded to be installed as SPI boot (vs. eMMC boot) + // to trigger GetFvNotifyCallback() + // + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gCseSpiSelectPpiGuid, + NULL + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiMasterBootModePpiGuid, + NULL + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiTpmDeviceSelectedGuid, + NULL + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiResetPpiGuid, + &mResetPpi + } +}; + +static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + &gPeiSmmAccessPpiGuid, + CpuS3SmmAccessNotifyCallback + }, + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiPpiNotifyCallback + } +}; + +EFI_STATUS +TpmPolicyInit ( + IN SYSTEM_CONFIGURATION *SystemConfiguration + ) +{ +#if FTPM_SUPPORT + EFI_STATUS Status; + UINTN Size; + BOOLEAN IsPttEnabled = TRUE; + MBP_ME_FW_CAPS Mbp_Me_Fw_Caps = { 0 }; + + DEBUG ((EFI_D_ERROR, "TpmPolicyInit entry.\n")); + + // + // Get ME FW Capability from MBP table to determine PTT State + // + Status = HeciGetMeFwCapability (&Mbp_Me_Fw_Caps); + if (!EFI_ERROR (Status)) { + IsPttEnabled = (BOOLEAN) Mbp_Me_Fw_Caps.CurrentFeatures.Fields.PTT; + } + + if ((IsPttEnabled) && (SystemConfiguration->TPM == TPM_PTT)) { + if (SystemConfiguration->PttSuppressCommandSend == 1) { + PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid); + DEBUG ((DEBUG_ERROR, "BIOS will send no further commands to PTT.\n")); + } else { + // + // Set PcdTpmInstanceGuid to PTT + // + Size = sizeof (gTpmDeviceInstanceTpm20PttPtpGuid); + PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gTpmDeviceInstanceTpm20PttPtpGuid); + DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to PTT.\n")); + } + } else if (SystemConfiguration->TPM == TPM_DTPM_1_2) { + // + // Set PcdTpmInstanceGuid to dTPM 1.2 + // + Size = sizeof (gEfiTpmDeviceInstanceTpm12Guid); + PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceTpm12Guid); + DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to dTPM 1.2.\n")); + } else if (SystemConfiguration->TPM == TPM_DTPM_2_0) { + // + // Set PcdTpmInstanceGuid to dTPM 2.0 + // + Size = sizeof (gEfiTpmDeviceInstanceTpm20DtpmGuid); + PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceTpm20DtpmGuid); + DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to dTPM 2.0.\n")); + } else { + // + // Set PcdTpmInstanceGuid to NONE + // + Size = sizeof (gEfiTpmDeviceInstanceNoneGuid); + PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid); + DEBUG ((DEBUG_INFO, "Set PcdTpmInstanceGuid to NONE.\n")); + } +#endif + + return EFI_SUCCESS; +} + + +/** + This function will power off the system at once. + +**/ +VOID +PowerOffNow ( + VOID + ) +{ + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + DEBUG ((DEBUG_INFO, " PowerOffNow: AcpiBaseAddr = 0x%x\n",AcpiBaseAddr)); + + // + // Set PM Register and Put system to S5 + // + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5); + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5 + B_ACPI_PM1_CNT_SLP_EN); +} + + +/** + This function gets system config. + + @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param[in] SystemConfiguration The pointer to get System Setup + + + @retval EFI_SUCCESS The system configuration is obtained + @retval Other values The system configuration cannot be obtained + +**/ +EFI_STATUS +GetSystemConfig ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT SYSTEM_CONFIGURATION *SystemConfiguration + ) +{ + EFI_STATUS Status; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; + UINTN VariableSize; + + Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + VariableSize = sizeof (SYSTEM_CONFIGURATION); + + Status = VariableServices->GetVariable ( + VariableServices, + PLATFORM_SETUP_VARIABLE_NAME, + &gEfiSetupVariableGuid, + NULL, + &VariableSize, + SystemConfiguration + ); + + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +EFI_STATUS +PWM_Fan_Start ( + VOID + ) +{ + PWMCTRL PwmCtl = {0}; + UINT32 TimeOut = 0; + EFI_STATUS Status = EFI_SUCCESS; + + // + // Program GPIO_37 to enable FAN device + // + GpioPadWrite(N_GPIO_37,0x400); + + // + // Set PWM Base Address + // + MmioWrite32 ( + MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_PMC_PWM, PCI_FUNCTION_NUMBER_PMC_PWM, R_LPSS_IO_BAR), + PWM_TEMP_MEM_BASE_ADDRESS + ); + + // + // Enable PWM Memory decode + // + MmioWrite16 ( + MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_PMC_PWM, PCI_FUNCTION_NUMBER_PMC_PWM, R_LPSS_IO_STSCMD), + B_LPSS_IO_STSCMD_BME| B_LPSS_IO_STSCMD_MSE + ); + + MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw); + + // + // Initial Enable or First Activation for PWM + // 1. Program the Base Unit and On Time Divisor values. + // 2. Set the Software Update Bit. + // 3. Enable the PWM Output by setting PWM Enable. + // 4. Repeat the above steps for the next PWM Module. + // + PwmCtl.BITS.Pwm_Base_Unit = 0x15; + PwmCtl.BITS.Pwm_On_Time_Divisor = 0x80; + MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw); + + PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00); + PwmCtl.BITS.Pwm_Sw_Update = 1; + MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00, PwmCtl.Raw); + + PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00); + while (((PwmCtl.Raw & BIT30) == BIT30) && (TimeOut < PWM_TIMEOUT_MAX)) { + MicroSecondDelay (1); + PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00); + TimeOut ++; + } + + PwmCtl.Raw = MmioRead32 (PWM_TEMP_MEM_BASE_ADDRESS + 0x0C00); + PwmCtl.BITS.Pwm_Enable = 1; + MmioWrite32 (PWM_TEMP_MEM_BASE_ADDRESS+0x0C00, PwmCtl.Raw); + + if (TimeOut > PWM_TIMEOUT_MAX) { + Status = EFI_TIMEOUT; + } + return Status; +} + + +EFI_STATUS +BXTPolicyInit ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ) +{ + EFI_STATUS Status; + SI_SA_POLICY_PPI *SiSaPolicyPpi; + SA_MISC_CONFIG *MiscConfig = NULL; + GRAPHICS_CONFIG *GtConfig = NULL; + IPU_CONFIG *IpuPolicy = NULL; +#if (ENBDT_PF_ENABLE == 1) + HYBRID_GRAPHICS_CONFIG *HgConfig = NULL; +#endif + VOID* Buffer; + UINT32 Size; + EFI_GUID PeiLogoGuid = { 0x7BB28B99, 0x61BB, 0x11D5, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }; + EFI_GUID TianmaVbtGuid = { 0xE08CA6D5, 0x8D02, 0x43ae, 0xAB, 0xB1, 0x95, 0x2C, 0xC7, 0x87, 0xC9, 0x33 }; + VBT_INFO VbtInfo; + EFI_BOOT_MODE BootMode; + + DEBUG ((DEBUG_INFO, " BXTPolicyInit: SystemAgent PEI Platform Policy Initialization begin \n")); + + Status = CreateConfigBlocks (&SiSaPolicyPpi); + DEBUG ((DEBUG_INFO, "SiSaPolicyPpi->TableHeader.NumberOfBlocks = 0x%x\n ", SiSaPolicyPpi->TableHeader.NumberOfBlocks )); + ASSERT_EFI_ERROR (Status); + + + Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gSaMiscConfigGuid , (VOID *) &MiscConfig); + ASSERT_EFI_ERROR (Status); + + Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gGraphicsConfigGuid, (VOID *) &GtConfig); + ASSERT_EFI_ERROR (Status); + + Status = GetConfigBlock ((VOID *) SiSaPolicyPpi, &gIpuConfigGuid, (VOID *) &IpuPolicy); + ASSERT_EFI_ERROR (Status); + +#if (ENBDT_PF_ENABLE == 1) + Status = GetConfigBlock((VOID *) SiSaPolicyPpi, &gHybridGraphicsConfigGuid, (VOID *) &HgConfig); + ASSERT_EFI_ERROR(Status); +#endif + + if (!EFI_ERROR (Status)) { + // + // Get the Platform Configuration from SetupData + // + GtConfig->GttMmAdr = GTTMM_BASE_ADDRESS; + GtConfig->GmAdr = GMADR_BASE_ADDRESS; + GtConfig->PeiGraphicsPeimInit = SystemConfiguration->PeiGraphicsPeimInit; + GtConfig->PmSupport = SystemConfiguration->PmSupport; + GtConfig->EnableRenderStandby = SystemConfiguration->EnableRenderStandby; + GtConfig->CdClock = SystemConfiguration->CdClock; + GtConfig->PavpEnable = SystemConfiguration->PavpEnable; + + GtConfig->ForceWake = 0; + GtConfig->PavpLock = 1; + GtConfig->GraphicsFreqModify = 0; + GtConfig->GraphicsFreqReq = 0; + GtConfig->GraphicsVideoFreq = 0; + GtConfig->PmLock = 1; + GtConfig->DopClockGating = 1; + GtConfig->UnsolicitedAttackOverride = 0; + GtConfig->WOPCMSupport = 1; + GtConfig->WOPCMSize = 0; + GtConfig->PowerGating = 0; + GtConfig->UnitLevelClockGating = 1; + + MiscConfig->FastBoot = 1; + MiscConfig->DynSR = 1; + IpuPolicy->SaIpuEnable = SystemConfiguration->IpuEn; + IpuPolicy->IpuAcpiMode = SystemConfiguration->IpuAcpiMode; + IpuPolicy->IpuMmAdr = IPUMM_BASE_ADDRESS; + +#if (ENBDT_PF_ENABLE == 1) + // + // In Hybrid Gfx mode PCIe needs to be always enabled + // and IGFX must be set as Primary Display. + // + if (SystemConfiguration->PrimaryVideoAdaptor == 4) { + HgConfig->HgEnabled = 1; + HgConfig->HgSubSystemId = 0x2112; + } else { + HgConfig->HgEnabled = 0; + HgConfig->HgSubSystemId = 0x2212; + } + + HgConfig->HgDelayAfterPwrEn = SystemConfiguration->DelayAfterPwrEn; + HgConfig->HgDelayAfterHoldReset = SystemConfiguration->DelayAfterHoldReset; + // + // Configure below based on the OEM platfrom design + // Hybrid Graphics Enabled - 0= Disabled, 1=Enabled + // + if (HgConfig->HgEnabled == 1) { + // + // dGPU HLD RST GPIO assigned + // + HgConfig->HgDgpuHoldRst.CommunityOffset = (((UINT32) GPIO_MMIO_OFFSET_W) << 16); + HgConfig->HgDgpuHoldRst.PinOffset = 0x05B0; + HgConfig->HgDgpuHoldRst.Active = 0; + // + // dGPU PWR Enable GPIO assigned + // + HgConfig->HgDgpuPwrEnable.CommunityOffset = (((UINT32) GPIO_MMIO_OFFSET_N) << 16); + HgConfig->HgDgpuPwrEnable.PinOffset = 0x0598; + HgConfig->HgDgpuPwrEnable.Active = 1; + + HgConfig->RootPortDev = PCI_DEVICE_NUMBER_SC_PCIE_DEVICE_2; + HgConfig->RootPortFun = PCI_FUNCTION_NUMBER_PCIE_ROOT_PORT_3; + + DEBUG ((DEBUG_INFO, "HG::Hybrid Graphics Policy updated\n")); + } +#endif + } + + Status = (*PeiServices)->GetBootMode ((CONST EFI_PEI_SERVICES **) PeiServices, &BootMode); + ASSERT_EFI_ERROR (Status); + + PeiGetSectionFromFv (PeiLogoGuid, &Buffer, &Size); + if (Buffer == NULL) { + DEBUG (( DEBUG_ERROR, "Could not locate PeiLogo")); + } + GtConfig->LogoPtr = Buffer; + GtConfig->LogoSize = Size; + DEBUG ((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", Buffer)); + DEBUG ((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", Size)); + DEBUG ((DEBUG_INFO, "SystemConfiguration->PanelSel = 0x%x\n", SystemConfiguration->PanelSel)); + + // + // May need a different VBT depending on PanelSel + // + PeiGetSectionFromFv (TianmaVbtGuid, &Buffer, &Size); + + if (Buffer == NULL) { + DEBUG (( DEBUG_ERROR, "Could not locate VBT")); + } + + if (BootMode == BOOT_ON_S3_RESUME) { + GtConfig->GraphicsConfigPtr = NULL; + } else { + GtConfig->GraphicsConfigPtr = Buffer; + } + + // + // Build the VBT data into HOB for DXE GOP + // + VbtInfo.VbtAddress = (EFI_PHYSICAL_ADDRESS) Buffer; + VbtInfo.VbtSize = Size; + DEBUG ((DEBUG_INFO, "VbtInfo VbtAddress is 0x%x\n", Buffer)); + DEBUG ((DEBUG_INFO, "VbtInfo VbtSize is 0x%x\n", Size)); + + BuildGuidDataHob ( + &gVbtInfoGuid, + &VbtInfo, + sizeof (VbtInfo) + ); + + // + // Install SiSaPolicyPpi. + // While installed, RC assumes the Policy is ready and finalized. So please + // update and override any setting before calling this function. + // + Status = SiSaInstallPolicyPpi (SiSaPolicyPpi); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, " SystemAgent PEI Platform Policy Initialization Done \n")); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + + +/** + Platform Init PEI module entry point + + @param[in] FileHandle Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database + +**/ +EFI_STATUS +EFIAPI +PlatformInitEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + SYSTEM_CONFIGURATION SystemConfiguration; + EFI_PLATFORM_INFO_HOB *PlatformInfo; + EFI_PEI_HOB_POINTERS Hob; + BOARD_POST_MEM_INIT_FUNC BoardPostMemInitFunc; + + DEBUG ((EFI_D_INFO, "PlatformInit EntryPoint\n")); + // + // Trigger board post mem init + // + Status = PeiServicesInstallPpi (mBoardPostMemInitStartPpi); + 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); + + if (PlatformInfo->SsidSvid != 0) { + PlatformInfo->SsidSvid = 0; + } + + + // + // Initialize GFX VT-d Base Address + // + if (BxtStepping () <= BxtA1) { + PcdSet32S (PcdVtdGfxBaseAddress, 0xFF000000); + } + + PWM_Fan_Start (); + + // + // Initialize PlatformInfo HOB + // + BoardPostMemInitFunc = (BOARD_POST_MEM_INIT_FUNC) (UINTN) PcdGet64 (PcdBoardPostMemInitFunc); + if (BoardPostMemInitFunc != NULL) { + BoardPostMemInitFunc (PeiServices, PlatformInfo); + } + // MultiPlatformInfoInit(PeiServices, PlatformInfo); + + // + // Set the new boot mode + // + Status = UpdateBootMode (PeiServices, PlatformInfo); + ASSERT_EFI_ERROR (Status); + + SetPlatformBootMode (PeiServices, PlatformInfo); + + GetSystemConfig (PeiServices, &SystemConfiguration); + + // + //Update the PlatformInfo Hob according to setup + // + PlatformInfo->OsSelection = 3; + + // + // Initialize all PEI Policy + // + PeiPolicyInit (PeiServices, &SystemConfiguration); + + // + // Do basic SC init + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_CAR_SB_INIT)); + Status = PlatformScInit (&SystemConfiguration, PeiServices, PlatformInfo->PlatformType); + ASSERT_EFI_ERROR (Status); + + // + // Initialize BxtPolicy PPI + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_PEI_CAR_NB_INIT)); + Status = BXTPolicyInit (PeiServices, &SystemConfiguration); + ASSERT_EFI_ERROR (Status); + + // + // Initialize TPM Policy before Initializing Platform PPIs - Tcg2Pei load depends on gEfiTpmDeviceSelectedGuid which will be installed as a part of Platform PPIs + // + Status = TpmPolicyInit (&SystemConfiguration); + ASSERT_EFI_ERROR (Status); + + // + // Initialize platform PPIs + // + Status = PeiServicesInstallPpi (&mPpiList[0]); + ASSERT_EFI_ERROR (Status); + + // + // Set LVDS_BKLT_CTRL to 50%. + // + MmPci8 (0, 0, 2, 0, 0xF4) = 128; + + // + // Initialize platform PPIs + // + Status = PeiServicesNotifyPpi (&mNotifyList[0]); + ASSERT_EFI_ERROR (Status); + + // + // Maybe move to MemoryCallBack.c (which would be called between PreMemPlatInit and PlatInit) + // + PlatformInitFinalConfig (PeiServices); + + return Status; +} + + +EFI_STATUS +EFIAPI +CpuOnlyReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + +#ifdef __GNUC__ + __asm__ + ( + "xorl %ecx, %ecx\n" + "1:hlt; hlt; hlt\n" + "jmp 1b\n" + ); +#else + _asm { + xor ecx, ecx + HltLoop: + hlt + hlt + hlt + loop HltLoop + } +#endif + + // + // If we get here we need to mark it as a failure. + // + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +PeiGetSectionFromFv ( + IN CONST EFI_GUID NameGuid, + OUT VOID **Address, + OUT UINT32 *Size + ) +{ + EFI_STATUS Status; + EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; + EFI_FV_FILE_INFO FvFileInfo; + PEI_CORE_INSTANCE *PrivateData; + UINTN CurrentFv; + PEI_CORE_FV_HANDLE *CoreFvHandle; + EFI_PEI_FILE_HANDLE VbtFileHandle; + EFI_GUID *VbtGuid; + EFI_COMMON_SECTION_HEADER *Section; + CONST EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + Status = PeiServicesLocatePpi ( + &gEfiFirmwareFileSystem2Guid, + 0, + NULL, + (VOID **) &FvPpi + ); + ASSERT_EFI_ERROR (Status); + + CurrentFv = PrivateData->CurrentPeimFvCount; + CoreFvHandle = &(PrivateData->Fv[CurrentFv]); + + Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle); + if (!EFI_ERROR (Status) && VbtFileHandle != NULL) { + + DEBUG ((DEBUG_INFO, "Find SectionByType \n")); + + Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid); + if (!EFI_ERROR (Status)) { + + DEBUG ((DEBUG_INFO, "GetFileInfo \n")); + + Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo); + Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer; + + if (IS_SECTION2 (Section)) { + ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF); + *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); + *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); + *Address = ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +CpuS3SmmAccessNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + // + // Restore Cpu settings only during S3 resume + // + S3InitializeCpu (PeiServices); + + return EFI_SUCCESS; +} + + +/** + Install Firmware Volume Hob's once there is main memory + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor Not uesed. + @param[in] Ppi Not uesed. + + @retval EFI_SUCCESS If the interface could be successfully installed. + +**/ +EFI_STATUS +EndOfPeiPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_PLATFORM_INFO_HOB *PlatformInfo; + EFI_PEI_HOB_POINTERS Hob; + + DEBUG ((EFI_D_INFO, "Platform Init End of PEI signal\n")); + + // + // 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); + + + DEBUG ((EFI_D_INFO, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm)); + DEBUG ((EFI_D_INFO, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase)); + DEBUG ( + (EFI_D_INFO, + "PCIE BASE: %lX Size : %X\n", + PlatformInfo->PciData.PciExpressBase, + PlatformInfo->PciData.PciExpressSize) + ); + DEBUG ( + (EFI_D_INFO, + "PCI32 BASE: %X Limit: %X\n", + PlatformInfo->PciData.PciResourceMem32Base, + PlatformInfo->PciData.PciResourceMem32Limit) + ); + DEBUG ( + (EFI_D_INFO, + "PCI64 BASE: %lX Limit: %lX\n", + PlatformInfo->PciData.PciResourceMem64Base, + PlatformInfo->PciData.PciResourceMem64Limit) + ); + DEBUG ((EFI_D_INFO, "UC START: %lX End : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1)); + + return EFI_SUCCESS; +} + + +/** + Install Firmware Volume Hob's once there is main memory + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor Notify that this module published. + @param[in] Ppi PPI that was installed. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +EFIAPI +PlatformInitFinalConfig ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + EFI_CPUID_REGISTER FeatureInfo; + UINT8 CpuAddressWidth; + UINT16 Pm1Cnt; + EFI_PEI_HOB_POINTERS Hob; + EFI_PLATFORM_INFO_HOB *PlatformInfo; + UINT16 AcpiBaseAddr; + + // + // Get Platform Info HOB + // + Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid); + ASSERT (Hob.Raw != NULL); + PlatformInfo = GET_GUID_HOB_DATA (Hob.Raw); + + Status = (*PeiServices)->GetBootMode ((CONST EFI_PEI_SERVICES **) PeiServices, &BootMode); + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // 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 (AcpiBaseAddr + R_ACPI_PM1_CNT); + Pm1Cnt &= ~B_ACPI_PM1_CNT_SLP_TYP; + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt); + } + + // + // Pulish memory tyoe info + // + PublishMemoryTypeInfo (); + + // + // Work done if on a S3 resume + // + if (BootMode == BOOT_ON_S3_RESUME) { + return EFI_SUCCESS; + } + + // + // Add HOP entries for reserved MMIO ranges so that DXE will know about them. + // Note: this really only need to be done for addresses that are outside the upper 16MB. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PMC_BASE_ADDRESS, + 0x1000 + ); + DEBUG ((EFI_D_INFO, "PmcBase : 0x%x\n", PMC_BASE_ADDRESS)); + + // + // Spi BAR needs to be set to SPI_BASE_ADDRESS before it can be read.. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + SPI_BASE_ADDRESS, + 0x1000 + ); + DEBUG ((EFI_D_INFO, "SpiBase : 0x%x\n", SPI_BASE_ADDRESS)); + + // + // Local APIC + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + LOCAL_APIC_BASE_ADDRESS, + 0x1000 + ); + DEBUG ((EFI_D_INFO, "LOCAL_APIC_BASE_ADDRESS : 0x%x\n", LOCAL_APIC_BASE_ADDRESS)); + + // + // IO APIC + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + IO_APIC_BASE_ADDRESS, + 0x1000 + ); + DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS : 0x%x\n", IO_APIC_BASE_ADDRESS)); + + // + // Adding the PCIE Express area to the 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 memory table as type 2 memory. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdFlashBaseAddress), + PcdGet32(PcdFlashSize) + ); + DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", PcdGet32(PcdFlashBaseAddress))); + + // + // P2SB (BXT) 16MB + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdP2SBBaseAddress), + 0x1000000 + ); + + // + // PMC IPC (BXT) 8KB and 4KB + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdPmcIpc1BaseAddress0), + 0x2000 + ); + + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdPmcIpc1BaseAddress1), + 0x1000 + ); + + // + // PMC SSRAM (BXT) 8KB and 4KB + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdPmcSsramBaseAddress0), + 0x2000 + ); + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + PcdGet32(PcdPmcSsramBaseAddress1), + 0x1000 + ); + + // + // Create a CPU hand-off information + // + CpuAddressWidth = 32; + AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); + if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) { + AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx); + CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF); + } + + 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; +} + +#ifdef __GNUC__ +#pragma GCC pop_options +#else +#pragma optimize ("", on) +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h new file mode 100644 index 0000000000..09813e904f --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformInit.h @@ -0,0 +1,283 @@ +/** @file + Platform Early Stage header file. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _EFI_PLATFORM_INIT_H_ +#define _EFI_PLATFORM_INIT_H_ + +#define EFI_FORWARD_DECLARATION(x) typedef struct _##x x + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CMOSMap.h" +#include "Platform.h" +#include +#include +#include +#include +#include +#include + +#define SMC_LAN_ON 0x46 +#define SMC_LAN_OFF 0x47 +#define SMC_DEEP_S3_STS 0xB2 + +// +// Wake Event Types +// +#define SMBIOS_WAKEUP_TYPE_RESERVED 0x00 +#define SMBIOS_WAKEUP_TYPE_OTHERS 0x01 +#define SMBIOS_WAKEUP_TYPE_UNKNOWN 0x02 +#define SMBIOS_WAKEUP_TYPE_APM_TIMER 0x03 +#define SMBIOS_WAKEUP_TYPE_MODEM_RING 0x04 +#define SMBIOS_WAKEUP_TYPE_LAN_REMOTE 0x05 +#define SMBIOS_WAKEUP_TYPE_POWER_SWITCH 0x06 +#define SMBIOS_WAKEUP_TYPE_PCI_PME 0x07 +#define SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED 0x08 + +// +// Defines for stall PPI +// +#define PEI_STALL_RESOLUTION 1 + +// +// Define for Vibra +// +#define PWM_DUTY_CYCLE 0x55 // zero duty cycle is 0x32/0xff +#define PWM_BASE_UNIT 0x3 // DRV2603 work on 10k-250k while PWM base is 19.2M, 0x3/0xFF*19.2MHz ~ 200KHz +#define PWM_TIMEOUT_MAX 100 +#define PWM_DELAY 1000000 + +extern EFI_GUID gVbtInfoGuid; + +typedef struct { + EFI_PHYSICAL_ADDRESS VbtAddress; + UINT32 VbtSize; +} VBT_INFO; + +#pragma pack(push, 1) +typedef union { + UINT32 Raw; + struct { + UINT32 Pwm_On_Time_Divisor :8; ///< [7:0] + UINT32 Pwm_Base_Unit :16; ///< [23:8] + UINT32 Pwm_Rsvd :6; ///< [29:24] + UINT32 Pwm_Sw_Update :1; ///< [30] + UINT32 Pwm_Enable :1; ///< [31] + } BITS; // Bits +} PWMCTRL; +#pragma pack(pop) + +// +// Function Prototypes +// +EFI_STATUS +PlatformScInit ( + IN SYSTEM_CONFIGURATION *SystemConfiguration, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 PlatformType + ); + +EFI_STATUS +EFIAPI +IchReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +BOOLEAN +GetSleepTypeAfterWakeup ( + IN CONST EFI_PEI_SERVICES **PeiServices, + OUT UINT16 *SleepType + ); + +EFI_STATUS +EndOfPeiPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +EFI_STATUS +EFIAPI +PeimInitializeRecovery ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +VOID +CheckPowerOffNow ( + VOID + ); + +VOID +SetPlatformBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +EFI_STATUS +EFIAPI +CpuOnlyReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +Stall ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_STALL_PPI *This, + IN UINTN Microseconds + ); + +EFI_STATUS +MultiPlatformInfoInit ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +BOOLEAN +IsRecoveryJumper ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +EFI_STATUS +PlatformInfoUpdate ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +EFI_STATUS +InitializePlatform ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PLATFORM_INFO_HOB *PlatformInfoHob, + IN SYSTEM_CONFIGURATION *SystemConfiguration + ); + +EFI_STATUS +GeneralPowerFailureHandler ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +BOOLEAN +IsRtcUipAlwaysSet ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +RtcPowerFailureHandler ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +PublishMemoryTypeInfo ( + VOID + ); + +EFI_STATUS +EFIAPI +PeiGetSectionFromFv ( + IN CONST EFI_GUID NameGuid, + OUT VOID **Address, + OUT UINT32 *Size + ); + +EFI_STATUS +EFIAPI +ConfigClockTrunk ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +PlatformInitFinalConfig ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +ValidateFvHeader ( + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ); + +EFI_STATUS +UpdateBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob + ); + +UINT8 +ConfigurePlatformPmic ( + VOID + ); + +VOID +ScUsb2PhyOverride ( + VOID + ); +#endif // _EFI_PLATFORM_INIT_H_ + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf new file mode 100644 index 0000000000..cd8b617017 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformPostMemPei.inf @@ -0,0 +1,130 @@ +## @file +# Component description file for PlatformInit module. +# +# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformInit + FILE_GUID = 0A5EA2E1-BE0B-44a0-A775-F429C9A018A0 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PlatformInitEntryPoint + +[Sources] + BootMode.c + PlatformScInitPeim.c + MemoryPeim.c + PlatformInit.c + PlatformInit.h + PowerFailureHandle.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + BroxtonPlatformPkg/PlatformPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + PeimEntryPoint + DebugLib + HobLib + IoLib + PcdLib + ReportStatusCodeLib + PciExpressLib + PeiScPolicyLib + SteppingLib + SideBandLib + ConfigBlockLib + PeiSaPolicyLib + PeiPolicyUpdateLib + PeiPolicyInitLib + CpuPolicyLib + TimerLib + ScPlatformLib + CpuS3Lib + SeCUmaLib + +[Ppis] + gEfiPeiStallPpiGuid + gEfiPeiMemoryDiscoveredPpiGuid + gEfiPeiReadOnlyVariable2PpiGuid + gEfiPeiResetPpiGuid + gEfiEndOfPeiSignalPpiGuid + gPeiCapsulePpiGuid + gEfiPeiBootInRecoveryModePpiGuid + gEfiPeiRecoveryModulePpiGuid + gEfiPeiDeviceRecoveryModulePpiGuid + gPeiCachePpiGuid + gEfiPeiMasterBootModePpiGuid + gEfiPeiSmbusPpiGuid + gEfiPeiSmbus2PpiGuid + gScPolicyPpiGuid + gEfiPeiVirtualBlockIoPpiGuid + gSiSaPolicyPpiGuid + gDramPolicyPpiGuid + gBiosGuardConfigGuid + gCpuConfigGuid + gCpuOverclockingConfigGuid + gPowerMgmtConfigGuid + gSiPolicyPpiGuid + +[Guids] + gEfiSetupVariableGuid + gEfiPlatformInfoGuid + gEfiPlatformBootModeGuid + gEfiPlatformCpuInfoGuid + gEfiGlobalVariableGuid + gRecoveryOnFatFloppyDiskGuid + gRecoveryOnFatUsbDiskGuid + gRecoveryOnFatIdeDiskGuid + gRecoveryOnDataCdGuid + gMfgModeVariableGuid + gEfiNormalSetupGuid + gEfiMemoryTypeInformationGuid + gVbtInfoGuid + gPcieRpConfigGuid + gSataConfigGuid + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdFlashBaseAddress + gPlatformModuleTokenSpaceGuid.PcdFlashSize + gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBBase + gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBSize + gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXBase + gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBXSize + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gEfiIchTokenSpaceGuid.PcdPeiIchEhciControllerMemoryBaseAddress + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress + gPlatformModuleTokenSpaceGuid.PcdScsiChunk + gPlatformModuleTokenSpaceGuid.PcdUfsInitStall + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress + gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress + gEfiBxtTokenSpaceGuid.PcdPmcIpc1BaseAddress0 + gEfiBxtTokenSpaceGuid.PcdPmcIpc1BaseAddress1 + gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress + gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress0 + gEfiBxtTokenSpaceGuid.PcdPmcSsramBaseAddress1 + gEfiBxtTokenSpaceGuid.PcdVtdGfxBaseAddress + gEfiBxtTokenSpaceGuid.PcdTcoBaseAddress + gPlatformModuleTokenSpaceGuid.PcdVibratorFeature + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdBoardPostMemInitFunc + +[Depex] + gDramPolicyPpiGuid + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c new file mode 100644 index 0000000000..554096db57 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PlatformScInitPeim.c @@ -0,0 +1,322 @@ +/** @file + Early SC platform initialization. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include "PlatformInit.h" +#include +#include +#include +#include +#include +#include + + +VOID +ScPolicySetupInit ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); +#ifndef __GNUC__ +#pragma warning (push) +#pragma warning (disable : 4245) +#pragma warning (pop) +#endif + + +UINT8 +ReadCmosBank1Byte ( + IN UINT8 Address + ) +{ + UINT8 Data; + + IoWrite8 (R_RTC_EXT_INDEX, Address); + Data = IoRead8 (R_RTC_EXT_TARGET); + + return Data; +} + + +VOID +WriteCmosBank1Byte ( + IN UINT8 Address, + IN UINT8 Data + ) +{ + IoWrite8 (R_RTC_EXT_INDEX, Address); + IoWrite8 (R_RTC_EXT_TARGET, Data); +} + + +EFI_STATUS +InstallPeiScUsbPolicy ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + + +VOID +CheckPowerOffNow ( + VOID + ) +{ + UINT16 Pm1Sts; + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Read and check the ACPI registers + // + Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS); + if ((Pm1Sts & B_ACPI_PM1_STS_PWRBTN) == B_ACPI_PM1_STS_PWRBTN) { + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_STS, B_ACPI_PM1_STS_PWRBTN); + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5); + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5 + B_ACPI_PM1_CNT_SLP_EN); + } +} + + +VOID +ClearPowerState ( + IN SYSTEM_CONFIGURATION *SystemConfiguration + ) +{ + UINT16 Data16; + UINT32 Data32; + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Clear the GPE and PM enable + // + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_EN, (UINT16) 0x00); + IoWrite32 (AcpiBaseAddr + R_ACPI_GPE0a_EN, (UINT32) 0x00); + + // + // Halt the TCO timer + // + Data16 = IoRead16 (AcpiBaseAddr + R_TCO_CNT); + Data16 |= B_TCO_CNT_TMR_HLT; + IoWrite16 (AcpiBaseAddr + R_TCO_CNT, Data16); + + // + // NMI NOW bit is "Write '1' to clear" + // + + // + // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use. + // + Data32 = IoRead16 (AcpiBaseAddr + R_TCO_STS); + if ((Data32 & B_TCO_STS_SECOND_TO) == B_TCO_STS_SECOND_TO) { +#if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0)) + WriteCmosBank1Byte ( + EFI_CMOS_PERFORMANCE_FLAGS, + ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET + ); +#endif + } + +} + + +/** + Clear any SMI status or wake status left over from boot. + +**/ +VOID +ClearSmiAndWake ( + VOID + ) +{ + UINT16 Pm1Sts; + UINT32 Gpe0Sts; + UINT32 SmiSts; + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Read the ACPI registers + // + Pm1Sts = IoRead16 (AcpiBaseAddr + R_ACPI_PM1_STS); + Gpe0Sts = IoRead32 (AcpiBaseAddr + R_ACPI_GPE0a_STS); + SmiSts = IoRead32 (AcpiBaseAddr + R_SMI_STS); + + // + // Register Wake up reason for S4. This information is used to notify + // WinXp of wake up reason because S4 wake up path doesn't keep SCI. + // This is important for Viiv(Quick resume) platform. + // + + // + // First Clear CMOS S4 Wake up flag. + // + WriteCmosBank1Byte (EFI_CMOS_S4_WAKEUP_FLAG_ADDRESS, 0); + + // + // Check wake up reason and set CMOS accordingly. Currently checks + // Power button, USB, PS/2. + // Note : PS/2 wake up is using GPI13 (IO_PME). This must be changed depending + // on board design. + // + if ((Pm1Sts & B_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_ACPI_GPE0a_STS_CORE_GPIO | B_ACPI_GPE0a_STS_SUS_GPIO))) { + WriteCmosBank1Byte (EFI_CMOS_S4_WAKEUP_FLAG_ADDRESS, 1); + } + + // + // Clear any SMI or wake state from the boot + // + Pm1Sts = (B_ACPI_PM1_STS_PRBTNOR | B_ACPI_PM1_STS_PWRBTN); + + Gpe0Sts |= + ( + B_ACPI_GPE0a_STS_CORE_GPIO | + B_ACPI_GPE0a_STS_SUS_GPIO | + B_ACPI_GPE0a_STS_PME_B0 | + B_ACPI_GPE0a_STS_BATLOW | + B_ACPI_GPE0a_STS_PCI_EXP | + B_ACPI_GPE0a_STS_GUNIT_SCI | + B_ACPI_GPE0a_STS_PUNIT_SCI | + B_ACPI_GPE0a_STS_SWGPE | + B_ACPI_GPE0a_STS_HOT_PLUG + ); + + SmiSts |= + ( + B_SMI_STS_PERIODIC | + B_SMI_STS_TCO | + B_SMI_STS_SWSMI_TMR | + B_SMI_STS_APM | + B_SMI_STS_ON_SLP_EN | + B_SMI_STS_BIOS + ); + + // + // Write them back + // + IoWrite16 (AcpiBaseAddr + R_ACPI_PM1_STS, Pm1Sts); + IoWrite32 (AcpiBaseAddr + R_ACPI_GPE0a_STS, Gpe0Sts); + IoWrite32 (AcpiBaseAddr + R_SMI_STS, SmiSts); +} + + +/** + Provide hard reset PPI service. + To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9). + + @param[in] PeiServices General purpose services available to every PEIM. + + @retval Not return System reset occurred. + @retval EFI_DEVICE_ERROR Device error, could not reset the system. + +**/ +EFI_STATUS +EFIAPI +IchReset ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + IoWrite8 ( + R_RST_CNT, + V_RST_CNT_HARDSTARTSTATE + ); + + IoWrite8 ( + R_RST_CNT, + V_RST_CNT_HARDRESET + ); + + // + // System reset occurred, should never reach at this line. + // + ASSERT_EFI_ERROR (EFI_DEVICE_ERROR); + + return EFI_DEVICE_ERROR; +} + + +EFI_STATUS +PlatformScInit ( + IN SYSTEM_CONFIGURATION *SystemConfiguration, + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 PlatformType + ) +{ + BXT_SERIES BxtSeries; + // + // SC Policy Initialization based on Setup variable. + // + ScPolicySetupInit (PeiServices); + + // + // Install PCIe device override table + // + BxtSeries = GetBxtSeries (); + if (BxtSeries == BxtP) { + // + // Set TCO Base Address + // + SetTcoBase (PcdGet16 (PcdTcoBaseAddress)); + } + + return EFI_SUCCESS; +} + + +VOID +ScPolicySetupInit ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + SC_POLICY_PPI *ScPolicyPpi; + + // + // Install SC Policy PPI. As we depend on SC Init PPI so we are executed after + // ScInit PEIM. Thus we can insure SC Initialization is performed when we install the SC Policy PPI, + // as ScInit PEIM registered a notification function on our policy PPI. + // + // For better code structure / modularity, we should use a notification function on SC Init PPI to perform + // actions that depend on ScInit PEIM's initialization. + // + DEBUG ((EFI_D_INFO, "ScPolicySetupInit() - Start\n")); + ScCreateConfigBlocks (&ScPolicyPpi); + + UpdatePeiScPolicy (ScPolicyPpi); + + // + // Install SC Policy PPI + // + Status = ScInstallPolicyPpi (ScPolicyPpi); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "ScPolicySetupInit() - End\n")); +} + diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c new file mode 100644 index 0000000000..e1cb27cbe7 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPostMemPei/PowerFailureHandle.c @@ -0,0 +1,126 @@ +/** @file + RTC Power failure handler. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformInit.h" + + +BOOLEAN +IsRtcUipAlwaysSet ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_PEI_STALL_PPI *StallPpi; + UINTN Count; + + (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi); + + for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500) + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA); + if ((IoRead8 (R_RTC_TARGET2) & B_RTC_REGISTERA_UIP) == 0) { + return FALSE; + } + + StallPpi->Stall (PeiServices, StallPpi, 3000); + } + + return TRUE; +} + + +EFI_STATUS +RtcPowerFailureHandler ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINT16 DataUint16; + UINT8 DataUint8; + BOOLEAN RtcUipIsAlwaysSet; + + // + // When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low. + // Software should clear this bit. Changing the RTC battery sets this bit. + // System BIOS should reset CMOS to default values if the RTC_PWR_STS bit is set. + // + // The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set before memory initialization. + // 1. If the RTC_PWR_STS bit is set which indicates a new coin-cell battery insertion or a battery failure, + // steps 2 through 5 should be executed. + // 2. Set RTC Register 0x0A[6:4] to '110' or '111'. + // 3. Set RTC Register 0x0B[7]. + // 4. Set RTC Register 0x0A[6:4] to '010'. + // 5. Clear RTC Register 0x0B[7]. + // + DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1); + RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices); + if ((DataUint16 & B_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) { + // + // Execute the sequence below. This will ensure that the RTC state machine has been initialized. + // + // Step 1. + // BIOS clears this bit by writing a '0' to it. + // + if (DataUint16 & B_PMC_GEN_PMCON_RTC_PWR_STS) { + DataUint16 &= ~B_PMC_GEN_PMCON_RTC_PWR_STS; + MmioWrite16 ((PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1), DataUint16); + + // + // Set to invalid date to be set later to a valid time + // + IoWrite8 (R_RTC_INDEX2, R_RTC_YEAR); + IoWrite8 (R_RTC_TARGET2, 0x0FF); + IoWrite8 (R_RTC_INDEX2, R_RTC_MONTH); + IoWrite8 (R_RTC_TARGET2, 0x0FF); + IoWrite8 (R_RTC_INDEX2, R_RTC_DAYOFMONTH); + IoWrite8 (R_RTC_TARGET2, 0x0FF); + IoWrite8 (R_RTC_INDEX2, R_RTC_DAYOFWEEK); + IoWrite8 (R_RTC_TARGET2, 0x0FF); + } + + // + // Step 2. + // Set RTC Register 0Ah[6:4] to '110' or '111'. + // + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA); + IoWrite8 (R_RTC_TARGET2, (V_RTC_REGISTERA_DV_DIV_RST1 | V_RTC_REGISTERA_RS_976P5US)); + + // + // Step 3. + // Set RTC Register 0Bh[7]. + // + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB); + DataUint8 = (IoRead8 (R_RTC_TARGET2) | B_RTC_REGISTERB_SET); + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB); + IoWrite8 (R_RTC_TARGET2, DataUint8); + + // + // Step 4. + // Set RTC Register 0Ah[6:4] to '010'. + // + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERA); + IoWrite8 (R_RTC_TARGET2, (V_RTC_REGISTERA_DV_NORM_OP | V_RTC_REGISTERA_RS_976P5US)); + + // + // Step 5. + // Clear RTC Register 0Bh[7]. + // + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB); + DataUint8 = (IoRead8 (R_RTC_TARGET2) & (UINT8)~B_RTC_REGISTERB_SET); + IoWrite8 (R_RTC_INDEX2, R_RTC_REGISTERB); + IoWrite8 (R_RTC_TARGET2, DataUint8); + } + + return EFI_SUCCESS; +} + + -- cgit v1.2.3