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