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
,
206 if (SystemConfiguration
.FastBoot
== 1) {
207 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
213 // Check if we need to boot in forced recovery mode
215 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
216 BootMode
= BOOT_IN_RECOVERY_MODE
;
219 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
220 Status
= (*PeiServices
)->InstallPpi (
222 &mPpiListRecoveryBootMode
224 ASSERT_EFI_ERROR (Status
);
226 if (GetSleepTypeAfterWakeup (PeiServices
, &SleepType
)) {
228 case V_PCH_ACPI_PM1_CNT_S3
:
229 BootMode
= BOOT_ON_S3_RESUME
;
232 // Determine if we're in capsule update mode
234 Status
= (*PeiServices
)->LocatePpi (
242 if (Status
== EFI_SUCCESS
) {
243 if (Capsule
->CheckCapsuleUpdate ((EFI_PEI_SERVICES
**)PeiServices
) == EFI_SUCCESS
) {
244 BootMode
= BOOT_ON_FLASH_UPDATE
;
250 case V_PCH_ACPI_PM1_CNT_S4
:
251 BootMode
= BOOT_ON_S4_RESUME
;
254 case V_PCH_ACPI_PM1_CNT_S5
:
255 BootMode
= BOOT_ON_S5_RESUME
;
257 } // switch (SleepType)
261 // Check for Safe Mode
266 case BOOT_WITH_FULL_CONFIGURATION
:
267 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION";
269 case BOOT_WITH_MINIMAL_CONFIGURATION
:
270 strBootMode
= L
"BOOT_WITH_MINIMAL_CONFIGURATION";
272 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
273 strBootMode
= L
"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
275 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
276 strBootMode
= L
"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
278 case BOOT_WITH_DEFAULT_SETTINGS
:
279 strBootMode
= L
"BOOT_WITH_DEFAULT_SETTINGS";
281 case BOOT_ON_S4_RESUME
:
282 strBootMode
= L
"BOOT_ON_S4_RESUME";
284 case BOOT_ON_S5_RESUME
:
285 strBootMode
= L
"BOOT_ON_S5_RESUME";
287 case BOOT_ON_S2_RESUME
:
288 strBootMode
= L
"BOOT_ON_S2_RESUME";
290 case BOOT_ON_S3_RESUME
:
291 strBootMode
= L
"BOOT_ON_S3_RESUME";
293 case BOOT_ON_FLASH_UPDATE
:
294 strBootMode
= L
"BOOT_ON_FLASH_UPDATE";
296 case BOOT_IN_RECOVERY_MODE
:
297 strBootMode
= L
"BOOT_IN_RECOVERY_MODE";
300 strBootMode
= L
"Unknown boot mode";
301 } // switch (BootMode)
303 DEBUG ((EFI_D_ERROR
, "Setting BootMode to %s\n", strBootMode
));
304 Status
= (*PeiServices
)->SetBootMode(
308 ASSERT_EFI_ERROR (Status
);
314 Get sleep type after wakeup
316 @param PeiServices Pointer to the PEI Service Table.
317 @param SleepType Sleep type to be returned.
319 @retval TRUE A wake event occured without power failure.
320 @retval FALSE Power failure occured or not a wakeup.
324 GetSleepTypeAfterWakeup (
325 IN CONST EFI_PEI_SERVICES
**PeiServices
,
326 OUT UINT16
*SleepType
332 GenPmCon1
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
335 // Read the ACPI registers
337 Pm1Sts
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
);
338 Pm1Cnt
= IoRead16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
);
340 if ((GenPmCon1
& (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR
| B_PCH_PMC_GEN_PMCON_GEN_RST_STS
)) ||
341 (Pm1Sts
& B_PCH_ACPI_PM1_STS_PRBTNOR
)) {
343 // If power failure indicator, then don't attempt s3 resume.
344 // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has
345 // lost already. This is to make sure no one will use PM1_CNT to check for S3 after
348 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
349 Pm1Cnt
= ((Pm1Cnt
& ~B_PCH_ACPI_PM1_CNT_SLP_TYP
) | V_PCH_ACPI_PM1_CNT_S5
);
350 IoWrite16 (ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_CNT
, Pm1Cnt
);
353 // Clear Wake Status (WAK_STS)
355 IoWrite16 ((ACPI_BASE_ADDRESS
+ R_PCH_ACPI_PM1_STS
), B_PCH_ACPI_PM1_STS_WAK
);
358 // Get sleep type if a wake event occurred and there is no power failure
360 if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S3
) {
361 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
363 } else if ((Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
) == V_PCH_ACPI_PM1_CNT_S4
){
364 *SleepType
= Pm1Cnt
& B_PCH_ACPI_PM1_CNT_SLP_TYP
;
371 SetPlatformBootMode (
372 IN CONST EFI_PEI_SERVICES
**PeiServices
,
373 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
376 EFI_PLATFORM_SETUP_ID PlatformSetupId
;
378 ZeroMem(&PlatformSetupId
, sizeof (EFI_PLATFORM_SETUP_ID
));
380 CopyMem (&PlatformSetupId
.SetupGuid
,
381 &gEfiNormalSetupGuid
,
384 if (CheckIfRecoveryMode(PeiServices
, PlatformInfoHob
)) {
388 CopyMem (&PlatformSetupId
.SetupName
,
390 StrSize (SAFE_SETUP_NAME
));
391 PlatformSetupId
.PlatformBootMode
= PLATFORM_RECOVERY_MODE
;
392 } else if (CheckIfSafeMode(PeiServices
, PlatformInfoHob
)) {
394 // Safe mode also called config mode or maintenace mode.
396 CopyMem (&PlatformSetupId
.SetupName
,
398 StrSize (SAFE_SETUP_NAME
));
399 PlatformSetupId
.PlatformBootMode
= PLATFORM_SAFE_MODE
;
401 } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
403 // Manufacturing mode
405 CopyMem (&PlatformSetupId
.SetupName
,
406 MANUFACTURE_SETUP_NAME
,
407 StrSize (MANUFACTURE_SETUP_NAME
));
408 PlatformSetupId
.PlatformBootMode
= PLATFORM_MANUFACTURING_MODE
;
412 // Default to normal mode.
414 CopyMem (&PlatformSetupId
.SetupName
,
416 StrSize (NORMAL_SETUP_NAME
));
417 PlatformSetupId
.PlatformBootMode
= PLATFORM_NORMAL_MODE
;
421 &gEfiPlatformBootModeGuid
,
423 sizeof (EFI_PLATFORM_SETUP_ID
)