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