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