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