+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-Module Name:\r
-\r
-\r
- BootMode.c\r
-\r
-Abstract:\r
-\r
- EFI PEIM to provide the platform support functionality on the Thurley.\r
-\r
-\r
---*/\r
-\r
-#include "PlatformEarlyInit.h"\r
-\r
-\r
-#define NORMALMODE 0\r
-#define RECOVERYMODE 1\r
-#define SAFEMODE 2\r
-#define MANUFACTURINGMODE 3\r
-\r
-#define GPIO_SSUS_OFFSET 0x2000\r
-#define PMU_PWRBTN_B_OFFSET 0x88\r
-\r
-EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gEfiPeiBootInRecoveryModePpiGuid,\r
- NULL\r
-};\r
-\r
-/**\r
- Return the setting of the Bios configuration jumper\r
-\r
- @param VOID\r
-\r
- @retval RECOVERYMODE jumper set to recovery mode\r
- @retval SAFEMODE jumper set to config mode\r
- @retval NORMALMODE jumper in normal mode\r
-\r
-**/\r
-UINTN\r
-GetConfigJumper(\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
- )\r
-{\r
- //\r
- // Do the Forced recovery detection based on logic chart above\r
- //\r
- if (IsRecoveryJumper(PeiServices, PlatformInfoHob)) {\r
- return RECOVERYMODE;\r
- } else {\r
- return NORMALMODE;\r
- }\r
-}\r
-\r
-BOOLEAN\r
-CheckIfRecoveryMode(\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
- )\r
-{\r
- if (GetConfigJumper(PeiServices, PlatformInfoHob) == RECOVERYMODE) {\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-CheckIfSafeMode(\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
- )\r
-{\r
- if (GetConfigJumper(PeiServices, PlatformInfoHob) == SAFEMODE) {\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-CheckIfManufacturingMode (\r
- IN CONST EFI_PEI_SERVICES **PeiServices\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
- UINT32 Attributes;\r
- UINTN DataSize;\r
- CHAR16 VarName[] = MFGMODE_VARIABLE_NAME;\r
- UINT8 MfgMode;\r
-\r
- Status = (*PeiServices)->LocatePpi (\r
- PeiServices,\r
- &gEfiPeiReadOnlyVariable2PpiGuid,\r
- 0,\r
- NULL,\r
- (void **)&Variable\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Check if SW MMJ mode\r
- //\r
- Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);\r
- DataSize = sizeof (MFG_MODE_VAR);\r
-\r
- Status = Variable->GetVariable (\r
- Variable,\r
- VarName,\r
- &gMfgModeVariableGuid,\r
- &Attributes,\r
- &DataSize,\r
- &MfgMode\r
- );\r
- if (!(EFI_ERROR (Status))) {\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateBootMode (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BOOT_MODE BootMode;\r
- UINT16 SleepType;\r
- CHAR16 *strBootMode;\r
- PEI_CAPSULE_PPI *Capsule;\r
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
- SYSTEM_CONFIGURATION SystemConfiguration;\r
- UINTN VarSize;\r
- volatile UINT32 GpioValue;\r
- BOOLEAN IsFirstBoot;\r
- UINT32 Data32;\r
-\r
- Status = (*PeiServices)->GetBootMode(\r
- PeiServices,\r
- &BootMode\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- if (BootMode == BOOT_IN_RECOVERY_MODE){\r
- return Status;\r
- }\r
- GetWakeupEventAndSaveToHob (PeiServices);\r
-\r
- //\r
- // Let's assume things are OK if not told otherwise\r
- //\r
- BootMode = BOOT_WITH_FULL_CONFIGURATION;\r
-\r
- //\r
- // When this boot is WDT reset, the system needs booting with CrashDump function eanbled.\r
- //\r
- Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);\r
-\r
- //\r
- // Check Power Button, click the power button, the system will boot in fast boot mode,\r
- // if it is pressed and hold for a second, it will boot in FullConfiguration/setup mode.\r
- //\r
- GpioValue = MmioRead32 (IO_BASE_ADDRESS + GPIO_SSUS_OFFSET + PMU_PWRBTN_B_OFFSET); // The value of GPIOS_16 (PMU_PWRBTN_B)\r
- if (((GpioValue & BIT0) != 0)&&((Data32 & B_PCH_TCO_STS_SECOND_TO) != B_PCH_TCO_STS_SECOND_TO)){\r
- IsFirstBoot = PcdGetBool(PcdBootState);\r
- if (!IsFirstBoot){\r
- VarSize = sizeof (SYSTEM_CONFIGURATION);\r
- ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));\r
-\r
- Status = (*PeiServices)->LocatePpi (\r
- PeiServices,\r
- &gEfiPeiReadOnlyVariable2PpiGuid,\r
- 0,\r
- NULL,\r
- (void **)&Variable\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Use normal setup default from NVRAM variable,\r
- // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.\r
- //\r
- VarSize = sizeof(SYSTEM_CONFIGURATION);\r
- Status = Variable->GetVariable (\r
- Variable,\r
- L"Setup",\r
- &gEfiSetupVariableGuid,\r
- NULL,\r
- &VarSize,\r
- &SystemConfiguration\r
- );\r
- if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {\r
- //The setup variable is corrupted\r
- VarSize = sizeof(SYSTEM_CONFIGURATION);\r
- Status = Variable->GetVariable(\r
- Variable,\r
- L"SetupRecovery",\r
- &gEfiSetupVariableGuid,\r
- NULL,\r
- &VarSize,\r
- &SystemConfiguration\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } \r
-\r
- if (SystemConfiguration.FastBoot == 1) {\r
- BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Check if we need to boot in forced recovery mode\r
- //\r
- if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {\r
- BootMode = BOOT_IN_RECOVERY_MODE;\r
- }\r
-\r
- if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
- Status = (*PeiServices)->InstallPpi (\r
- PeiServices,\r
- &mPpiListRecoveryBootMode\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } else {\r
- if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {\r
- switch (SleepType) {\r
- case V_PCH_ACPI_PM1_CNT_S3:\r
- BootMode = BOOT_ON_S3_RESUME;\r
-\r
- //\r
- // Determine if we're in capsule update mode\r
- //\r
- Status = (*PeiServices)->LocatePpi (\r
- PeiServices,\r
- &gPeiCapsulePpiGuid,\r
- 0,\r
- NULL,\r
- (void **)&Capsule\r
- );\r
-\r
- if (Status == EFI_SUCCESS) {\r
- if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {\r
- BootMode = BOOT_ON_FLASH_UPDATE;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case V_PCH_ACPI_PM1_CNT_S4:\r
- BootMode = BOOT_ON_S4_RESUME;\r
- break;\r
-\r
- case V_PCH_ACPI_PM1_CNT_S5:\r
- BootMode = BOOT_ON_S5_RESUME;\r
- break;\r
- } // switch (SleepType)\r
- }\r
-\r
- //\r
- // Check for Safe Mode\r
- //\r
- }\r
-\r
- switch (BootMode) {\r
- case BOOT_WITH_FULL_CONFIGURATION:\r
- strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";\r
- break;\r
- case BOOT_WITH_MINIMAL_CONFIGURATION:\r
- strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";\r
- break;\r
- case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
- strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";\r
- break;\r
- case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:\r
- strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";\r
- break;\r
- case BOOT_WITH_DEFAULT_SETTINGS:\r
- strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";\r
- break;\r
- case BOOT_ON_S4_RESUME:\r
- strBootMode = L"BOOT_ON_S4_RESUME";\r
- break;\r
- case BOOT_ON_S5_RESUME:\r
- strBootMode = L"BOOT_ON_S5_RESUME";\r
- break;\r
- case BOOT_ON_S2_RESUME:\r
- strBootMode = L"BOOT_ON_S2_RESUME";\r
- break;\r
- case BOOT_ON_S3_RESUME:\r
- strBootMode = L"BOOT_ON_S3_RESUME";\r
- break;\r
- case BOOT_ON_FLASH_UPDATE:\r
- strBootMode = L"BOOT_ON_FLASH_UPDATE";\r
- break;\r
- case BOOT_IN_RECOVERY_MODE:\r
- strBootMode = L"BOOT_IN_RECOVERY_MODE";\r
- break;\r
- default:\r
- strBootMode = L"Unknown boot mode";\r
- } // switch (BootMode)\r
-\r
- DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));\r
- Status = (*PeiServices)->SetBootMode(\r
- PeiServices,\r
- BootMode\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Get sleep type after wakeup\r
-\r
- @param PeiServices Pointer to the PEI Service Table.\r
- @param SleepType Sleep type to be returned.\r
-\r
- @retval TRUE A wake event occured without power failure.\r
- @retval FALSE Power failure occured or not a wakeup.\r
-\r
-**/\r
-BOOLEAN\r
-GetSleepTypeAfterWakeup (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- OUT UINT16 *SleepType\r
- )\r
-{\r
- UINT16 Pm1Sts;\r
- UINT16 Pm1Cnt;\r
- UINT16 GenPmCon1;\r
- GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);\r
-\r
- //\r
- // Read the ACPI registers\r
- //\r
- Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);\r
- Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);\r
-\r
- if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR | B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||\r
- (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {\r
- //\r
- // If power failure indicator, then don't attempt s3 resume.\r
- // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has\r
- // lost already. This is to make sure no one will use PM1_CNT to check for S3 after\r
- // power failure.\r
- //\r
- if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {\r
- Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) | V_PCH_ACPI_PM1_CNT_S5);\r
- IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);\r
- }\r
- //\r
- // Clear Wake Status (WAK_STS)\r
- //\r
- IoWrite16 ((ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS), B_PCH_ACPI_PM1_STS_WAK);\r
- }\r
- //\r
- // Get sleep type if a wake event occurred and there is no power failure\r
- //\r
- if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {\r
- *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;\r
- return TRUE;\r
- } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4){\r
- *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-VOID\r
-SetPlatformBootMode (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
- )\r
-{\r
- EFI_PLATFORM_SETUP_ID PlatformSetupId;\r
-\r
- ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));\r
-\r
- CopyMem (&PlatformSetupId.SetupGuid,\r
- &gEfiNormalSetupGuid,\r
- sizeof (EFI_GUID));\r
-\r
- if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {\r
- //\r
- // Recovery mode\r
- //\r
- CopyMem (&PlatformSetupId.SetupName,\r
- &NORMAL_SETUP_NAME,\r
- StrSize (NORMAL_SETUP_NAME)); \r
- PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;\r
- } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {\r
- //\r
- // Safe mode also called config mode or maintenace mode.\r
- //\r
- CopyMem (&PlatformSetupId.SetupName,\r
- &NORMAL_SETUP_NAME,\r
- StrSize (NORMAL_SETUP_NAME));\r
- PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;\r
-\r
- } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {\r
- //\r
- // Manufacturing mode\r
- //\r
- CopyMem (&PlatformSetupId.SetupName,\r
- MANUFACTURE_SETUP_NAME,\r
- StrSize (MANUFACTURE_SETUP_NAME));\r
- PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;\r
-\r
- } else {\r
- //\r
- // Default to normal mode.\r
- //\r
- CopyMem (&PlatformSetupId.SetupName,\r
- &NORMAL_SETUP_NAME,\r
- StrSize (NORMAL_SETUP_NAME));\r
- PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;\r
- }\r
-\r
- BuildGuidDataHob (\r
- &gEfiPlatformBootModeGuid,\r
- &PlatformSetupId,\r
- sizeof (EFI_PLATFORM_SETUP_ID)\r
- );\r
- return;\r
-}\r