3 Copyright (c) 2006 - 2007, 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
22 #include "BdsPlatform.h"
23 #include "FrontPage.h"
24 #include "BdsString.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
;
42 FrontPageCallbackRoutine (
43 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
45 IN EFI_IFR_DATA_ARRAY
*DataArray
,
46 OUT EFI_HII_CALLBACK_PACKET
**Packet
52 This is the function that is called to provide results data to the driver. This data
53 consists of a unique key which is used to identify what data is either being passed back
58 KeyValue - A unique value which is sent to the original exporting driver so that it
59 can identify the type of data to expect. The format of the data tends to
60 vary based on the op-code that geerated the callback.
62 Data - A pointer to the data being sent to the original exporting driver.
68 CHAR16
*LanguageString
;
70 CHAR16 UnicodeLang
[3];
75 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
76 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
77 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
79 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
80 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
81 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
86 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
87 // describe to their customers in documentation how to find their setup information (namely
88 // under the device manager and specific buckets)
93 // This is the continue - clear the screen and return an error to get out of FrontPage loop
100 // Collect the languages from what our current Language support is based on our VFR
102 gHii
->GetPrimaryLanguages (gHii
, gFrontPageHandle
, &LanguageString
);
105 // Based on the DataArray->Data->Data value, we can determine
106 // which language was chosen by the user
108 for (Index
= 0; Count
!= (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+ 1))->Data
); Index
+= 3) {
112 // Preserve the choice the user made
114 mLastSelection
= (UINT16
) Count
;
117 // The Language (in Unicode format) the user chose
119 CopyMem (UnicodeLang
, &LanguageString
[Index
], 6);
122 // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
123 // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
125 for (Index
= 0; Index
< 3; Index
++) {
126 Lang
[Index
] = (CHAR8
) UnicodeLang
[Index
];
129 Status
= gRT
->SetVariable (
131 &gEfiGlobalVariableGuid
,
132 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
137 FreePool (LanguageString
);
157 // Boot Maintenance Manager
168 // FrontPage TimeOut Callback
170 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
171 if (TmpStr
!= NULL
) {
172 PlatformBdsShowProgress (
177 (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+1))->Data
),
193 InitializeFrontPage (
194 BOOLEAN ReInitializeStrings
200 Initialize HII information for the FrontPage
206 EFI_SUCCESS - The operation is successful.
207 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
212 EFI_HII_PACKAGES
*PackageList
;
213 EFI_HII_UPDATE_DATA
*UpdateData
;
214 IFR_OPTION
*OptionList
;
215 CHAR16
*LanguageString
;
221 CHAR16 UnicodeLang
[4];
223 CHAR16
*StringBuffer
;
230 if (ReInitializeStrings
) {
232 // BugBug: Dont' use a goto
237 // Go ahead and initialize the Device Manager
239 InitializeDeviceManager ();
242 // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
244 TempBuffer
= (UINT8
*) FrontPageVfrBin
;
245 TempBuffer
= TempBuffer
+ sizeof (EFI_HII_PACK_HEADER
);
246 TempBuffer
= (UINT8
*) &((EFI_IFR_FORM_SET
*) TempBuffer
)->NvDataSize
;
251 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, FrontPageVfrBin
);
253 Status
= gHii
->NewPack (gHii
, PackageList
, &gFrontPageHandle
);
255 FreePool (PackageList
);
258 // There will be only one FormConfig in the system
259 // If there is another out there, someone is trying to install us
260 // again. Fail that scenario.
262 Status
= gBS
->LocateProtocol (
263 &gEfiFormBrowserProtocolGuid
,
269 // This example does not implement worker functions
270 // for the NV accessor functions. Only a callback evaluator
272 FrontPageCallback
.NvRead
= NULL
;
273 FrontPageCallback
.NvWrite
= NULL
;
274 FrontPageCallback
.Callback
= FrontPageCallbackRoutine
;
277 // Install protocol interface
279 FrontPageCallbackHandle
= NULL
;
280 Status
= gBS
->InstallProtocolInterface (
281 &FrontPageCallbackHandle
,
282 &gEfiFormCallbackProtocolGuid
,
283 EFI_NATIVE_INTERFACE
,
286 ASSERT_EFI_ERROR (Status
);
290 // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
293 Status
= gRT
->GetVariable (
295 &gEfiGlobalVariableGuid
,
301 for (Index
= 0; Index
< 3; Index
++) {
302 UnicodeLang
[Index
] = (CHAR16
) AsciiLang
[Index
];
308 // Allocate space for creation of UpdateData Buffer
310 UpdateData
= AllocateZeroPool (0x1000);
311 ASSERT (UpdateData
!= NULL
);
313 OptionList
= AllocateZeroPool (0x1000);
314 ASSERT (OptionList
!= NULL
);
317 // Flag update pending in FormSet
319 UpdateData
->FormSetUpdate
= TRUE
;
321 // Register CallbackHandle data for FormSet
323 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FrontPageCallbackHandle
;
324 UpdateData
->FormUpdate
= FALSE
;
325 UpdateData
->FormTitle
= 0;
326 UpdateData
->DataCount
= 1;
329 // Collect the languages from what our current Language support is based on our VFR
331 gHii
->GetPrimaryLanguages (gHii
, gFrontPageHandle
, &LanguageString
);
336 // Try for a 512 byte Buffer
341 // Allocate memory for our Form binary
343 StringBuffer
= AllocateZeroPool (BufferSize
);
344 ASSERT (StringBuffer
!= NULL
);
346 for (Index
= 0; LanguageString
[Index
] != 0; Index
+= 3) {
348 CopyMem (Lang
, &LanguageString
[Index
], 6);
351 if (!StrCmp (Lang
, UnicodeLang
)) {
352 mLastSelection
= (UINT16
) OptionCount
;
355 Status
= gHii
->GetString (gHii
, gStringPackHandle
, 1, TRUE
, Lang
, &BufferSize
, StringBuffer
);
356 gHii
->NewString (gHii
, NULL
, gStringPackHandle
, &Token
, StringBuffer
);
357 CopyMem (&OptionList
[OptionCount
].StringToken
, &Token
, sizeof (UINT16
));
358 CopyMem (&OptionList
[OptionCount
].Value
, &OptionCount
, sizeof (UINT16
));
360 CopyMem (&OptionList
[OptionCount
].Key
, &Key
, sizeof (UINT16
));
361 OptionList
[OptionCount
].Flags
= EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
;
365 FreePool (LanguageString
);
367 if (ReInitializeStrings
) {
368 FreePool (StringBuffer
);
369 FreePool (OptionList
);
373 Status
= CreateOneOfOpCode (
374 FRONT_PAGE_QUESTION_ID
, // Question ID
375 FRONT_PAGE_DATA_WIDTH
, // Data Width
376 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT
), // Prompt Token
377 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
), // Help Token
378 OptionList
, // List of Options
379 OptionCount
, // Number of Options
380 &UpdateData
->Data
// Data Buffer
384 // Assign the number of options and the oneof and endoneof op-codes to count
386 UpdateData
->DataCount
= (UINT8
) (OptionCount
+ 2);
388 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
390 FreePool (UpdateData
);
392 // FreePool (OptionList);
394 FreePool (StringBuffer
);
406 Call the browser and display the front page
417 UINT8 FakeNvRamMap
[1];
418 BOOLEAN FrontPageMenuResetRequired
;
421 // Begin waiting for USER INPUT
425 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
428 FakeNvRamMap
[0] = (UINT8
) mLastSelection
;
429 FrontPageMenuResetRequired
= FALSE
;
430 Status
= gBrowser
->SendForm (
432 TRUE
, // Use the database
433 &gFrontPageHandle
, // The HII Handle
436 FrontPageCallbackHandle
, // This is the handle that the interface to the callback was installed on
439 &FrontPageMenuResetRequired
442 // Check whether user change any option setting which needs a reset to be effective
444 if (FrontPageMenuResetRequired
) {
445 EnableResetRequired ();
448 gHii
->ResetStrings (gHii
, gFrontPageHandle
);
455 IN EFI_GUID
*ProducerGuid
,
463 Acquire the string associated with the ProducerGuid and return it.
467 ProducerGuid - The Guid to search the HII database for
468 Token - The token value of the string to extract
469 String - The string that is extracted
473 EFI_SUCCESS - The function returns EFI_SUCCESS always.
478 UINT16 HandleBufferLength
;
479 EFI_HII_HANDLE
*HiiHandleBuffer
;
480 UINTN StringBufferLength
;
481 UINTN NumberOfHiiHandles
;
487 // Initialize params.
489 HandleBufferLength
= 0;
490 HiiHandleBuffer
= NULL
;
493 // Get all the Hii handles
495 Status
= BdsLibGetHiiHandles (gHii
, &HandleBufferLength
, &HiiHandleBuffer
);
496 ASSERT_EFI_ERROR (Status
);
499 // Get the gHii Handle that matches the StructureNode->ProducerName
501 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
502 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
504 Status
= ExtractDataFromHiiHandle (
505 HiiHandleBuffer
[Index
],
510 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
515 // Find the string based on the current language
517 StringBufferLength
= 0x100;
518 *String
= AllocateZeroPool (0x100);
519 Status
= gHii
->GetString (
521 HiiHandleBuffer
[Index
],
529 if (EFI_ERROR (Status
)) {
531 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
534 FreePool (HiiHandleBuffer
);
539 ConvertProcessorToString (
540 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
,
547 Convert Processor Frequency Data to a string
551 ProcessorFrequency - The frequency data to process
552 String - The string that is created
558 CHAR16
*StringBuffer
;
562 if (ProcessorFrequency
->Exponent
>= 6) {
563 FreqMhz
= ProcessorFrequency
->Value
;
564 for (Index
= 0; Index
< (UINTN
) (ProcessorFrequency
->Exponent
- 6); Index
++) {
571 StringBuffer
= AllocateZeroPool (0x20);
572 ASSERT (StringBuffer
!= NULL
);
573 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
574 StrCat (StringBuffer
, L
".");
575 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
576 StrCat (StringBuffer
, L
" GHz");
578 *String
= (CHAR16
*) StringBuffer
;
584 ConvertMemorySizeToString (
585 IN UINT32 MemorySize
,
592 Convert Memory Size to a string
596 MemorySize - The size of the memory to process
597 String - The string that is created
603 CHAR16
*StringBuffer
;
605 StringBuffer
= AllocateZeroPool (0x20);
606 ASSERT (StringBuffer
!= NULL
);
607 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
608 StrCat (StringBuffer
, L
" MB RAM");
610 *String
= (CHAR16
*) StringBuffer
;
616 UpdateFrontPageStrings (
623 Update the banner information for the Front Page based on DataHub information
634 STRING_REF TokenToUpdate
;
636 UINT64 MonotonicCount
;
637 EFI_DATA_HUB_PROTOCOL
*DataHub
;
638 EFI_DATA_RECORD_HEADER
*Record
;
639 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
640 EFI_MISC_BIOS_VENDOR_DATA
*BiosVendor
;
641 EFI_MISC_SYSTEM_MANUFACTURER_DATA
*SystemManufacturer
;
642 EFI_PROCESSOR_VERSION_DATA
*ProcessorVersion
;
643 EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
;
644 EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*MemoryArray
;
651 ZeroMem (Find
, sizeof (Find
));
654 // Update Front Page strings
656 Status
= gBS
->LocateProtocol (
657 &gEfiDataHubProtocolGuid
,
661 ASSERT_EFI_ERROR (Status
);
665 Status
= gRT
->GetVariable (
667 &gEfiGlobalVariableGuid
,
673 for (Index
= 0; Index
< 3; Index
++) {
674 Lang
[Index
] = (CHAR16
) LangCode
[Index
];
680 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
681 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
682 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
683 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
684 (DataHeader
->RecordType
== EFI_MISC_BIOS_VENDOR_RECORD_NUMBER
)
686 BiosVendor
= (EFI_MISC_BIOS_VENDOR_DATA
*) (DataHeader
+ 1);
687 GetStringFromToken (&Record
->ProducerName
, BiosVendor
->BiosVersion
, &NewString
);
688 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_BIOS_VERSION
;
689 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
690 FreePool (NewString
);
694 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
695 (DataHeader
->RecordType
== EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER
)
697 SystemManufacturer
= (EFI_MISC_SYSTEM_MANUFACTURER_DATA
*) (DataHeader
+ 1);
698 GetStringFromToken (&Record
->ProducerName
, SystemManufacturer
->SystemProductName
, &NewString
);
699 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_COMPUTER_MODEL
;
700 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
701 FreePool (NewString
);
705 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
706 (DataHeader
->RecordType
== ProcessorVersionRecordType
)
708 ProcessorVersion
= (EFI_PROCESSOR_VERSION_DATA
*) (DataHeader
+ 1);
709 GetStringFromToken (&Record
->ProducerName
, *ProcessorVersion
, &NewString
);
710 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_MODEL
;
711 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
712 FreePool (NewString
);
716 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
717 (DataHeader
->RecordType
== ProcessorCoreFrequencyRecordType
)
719 ProcessorFrequency
= (EFI_PROCESSOR_CORE_FREQUENCY_DATA
*) (DataHeader
+ 1);
720 ConvertProcessorToString (ProcessorFrequency
, &NewString
);
721 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_SPEED
;
722 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
723 FreePool (NewString
);
727 if (CompareGuid (&Record
->DataRecordGuid
, &mMemorySubClass
) &&
728 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
730 MemoryArray
= (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*) (DataHeader
+ 1);
731 ConvertMemorySizeToString((UINT32
)(RShiftU64((MemoryArray
->MemoryArrayEndAddress
-
732 MemoryArray
->MemoryArrayStartAddress
+ 1), 20)),
734 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_MEMORY_SIZE
;
735 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
736 FreePool (NewString
);
740 } while (!EFI_ERROR (Status
) && (MonotonicCount
!= 0) && !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
746 PlatformBdsEnterFrontPage (
747 IN UINT16 TimeoutDefault
,
748 IN BOOLEAN ConnectAllHappened
753 This function is the main entry of the platform setup entry.
754 The function will present the main menu of the system setup,
755 this is the platform reference part and can be customize.
758 TimeoutDefault - The fault time out value before the system
760 ConnectAllHappened - The indicater to check if the connect all have
769 EFI_HII_UPDATE_DATA
*UpdateData
;
770 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
773 // Indicate if we need connect all in the platform setup
775 if (ConnectAllHappened
) {
776 gConnectAllHappened
= TRUE
;
779 // Allocate space for creation of Buffer
781 UpdateData
= AllocateZeroPool (0x1000);
782 ASSERT (UpdateData
!= NULL
);
784 UpdateData
->FormSetUpdate
= FALSE
;
785 UpdateData
->FormCallbackHandle
= 0;
786 UpdateData
->FormUpdate
= FALSE
;
787 UpdateData
->FormTitle
= 0;
788 UpdateData
->DataCount
= 1;
791 // Remove Banner Op-code if any at this label
793 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, FALSE
, UpdateData
);
796 // Create Banner Op-code which reflects correct timeout value
799 STRING_TOKEN (STR_TIME_OUT_PROMPT
),
801 (UINT8
) EFI_IFR_BANNER_TIMEOUT
,
806 // Add Banner Op-code at this label
808 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, TRUE
, UpdateData
);
812 InitializeFrontPage (TRUE
);
815 // Update Front Page strings
817 UpdateFrontPageStrings ();
820 PERF_START (0, "BdsTimeOut", "BDS", 0);
821 Status
= CallFrontPage ();
822 PERF_END (0, "BdsTimeOut", "BDS", 0);
825 // If gCallbackKey is greater than 1 and less or equal to 5,
826 // it will lauch configuration utilities.
829 // 4 = device manager
830 // 5 = boot maintainenance manager
832 if ((gCallbackKey
> 0x0001) && (gCallbackKey
<= 0x0005)) {
835 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
839 // Based on the key that was set, we can determine what to do
841 switch (gCallbackKey
) {
843 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
844 // describe to their customers in documentation how to find their setup information (namely
845 // under the device manager and specific buckets)
847 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
857 // User made a language setting change - display front page again
863 // User chose to run the Boot Manager
870 // Display the Device Manager
874 } while (gCallbackKey
== 4);
879 // Display the Boot Maintenance Manager
881 BdsStartBootMaint ();
885 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= 1));
888 //Will leave browser, check any reset required change is applied? if yes, reset system
890 SetupResetReminder ();
893 // Automatically load current entry
894 // Note: The following lines of code only execute when Auto boot
897 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, &ConsoleControl
);
898 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);