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 "BdsPlatform.h"
24 #include "FrontPage.h"
27 EFI_GUID mProcessorSubClass
= EFI_PROCESSOR_SUBCLASS_GUID
;
28 EFI_GUID mMemorySubClass
= EFI_MEMORY_SUBCLASS_GUID
;
29 EFI_GUID mMiscSubClass
= EFI_MISC_SUBCLASS_GUID
;
31 UINT16 mLastSelection
;
32 EFI_HII_HANDLE gFrontPageHandle
;
33 EFI_HANDLE FrontPageCallbackHandle
;
34 EFI_FORM_CALLBACK_PROTOCOL FrontPageCallback
;
35 EFI_FORM_BROWSER_PROTOCOL
*gBrowser
;
37 BOOLEAN gConnectAllHappened
= FALSE
;
39 extern EFI_HII_HANDLE gFrontPageHandle
;
40 extern EFI_GUID gBdsStringPackGuid
;
44 FrontPageCallbackRoutine (
45 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
47 IN EFI_IFR_DATA_ARRAY
*DataArray
,
48 OUT EFI_HII_CALLBACK_PACKET
**Packet
54 This is the function that is called to provide results data to the driver. This data
55 consists of a unique key which is used to identify what data is either being passed back
60 KeyValue - A unique value which is sent to the original exporting driver so that it
61 can identify the type of data to expect. The format of the data tends to
62 vary based on the op-code that geerated the callback.
64 Data - A pointer to the data being sent to the original exporting driver.
70 CHAR16
*LanguageString
;
72 CHAR16 UnicodeLang
[3];
77 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
78 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
79 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
81 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
82 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
83 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
88 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
89 // describe to their customers in documentation how to find their setup information (namely
90 // under the device manager and specific buckets)
95 // This is the continue - clear the screen and return an error to get out of FrontPage loop
102 // Collect the languages from what our current Language support is based on our VFR
104 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
107 // Based on the DataArray->Data->Data value, we can determine
108 // which language was chosen by the user
110 for (Index
= 0; Count
!= (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+ 1))->Data
); Index
+= 3) {
114 // Preserve the choice the user made
116 mLastSelection
= (UINT16
) Count
;
119 // The Language (in Unicode format) the user chose
121 CopyMem (UnicodeLang
, &LanguageString
[Index
], 6);
124 // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
125 // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
127 for (Index
= 0; Index
< 3; Index
++) {
128 Lang
[Index
] = (CHAR8
) UnicodeLang
[Index
];
131 Status
= gRT
->SetVariable (
133 &gEfiGlobalVariableGuid
,
134 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
139 gBS
->FreePool (LanguageString
);
159 // Boot Maintenance Manager
170 // FrontPage TimeOut Callback
172 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
173 if (TmpStr
!= NULL
) {
174 PlatformBdsShowProgress (
179 (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+1))->Data
),
182 gBS
->FreePool (TmpStr
);
195 InitializeFrontPage (
196 BOOLEAN ReInitializeStrings
202 Initialize HII information for the FrontPage
208 EFI_SUCCESS - The operation is successful.
209 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
214 EFI_HII_PACKAGES
*PackageList
;
215 EFI_HII_UPDATE_DATA
*UpdateData
;
216 IFR_OPTION
*OptionList
;
217 CHAR16
*LanguageString
;
223 CHAR16 UnicodeLang
[4];
225 CHAR16
*StringBuffer
;
232 if (ReInitializeStrings
) {
234 // BugBug: Dont' use a goto
239 // Go ahead and initialize the Device Manager
241 InitializeDeviceManager ();
244 // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
246 TempBuffer
= (UINT8
*) FrontPageVfrBin
;
247 TempBuffer
= TempBuffer
+ sizeof (EFI_HII_PACK_HEADER
);
248 TempBuffer
= (UINT8
*) &((EFI_IFR_FORM_SET
*) TempBuffer
)->NvDataSize
;
253 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FrontPageVfrBin
);
255 Status
= Hii
->NewPack (Hii
, PackageList
, &gFrontPageHandle
);
257 gBS
->FreePool (PackageList
);
260 // There will be only one FormConfig in the system
261 // If there is another out there, someone is trying to install us
262 // again. Fail that scenario.
264 Status
= gBS
->LocateProtocol (
265 &gEfiFormBrowserProtocolGuid
,
271 // This example does not implement worker functions
272 // for the NV accessor functions. Only a callback evaluator
274 FrontPageCallback
.NvRead
= NULL
;
275 FrontPageCallback
.NvWrite
= NULL
;
276 FrontPageCallback
.Callback
= FrontPageCallbackRoutine
;
279 // Install protocol interface
281 FrontPageCallbackHandle
= NULL
;
282 Status
= gBS
->InstallProtocolInterface (
283 &FrontPageCallbackHandle
,
284 &gEfiFormCallbackProtocolGuid
,
285 EFI_NATIVE_INTERFACE
,
288 ASSERT_EFI_ERROR (Status
);
292 // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
295 Status
= gRT
->GetVariable (
297 &gEfiGlobalVariableGuid
,
303 for (Index
= 0; Index
< 3; Index
++) {
304 UnicodeLang
[Index
] = (CHAR16
) AsciiLang
[Index
];
310 // Allocate space for creation of UpdateData Buffer
312 UpdateData
= AllocateZeroPool (0x1000);
313 ASSERT (UpdateData
!= NULL
);
315 OptionList
= AllocateZeroPool (0x1000);
316 ASSERT (OptionList
!= NULL
);
319 // Flag update pending in FormSet
321 UpdateData
->FormSetUpdate
= TRUE
;
323 // Register CallbackHandle data for FormSet
325 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FrontPageCallbackHandle
;
326 UpdateData
->FormUpdate
= FALSE
;
327 UpdateData
->FormTitle
= 0;
328 UpdateData
->DataCount
= 1;
331 // Collect the languages from what our current Language support is based on our VFR
333 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
338 // Try for a 512 byte Buffer
343 // Allocate memory for our Form binary
345 StringBuffer
= AllocateZeroPool (BufferSize
);
346 ASSERT (StringBuffer
!= NULL
);
348 for (Index
= 0; LanguageString
[Index
] != 0; Index
+= 3) {
350 CopyMem (Lang
, &LanguageString
[Index
], 6);
353 if (!StrCmp (Lang
, UnicodeLang
)) {
354 mLastSelection
= (UINT16
) OptionCount
;
357 Status
= Hii
->GetString (Hii
, gStringPackHandle
, 1, TRUE
, Lang
, &BufferSize
, StringBuffer
);
358 Hii
->NewString (Hii
, NULL
, gStringPackHandle
, &Token
, StringBuffer
);
359 CopyMem (&OptionList
[OptionCount
].StringToken
, &Token
, sizeof (UINT16
));
360 CopyMem (&OptionList
[OptionCount
].Value
, &OptionCount
, sizeof (UINT16
));
362 CopyMem (&OptionList
[OptionCount
].Key
, &Key
, sizeof (UINT16
));
363 OptionList
[OptionCount
].Flags
= EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
;
367 gBS
->FreePool (LanguageString
);
369 if (ReInitializeStrings
) {
370 gBS
->FreePool (StringBuffer
);
371 gBS
->FreePool (OptionList
);
375 Status
= CreateOneOfOpCode (
376 FRONT_PAGE_QUESTION_ID
, // Question ID
377 FRONT_PAGE_DATA_WIDTH
, // Data Width
378 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT
), // Prompt Token
379 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
), // Help Token
380 OptionList
, // List of Options
381 OptionCount
, // Number of Options
382 &UpdateData
->Data
// Data Buffer
386 // Assign the number of options and the oneof and endoneof op-codes to count
388 UpdateData
->DataCount
= (UINT8
) (OptionCount
+ 2);
390 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
392 gBS
->FreePool (UpdateData
);
394 // gBS->FreePool (OptionList);
396 gBS
->FreePool (StringBuffer
);
408 Call the browser and display the front page
419 UINT8 FakeNvRamMap
[1];
420 BOOLEAN FrontPageMenuResetRequired
;
423 // Begin waiting for USER INPUT
427 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
430 FakeNvRamMap
[0] = (UINT8
) mLastSelection
;
431 FrontPageMenuResetRequired
= FALSE
;
432 Status
= gBrowser
->SendForm (
434 TRUE
, // Use the database
435 &gFrontPageHandle
, // The HII Handle
438 FrontPageCallbackHandle
, // This is the handle that the interface to the callback was installed on
441 &FrontPageMenuResetRequired
444 // Check whether user change any option setting which needs a reset to be effective
446 if (FrontPageMenuResetRequired
) {
447 EnableResetRequired ();
450 Hii
->ResetStrings (Hii
, gFrontPageHandle
);
457 IN EFI_GUID
*ProducerGuid
,
465 Acquire the string associated with the ProducerGuid and return it.
469 ProducerGuid - The Guid to search the HII database for
470 Token - The token value of the string to extract
471 String - The string that is extracted
475 EFI_SUCCESS - The function returns EFI_SUCCESS always.
480 UINT16 HandleBufferLength
;
481 EFI_HII_HANDLE
*HiiHandleBuffer
;
482 UINTN StringBufferLength
;
483 UINTN NumberOfHiiHandles
;
489 // Initialize params.
491 HandleBufferLength
= 0;
492 HiiHandleBuffer
= NULL
;
495 // Get all the Hii handles
497 Status
= BdsLibGetHiiHandles (Hii
, &HandleBufferLength
, &HiiHandleBuffer
);
498 ASSERT_EFI_ERROR (Status
);
501 // Get the Hii Handle that matches the StructureNode->ProducerName
503 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
504 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
506 Status
= ExtractDataFromHiiHandle (
507 HiiHandleBuffer
[Index
],
512 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
517 // Find the string based on the current language
519 StringBufferLength
= 0x100;
520 *String
= AllocateZeroPool (0x100);
521 Status
= Hii
->GetString (
523 HiiHandleBuffer
[Index
],
531 if (EFI_ERROR (Status
)) {
532 gBS
->FreePool (*String
);
533 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
536 gBS
->FreePool (HiiHandleBuffer
);
541 ConvertProcessorToString (
542 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
,
549 Convert Processor Frequency Data to a string
553 ProcessorFrequency - The frequency data to process
554 String - The string that is created
560 CHAR16
*StringBuffer
;
564 if (ProcessorFrequency
->Exponent
>= 6) {
565 FreqMhz
= ProcessorFrequency
->Value
;
566 for (Index
= 0; Index
< (UINTN
) (ProcessorFrequency
->Exponent
- 6); Index
++) {
573 StringBuffer
= AllocateZeroPool (0x20);
574 ASSERT (StringBuffer
!= NULL
);
575 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
576 StrCat (StringBuffer
, L
".");
577 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
578 StrCat (StringBuffer
, L
" GHz");
580 *String
= (CHAR16
*) StringBuffer
;
586 ConvertMemorySizeToString (
587 IN UINT32 MemorySize
,
594 Convert Memory Size to a string
598 MemorySize - The size of the memory to process
599 String - The string that is created
605 CHAR16
*StringBuffer
;
607 StringBuffer
= AllocateZeroPool (0x20);
608 ASSERT (StringBuffer
!= NULL
);
609 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
610 StrCat (StringBuffer
, L
" MB RAM");
612 *String
= (CHAR16
*) StringBuffer
;
618 UpdateFrontPageStrings (
625 Update the banner information for the Front Page based on DataHub information
636 STRING_REF TokenToUpdate
;
638 UINT64 MonotonicCount
;
639 EFI_DATA_HUB_PROTOCOL
*DataHub
;
640 EFI_DATA_RECORD_HEADER
*Record
;
641 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
642 EFI_MISC_BIOS_VENDOR_DATA
*BiosVendor
;
643 EFI_MISC_SYSTEM_MANUFACTURER_DATA
*SystemManufacturer
;
644 EFI_PROCESSOR_VERSION_DATA
*ProcessorVersion
;
645 EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
;
646 EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*MemoryArray
;
653 ZeroMem (Find
, sizeof (Find
));
656 // Update Front Page strings
658 Status
= gBS
->LocateProtocol (
659 &gEfiDataHubProtocolGuid
,
663 ASSERT_EFI_ERROR (Status
);
667 Status
= gRT
->GetVariable (
669 &gEfiGlobalVariableGuid
,
675 for (Index
= 0; Index
< 3; Index
++) {
676 Lang
[Index
] = (CHAR16
) LangCode
[Index
];
682 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
683 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
684 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
685 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
686 (DataHeader
->RecordType
== EFI_MISC_BIOS_VENDOR_RECORD_NUMBER
)
688 BiosVendor
= (EFI_MISC_BIOS_VENDOR_DATA
*) (DataHeader
+ 1);
689 GetStringFromToken (&Record
->ProducerName
, BiosVendor
->BiosVersion
, &NewString
);
690 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_BIOS_VERSION
;
691 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
692 gBS
->FreePool (NewString
);
696 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
697 (DataHeader
->RecordType
== EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER
)
699 SystemManufacturer
= (EFI_MISC_SYSTEM_MANUFACTURER_DATA
*) (DataHeader
+ 1);
700 GetStringFromToken (&Record
->ProducerName
, SystemManufacturer
->SystemProductName
, &NewString
);
701 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_COMPUTER_MODEL
;
702 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
703 gBS
->FreePool (NewString
);
707 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
708 (DataHeader
->RecordType
== ProcessorVersionRecordType
)
710 ProcessorVersion
= (EFI_PROCESSOR_VERSION_DATA
*) (DataHeader
+ 1);
711 GetStringFromToken (&Record
->ProducerName
, *ProcessorVersion
, &NewString
);
712 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_MODEL
;
713 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
714 gBS
->FreePool (NewString
);
718 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
719 (DataHeader
->RecordType
== ProcessorCoreFrequencyRecordType
)
721 ProcessorFrequency
= (EFI_PROCESSOR_CORE_FREQUENCY_DATA
*) (DataHeader
+ 1);
722 ConvertProcessorToString (ProcessorFrequency
, &NewString
);
723 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_SPEED
;
724 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
725 gBS
->FreePool (NewString
);
729 if (CompareGuid (&Record
->DataRecordGuid
, &mMemorySubClass
) &&
730 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
732 MemoryArray
= (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*) (DataHeader
+ 1);
733 ConvertMemorySizeToString((UINT32
)(RShiftU64((MemoryArray
->MemoryArrayEndAddress
-
734 MemoryArray
->MemoryArrayStartAddress
+ 1), 20)),
736 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_MEMORY_SIZE
;
737 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
738 gBS
->FreePool (NewString
);
742 } while (!EFI_ERROR (Status
) && (MonotonicCount
!= 0) && !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
748 PlatformBdsEnterFrontPage (
749 IN UINT16 TimeoutDefault
,
750 IN BOOLEAN ConnectAllHappened
755 This function is the main entry of the platform setup entry.
756 The function will present the main menu of the system setup,
757 this is the platform reference part and can be customize.
760 TimeoutDefault - The fault time out value before the system
762 ConnectAllHappened - The indicater to check if the connect all have
771 EFI_HII_UPDATE_DATA
*UpdateData
;
772 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
775 // Indicate if we need connect all in the platform setup
777 if (ConnectAllHappened
) {
778 gConnectAllHappened
= TRUE
;
781 // Allocate space for creation of Buffer
783 UpdateData
= AllocateZeroPool (0x1000);
784 ASSERT (UpdateData
!= NULL
);
786 UpdateData
->FormSetUpdate
= FALSE
;
787 UpdateData
->FormCallbackHandle
= 0;
788 UpdateData
->FormUpdate
= FALSE
;
789 UpdateData
->FormTitle
= 0;
790 UpdateData
->DataCount
= 1;
793 // Remove Banner Op-code if any at this label
795 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, FALSE
, UpdateData
);
798 // Create Banner Op-code which reflects correct timeout value
801 STRING_TOKEN (STR_TIME_OUT_PROMPT
),
803 (UINT8
) EFI_IFR_BANNER_TIMEOUT
,
808 // Add Banner Op-code at this label
810 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, TRUE
, UpdateData
);
814 InitializeFrontPage (TRUE
);
817 // Update Front Page strings
819 UpdateFrontPageStrings ();
822 PERF_START (0, "BdsTimeOut", "BDS", 0);
823 Status
= CallFrontPage ();
824 PERF_END (0, "BdsTimeOut", "BDS", 0);
827 // If gCallbackKey is greater than 1 and less or equal to 5,
828 // it will lauch configuration utilities.
831 // 4 = device manager
832 // 5 = boot maintainenance manager
834 if ((gCallbackKey
> 0x0001) && (gCallbackKey
<= 0x0005)) {
837 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
841 // Based on the key that was set, we can determine what to do
843 switch (gCallbackKey
) {
845 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
846 // describe to their customers in documentation how to find their setup information (namely
847 // under the device manager and specific buckets)
849 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
859 // User made a language setting change - display front page again
865 // User chose to run the Boot Manager
872 // Display the Device Manager
876 } while (gCallbackKey
== 4);
881 // Display the Boot Maintenance Manager
883 BdsStartBootMaint ();
887 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= 1));
890 //Will leave browser, check any reset required change is applied? if yes, reset system
892 SetupResetReminder ();
895 // Automatically load current entry
896 // Note: The following lines of code only execute when Auto boot
899 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, &ConsoleControl
);
900 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);