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
23 // Include common header file for this module.
25 #include "CommonHeader.h"
28 #include "BdsPlatform.h"
29 #include "FrontPage.h"
32 EFI_GUID mProcessorSubClass
= EFI_PROCESSOR_SUBCLASS_GUID
;
33 EFI_GUID mMemorySubClass
= EFI_MEMORY_SUBCLASS_GUID
;
34 EFI_GUID mMiscSubClass
= EFI_MISC_SUBCLASS_GUID
;
36 UINT16 mLastSelection
;
37 EFI_HII_HANDLE gFrontPageHandle
;
38 EFI_HANDLE FrontPageCallbackHandle
;
39 EFI_FORM_CALLBACK_PROTOCOL FrontPageCallback
;
40 EFI_FORM_BROWSER_PROTOCOL
*gBrowser
;
42 BOOLEAN gConnectAllHappened
= FALSE
;
44 extern EFI_HII_HANDLE gFrontPageHandle
;
45 extern EFI_GUID gBdsStringPackGuid
;
49 FrontPageCallbackRoutine (
50 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
52 IN EFI_IFR_DATA_ARRAY
*DataArray
,
53 OUT EFI_HII_CALLBACK_PACKET
**Packet
59 This is the function that is called to provide results data to the driver. This data
60 consists of a unique key which is used to identify what data is either being passed back
65 KeyValue - A unique value which is sent to the original exporting driver so that it
66 can identify the type of data to expect. The format of the data tends to
67 vary based on the op-code that geerated the callback.
69 Data - A pointer to the data being sent to the original exporting driver.
75 CHAR16
*LanguageString
;
77 CHAR16 UnicodeLang
[3];
82 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
83 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
84 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
86 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
87 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
88 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
93 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
94 // describe to their customers in documentation how to find their setup information (namely
95 // under the device manager and specific buckets)
100 // This is the continue - clear the screen and return an error to get out of FrontPage loop
107 // Collect the languages from what our current Language support is based on our VFR
109 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
112 // Based on the DataArray->Data->Data value, we can determine
113 // which language was chosen by the user
115 for (Index
= 0; Count
!= (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+ 1))->Data
); Index
+= 3) {
119 // Preserve the choice the user made
121 mLastSelection
= (UINT16
) Count
;
124 // The Language (in Unicode format) the user chose
126 CopyMem (UnicodeLang
, &LanguageString
[Index
], 6);
129 // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
130 // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
132 for (Index
= 0; Index
< 3; Index
++) {
133 Lang
[Index
] = (CHAR8
) UnicodeLang
[Index
];
136 Status
= gRT
->SetVariable (
138 &gEfiGlobalVariableGuid
,
139 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
144 FreePool (LanguageString
);
164 // Boot Maintenance Manager
175 // FrontPage TimeOut Callback
177 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
178 if (TmpStr
!= NULL
) {
179 PlatformBdsShowProgress (
184 (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+1))->Data
),
200 InitializeFrontPage (
201 BOOLEAN ReInitializeStrings
207 Initialize HII information for the FrontPage
213 EFI_SUCCESS - The operation is successful.
214 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
219 EFI_HII_PACKAGES
*PackageList
;
220 EFI_HII_UPDATE_DATA
*UpdateData
;
221 IFR_OPTION
*OptionList
;
222 CHAR16
*LanguageString
;
228 CHAR16 UnicodeLang
[4];
230 CHAR16
*StringBuffer
;
237 if (ReInitializeStrings
) {
239 // BugBug: Dont' use a goto
244 // Go ahead and initialize the Device Manager
246 InitializeDeviceManager ();
249 // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
251 TempBuffer
= (UINT8
*) FrontPageVfrBin
;
252 TempBuffer
= TempBuffer
+ sizeof (EFI_HII_PACK_HEADER
);
253 TempBuffer
= (UINT8
*) &((EFI_IFR_FORM_SET
*) TempBuffer
)->NvDataSize
;
258 PackageList
= PreparePackages (1, &gBdsStringPackGuid
, FrontPageVfrBin
);
260 Status
= Hii
->NewPack (Hii
, PackageList
, &gFrontPageHandle
);
262 FreePool (PackageList
);
265 // There will be only one FormConfig in the system
266 // If there is another out there, someone is trying to install us
267 // again. Fail that scenario.
269 Status
= gBS
->LocateProtocol (
270 &gEfiFormBrowserProtocolGuid
,
276 // This example does not implement worker functions
277 // for the NV accessor functions. Only a callback evaluator
279 FrontPageCallback
.NvRead
= NULL
;
280 FrontPageCallback
.NvWrite
= NULL
;
281 FrontPageCallback
.Callback
= FrontPageCallbackRoutine
;
284 // Install protocol interface
286 FrontPageCallbackHandle
= NULL
;
287 Status
= gBS
->InstallProtocolInterface (
288 &FrontPageCallbackHandle
,
289 &gEfiFormCallbackProtocolGuid
,
290 EFI_NATIVE_INTERFACE
,
293 ASSERT_EFI_ERROR (Status
);
297 // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
300 Status
= gRT
->GetVariable (
302 &gEfiGlobalVariableGuid
,
308 for (Index
= 0; Index
< 3; Index
++) {
309 UnicodeLang
[Index
] = (CHAR16
) AsciiLang
[Index
];
315 // Allocate space for creation of UpdateData Buffer
317 UpdateData
= AllocateZeroPool (0x1000);
318 ASSERT (UpdateData
!= NULL
);
320 OptionList
= AllocateZeroPool (0x1000);
321 ASSERT (OptionList
!= NULL
);
324 // Flag update pending in FormSet
326 UpdateData
->FormSetUpdate
= TRUE
;
328 // Register CallbackHandle data for FormSet
330 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FrontPageCallbackHandle
;
331 UpdateData
->FormUpdate
= FALSE
;
332 UpdateData
->FormTitle
= 0;
333 UpdateData
->DataCount
= 1;
336 // Collect the languages from what our current Language support is based on our VFR
338 Hii
->GetPrimaryLanguages (Hii
, gFrontPageHandle
, &LanguageString
);
343 // Try for a 512 byte Buffer
348 // Allocate memory for our Form binary
350 StringBuffer
= AllocateZeroPool (BufferSize
);
351 ASSERT (StringBuffer
!= NULL
);
353 for (Index
= 0; LanguageString
[Index
] != 0; Index
+= 3) {
355 CopyMem (Lang
, &LanguageString
[Index
], 6);
358 if (!StrCmp (Lang
, UnicodeLang
)) {
359 mLastSelection
= (UINT16
) OptionCount
;
362 Status
= Hii
->GetString (Hii
, gStringPackHandle
, 1, TRUE
, Lang
, &BufferSize
, StringBuffer
);
363 Hii
->NewString (Hii
, NULL
, gStringPackHandle
, &Token
, StringBuffer
);
364 CopyMem (&OptionList
[OptionCount
].StringToken
, &Token
, sizeof (UINT16
));
365 CopyMem (&OptionList
[OptionCount
].Value
, &OptionCount
, sizeof (UINT16
));
367 CopyMem (&OptionList
[OptionCount
].Key
, &Key
, sizeof (UINT16
));
368 OptionList
[OptionCount
].Flags
= EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
;
372 FreePool (LanguageString
);
374 if (ReInitializeStrings
) {
375 FreePool (StringBuffer
);
376 FreePool (OptionList
);
380 Status
= CreateOneOfOpCode (
381 FRONT_PAGE_QUESTION_ID
, // Question ID
382 FRONT_PAGE_DATA_WIDTH
, // Data Width
383 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT
), // Prompt Token
384 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
), // Help Token
385 OptionList
, // List of Options
386 OptionCount
, // Number of Options
387 &UpdateData
->Data
// Data Buffer
391 // Assign the number of options and the oneof and endoneof op-codes to count
393 UpdateData
->DataCount
= (UINT8
) (OptionCount
+ 2);
395 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
397 FreePool (UpdateData
);
399 // FreePool (OptionList);
401 FreePool (StringBuffer
);
413 Call the browser and display the front page
424 UINT8 FakeNvRamMap
[1];
425 BOOLEAN FrontPageMenuResetRequired
;
428 // Begin waiting for USER INPUT
432 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
435 FakeNvRamMap
[0] = (UINT8
) mLastSelection
;
436 FrontPageMenuResetRequired
= FALSE
;
437 Status
= gBrowser
->SendForm (
439 TRUE
, // Use the database
440 &gFrontPageHandle
, // The HII Handle
443 FrontPageCallbackHandle
, // This is the handle that the interface to the callback was installed on
446 &FrontPageMenuResetRequired
449 // Check whether user change any option setting which needs a reset to be effective
451 if (FrontPageMenuResetRequired
) {
452 EnableResetRequired ();
455 Hii
->ResetStrings (Hii
, gFrontPageHandle
);
462 IN EFI_GUID
*ProducerGuid
,
470 Acquire the string associated with the ProducerGuid and return it.
474 ProducerGuid - The Guid to search the HII database for
475 Token - The token value of the string to extract
476 String - The string that is extracted
480 EFI_SUCCESS - The function returns EFI_SUCCESS always.
485 UINT16 HandleBufferLength
;
486 EFI_HII_HANDLE
*HiiHandleBuffer
;
487 UINTN StringBufferLength
;
488 UINTN NumberOfHiiHandles
;
494 // Initialize params.
496 HandleBufferLength
= 0;
497 HiiHandleBuffer
= NULL
;
500 // Get all the Hii handles
502 Status
= BdsLibGetHiiHandles (Hii
, &HandleBufferLength
, &HiiHandleBuffer
);
503 ASSERT_EFI_ERROR (Status
);
506 // Get the Hii Handle that matches the StructureNode->ProducerName
508 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
509 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
511 Status
= ExtractDataFromHiiHandle (
512 HiiHandleBuffer
[Index
],
517 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
522 // Find the string based on the current language
524 StringBufferLength
= 0x100;
525 *String
= AllocateZeroPool (0x100);
526 Status
= Hii
->GetString (
528 HiiHandleBuffer
[Index
],
536 if (EFI_ERROR (Status
)) {
538 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
541 FreePool (HiiHandleBuffer
);
546 ConvertProcessorToString (
547 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
,
554 Convert Processor Frequency Data to a string
558 ProcessorFrequency - The frequency data to process
559 String - The string that is created
565 CHAR16
*StringBuffer
;
569 if (ProcessorFrequency
->Exponent
>= 6) {
570 FreqMhz
= ProcessorFrequency
->Value
;
571 for (Index
= 0; Index
< (UINTN
) (ProcessorFrequency
->Exponent
- 6); Index
++) {
578 StringBuffer
= AllocateZeroPool (0x20);
579 ASSERT (StringBuffer
!= NULL
);
580 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
581 StrCat (StringBuffer
, L
".");
582 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
583 StrCat (StringBuffer
, L
" GHz");
585 *String
= (CHAR16
*) StringBuffer
;
591 ConvertMemorySizeToString (
592 IN UINT32 MemorySize
,
599 Convert Memory Size to a string
603 MemorySize - The size of the memory to process
604 String - The string that is created
610 CHAR16
*StringBuffer
;
612 StringBuffer
= AllocateZeroPool (0x20);
613 ASSERT (StringBuffer
!= NULL
);
614 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
615 StrCat (StringBuffer
, L
" MB RAM");
617 *String
= (CHAR16
*) StringBuffer
;
623 UpdateFrontPageStrings (
630 Update the banner information for the Front Page based on DataHub information
641 STRING_REF TokenToUpdate
;
643 UINT64 MonotonicCount
;
644 EFI_DATA_HUB_PROTOCOL
*DataHub
;
645 EFI_DATA_RECORD_HEADER
*Record
;
646 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
647 EFI_MISC_BIOS_VENDOR_DATA
*BiosVendor
;
648 EFI_MISC_SYSTEM_MANUFACTURER_DATA
*SystemManufacturer
;
649 EFI_PROCESSOR_VERSION_DATA
*ProcessorVersion
;
650 EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
;
651 EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*MemoryArray
;
658 ZeroMem (Find
, sizeof (Find
));
661 // Update Front Page strings
663 Status
= gBS
->LocateProtocol (
664 &gEfiDataHubProtocolGuid
,
668 ASSERT_EFI_ERROR (Status
);
672 Status
= gRT
->GetVariable (
674 &gEfiGlobalVariableGuid
,
680 for (Index
= 0; Index
< 3; Index
++) {
681 Lang
[Index
] = (CHAR16
) LangCode
[Index
];
687 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
688 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
689 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
690 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
691 (DataHeader
->RecordType
== EFI_MISC_BIOS_VENDOR_RECORD_NUMBER
)
693 BiosVendor
= (EFI_MISC_BIOS_VENDOR_DATA
*) (DataHeader
+ 1);
694 GetStringFromToken (&Record
->ProducerName
, BiosVendor
->BiosVersion
, &NewString
);
695 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_BIOS_VERSION
;
696 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
697 FreePool (NewString
);
701 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
702 (DataHeader
->RecordType
== EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER
)
704 SystemManufacturer
= (EFI_MISC_SYSTEM_MANUFACTURER_DATA
*) (DataHeader
+ 1);
705 GetStringFromToken (&Record
->ProducerName
, SystemManufacturer
->SystemProductName
, &NewString
);
706 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_COMPUTER_MODEL
;
707 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
708 FreePool (NewString
);
712 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
713 (DataHeader
->RecordType
== ProcessorVersionRecordType
)
715 ProcessorVersion
= (EFI_PROCESSOR_VERSION_DATA
*) (DataHeader
+ 1);
716 GetStringFromToken (&Record
->ProducerName
, *ProcessorVersion
, &NewString
);
717 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_MODEL
;
718 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
719 FreePool (NewString
);
723 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
724 (DataHeader
->RecordType
== ProcessorCoreFrequencyRecordType
)
726 ProcessorFrequency
= (EFI_PROCESSOR_CORE_FREQUENCY_DATA
*) (DataHeader
+ 1);
727 ConvertProcessorToString (ProcessorFrequency
, &NewString
);
728 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_SPEED
;
729 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
730 FreePool (NewString
);
734 if (CompareGuid (&Record
->DataRecordGuid
, &mMemorySubClass
) &&
735 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
737 MemoryArray
= (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*) (DataHeader
+ 1);
738 ConvertMemorySizeToString((UINT32
)(RShiftU64((MemoryArray
->MemoryArrayEndAddress
-
739 MemoryArray
->MemoryArrayStartAddress
+ 1), 20)),
741 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_MEMORY_SIZE
;
742 Hii
->NewString (Hii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
743 FreePool (NewString
);
747 } while (!EFI_ERROR (Status
) && (MonotonicCount
!= 0) && !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
753 PlatformBdsEnterFrontPage (
754 IN UINT16 TimeoutDefault
,
755 IN BOOLEAN ConnectAllHappened
760 This function is the main entry of the platform setup entry.
761 The function will present the main menu of the system setup,
762 this is the platform reference part and can be customize.
765 TimeoutDefault - The fault time out value before the system
767 ConnectAllHappened - The indicater to check if the connect all have
776 EFI_HII_UPDATE_DATA
*UpdateData
;
777 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
780 // Indicate if we need connect all in the platform setup
782 if (ConnectAllHappened
) {
783 gConnectAllHappened
= TRUE
;
786 // Allocate space for creation of Buffer
788 UpdateData
= AllocateZeroPool (0x1000);
789 ASSERT (UpdateData
!= NULL
);
791 UpdateData
->FormSetUpdate
= FALSE
;
792 UpdateData
->FormCallbackHandle
= 0;
793 UpdateData
->FormUpdate
= FALSE
;
794 UpdateData
->FormTitle
= 0;
795 UpdateData
->DataCount
= 1;
798 // Remove Banner Op-code if any at this label
800 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, FALSE
, UpdateData
);
803 // Create Banner Op-code which reflects correct timeout value
806 STRING_TOKEN (STR_TIME_OUT_PROMPT
),
808 (UINT8
) EFI_IFR_BANNER_TIMEOUT
,
813 // Add Banner Op-code at this label
815 Hii
->UpdateForm (Hii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, TRUE
, UpdateData
);
819 InitializeFrontPage (TRUE
);
822 // Update Front Page strings
824 UpdateFrontPageStrings ();
827 PERF_START (0, "BdsTimeOut", "BDS", 0);
828 Status
= CallFrontPage ();
829 PERF_END (0, "BdsTimeOut", "BDS", 0);
832 // If gCallbackKey is greater than 1 and less or equal to 5,
833 // it will lauch configuration utilities.
836 // 4 = device manager
837 // 5 = boot maintainenance manager
839 if ((gCallbackKey
> 0x0001) && (gCallbackKey
<= 0x0005)) {
842 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
846 // Based on the key that was set, we can determine what to do
848 switch (gCallbackKey
) {
850 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
851 // describe to their customers in documentation how to find their setup information (namely
852 // under the device manager and specific buckets)
854 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
864 // User made a language setting change - display front page again
870 // User chose to run the Boot Manager
877 // Display the Device Manager
881 } while (gCallbackKey
== 4);
886 // Display the Boot Maintenance Manager
888 BdsStartBootMaint ();
892 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= 1));
895 //Will leave browser, check any reset required change is applied? if yes, reset system
897 SetupResetReminder ();
900 // Automatically load current entry
901 // Note: The following lines of code only execute when Auto boot
904 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, &ConsoleControl
);
905 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);