]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformInitPei / BootMode.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
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.
9
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.
12
13
14 Module Name:
15
16
17 BootMode.c
18
19 Abstract:
20
21 EFI PEIM to provide the platform support functionality on the Thurley.
22
23
24 --*/
25
26 #include "PlatformEarlyInit.h"
27
28
29 #define NORMALMODE 0
30 #define RECOVERYMODE 1
31 #define SAFEMODE 2
32 #define MANUFACTURINGMODE 3
33
34 #define GPIO_SSUS_OFFSET 0x2000
35 #define PMU_PWRBTN_B_OFFSET 0x88
36
37 EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
38 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
39 &gEfiPeiBootInRecoveryModePpiGuid,
40 NULL
41 };
42
43 /**
44 Return the setting of the Bios configuration jumper
45
46 @param VOID
47
48 @retval RECOVERYMODE jumper set to recovery mode
49 @retval SAFEMODE jumper set to config mode
50 @retval NORMALMODE jumper in normal mode
51
52 **/
53 UINTN
54 GetConfigJumper(
55 IN CONST EFI_PEI_SERVICES **PeiServices,
56 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
57 )
58 {
59 //
60 // Do the Forced recovery detection based on logic chart above
61 //
62 if (IsRecoveryJumper(PeiServices, PlatformInfoHob)) {
63 return RECOVERYMODE;
64 } else {
65 return NORMALMODE;
66 }
67 }
68
69 BOOLEAN
70 CheckIfRecoveryMode(
71 IN CONST EFI_PEI_SERVICES **PeiServices,
72 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
73 )
74 {
75 if (GetConfigJumper(PeiServices, PlatformInfoHob) == RECOVERYMODE) {
76 return TRUE;
77 }
78 return FALSE;
79 }
80
81 BOOLEAN
82 CheckIfSafeMode(
83 IN CONST EFI_PEI_SERVICES **PeiServices,
84 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
85 )
86 {
87 if (GetConfigJumper(PeiServices, PlatformInfoHob) == SAFEMODE) {
88 return TRUE;
89 }
90 return FALSE;
91 }
92
93 BOOLEAN
94 CheckIfManufacturingMode (
95 IN CONST EFI_PEI_SERVICES **PeiServices
96 )
97 {
98 EFI_STATUS Status;
99 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
100 UINT32 Attributes;
101 UINTN DataSize;
102 CHAR16 VarName[] = MFGMODE_VARIABLE_NAME;
103 UINT8 MfgMode;
104
105 Status = (*PeiServices)->LocatePpi (
106 PeiServices,
107 &gEfiPeiReadOnlyVariable2PpiGuid,
108 0,
109 NULL,
110 (void **)&Variable
111 );
112 ASSERT_EFI_ERROR (Status);
113
114 //
115 // Check if SW MMJ mode
116 //
117 Attributes = (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
118 DataSize = sizeof (MFG_MODE_VAR);
119
120 Status = Variable->GetVariable (
121 Variable,
122 VarName,
123 &gMfgModeVariableGuid,
124 &Attributes,
125 &DataSize,
126 &MfgMode
127 );
128 if (!(EFI_ERROR (Status))) {
129 return TRUE;
130 }
131 return FALSE;
132 }
133
134 EFI_STATUS
135 UpdateBootMode (
136 IN CONST EFI_PEI_SERVICES **PeiServices,
137 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
138 )
139 {
140 EFI_STATUS Status;
141 EFI_BOOT_MODE BootMode;
142 UINT16 SleepType;
143 CHAR16 *strBootMode;
144 PEI_CAPSULE_PPI *Capsule;
145 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
146 SYSTEM_CONFIGURATION SystemConfiguration;
147 UINTN VarSize;
148 volatile UINT32 GpioValue;
149 BOOLEAN IsFirstBoot;
150 UINT32 Data32;
151
152 Status = (*PeiServices)->GetBootMode(
153 PeiServices,
154 &BootMode
155 );
156 ASSERT_EFI_ERROR (Status);
157 if (BootMode == BOOT_IN_RECOVERY_MODE){
158 return Status;
159 }
160 GetWakeupEventAndSaveToHob (PeiServices);
161
162 //
163 // Let's assume things are OK if not told otherwise
164 //
165 BootMode = BOOT_WITH_FULL_CONFIGURATION;
166
167 //
168 // When this boot is WDT reset, the system needs booting with CrashDump function eanbled.
169 //
170 Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);
171
172 //
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.
175 //
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);
179 if (!IsFirstBoot){
180 VarSize = sizeof (SYSTEM_CONFIGURATION);
181 ZeroMem (&SystemConfiguration, sizeof (SYSTEM_CONFIGURATION));
182
183 Status = (*PeiServices)->LocatePpi (
184 PeiServices,
185 &gEfiPeiReadOnlyVariable2PpiGuid,
186 0,
187 NULL,
188 (void **)&Variable
189 );
190 ASSERT_EFI_ERROR (Status);
191
192 //
193 // Use normal setup default from NVRAM variable,
194 // the Platform Mode (manufacturing/safe/normal) is handle in PeiGetVariable.
195 //
196 VarSize = sizeof(SYSTEM_CONFIGURATION);
197 Status = Variable->GetVariable (
198 Variable,
199 L"Setup",
200 &gEfiSetupVariableGuid,
201 NULL,
202 &VarSize,
203 &SystemConfiguration
204 );
205
206 if (SystemConfiguration.FastBoot == 1) {
207 BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
208 }
209 }
210 }
211
212 //
213 // Check if we need to boot in forced recovery mode
214 //
215 if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
216 BootMode = BOOT_IN_RECOVERY_MODE;
217 }
218
219 if (BootMode == BOOT_IN_RECOVERY_MODE) {
220 Status = (*PeiServices)->InstallPpi (
221 PeiServices,
222 &mPpiListRecoveryBootMode
223 );
224 ASSERT_EFI_ERROR (Status);
225 } else {
226 if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {
227 switch (SleepType) {
228 case V_PCH_ACPI_PM1_CNT_S3:
229 BootMode = BOOT_ON_S3_RESUME;
230
231 //
232 // Determine if we're in capsule update mode
233 //
234 Status = (*PeiServices)->LocatePpi (
235 PeiServices,
236 &gPeiCapsulePpiGuid,
237 0,
238 NULL,
239 (void **)&Capsule
240 );
241
242 if (Status == EFI_SUCCESS) {
243 if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {
244 BootMode = BOOT_ON_FLASH_UPDATE;
245 }
246 }
247
248 break;
249
250 case V_PCH_ACPI_PM1_CNT_S4:
251 BootMode = BOOT_ON_S4_RESUME;
252 break;
253
254 case V_PCH_ACPI_PM1_CNT_S5:
255 BootMode = BOOT_ON_S5_RESUME;
256 break;
257 } // switch (SleepType)
258 }
259
260 //
261 // Check for Safe Mode
262 //
263 }
264
265 switch (BootMode) {
266 case BOOT_WITH_FULL_CONFIGURATION:
267 strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
268 break;
269 case BOOT_WITH_MINIMAL_CONFIGURATION:
270 strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
271 break;
272 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
273 strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
274 break;
275 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
276 strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
277 break;
278 case BOOT_WITH_DEFAULT_SETTINGS:
279 strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
280 break;
281 case BOOT_ON_S4_RESUME:
282 strBootMode = L"BOOT_ON_S4_RESUME";
283 break;
284 case BOOT_ON_S5_RESUME:
285 strBootMode = L"BOOT_ON_S5_RESUME";
286 break;
287 case BOOT_ON_S2_RESUME:
288 strBootMode = L"BOOT_ON_S2_RESUME";
289 break;
290 case BOOT_ON_S3_RESUME:
291 strBootMode = L"BOOT_ON_S3_RESUME";
292 break;
293 case BOOT_ON_FLASH_UPDATE:
294 strBootMode = L"BOOT_ON_FLASH_UPDATE";
295 break;
296 case BOOT_IN_RECOVERY_MODE:
297 strBootMode = L"BOOT_IN_RECOVERY_MODE";
298 break;
299 default:
300 strBootMode = L"Unknown boot mode";
301 } // switch (BootMode)
302
303 DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));
304 Status = (*PeiServices)->SetBootMode(
305 PeiServices,
306 BootMode
307 );
308 ASSERT_EFI_ERROR (Status);
309
310 return Status;
311 }
312
313 /**
314 Get sleep type after wakeup
315
316 @param PeiServices Pointer to the PEI Service Table.
317 @param SleepType Sleep type to be returned.
318
319 @retval TRUE A wake event occured without power failure.
320 @retval FALSE Power failure occured or not a wakeup.
321
322 **/
323 BOOLEAN
324 GetSleepTypeAfterWakeup (
325 IN CONST EFI_PEI_SERVICES **PeiServices,
326 OUT UINT16 *SleepType
327 )
328 {
329 UINT16 Pm1Sts;
330 UINT16 Pm1Cnt;
331 UINT16 GenPmCon1;
332 GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
333
334 //
335 // Read the ACPI registers
336 //
337 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);
338 Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
339
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)) {
342 //
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
346 // power failure.
347 //
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);
351 }
352 //
353 // Clear Wake Status (WAK_STS)
354 //
355 IoWrite16 ((ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS), B_PCH_ACPI_PM1_STS_WAK);
356 }
357 //
358 // Get sleep type if a wake event occurred and there is no power failure
359 //
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;
362 return TRUE;
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;
365 return TRUE;
366 }
367 return FALSE;
368 }
369
370 VOID
371 SetPlatformBootMode (
372 IN CONST EFI_PEI_SERVICES **PeiServices,
373 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
374 )
375 {
376 EFI_PLATFORM_SETUP_ID PlatformSetupId;
377
378 ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));
379
380 CopyMem (&PlatformSetupId.SetupGuid,
381 &gEfiNormalSetupGuid,
382 sizeof (EFI_GUID));
383
384 if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {
385 //
386 // Recovery mode
387 //
388 CopyMem (&PlatformSetupId.SetupName,
389 SAFE_SETUP_NAME,
390 StrSize (SAFE_SETUP_NAME));
391 PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;
392 } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {
393 //
394 // Safe mode also called config mode or maintenace mode.
395 //
396 CopyMem (&PlatformSetupId.SetupName,
397 SAFE_SETUP_NAME,
398 StrSize (SAFE_SETUP_NAME));
399 PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;
400
401 } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {
402 //
403 // Manufacturing mode
404 //
405 CopyMem (&PlatformSetupId.SetupName,
406 MANUFACTURE_SETUP_NAME,
407 StrSize (MANUFACTURE_SETUP_NAME));
408 PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;
409
410 } else {
411 //
412 // Default to normal mode.
413 //
414 CopyMem (&PlatformSetupId.SetupName,
415 &NORMAL_SETUP_NAME,
416 StrSize (NORMAL_SETUP_NAME));
417 PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;
418 }
419
420 BuildGuidDataHob (
421 &gEfiPlatformBootModeGuid,
422 &PlatformSetupId,
423 sizeof (EFI_PLATFORM_SETUP_ID)
424 );
425 return;
426 }