3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 EFI PEIM to provide the platform support functionality on the Thurley.
26 #include "PlatformEarlyInit.h"
30 #define RECOVERYMODE 1
32 #define MANUFACTURINGMODE 3
34 #define GPIO_SSUS_OFFSET 0x2000
35 #define PMU_PWRBTN_B_OFFSET 0x88
37 EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode
= {
38 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
39 &gEfiPeiBootInRecoveryModePpiGuid
,
44 Return the setting of the Bios configuration jumper
48 @retval RECOVERYMODE jumper set to recovery mode
49 @retval SAFEMODE jumper set to config mode
50 @retval NORMALMODE jumper in normal mode
55 IN CONST EFI_PEI_SERVICES
**PeiServices
,
56 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
60 // Do the Forced recovery detection based on logic chart above
62 if (IsRecoveryJumper(PeiServices
, PlatformInfoHob
)) {
71 IN CONST EFI_PEI_SERVICES
**PeiServices
,
72 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
75 if (GetConfigJumper(PeiServices
, PlatformInfoHob
) == RECOVERYMODE
) {
83 IN CONST EFI_PEI_SERVICES
**PeiServices
,
84 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
87 if (GetConfigJumper(PeiServices
, PlatformInfoHob
) == SAFEMODE
) {
94 CheckIfManufacturingMode (
95 IN CONST EFI_PEI_SERVICES
**PeiServices
99 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
102 CHAR16 VarName
[] = MFGMODE_VARIABLE_NAME
;
105 Status
= (*PeiServices
)->LocatePpi (
107 &gEfiPeiReadOnlyVariable2PpiGuid
,
112 ASSERT_EFI_ERROR (Status
);
115 // Check if SW MMJ mode
117 Attributes
= (EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
);
118 DataSize
= sizeof (MFG_MODE_VAR
);
120 Status
= Variable
->GetVariable (
123 &gMfgModeVariableGuid
,
128 if (!(EFI_ERROR (Status
))) {
136 IN CONST EFI_PEI_SERVICES
**PeiServices
,
137 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
141 EFI_BOOT_MODE BootMode
;
144 PEI_CAPSULE_PPI
*Capsule
;
145 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
;
146 SYSTEM_CONFIGURATION SystemConfiguration
;
148 volatile UINT32 GpioValue
;
152 Status
= (*PeiServices
)->GetBootMode(
156 ASSERT_EFI_ERROR (Status
);
157 if (BootMode
== BOOT_IN_RECOVERY_MODE
){
160 GetWakeupEventAndSaveToHob (PeiServices
);
163 // Let's assume things are OK if not told otherwise
165 BootMode
= BOOT_WITH_FULL_CONFIGURATION
;
168 // When this boot is WDT reset, the system needs booting with CrashDump function eanbled.
170 Data32
= IoRead32 (ACPI_BASE_ADDRESS
+ R_PCH_TCO_STS
);
173 // Check Power Button, click the power button, the system will boot in fast boot mode,
174 // if it is pressed and hold for a second, it will boot in FullConfiguration/setup mode.
176 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ GPIO_SSUS_OFFSET
+ PMU_PWRBTN_B_OFFSET
); // The value of GPIOS_16 (PMU_PWRBTN_B)
177 if (((GpioValue
& BIT0
) != 0)&&((Data32
& B_PCH_TCO_STS_SECOND_TO
) != B_PCH_TCO_STS_SECOND_TO
)){
178 IsFirstBoot
= PcdGetBool(PcdBootState
);
180 VarSize
= sizeof (SYSTEM_CONFIGURATION
);
181 ZeroMem (&SystemConfiguration
, sizeof (SYSTEM_CONFIGURATION
));
183 Status
= (*PeiServices
)->LocatePpi (
185 &gEfiPeiReadOnlyVariable2PpiGuid
,
190 ASSERT_EFI_ERROR (Status
);
193 // Use normal setup default from NVRAM variable,
194 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
196 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
197 Status
= Variable
->GetVariable (
200 &gEfiSetupVariableGuid
,
205 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
206 //The setup variable is corrupted
207 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
208 Status
= Variable
->GetVariable(
211 &gEfiSetupVariableGuid
,
216 ASSERT_EFI_ERROR (Status
);
219 if (SystemConfiguration
.FastBoot
== 1) {
220 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
226 // Check if we need to boot in forced recovery mode
228 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
229 BootMode
= BOOT_IN_RECOVERY_MODE
;
232 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
233 Status
= (*PeiServices
)->InstallPpi (
235 &mPpiListRecoveryBootMode
237 ASSERT_EFI_ERROR (Status
);
239 if (GetSleepTypeAfterWakeup (PeiServices
, &SleepType
)) {
241 case V_PCH_ACPI_PM1_CNT_S3
:
242 BootMode
= BOOT_ON_S3_RESUME
;
245 // Determine if we're in capsule update mode
247 Status
= (*PeiServices
)->LocatePpi (
255 if (Status
== EFI_SUCCESS
) {
256 if (Capsule
->CheckCapsuleUpdate ((EFI_PEI_SERVICES
**)PeiServices
) == EFI_SUCCESS
) {
257 BootMode
= BOOT_ON_FLASH_UPDATE
;
263 case V_PCH_ACPI_PM1_CNT_S4
:
264 BootMode
= BOOT_ON_S4_RESUME
;
267 case V_PCH_ACPI_PM1_CNT_S5
:
268 BootMode
= BOOT_ON_S5_RESUME
;
270 } // switch (SleepType)
274 // Check for Safe Mode
279 case BOOT_WITH_FULL_CONFIGURATION
:
280 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION";
282 case BOOT_WITH_MINIMAL_CONFIGURATION
:
283 strBootMode
= L
"BOOT_WITH_MINIMAL_CONFIGURATION";
285 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
286 strBootMode
= L
"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
288 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
289 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
291 case BOOT_WITH_DEFAULT_SETTINGS
:
292 strBootMode
= L
"BOOT_WITH_DEFAULT_SETTINGS";
294 case BOOT_ON_S4_RESUME
:
295 strBootMode
= L
"BOOT_ON_S4_RESUME";
297 case BOOT_ON_S5_RESUME
:
298 strBootMode
= L
"BOOT_ON_S5_RESUME";
300 case BOOT_ON_S2_RESUME
:
301 strBootMode
= L
"BOOT_ON_S2_RESUME";
303 case BOOT_ON_S3_RESUME
:
304 strBootMode
= L
"BOOT_ON_S3_RESUME";
306 case BOOT_ON_FLASH_UPDATE
:
307 strBootMode
= L
"BOOT_ON_FLASH_UPDATE";
309 case BOOT_IN_RECOVERY_MODE
:
310 strBootMode
= L
"BOOT_IN_RECOVERY_MODE";
313 strBootMode
= L
"Unknown boot mode";
314 } // switch (BootMode)
316 DEBUG ((EFI_D_ERROR
, "Setting BootMode to %s\n", strBootMode
));
317 Status
= (*PeiServices
)->SetBootMode(
321 ASSERT_EFI_ERROR (Status
);
327 Get sleep type after wakeup
329 @param PeiServices Pointer to the PEI Service Table.
330 @param SleepType Sleep type to be returned.
332 @retval TRUE A wake event occured without power failure.
333 @retval FALSE Power failure occured or not a wakeup.
337 GetSleepTypeAfterWakeup (
338 IN CONST EFI_PEI_SERVICES
**PeiServices
,
339 OUT UINT16
*SleepType
345 GenPmCon1
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
348 // Read the ACPI registers
350 Pm1Sts
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
);
351 Pm1Cnt
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
);
353 if ((GenPmCon1
& (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR
| B_PCH_PMC_GEN_PMCON_GEN_RST_STS
)) ||
354 (Pm1Sts
& B_PCH_ACPI_PM1_STS_PRBTNOR
)) {
356 // If power failure indicator, then don't attempt s3 resume.
357 // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
358 // lost already. This is to make sure no one will use PM1_CNT to check for S3 after
361 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
362 Pm1Cnt
= ((Pm1Cnt
& ~B_PCH_ACPI_PM1_CNT_SLP_TYP
) | V_PCH_ACPI_PM1_CNT_S5
);
363 IoWrite16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
, Pm1Cnt
);
366 // Clear Wake Status (WAK_STS)
368 IoWrite16 ((ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
), B_PCH_ACPI_PM1_STS_WAK
);
371 // Get sleep type if a wake event occurred and there is no power failure
373 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
374 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
376 } else if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S4
){
377 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
384 SetPlatformBootMode (
385 IN CONST EFI_PEI_SERVICES
**PeiServices
,
386 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
389 EFI_PLATFORM_SETUP_ID PlatformSetupId
;
391 ZeroMem(&PlatformSetupId
, sizeof (EFI_PLATFORM_SETUP_ID
));
393 CopyMem (&PlatformSetupId
.SetupGuid
,
394 &gEfiNormalSetupGuid
,
397 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
401 CopyMem (&PlatformSetupId
.SetupName
,
403 StrSize (NORMAL_SETUP_NAME
));
404 PlatformSetupId
.PlatformBootMode
= PLATFORM_RECOVERY_MODE
;
405 } else if (CheckIfSafeMode(PeiServices
, PlatformInfoHob
)) {
407 // Safe mode also called config mode or maintenace mode.
409 CopyMem (&PlatformSetupId
.SetupName
,
411 StrSize (NORMAL_SETUP_NAME
));
412 PlatformSetupId
.PlatformBootMode
= PLATFORM_SAFE_MODE
;
414 } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
416 // Manufacturing mode
418 CopyMem (&PlatformSetupId
.SetupName
,
419 MANUFACTURE_SETUP_NAME
,
420 StrSize (MANUFACTURE_SETUP_NAME
));
421 PlatformSetupId
.PlatformBootMode
= PLATFORM_MANUFACTURING_MODE
;
425 // Default to normal mode.
427 CopyMem (&PlatformSetupId
.SetupName
,
429 StrSize (NORMAL_SETUP_NAME
));
430 PlatformSetupId
.PlatformBootMode
= PLATFORM_NORMAL_MODE
;
434 &gEfiPlatformBootModeGuid
,
436 sizeof (EFI_PLATFORM_SETUP_ID
)