]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/FrontPage.c
Merged in the following trackers from EDK:
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / FrontPage.c
CommitLineData
fd6a62f3 1/** @file\r
2 FrontPage routines to handle the callbacks and browser calls\r
93e3992d 3\r
fd6a62f3 4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
93e3992d 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
fd6a62f3 13**/\r
93e3992d 14\r
15#include "Bds.h"\r
16#include "FrontPage.h"\r
17\r
18EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;\r
19\r
20BOOLEAN gConnectAllHappened = FALSE;\r
21UINTN gCallbackKey;\r
22\r
23EFI_HII_DATABASE_PROTOCOL *gHiiDatabase;\r
24EFI_HII_STRING_PROTOCOL *gHiiString;\r
25EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
26EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting;\r
27\r
28FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {\r
29 FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
30 NULL,\r
31 NULL,\r
32 NULL,\r
33 {\r
34 FakeExtractConfig,\r
35 FakeRouteConfig,\r
36 FrontPageCallback\r
37 }\r
38};\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42FakeExtractConfig (\r
43 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
44 IN CONST EFI_STRING Request,\r
45 OUT EFI_STRING *Progress,\r
46 OUT EFI_STRING *Results\r
47 )\r
48/*++\r
49\r
50 Routine Description:\r
51 This function allows a caller to extract the current configuration for one\r
52 or more named elements from the target driver.\r
53\r
54 Arguments:\r
55 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
56 Request - A null-terminated Unicode string in <ConfigRequest> format.\r
57 Progress - On return, points to a character in the Request string.\r
58 Points to the string's null terminator if request was successful.\r
59 Points to the most recent '&' before the first failing name/value\r
60 pair (or the beginning of the string if the failure is in the\r
61 first name/value pair) if the request was not successful.\r
62 Results - A null-terminated Unicode string in <ConfigAltResp> format which\r
63 has all values filled in for the names in the Request string.\r
64 String to be allocated by the called function.\r
65\r
66 Returns:\r
67 EFI_SUCCESS - The Results is filled with the requested values.\r
68 EFI_OUT_OF_RESOURCES - Not enough memory to store the results.\r
69 EFI_INVALID_PARAMETER - Request is NULL, illegal syntax, or unknown name.\r
70 EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.\r
71\r
72--*/\r
73{\r
74 return EFI_NOT_FOUND;\r
75}\r
76\r
77EFI_STATUS\r
78EFIAPI\r
79FakeRouteConfig (\r
80 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
81 IN CONST EFI_STRING Configuration,\r
82 OUT EFI_STRING *Progress\r
83 )\r
84/*++\r
85\r
86 Routine Description:\r
87 This function processes the results of changes in configuration.\r
88\r
89 Arguments:\r
90 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
91 Configuration - A null-terminated Unicode string in <ConfigResp> format.\r
92 Progress - A pointer to a string filled in with the offset of the most\r
93 recent '&' before the first failing name/value pair (or the\r
94 beginning of the string if the failure is in the first\r
95 name/value pair) or the terminating NULL if all was successful.\r
96\r
97 Returns:\r
98 EFI_SUCCESS - The Results is processed successfully.\r
99 EFI_INVALID_PARAMETER - Configuration is NULL.\r
100 EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.\r
101\r
102--*/\r
103{\r
104 return EFI_SUCCESS;\r
105}\r
106\r
107EFI_STATUS\r
108EFIAPI\r
109FrontPageCallback (\r
110 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
111 IN EFI_BROWSER_ACTION Action,\r
112 IN EFI_QUESTION_ID QuestionId,\r
113 IN UINT8 Type,\r
114 IN EFI_IFR_TYPE_VALUE *Value,\r
115 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
116 )\r
117/*++\r
118\r
119 Routine Description:\r
120 This function processes the results of changes in configuration.\r
121\r
122 Arguments:\r
123 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
124 Action - Specifies the type of action taken by the browser.\r
125 QuestionId - A unique value which is sent to the original exporting driver\r
126 so that it can identify the type of data to expect.\r
127 Type - The type of value for the question.\r
128 Value - A pointer to the data being sent to the original exporting driver.\r
129 ActionRequest - On return, points to the action requested by the callback function.\r
130\r
131 Returns:\r
132 EFI_SUCCESS - The callback successfully handled the action.\r
133 EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.\r
134 EFI_DEVICE_ERROR - The variable could not be saved.\r
135 EFI_UNSUPPORTED - The specified Action is not supported by the callback.\r
136\r
137--*/\r
138{\r
139 CHAR8 *LanguageString;\r
140 CHAR8 *LangCode;\r
141 CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
93e3992d 142 CHAR8 OldLang[ISO_639_2_ENTRY_SIZE];\r
93e3992d 143 UINTN Index;\r
144 EFI_STATUS Status;\r
145\r
146 if ((Value == NULL) || (ActionRequest == NULL)) {\r
147 return EFI_INVALID_PARAMETER;\r
148 }\r
149\r
150 gCallbackKey = QuestionId;\r
151\r
152 //\r
153 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
154 // describe to their customers in documentation how to find their setup information (namely\r
155 // under the device manager and specific buckets)\r
156 //\r
157 switch (QuestionId) {\r
158 case FRONT_PAGE_KEY_CONTINUE:\r
159 //\r
160 // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
161 //\r
162 break;\r
163\r
164 case FRONT_PAGE_KEY_LANGUAGE:\r
165 //\r
166 // Collect the languages from what our current Language support is based on our VFR\r
167 //\r
9226efe5 168 LanguageString = HiiLibGetSupportedLanguages (gFrontPagePrivate.HiiHandle);\r
93e3992d 169 ASSERT (LanguageString != NULL);\r
170\r
171 Index = 0;\r
172 LangCode = LanguageString;\r
173 while (*LangCode != 0) {\r
9226efe5 174 HiiLibGetNextLanguage (&LangCode, Lang);\r
93e3992d 175\r
176 if (Index == Value->u8) {\r
177 break;\r
178 }\r
179\r
180 Index++;\r
181 }\r
182\r
183 Status = gRT->SetVariable (\r
184 L"PlatformLang",\r
185 &gEfiGlobalVariableGuid,\r
186 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
187 AsciiStrSize (Lang),\r
188 Lang\r
189 );\r
190\r
d6c0ec55 191 if (!FeaturePcdGet (PcdUefiVariableDefaultLangDepricate)) {\r
192 //\r
193 // Set UEFI deprecated variable "Lang" for backwards compatibility\r
194 //\r
195 Status = ConvertRfc3066LanguageToIso639Language (Lang, OldLang);\r
196 if (!EFI_ERROR (Status)) {\r
197 Status = gRT->SetVariable (\r
198 L"Lang",\r
199 &gEfiGlobalVariableGuid,\r
200 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
201 ISO_639_2_ENTRY_SIZE,\r
202 OldLang\r
203 );\r
204 }\r
93e3992d 205 }\r
93e3992d 206\r
207 FreePool (LanguageString);\r
208 break;\r
209\r
210 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
211 //\r
212 // Boot Manager\r
213 //\r
214 break;\r
215\r
216 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
217 //\r
218 // Device Manager\r
219 //\r
220 break;\r
221\r
222 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
223 //\r
224 // Boot Maintenance Manager\r
225 //\r
226 break;\r
227\r
228 default:\r
229 gCallbackKey = 0;\r
230 break;\r
231 }\r
232\r
233 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
234\r
235 return EFI_SUCCESS;\r
236}\r
237\r
238EFI_STATUS\r
239InitializeFrontPage (\r
240 BOOLEAN ReInitializeStrings\r
241 )\r
242/*++\r
243\r
244Routine Description:\r
245 Initialize HII information for the FrontPage\r
246\r
247Arguments:\r
248 None\r
249\r
250Returns:\r
251 EFI_SUCCESS - The operation is successful.\r
252 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.\r
253\r
254--*/\r
255{\r
256 EFI_STATUS Status;\r
257 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
258 EFI_HII_UPDATE_DATA UpdateData;\r
259 IFR_OPTION *OptionList;\r
260 CHAR8 *LanguageString;\r
261 CHAR8 *LangCode;\r
262 CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
263 CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];\r
264 UINTN OptionCount;\r
265 EFI_STRING_ID Token;\r
266 CHAR16 *StringBuffer;\r
267 UINTN BufferSize;\r
268 UINTN Index;\r
269 EFI_HII_HANDLE HiiHandle;\r
270\r
271 if (!ReInitializeStrings) {\r
272 //\r
273 // Initialize the Device Manager\r
274 //\r
275 InitializeDeviceManager ();\r
276\r
277 //\r
278 // Initialize the Device Manager\r
279 //\r
280 InitializeBootManager ();\r
281\r
282 gCallbackKey = 0;\r
283\r
284 //\r
285 // Locate Hii relative protocols\r
286 //\r
287 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase);\r
288 if (EFI_ERROR (Status)) {\r
289 return Status;\r
290 }\r
291\r
292 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gHiiString);\r
293 if (EFI_ERROR (Status)) {\r
294 return Status;\r
295 }\r
296\r
297 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
298 if (EFI_ERROR (Status)) {\r
299 return Status;\r
300 }\r
301\r
302 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting);\r
303 if (EFI_ERROR (Status)) {\r
304 return Status;\r
305 }\r
306\r
307 //\r
308 // Create driver handle used by HII database\r
309 //\r
310 Status = HiiLibCreateHiiDriverHandle (&gFrontPagePrivate.DriverHandle);\r
311 if (EFI_ERROR (Status)) {\r
312 return Status;\r
313 }\r
314\r
315 //\r
316 // Install Config Access protocol to driver handle\r
317 //\r
318 Status = gBS->InstallProtocolInterface (\r
319 &gFrontPagePrivate.DriverHandle,\r
320 &gEfiHiiConfigAccessProtocolGuid,\r
321 EFI_NATIVE_INTERFACE,\r
322 &gFrontPagePrivate.ConfigAccess\r
323 );\r
324 ASSERT_EFI_ERROR (Status);\r
325\r
326 //\r
327 // Publish our HII data\r
328 //\r
062539cf 329 PackageList = HiiLibPreparePackageList (2, &mFrontPageGuid, FrontPageVfrBin, BdsDxeStrings);\r
93e3992d 330 ASSERT (PackageList != NULL);\r
331\r
332 Status = gHiiDatabase->NewPackageList (\r
333 gHiiDatabase,\r
334 PackageList,\r
335 gFrontPagePrivate.DriverHandle,\r
336 &gFrontPagePrivate.HiiHandle\r
337 );\r
338 FreePool (PackageList);\r
339 if (EFI_ERROR (Status)) {\r
340 return Status;\r
341 }\r
342 }\r
343\r
344 //\r
345 // Get current language setting\r
346 //\r
9226efe5 347 HiiLibGetCurrentLanguage (CurrentLang);\r
93e3992d 348\r
349 //\r
350 // Allocate space for creation of UpdateData Buffer\r
351 //\r
352 UpdateData.BufferSize = 0x1000;\r
353 UpdateData.Data = AllocateZeroPool (0x1000);\r
354 ASSERT (UpdateData.Data != NULL);\r
355\r
356 OptionList = AllocateZeroPool (0x1000);\r
357 ASSERT (OptionList != NULL);\r
358\r
359 //\r
360 // Collect the languages from what our current Language support is based on our VFR\r
361 //\r
362 HiiHandle = gFrontPagePrivate.HiiHandle;\r
9226efe5 363 LanguageString = HiiLibGetSupportedLanguages (HiiHandle);\r
93e3992d 364 ASSERT (LanguageString != NULL);\r
365\r
366 OptionCount = 0;\r
367 LangCode = LanguageString;\r
368 while (*LangCode != 0) {\r
9226efe5 369 HiiLibGetNextLanguage (&LangCode, Lang);\r
93e3992d 370\r
371 if (gFrontPagePrivate.LanguageToken == NULL) {\r
372 //\r
373 // Get Language Name from String Package. The StringId of Printable Language\r
374 // Name is always 1 which is generated by StringGather Tool.\r
375 //\r
376 BufferSize = 0x100;\r
377 StringBuffer = AllocatePool (BufferSize);\r
378 Status = gHiiString->GetString (\r
379 gHiiString,\r
380 Lang,\r
381 HiiHandle,\r
382 PRINTABLE_LANGUAGE_NAME_STRING_ID,\r
383 StringBuffer,\r
384 &BufferSize,\r
385 NULL\r
386 );\r
387 if (Status == EFI_BUFFER_TOO_SMALL) {\r
388 FreePool (StringBuffer);\r
389 StringBuffer = AllocatePool (BufferSize);\r
390 Status = gHiiString->GetString (\r
391 gHiiString,\r
392 Lang,\r
393 HiiHandle,\r
394 PRINTABLE_LANGUAGE_NAME_STRING_ID,\r
395 StringBuffer,\r
396 &BufferSize,\r
397 NULL\r
398 );\r
399 }\r
400 ASSERT_EFI_ERROR (Status);\r
401\r
402 Token = 0;\r
9226efe5 403 Status = HiiLibNewString (HiiHandle, &Token, StringBuffer);\r
93e3992d 404 FreePool (StringBuffer);\r
405 } else {\r
406 Token = gFrontPagePrivate.LanguageToken[OptionCount];\r
407 }\r
408\r
409 if (AsciiStrCmp (Lang, CurrentLang) == 0) {\r
410 OptionList[OptionCount].Flags = EFI_IFR_OPTION_DEFAULT;\r
411 } else {\r
412 OptionList[OptionCount].Flags = 0;\r
413 }\r
414 OptionList[OptionCount].StringToken = Token;\r
415 OptionList[OptionCount].Value.u8 = (UINT8) OptionCount;\r
416\r
417 OptionCount++;\r
418 }\r
419\r
420 FreePool (LanguageString);\r
421\r
422 UpdateData.Offset = 0;\r
423 CreateOneOfOpCode (\r
424 FRONT_PAGE_KEY_LANGUAGE,\r
425 0,\r
426 0,\r
427 STRING_TOKEN (STR_LANGUAGE_SELECT),\r
428 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
429 EFI_IFR_FLAG_CALLBACK,\r
430 EFI_IFR_NUMERIC_SIZE_1,\r
431 OptionList,\r
432 OptionCount,\r
433 &UpdateData\r
434 );\r
435\r
436 Status = IfrLibUpdateForm (\r
437 HiiHandle,\r
438 &mFrontPageGuid,\r
439 FRONT_PAGE_FORM_ID,\r
440 LABEL_SELECT_LANGUAGE,\r
441 FALSE,\r
442 &UpdateData\r
443 );\r
444\r
445 //\r
446 // Save the string Id for each language\r
447 //\r
448 gFrontPagePrivate.LanguageToken = AllocatePool (OptionCount * sizeof (EFI_STRING_ID));\r
449 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
450 for (Index = 0; Index < OptionCount; Index++) {\r
451 gFrontPagePrivate.LanguageToken[Index] = OptionList[Index].StringToken;\r
452 }\r
453\r
454 FreePool (UpdateData.Data);\r
455 FreePool (OptionList);\r
456 return Status;\r
457}\r
458\r
459EFI_STATUS\r
460CallFrontPage (\r
461 VOID\r
462 )\r
463/*++\r
464\r
465Routine Description:\r
466 Call the browser and display the front page\r
467\r
468Arguments:\r
469 None\r
470\r
471Returns:\r
472\r
473--*/\r
474{\r
475 EFI_STATUS Status;\r
476 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
477\r
478 //\r
479 // Begin waiting for USER INPUT\r
480 //\r
481 REPORT_STATUS_CODE (\r
482 EFI_PROGRESS_CODE,\r
483 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
484 );\r
485\r
486\r
487 //\r
488 // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION\r
489 //\r
490 gBS->RestoreTPL (TPL_APPLICATION);\r
491\r
492 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
493 Status = gFormBrowser2->SendForm (\r
494 gFormBrowser2,\r
495 &gFrontPagePrivate.HiiHandle,\r
496 1,\r
497 NULL,\r
498 0,\r
499 NULL,\r
500 &ActionRequest\r
501 );\r
502 //\r
503 // Check whether user change any option setting which needs a reset to be effective\r
504 //\r
505 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
506 EnableResetRequired ();\r
507 }\r
508\r
509 gBS->RaiseTPL (TPL_APPLICATION);\r
510 return Status;\r
511}\r
512\r
513EFI_STATUS\r
514GetProducerString (\r
515 IN EFI_GUID *ProducerGuid,\r
516 IN EFI_STRING_ID Token,\r
517 OUT CHAR16 **String\r
518 )\r
519/*++\r
520\r
521Routine Description:\r
522 Acquire the string associated with the ProducerGuid and return it.\r
523\r
524Arguments:\r
525 ProducerGuid - The Guid to search the HII database for\r
526 Token - The token value of the string to extract\r
527 String - The string that is extracted\r
528\r
529Returns:\r
530 EFI_SUCCESS - The function returns EFI_SUCCESS always.\r
531\r
532--*/\r
533{\r
534 EFI_STATUS Status;\r
535\r
9226efe5 536 Status = HiiLibGetStringFromToken (ProducerGuid, Token, String);\r
93e3992d 537 if (EFI_ERROR (Status)) {\r
538 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
539 }\r
540\r
541 return EFI_SUCCESS;\r
542}\r
543\r
544VOID\r
545ConvertProcessorToString (\r
546 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,\r
547 OUT CHAR16 **String\r
548 )\r
549/*++\r
550\r
551Routine Description:\r
552 Convert Processor Frequency Data to a string\r
553\r
554Arguments:\r
555 ProcessorFrequency - The frequency data to process\r
556 String - The string that is created\r
557\r
558Returns:\r
559\r
560--*/\r
561{\r
562 CHAR16 *StringBuffer;\r
563 UINTN Index;\r
564 UINT32 FreqMhz;\r
565\r
566 if (ProcessorFrequency->Exponent >= 6) {\r
567 FreqMhz = ProcessorFrequency->Value;\r
568 for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {\r
569 FreqMhz *= 10;\r
570 }\r
571 } else {\r
572 FreqMhz = 0;\r
573 }\r
574\r
575 StringBuffer = AllocateZeroPool (0x20);\r
576 ASSERT (StringBuffer != NULL);\r
577 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
578 StrCat (StringBuffer, L".");\r
579 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
580 StrCat (StringBuffer, L" GHz");\r
581\r
582 *String = (CHAR16 *) StringBuffer;\r
583\r
584 return ;\r
585}\r
586\r
587VOID\r
588ConvertMemorySizeToString (\r
589 IN UINT32 MemorySize,\r
590 OUT CHAR16 **String\r
591 )\r
592/*++\r
593\r
594Routine Description:\r
595 Convert Memory Size to a string\r
596\r
597Arguments:\r
598 MemorySize - The size of the memory to process\r
599 String - The string that is created\r
600\r
601Returns:\r
602\r
603--*/\r
604{\r
605 CHAR16 *StringBuffer;\r
606\r
607 StringBuffer = AllocateZeroPool (0x20);\r
608 ASSERT (StringBuffer != NULL);\r
609 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);\r
610 StrCat (StringBuffer, L" MB RAM");\r
611\r
612 *String = (CHAR16 *) StringBuffer;\r
613\r
614 return ;\r
615}\r
616\r
617VOID\r
618UpdateFrontPageStrings (\r
619 VOID\r
620 )\r
621/*++\r
622\r
623Routine Description:\r
624 Update the banner information for the Front Page based on DataHub information\r
625\r
626Arguments:\r
627 None\r
628\r
629Returns:\r
630\r
631--*/\r
632{\r
633 EFI_STATUS Status;\r
634 EFI_STRING_ID TokenToUpdate;\r
635 CHAR16 *NewString;\r
636 UINT64 MonotonicCount;\r
637 EFI_DATA_HUB_PROTOCOL *DataHub;\r
638 EFI_DATA_RECORD_HEADER *Record;\r
639 EFI_SUBCLASS_TYPE1_HEADER *DataHeader;\r
640 EFI_MISC_BIOS_VENDOR_DATA *BiosVendor;\r
641 EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;\r
642 EFI_PROCESSOR_VERSION_DATA *ProcessorVersion;\r
643 EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;\r
644 EFI_MEMORY_ARRAY_START_ADDRESS_DATA *MemoryArray;\r
645 BOOLEAN Find[5];\r
646\r
647 ZeroMem (Find, sizeof (Find));\r
648\r
649 //\r
650 // Update Front Page strings\r
651 //\r
652 Status = gBS->LocateProtocol (\r
653 &gEfiDataHubProtocolGuid,\r
654 NULL,\r
655 (VOID **) &DataHub\r
656 );\r
657 ASSERT_EFI_ERROR (Status);\r
658\r
659 MonotonicCount = 0;\r
660 Record = NULL;\r
661 do {\r
662 Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);\r
663 if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {\r
664 DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);\r
665 if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&\r
666 (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)\r
667 ) {\r
668 BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);\r
669 GetProducerString (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);\r
670 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
9226efe5 671 HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);\r
93e3992d 672 FreePool (NewString);\r
673 Find[0] = TRUE;\r
674 }\r
675\r
676 if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&\r
677 (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)\r
678 ) {\r
679 SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);\r
680 GetProducerString (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);\r
681 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
9226efe5 682 HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);\r
93e3992d 683 FreePool (NewString);\r
684 Find[1] = TRUE;\r
685 }\r
686\r
687 if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&\r
688 (DataHeader->RecordType == ProcessorVersionRecordType)\r
689 ) {\r
690 ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);\r
691 GetProducerString (&Record->ProducerName, *ProcessorVersion, &NewString);\r
692 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
9226efe5 693 HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);\r
93e3992d 694 FreePool (NewString);\r
695 Find[2] = TRUE;\r
696 }\r
697\r
698 if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&\r
699 (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)\r
700 ) {\r
701 ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);\r
702 ConvertProcessorToString (ProcessorFrequency, &NewString);\r
703 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
9226efe5 704 HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);\r
93e3992d 705 FreePool (NewString);\r
706 Find[3] = TRUE;\r
707 }\r
708\r
709 if (CompareGuid (&Record->DataRecordGuid, &gEfiMemorySubClassGuid) &&\r
710 (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)\r
711 ) {\r
712 MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);\r
713 ConvertMemorySizeToString (\r
714 (UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20)),\r
715 &NewString\r
716 );\r
717 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
9226efe5 718 HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);\r
93e3992d 719 FreePool (NewString);\r
720 Find[4] = TRUE;\r
721 }\r
722 }\r
723 } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
724\r
725 return ;\r
726}\r
727\r
728EFI_STATUS\r
729WaitForSingleEvent (\r
730 IN EFI_EVENT Event,\r
731 IN UINT64 Timeout OPTIONAL\r
732 )\r
733/*++\r
734\r
735Routine Description:\r
736 Function waits for a given event to fire, or for an optional timeout to expire.\r
737\r
738Arguments:\r
739 Event - The event to wait for\r
740 Timeout - An optional timeout value in 100 ns units.\r
741\r
742Returns:\r
743 EFI_SUCCESS - Event fired before Timeout expired.\r
744 EFI_TIME_OUT - Timout expired before Event fired..\r
745\r
746--*/\r
747{\r
748 EFI_STATUS Status;\r
749 UINTN Index;\r
750 EFI_EVENT TimerEvent;\r
751 EFI_EVENT WaitList[2];\r
752\r
753 if (Timeout) {\r
754 //\r
755 // Create a timer event\r
756 //\r
757 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
758 if (!EFI_ERROR (Status)) {\r
759 //\r
760 // Set the timer event\r
761 //\r
762 gBS->SetTimer (\r
763 TimerEvent,\r
764 TimerRelative,\r
765 Timeout\r
766 );\r
767\r
768 //\r
769 // Wait for the original event or the timer\r
770 //\r
771 WaitList[0] = Event;\r
772 WaitList[1] = TimerEvent;\r
773 Status = gBS->WaitForEvent (2, WaitList, &Index);\r
774 gBS->CloseEvent (TimerEvent);\r
775\r
776 //\r
777 // If the timer expired, change the return to timed out\r
778 //\r
779 if (!EFI_ERROR (Status) && Index == 1) {\r
780 Status = EFI_TIMEOUT;\r
781 }\r
782 }\r
783 } else {\r
784 //\r
785 // No timeout... just wait on the event\r
786 //\r
787 Status = gBS->WaitForEvent (1, &Event, &Index);\r
788 ASSERT (!EFI_ERROR (Status));\r
789 ASSERT (Index == 0);\r
790 }\r
791\r
792 return Status;\r
793}\r
794\r
795EFI_STATUS\r
796ShowProgress (\r
797 IN UINT16 TimeoutDefault\r
798 )\r
799/*++\r
800\r
801Routine Description:\r
802 Function show progress bar to wait for user input.\r
803\r
804Arguments:\r
805 TimeoutDefault - The fault time out value before the system\r
806 continue to boot.\r
807\r
808Returns:\r
809 EFI_SUCCESS - User pressed some key except "Enter"\r
810 EFI_TIME_OUT - Timout expired or user press "Enter"\r
811\r
812--*/\r
813{\r
814 EFI_STATUS Status;\r
815 CHAR16 *TmpStr;\r
816 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
817 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
818 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
819 EFI_INPUT_KEY Key;\r
820 UINT16 TimeoutRemain;\r
821\r
822 if (TimeoutDefault == 0) {\r
823 return EFI_TIMEOUT;\r
824 }\r
825\r
0fc82496 826 DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
827 \r
93e3992d 828 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
829 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
830 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
831\r
832 //\r
833 // Clear the progress status bar first\r
834 //\r
835 TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
836 if (TmpStr != NULL) {\r
837 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
838 }\r
839\r
840 TimeoutRemain = TimeoutDefault;\r
841 while (TimeoutRemain != 0) {\r
0fc82496 842 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
843 \r
93e3992d 844 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
845 if (Status != EFI_TIMEOUT) {\r
846 break;\r
847 }\r
848 TimeoutRemain--;\r
849\r
850 //\r
851 // Show progress\r
852 //\r
853 if (TmpStr != NULL) {\r
854 PlatformBdsShowProgress (\r
855 Foreground,\r
856 Background,\r
857 TmpStr,\r
858 Color,\r
859 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
860 0\r
861 );\r
862 }\r
863 }\r
864 gBS->FreePool (TmpStr);\r
865\r
866 //\r
867 // Timeout expired\r
868 //\r
869 if (TimeoutRemain == 0) {\r
870 return EFI_TIMEOUT;\r
871 }\r
872\r
873 //\r
874 // User pressed some key\r
875 //\r
876 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
877 if (EFI_ERROR (Status)) {\r
878 return Status;\r
879 }\r
880\r
881 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
882 //\r
883 // User pressed enter, equivalent to select "continue"\r
884 //\r
885 return EFI_TIMEOUT;\r
886 }\r
887\r
888 return EFI_SUCCESS;\r
889}\r
890\r
891VOID\r
892PlatformBdsEnterFrontPage (\r
893 IN UINT16 TimeoutDefault,\r
894 IN BOOLEAN ConnectAllHappened\r
895 )\r
896/*++\r
897\r
898Routine Description:\r
899 This function is the main entry of the platform setup entry.\r
900 The function will present the main menu of the system setup,\r
901 this is the platform reference part and can be customize.\r
902\r
903Arguments:\r
904 TimeoutDefault - The fault time out value before the system\r
905 continue to boot.\r
906 ConnectAllHappened - The indicater to check if the connect all have\r
907 already happended.\r
908\r
909Returns:\r
910 None\r
911\r
912--*/\r
913{\r
914 EFI_STATUS Status;\r
915 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;\r
916\r
b3bac2c9 917 PERF_START (0, "BdsTimeOut", "BDS", 0);\r
93e3992d 918 //\r
919 // Indicate if we need connect all in the platform setup\r
920 //\r
921 if (ConnectAllHappened) {\r
922 gConnectAllHappened = TRUE;\r
923 }\r
924\r
925 if (TimeoutDefault != 0xffff) {\r
926 gBS->RestoreTPL (TPL_APPLICATION);\r
927 Status = ShowProgress (TimeoutDefault);\r
928 gBS->RaiseTPL (TPL_APPLICATION);\r
929\r
930 if (EFI_ERROR (Status)) {\r
931 //\r
932 // Timeout or user press enter to continue\r
933 //\r
813acf3a 934 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
935 gST->ConOut->ClearScreen (gST->ConOut);\r
93e3992d 936 goto Exit;\r
937 }\r
938 }\r
939\r
940 do {\r
941\r
942 InitializeFrontPage (TRUE);\r
943\r
944 //\r
945 // Update Front Page strings\r
946 //\r
947 UpdateFrontPageStrings ();\r
948\r
949 gCallbackKey = 0;\r
93e3992d 950 Status = CallFrontPage ();\r
93e3992d 951\r
952 //\r
953 // If gCallbackKey is greater than 1 and less or equal to 5,\r
954 // it will lauch configuration utilities.\r
955 // 2 = set language\r
956 // 3 = boot manager\r
957 // 4 = device manager\r
958 // 5 = boot maintainenance manager\r
959 //\r
960 if (gCallbackKey != 0) {\r
961 REPORT_STATUS_CODE (\r
962 EFI_PROGRESS_CODE,\r
963 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
964 );\r
965 }\r
966 //\r
967 // Based on the key that was set, we can determine what to do\r
968 //\r
969 switch (gCallbackKey) {\r
970 //\r
971 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
972 // describe to their customers in documentation how to find their setup information (namely\r
973 // under the device manager and specific buckets)\r
974 //\r
975 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
976 //\r
977 case FRONT_PAGE_KEY_CONTINUE:\r
978 //\r
979 // User hit continue\r
980 //\r
981 break;\r
982\r
983 case FRONT_PAGE_KEY_LANGUAGE:\r
984 //\r
985 // User made a language setting change - display front page again\r
986 //\r
987 break;\r
988\r
989 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
990 //\r
991 // User chose to run the Boot Manager\r
992 //\r
993 CallBootManager ();\r
994 break;\r
995\r
996 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
997 //\r
998 // Display the Device Manager\r
999 //\r
1000 do {\r
1001 CallDeviceManager();\r
1002 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
1003 break;\r
1004\r
1005 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
1006 //\r
1007 // Display the Boot Maintenance Manager\r
1008 //\r
1009 BdsStartBootMaint ();\r
1010 break;\r
1011 }\r
1012\r
1013 } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));\r
1014\r
1015 //\r
1016 //Will leave browser, check any reset required change is applied? if yes, reset system\r
1017 //\r
1018 gBS->RestoreTPL (TPL_APPLICATION);\r
1019 SetupResetReminder ();\r
1020 gBS->RaiseTPL (TPL_APPLICATION);\r
1021\r
1022Exit:\r
1023 //\r
1024 // Automatically load current entry\r
1025 // Note: The following lines of code only execute when Auto boot\r
1026 // takes affect\r
1027 //\r
b3bac2c9 1028 PERF_END (0, "BdsTimeOut", "BDS", 0);\r
93e3992d 1029 Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
1030 ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
1031\r
1032}\r