]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/PlatformInitPei/BootMode.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[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
205\r
206 if (SystemConfiguration.FastBoot == 1) {\r
207 BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;\r
208 }\r
209 }\r
210 }\r
211\r
212 //\r
213 // Check if we need to boot in forced recovery mode\r
214 //\r
215 if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {\r
216 BootMode = BOOT_IN_RECOVERY_MODE;\r
217 }\r
218\r
219 if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
220 Status = (*PeiServices)->InstallPpi (\r
221 PeiServices,\r
222 &mPpiListRecoveryBootMode\r
223 );\r
224 ASSERT_EFI_ERROR (Status);\r
225 } else {\r
226 if (GetSleepTypeAfterWakeup (PeiServices, &SleepType)) {\r
227 switch (SleepType) {\r
228 case V_PCH_ACPI_PM1_CNT_S3:\r
229 BootMode = BOOT_ON_S3_RESUME;\r
230\r
231 //\r
232 // Determine if we're in capsule update mode\r
233 //\r
234 Status = (*PeiServices)->LocatePpi (\r
235 PeiServices,\r
236 &gPeiCapsulePpiGuid,\r
237 0,\r
238 NULL,\r
239 (void **)&Capsule\r
240 );\r
241\r
242 if (Status == EFI_SUCCESS) {\r
243 if (Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES**)PeiServices) == EFI_SUCCESS) {\r
244 BootMode = BOOT_ON_FLASH_UPDATE;\r
245 }\r
246 }\r
247\r
248 break;\r
249\r
250 case V_PCH_ACPI_PM1_CNT_S4:\r
251 BootMode = BOOT_ON_S4_RESUME;\r
252 break;\r
253\r
254 case V_PCH_ACPI_PM1_CNT_S5:\r
255 BootMode = BOOT_ON_S5_RESUME;\r
256 break;\r
257 } // switch (SleepType)\r
258 }\r
259\r
260 //\r
261 // Check for Safe Mode\r
262 //\r
263 }\r
264\r
265 switch (BootMode) {\r
266 case BOOT_WITH_FULL_CONFIGURATION:\r
267 strBootMode = L"BOOT_WITH_FULL_CONFIGURATION";\r
268 break;\r
269 case BOOT_WITH_MINIMAL_CONFIGURATION:\r
270 strBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";\r
271 break;\r
272 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
273 strBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";\r
274 break;\r
275 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:\r
276 strBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";\r
277 break;\r
278 case BOOT_WITH_DEFAULT_SETTINGS:\r
279 strBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";\r
280 break;\r
281 case BOOT_ON_S4_RESUME:\r
282 strBootMode = L"BOOT_ON_S4_RESUME";\r
283 break;\r
284 case BOOT_ON_S5_RESUME:\r
285 strBootMode = L"BOOT_ON_S5_RESUME";\r
286 break;\r
287 case BOOT_ON_S2_RESUME:\r
288 strBootMode = L"BOOT_ON_S2_RESUME";\r
289 break;\r
290 case BOOT_ON_S3_RESUME:\r
291 strBootMode = L"BOOT_ON_S3_RESUME";\r
292 break;\r
293 case BOOT_ON_FLASH_UPDATE:\r
294 strBootMode = L"BOOT_ON_FLASH_UPDATE";\r
295 break;\r
296 case BOOT_IN_RECOVERY_MODE:\r
297 strBootMode = L"BOOT_IN_RECOVERY_MODE";\r
298 break;\r
299 default:\r
300 strBootMode = L"Unknown boot mode";\r
301 } // switch (BootMode)\r
302\r
303 DEBUG ((EFI_D_ERROR, "Setting BootMode to %s\n", strBootMode));\r
304 Status = (*PeiServices)->SetBootMode(\r
305 PeiServices,\r
306 BootMode\r
307 );\r
308 ASSERT_EFI_ERROR (Status);\r
309\r
310 return Status;\r
311}\r
312\r
313/**\r
314 Get sleep type after wakeup\r
315\r
316 @param PeiServices Pointer to the PEI Service Table.\r
317 @param SleepType Sleep type to be returned.\r
318\r
319 @retval TRUE A wake event occured without power failure.\r
320 @retval FALSE Power failure occured or not a wakeup.\r
321\r
322**/\r
323BOOLEAN\r
324GetSleepTypeAfterWakeup (\r
325 IN CONST EFI_PEI_SERVICES **PeiServices,\r
326 OUT UINT16 *SleepType\r
327 )\r
328{\r
329 UINT16 Pm1Sts;\r
330 UINT16 Pm1Cnt;\r
331 UINT16 GenPmCon1;\r
332 GenPmCon1 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);\r
333\r
334 //\r
335 // Read the ACPI registers\r
336 //\r
337 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);\r
338 Pm1Cnt = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);\r
339\r
340 if ((GenPmCon1 & (B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR | B_PCH_PMC_GEN_PMCON_GEN_RST_STS)) ||\r
341 (Pm1Sts & B_PCH_ACPI_PM1_STS_PRBTNOR)) {\r
342 //\r
343 // If power failure indicator, then don't attempt s3 resume.\r
344 // Clear PM1_CNT of S3 and set it to S5 as we just had a power failure, and memory has\r
345 // lost already. This is to make sure no one will use PM1_CNT to check for S3 after\r
346 // power failure.\r
347 //\r
348 if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {\r
349 Pm1Cnt = ((Pm1Cnt & ~B_PCH_ACPI_PM1_CNT_SLP_TYP) | V_PCH_ACPI_PM1_CNT_S5);\r
350 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);\r
351 }\r
352 //\r
353 // Clear Wake Status (WAK_STS)\r
354 //\r
355 IoWrite16 ((ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS), B_PCH_ACPI_PM1_STS_WAK);\r
356 }\r
357 //\r
358 // Get sleep type if a wake event occurred and there is no power failure\r
359 //\r
360 if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {\r
361 *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;\r
362 return TRUE;\r
363 } else if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4){\r
364 *SleepType = Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP;\r
365 return TRUE;\r
366 }\r
367 return FALSE;\r
368}\r
369\r
370VOID\r
371SetPlatformBootMode (\r
372 IN CONST EFI_PEI_SERVICES **PeiServices,\r
373 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
374 )\r
375{\r
376 EFI_PLATFORM_SETUP_ID PlatformSetupId;\r
377\r
378 ZeroMem(&PlatformSetupId, sizeof (EFI_PLATFORM_SETUP_ID));\r
379\r
380 CopyMem (&PlatformSetupId.SetupGuid,\r
381 &gEfiNormalSetupGuid,\r
382 sizeof (EFI_GUID));\r
383\r
384 if (CheckIfRecoveryMode(PeiServices, PlatformInfoHob)) {\r
385 //\r
386 // Recovery mode\r
387 //\r
388 CopyMem (&PlatformSetupId.SetupName,\r
389 SAFE_SETUP_NAME,\r
390 StrSize (SAFE_SETUP_NAME));\r
391 PlatformSetupId.PlatformBootMode = PLATFORM_RECOVERY_MODE;\r
392 } else if (CheckIfSafeMode(PeiServices, PlatformInfoHob)) {\r
393 //\r
394 // Safe mode also called config mode or maintenace mode.\r
395 //\r
396 CopyMem (&PlatformSetupId.SetupName,\r
397 SAFE_SETUP_NAME,\r
398 StrSize (SAFE_SETUP_NAME));\r
399 PlatformSetupId.PlatformBootMode = PLATFORM_SAFE_MODE;\r
400\r
401 } else if(0) { // else if (CheckIfManufacturingMode(PeiServices)) {\r
402 //\r
403 // Manufacturing mode\r
404 //\r
405 CopyMem (&PlatformSetupId.SetupName,\r
406 MANUFACTURE_SETUP_NAME,\r
407 StrSize (MANUFACTURE_SETUP_NAME));\r
408 PlatformSetupId.PlatformBootMode = PLATFORM_MANUFACTURING_MODE;\r
409\r
410 } else {\r
411 //\r
412 // Default to normal mode.\r
413 //\r
414 CopyMem (&PlatformSetupId.SetupName,\r
415 &NORMAL_SETUP_NAME,\r
416 StrSize (NORMAL_SETUP_NAME));\r
417 PlatformSetupId.PlatformBootMode = PLATFORM_NORMAL_MODE;\r
418 }\r
419\r
420 BuildGuidDataHob (\r
421 &gEfiPlatformBootModeGuid,\r
422 &PlatformSetupId,\r
423 sizeof (EFI_PLATFORM_SETUP_ID)\r
424 );\r
425 return;\r
426}\r