3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
16 EFI PEIM to provide the platform support functionality on the Thurley.
21 #include "PlatformEarlyInit.h"
25 #define RECOVERYMODE 1
27 #define MANUFACTURINGMODE 3
29 #define GPIO_SSUS_OFFSET 0x2000
30 #define PMU_PWRBTN_B_OFFSET 0x88
32 EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode
= {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
34 &gEfiPeiBootInRecoveryModePpiGuid
,
39 Return the setting of the Bios configuration jumper
43 @retval RECOVERYMODE jumper set to recovery mode
44 @retval SAFEMODE jumper set to config mode
45 @retval NORMALMODE jumper in normal mode
50 IN CONST EFI_PEI_SERVICES
**PeiServices
,
51 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
55 // Do the Forced recovery detection based on logic chart above
57 if (IsRecoveryJumper(PeiServices
, PlatformInfoHob
)) {
66 IN CONST EFI_PEI_SERVICES
**PeiServices
,
67 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
70 if (GetConfigJumper(PeiServices
, PlatformInfoHob
) == RECOVERYMODE
) {
78 IN CONST EFI_PEI_SERVICES
**PeiServices
,
79 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
82 if (GetConfigJumper(PeiServices
, PlatformInfoHob
) == SAFEMODE
) {
89 CheckIfManufacturingMode (
90 IN CONST EFI_PEI_SERVICES
**PeiServices
94 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
97 CHAR16 VarName
[] = MFGMODE_VARIABLE_NAME
;
100 Status
= (*PeiServices
)->LocatePpi (
102 &gEfiPeiReadOnlyVariable2PpiGuid
,
107 ASSERT_EFI_ERROR (Status
);
110 // Check if SW MMJ mode
112 Attributes
= (EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
);
113 DataSize
= sizeof (MFG_MODE_VAR
);
115 Status
= Variable
->GetVariable (
118 &gMfgModeVariableGuid
,
123 if (!(EFI_ERROR (Status
))) {
131 IN CONST EFI_PEI_SERVICES
**PeiServices
,
132 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
136 EFI_BOOT_MODE BootMode
;
139 PEI_CAPSULE_PPI
*Capsule
;
140 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
141 SYSTEM_CONFIGURATION SystemConfiguration
;
143 volatile UINT32 GpioValue
;
147 Status
= (*PeiServices
)->GetBootMode(
151 ASSERT_EFI_ERROR (Status
);
152 if (BootMode
== BOOT_IN_RECOVERY_MODE
){
155 GetWakeupEventAndSaveToHob (PeiServices
);
158 // Let's assume things are OK if not told otherwise
160 BootMode
= BOOT_WITH_FULL_CONFIGURATION
;
163 // When this boot is WDT reset, the system needs booting with CrashDump function eanbled.
165 Data32
= IoRead32 (ACPI_BASE_ADDRESS
+ R_PCH_TCO_STS
);
168 // Check Power Button, click the power button, the system will boot in fast boot mode,
169 // if it is pressed and hold for a second, it will boot in FullConfiguration/setup mode.
171 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ GPIO_SSUS_OFFSET
+ PMU_PWRBTN_B_OFFSET
); // The value of GPIOS_16 (PMU_PWRBTN_B)
172 if (((GpioValue
& BIT0
) != 0)&&((Data32
& B_PCH_TCO_STS_SECOND_TO
) != B_PCH_TCO_STS_SECOND_TO
)){
173 IsFirstBoot
= PcdGetBool(PcdBootState
);
175 VarSize
= sizeof (SYSTEM_CONFIGURATION
);
176 ZeroMem (&SystemConfiguration
, sizeof (SYSTEM_CONFIGURATION
));
178 Status
= (*PeiServices
)->LocatePpi (
180 &gEfiPeiReadOnlyVariable2PpiGuid
,
185 ASSERT_EFI_ERROR (Status
);
188 // Use normal setup default from NVRAM variable,
189 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
191 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
192 Status
= Variable
->GetVariable (
195 &gEfiSetupVariableGuid
,
200 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
201 //The setup variable is corrupted
202 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
203 Status
= Variable
->GetVariable(
206 &gEfiSetupVariableGuid
,
211 ASSERT_EFI_ERROR (Status
);
214 if (SystemConfiguration
.FastBoot
== 1) {
215 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
221 // Check if we need to boot in forced recovery mode
223 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
224 BootMode
= BOOT_IN_RECOVERY_MODE
;
227 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
228 Status
= (*PeiServices
)->InstallPpi (
230 &mPpiListRecoveryBootMode
232 ASSERT_EFI_ERROR (Status
);
234 if (GetSleepTypeAfterWakeup (PeiServices
, &SleepType
)) {
236 case V_PCH_ACPI_PM1_CNT_S3
:
237 BootMode
= BOOT_ON_S3_RESUME
;
240 // Determine if we're in capsule update mode
242 Status
= (*PeiServices
)->LocatePpi (
250 if (Status
== EFI_SUCCESS
) {
251 if (Capsule
->CheckCapsuleUpdate ((EFI_PEI_SERVICES
**)PeiServices
) == EFI_SUCCESS
) {
252 BootMode
= BOOT_ON_FLASH_UPDATE
;
258 case V_PCH_ACPI_PM1_CNT_S4
:
259 BootMode
= BOOT_ON_S4_RESUME
;
262 case V_PCH_ACPI_PM1_CNT_S5
:
263 BootMode
= BOOT_ON_S5_RESUME
;
265 } // switch (SleepType)
269 // Check for Safe Mode
274 case BOOT_WITH_FULL_CONFIGURATION
:
275 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION";
277 case BOOT_WITH_MINIMAL_CONFIGURATION
:
278 strBootMode
= L
"BOOT_WITH_MINIMAL_CONFIGURATION";
280 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
281 strBootMode
= L
"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
283 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
284 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
286 case BOOT_WITH_DEFAULT_SETTINGS
:
287 strBootMode
= L
"BOOT_WITH_DEFAULT_SETTINGS";
289 case BOOT_ON_S4_RESUME
:
290 strBootMode
= L
"BOOT_ON_S4_RESUME";
292 case BOOT_ON_S5_RESUME
:
293 strBootMode
= L
"BOOT_ON_S5_RESUME";
295 case BOOT_ON_S2_RESUME
:
296 strBootMode
= L
"BOOT_ON_S2_RESUME";
298 case BOOT_ON_S3_RESUME
:
299 strBootMode
= L
"BOOT_ON_S3_RESUME";
301 case BOOT_ON_FLASH_UPDATE
:
302 strBootMode
= L
"BOOT_ON_FLASH_UPDATE";
304 case BOOT_IN_RECOVERY_MODE
:
305 strBootMode
= L
"BOOT_IN_RECOVERY_MODE";
308 strBootMode
= L
"Unknown boot mode";
309 } // switch (BootMode)
311 DEBUG ((EFI_D_ERROR
, "Setting BootMode to %s\n", strBootMode
));
312 Status
= (*PeiServices
)->SetBootMode(
316 ASSERT_EFI_ERROR (Status
);
322 Get sleep type after wakeup
324 @param PeiServices Pointer to the PEI Service Table.
325 @param SleepType Sleep type to be returned.
327 @retval TRUE A wake event occured without power failure.
328 @retval FALSE Power failure occured or not a wakeup.
332 GetSleepTypeAfterWakeup (
333 IN CONST EFI_PEI_SERVICES
**PeiServices
,
334 OUT UINT16
*SleepType
340 GenPmCon1
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
343 // Read the ACPI registers
345 Pm1Sts
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
);
346 Pm1Cnt
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
);
348 if ((GenPmCon1
& (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR
| B_PCH_PMC_GEN_PMCON_GEN_RST_STS
)) ||
349 (Pm1Sts
& B_PCH_ACPI_PM1_STS_PRBTNOR
)) {
351 // If power failure indicator, then don't attempt s3 resume.
352 // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
353 // lost already. This is to make sure no one will use PM1_CNT to check for S3 after
356 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
357 Pm1Cnt
= ((Pm1Cnt
& ~B_PCH_ACPI_PM1_CNT_SLP_TYP
) | V_PCH_ACPI_PM1_CNT_S5
);
358 IoWrite16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
, Pm1Cnt
);
361 // Clear Wake Status (WAK_STS)
363 IoWrite16 ((ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
), B_PCH_ACPI_PM1_STS_WAK
);
366 // Get sleep type if a wake event occurred and there is no power failure
368 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
369 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
371 } else if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S4
){
372 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
379 SetPlatformBootMode (
380 IN CONST EFI_PEI_SERVICES
**PeiServices
,
381 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
384 EFI_PLATFORM_SETUP_ID PlatformSetupId
;
386 ZeroMem(&PlatformSetupId
, sizeof (EFI_PLATFORM_SETUP_ID
));
388 CopyMem (&PlatformSetupId
.SetupGuid
,
389 &gEfiNormalSetupGuid
,
392 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
396 CopyMem (&PlatformSetupId
.SetupName
,
398 StrSize (NORMAL_SETUP_NAME
));
399 PlatformSetupId
.PlatformBootMode
= PLATFORM_RECOVERY_MODE
;
400 } else if (CheckIfSafeMode(PeiServices
, PlatformInfoHob
)) {
402 // Safe mode also called config mode or maintenace mode.
404 CopyMem (&PlatformSetupId
.SetupName
,
406 StrSize (NORMAL_SETUP_NAME
));
407 PlatformSetupId
.PlatformBootMode
= PLATFORM_SAFE_MODE
;
409 } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
411 // Manufacturing mode
413 CopyMem (&PlatformSetupId
.SetupName
,
414 MANUFACTURE_SETUP_NAME
,
415 StrSize (MANUFACTURE_SETUP_NAME
));
416 PlatformSetupId
.PlatformBootMode
= PLATFORM_MANUFACTURING_MODE
;
420 // Default to normal mode.
422 CopyMem (&PlatformSetupId
.SetupName
,
424 StrSize (NORMAL_SETUP_NAME
));
425 PlatformSetupId
.PlatformBootMode
= PLATFORM_NORMAL_MODE
;
429 &gEfiPlatformBootModeGuid
,
431 sizeof (EFI_PLATFORM_SETUP_ID
)