3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 FrontPage routines to handle the callbacks and browser calls
23 #include "FrontPage.h"
26 EFI_GUID mProcessorSubClass
= EFI_PROCESSOR_SUBCLASS_GUID
;
27 EFI_GUID mMemorySubClass
= EFI_MEMORY_SUBCLASS_GUID
;
28 EFI_GUID mMiscSubClass
= EFI_MISC_SUBCLASS_GUID
;
30 UINT16 mLastSelection
;
31 EFI_HII_HANDLE gFrontPageHandle
;
32 EFI_HANDLE FrontPageCallbackHandle
;
33 EFI_FORM_CALLBACK_PROTOCOL FrontPageCallback
;
34 EFI_FORM_BROWSER_PROTOCOL
*gBrowser
;
36 BOOLEAN gConnectAllHappened
= FALSE
;
38 extern EFI_HII_HANDLE gFrontPageHandle
;
39 extern EFI_GUID gBdsStringPackGuid
;
43 FrontPageCallbackRoutine (
44 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
46 IN EFI_IFR_DATA_ARRAY
*DataArray
,
47 OUT EFI_HII_CALLBACK_PACKET
**Packet
53 This is the function that is called to provide results data to the driver. This data
54 consists of a unique key which is used to identify what data is either being passed back
59 KeyValue - A unique value which is sent to the original exporting driver so that it
60 can identify the type of data to expect. The format of the data tends to
61 vary based on the op-code that geerated the callback.
63 Data - A pointer to the data being sent to the original exporting driver.
69 CHAR16
*LanguageString
;
71 CHAR16 UnicodeLang
[3];
76 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
77 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
78 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
80 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
81 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
82 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
87 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
88 // describe to their customers in documentation how to find their setup information (namely
89 // under the device manager and specific buckets)
94 // This is the continue - clear the screen and return an error to get out of FrontPage loop
101 // Collect the languages from what our current Language support is based on our VFR
103 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
106 // Based on the DataArray->Data->Data value, we can determine
107 // which language was chosen by the user
109 for (Index
= 0; Count
!= (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+ 1))->Data
); Index
+= 3) {
113 // Preserve the choice the user made
115 mLastSelection
= (UINT16
) Count
;
118 // The Language (in Unicode format) the user chose
120 CopyMem (UnicodeLang
, &LanguageString
[Index
], 6);
123 // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
124 // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
126 for (Index
= 0; Index
< 3; Index
++) {
127 Lang
[Index
] = (CHAR8
) UnicodeLang
[Index
];
130 Status
= gRT
->SetVariable (
132 &gEfiGlobalVariableGuid
,
133 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
138 gBS
->FreePool (LanguageString
);
158 // Boot Maintenance Manager
169 // FrontPage TimeOut Callback
171 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
172 if (TmpStr
!= NULL
) {
173 PlatformBdsShowProgress (
178 (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+1))->Data
),
181 gBS
->FreePool (TmpStr
);
194 InitializeFrontPage (
195 BOOLEAN ReInitializeStrings
201 Initialize HII information for the FrontPage
207 EFI_SUCCESS - The operation is successful.
208 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
213 EFI_HII_PACKAGES
*PackageList
;
214 EFI_HII_UPDATE_DATA
*UpdateData
;
215 IFR_OPTION
*OptionList
;
216 CHAR16
*LanguageString
;
222 CHAR16 UnicodeLang
[4];
224 CHAR16
*StringBuffer
;
231 if (ReInitializeStrings
) {
233 // BugBug: Dont' use a goto
238 // Go ahead and initialize the Device Manager
240 InitializeDeviceManager ();
243 // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
245 TempBuffer
= (UINT8
*) FrontPageVfrBin
;
246 TempBuffer
= TempBuffer
+ sizeof (EFI_HII_PACK_HEADER
);
247 TempBuffer
= (UINT8
*) &((EFI_IFR_FORM_SET
*) TempBuffer
)->NvDataSize
;
252 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FrontPageVfrBin
);
254 Status
= Hii
->NewPack (Hii
, PackageList
, &gFrontPageHandle
);
256 gBS
->FreePool (PackageList
);
259 // There will be only one FormConfig in the system
260 // If there is another out there, someone is trying to install us
261 // again. Fail that scenario.
263 Status
= gBS
->LocateProtocol (
264 &gEfiFormBrowserProtocolGuid
,
270 // This example does not implement worker functions
271 // for the NV accessor functions. Only a callback evaluator
273 FrontPageCallback
.NvRead
= NULL
;
274 FrontPageCallback
.NvWrite
= NULL
;
275 FrontPageCallback
.Callback
= FrontPageCallbackRoutine
;
278 // Install protocol interface
280 FrontPageCallbackHandle
= NULL
;
281 Status
= gBS
->InstallProtocolInterface (
282 &FrontPageCallbackHandle
,
283 &gEfiFormCallbackProtocolGuid
,
284 EFI_NATIVE_INTERFACE
,
287 ASSERT_EFI_ERROR (Status
);
291 // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
294 Status
= gRT
->GetVariable (
296 &gEfiGlobalVariableGuid
,
302 for (Index
= 0; Index
< 3; Index
++) {
303 UnicodeLang
[Index
] = (CHAR16
) AsciiLang
[Index
];
309 // Allocate space for creation of UpdateData Buffer
311 UpdateData
= AllocateZeroPool (0x1000);
312 ASSERT (UpdateData
!= NULL
);
314 OptionList
= AllocateZeroPool (0x1000);
315 ASSERT (OptionList
!= NULL
);
318 // Flag update pending in FormSet
320 UpdateData
->FormSetUpdate
= TRUE
;
322 // Register CallbackHandle data for FormSet
324 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FrontPageCallbackHandle
;
325 UpdateData
->FormUpdate
= FALSE
;
326 UpdateData
->FormTitle
= 0;
327 UpdateData
->DataCount
= 1;
330 // Collect the languages from what our current Language support is based on our VFR
332 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
337 // Try for a 512 byte Buffer
342 // Allocate memory for our Form binary
344 StringBuffer
= AllocateZeroPool (BufferSize
);
345 ASSERT (StringBuffer
!= NULL
);
347 for (Index
= 0; LanguageString
[Index
] != 0; Index
+= 3) {
349 CopyMem (Lang
, &LanguageString
[Index
], 6);
352 if (!StrCmp (Lang
, UnicodeLang
)) {
353 mLastSelection
= (UINT16
) OptionCount
;
356 Status
= Hii
->GetString (Hii
, gStringPackHandle
, 1, TRUE
, Lang
, &BufferSize
, StringBuffer
);
357 Hii
->NewString (Hii
, NULL
, gStringPackHandle
, &Token
, StringBuffer
);
358 CopyMem (&OptionList
[OptionCount
].StringToken
, &Token
, sizeof (UINT16
));
359 CopyMem (&OptionList
[OptionCount
].Value
, &OptionCount
, sizeof (UINT16
));
361 CopyMem (&OptionList
[OptionCount
].Key
, &Key
, sizeof (UINT16
));
362 OptionList
[OptionCount
].Flags
= EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
;
366 gBS
->FreePool (LanguageString
);
368 if (ReInitializeStrings
) {
369 gBS
->FreePool (StringBuffer
);
370 gBS
->FreePool (OptionList
);
374 Status
= CreateOneOfOpCode (
375 FRONT_PAGE_QUESTION_ID
, // Question ID
376 FRONT_PAGE_DATA_WIDTH
, // Data Width
377 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT
), // Prompt Token
378 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
), // Help Token
379 OptionList
, // List of Options
380 OptionCount
, // Number of Options
381 &UpdateData
->Data
// Data Buffer
385 // Assign the number of options and the oneof and endoneof op-codes to count
387 UpdateData
->DataCount
= (UINT8
) (OptionCount
+ 2);
389 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
391 gBS
->FreePool (UpdateData
);
393 // gBS->FreePool (OptionList);
395 gBS
->FreePool (StringBuffer
);
407 Call the browser and display the front page
418 UINT8 FakeNvRamMap
[1];
419 BOOLEAN FrontPageMenuResetRequired
;
422 // Begin waiting for USER INPUT
426 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
429 FakeNvRamMap
[0] = (UINT8
) mLastSelection
;
430 FrontPageMenuResetRequired
= FALSE
;
431 Status
= gBrowser
->SendForm (
433 TRUE
, // Use the database
434 &gFrontPageHandle
, // The HII Handle
437 FrontPageCallbackHandle
, // This is the handle that the interface to the callback was installed on
440 &FrontPageMenuResetRequired
443 // Check whether user change any option setting which needs a reset to be effective
445 if (FrontPageMenuResetRequired
) {
446 EnableResetRequired ();
449 Hii
->ResetStrings (Hii
, gFrontPageHandle
);
456 IN EFI_GUID
*ProducerGuid
,
464 Acquire the string associated with the ProducerGuid and return it.
468 ProducerGuid - The Guid to search the HII database for
469 Token - The token value of the string to extract
470 String - The string that is extracted
474 EFI_SUCCESS - The function returns EFI_SUCCESS always.
479 UINT16 HandleBufferLength
;
480 EFI_HII_HANDLE
*HiiHandleBuffer
;
481 UINTN StringBufferLength
;
482 UINTN NumberOfHiiHandles
;
488 // Initialize params.
490 HandleBufferLength
= 0;
491 HiiHandleBuffer
= NULL
;
494 // Get all the Hii handles
496 Status
= BdsLibGetHiiHandles (Hii
, &HandleBufferLength
, &HiiHandleBuffer
);
497 ASSERT_EFI_ERROR (Status
);
500 // Get the Hii Handle that matches the StructureNode->ProducerName
502 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
503 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
505 Status
= ExtractDataFromHiiHandle (
506 HiiHandleBuffer
[Index
],
511 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
516 // Find the string based on the current language
518 StringBufferLength
= 0x100;
519 *String
= AllocateZeroPool (0x100);
520 Status
= Hii
->GetString (
522 HiiHandleBuffer
[Index
],
530 if (EFI_ERROR (Status
)) {
531 gBS
->FreePool (*String
);
532 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
535 gBS
->FreePool (HiiHandleBuffer
);
540 ConvertProcessorToString (
541 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
,
548 Convert Processor Frequency Data to a string
552 ProcessorFrequency - The frequency data to process
553 String - The string that is created
559 CHAR16
*StringBuffer
;
563 if (ProcessorFrequency
->Exponent
>= 6) {
564 FreqMhz
= ProcessorFrequency
->Value
;
565 for (Index
= 0; Index
< (UINTN
) (ProcessorFrequency
->Exponent
- 6); Index
++) {
572 StringBuffer
= AllocateZeroPool (0x20);
573 ASSERT (StringBuffer
!= NULL
);
574 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
575 StrCat (StringBuffer
, L
".");
576 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
577 StrCat (StringBuffer
, L
" GHz");
579 *String
= (CHAR16
*) StringBuffer
;
585 ConvertMemorySizeToString (
586 IN UINT32 MemorySize
,
593 Convert Memory Size to a string
597 MemorySize - The size of the memory to process
598 String - The string that is created
604 CHAR16
*StringBuffer
;
606 StringBuffer
= AllocateZeroPool (0x20);
607 ASSERT (StringBuffer
!= NULL
);
608 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
609 StrCat (StringBuffer
, L
" MB RAM");
611 *String
= (CHAR16
*) StringBuffer
;
617 UpdateFrontPageStrings (
624 Update the banner information for the Front Page based on DataHub information
635 STRING_REF TokenToUpdate
;
637 UINT64 MonotonicCount
;
638 EFI_DATA_HUB_PROTOCOL
*DataHub
;
639 EFI_DATA_RECORD_HEADER
*Record
;
640 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
641 EFI_MISC_BIOS_VENDOR_DATA
*BiosVendor
;
642 EFI_MISC_SYSTEM_MANUFACTURER_DATA
*SystemManufacturer
;
643 EFI_PROCESSOR_VERSION_DATA
*ProcessorVersion
;
644 EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
;
645 EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*MemoryArray
;
652 ZeroMem (Find
, sizeof (Find
));
655 // Update Front Page strings
657 Status
= gBS
->LocateProtocol (
658 &gEfiDataHubProtocolGuid
,
662 ASSERT_EFI_ERROR (Status
);
666 Status
= gRT
->GetVariable (
668 &gEfiGlobalVariableGuid
,
674 for (Index
= 0; Index
< 3; Index
++) {
675 Lang
[Index
] = (CHAR16
) LangCode
[Index
];
681 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
682 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
683 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
684 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
685 (DataHeader
->RecordType
== EFI_MISC_BIOS_VENDOR_RECORD_NUMBER
)
687 BiosVendor
= (EFI_MISC_BIOS_VENDOR_DATA
*) (DataHeader
+ 1);
688 GetStringFromToken (&Record
->ProducerName
, BiosVendor
->BiosVersion
, &NewString
);
689 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_BIOS_VERSION
;
690 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
691 gBS
->FreePool (NewString
);
695 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
696 (DataHeader
->RecordType
== EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER
)
698 SystemManufacturer
= (EFI_MISC_SYSTEM_MANUFACTURER_DATA
*) (DataHeader
+ 1);
699 GetStringFromToken (&Record
->ProducerName
, SystemManufacturer
->SystemProductName
, &NewString
);
700 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_COMPUTER_MODEL
;
701 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
702 gBS
->FreePool (NewString
);
706 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
707 (DataHeader
->RecordType
== ProcessorVersionRecordType
)
709 ProcessorVersion
= (EFI_PROCESSOR_VERSION_DATA
*) (DataHeader
+ 1);
710 GetStringFromToken (&Record
->ProducerName
, *ProcessorVersion
, &NewString
);
711 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_MODEL
;
712 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
713 gBS
->FreePool (NewString
);
717 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
718 (DataHeader
->RecordType
== ProcessorCoreFrequencyRecordType
)
720 ProcessorFrequency
= (EFI_PROCESSOR_CORE_FREQUENCY_DATA
*) (DataHeader
+ 1);
721 ConvertProcessorToString (ProcessorFrequency
, &NewString
);
722 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_SPEED
;
723 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
724 gBS
->FreePool (NewString
);
728 if (CompareGuid (&Record
->DataRecordGuid
, &mMemorySubClass
) &&
729 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
731 MemoryArray
= (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*) (DataHeader
+ 1);
732 ConvertMemorySizeToString((UINT32
)(RShiftU64((MemoryArray
->MemoryArrayEndAddress
-
733 MemoryArray
->MemoryArrayStartAddress
+ 1), 20)),
735 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_MEMORY_SIZE
;
736 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
737 gBS
->FreePool (NewString
);
741 } while (!EFI_ERROR (Status
) && (MonotonicCount
!= 0) && !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
747 PlatformBdsEnterFrontPage (
748 IN UINT16 TimeoutDefault
,
749 IN BOOLEAN ConnectAllHappened
754 This function is the main entry of the platform setup entry.
755 The function will present the main menu of the system setup,
756 this is the platform reference part and can be customize.
759 TimeoutDefault - The fault time out value before the system
761 ConnectAllHappened - The indicater to check if the connect all have
770 EFI_HII_UPDATE_DATA
*UpdateData
;
771 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
774 // Indicate if we need connect all in the platform setup
776 if (ConnectAllHappened
) {
777 gConnectAllHappened
= TRUE
;
780 // Allocate space for creation of Buffer
782 UpdateData
= AllocateZeroPool (0x1000);
783 ASSERT (UpdateData
!= NULL
);
785 UpdateData
->FormSetUpdate
= FALSE
;
786 UpdateData
->FormCallbackHandle
= 0;
787 UpdateData
->FormUpdate
= FALSE
;
788 UpdateData
->FormTitle
= 0;
789 UpdateData
->DataCount
= 1;
792 // Remove Banner Op-code if any at this label
794 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, FALSE
, UpdateData
);
797 // Create Banner Op-code which reflects correct timeout value
800 STRING_TOKEN (STR_TIME_OUT_PROMPT
),
802 (UINT8
) EFI_IFR_BANNER_TIMEOUT
,
807 // Add Banner Op-code at this label
809 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, TRUE
, UpdateData
);
813 InitializeFrontPage (TRUE
);
816 // Update Front Page strings
818 UpdateFrontPageStrings ();
821 PERF_START (0, "BdsTimeOut", "BDS", 0);
822 Status
= CallFrontPage ();
823 PERF_END (0, "BdsTimeOut", "BDS", 0);
826 // If gCallbackKey is greater than 1 and less or equal to 5,
827 // it will lauch configuration utilities.
830 // 4 = device manager
831 // 5 = boot maintainenance manager
833 if ((gCallbackKey
> 0x0001) && (gCallbackKey
<= 0x0005)) {
836 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
840 // Based on the key that was set, we can determine what to do
842 switch (gCallbackKey
) {
844 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
845 // describe to their customers in documentation how to find their setup information (namely
846 // under the device manager and specific buckets)
848 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
858 // User made a language setting change - display front page again
864 // User chose to run the Boot Manager
871 // Display the Device Manager
875 } while (gCallbackKey
== 4);
880 // Display the Boot Maintenance Manager
882 BdsStartBootMaint ();
886 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= 1));
889 //Will leave browser, check any reset required change is applied? if yes, reset system
891 SetupResetReminder ();
894 // Automatically load current entry
895 // Note: The following lines of code only execute when Auto boot
898 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, (VOID
**)&ConsoleControl
);
899 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);