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"
30 #include "BdsString.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
;
48 FrontPageCallbackRoutine (
49 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
51 IN EFI_IFR_DATA_ARRAY
*DataArray
,
52 OUT EFI_HII_CALLBACK_PACKET
**Packet
58 This is the function that is called to provide results data to the driver. This data
59 consists of a unique key which is used to identify what data is either being passed back
64 KeyValue - A unique value which is sent to the original exporting driver so that it
65 can identify the type of data to expect. The format of the data tends to
66 vary based on the op-code that geerated the callback.
68 Data - A pointer to the data being sent to the original exporting driver.
74 CHAR16
*LanguageString
;
76 CHAR16 UnicodeLang
[3];
81 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
82 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
83 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
85 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
86 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
87 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
92 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
93 // describe to their customers in documentation how to find their setup information (namely
94 // under the device manager and specific buckets)
99 // This is the continue - clear the screen and return an error to get out of FrontPage loop
106 // Collect the languages from what our current Language support is based on our VFR
108 gHii
->GetPrimaryLanguages (gHii
, gFrontPageHandle
, &LanguageString
);
111 // Based on the DataArray->Data->Data value, we can determine
112 // which language was chosen by the user
114 for (Index
= 0; Count
!= (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+ 1))->Data
); Index
+= 3) {
118 // Preserve the choice the user made
120 mLastSelection
= (UINT16
) Count
;
123 // The Language (in Unicode format) the user chose
125 CopyMem (UnicodeLang
, &LanguageString
[Index
], 6);
128 // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
129 // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
131 for (Index
= 0; Index
< 3; Index
++) {
132 Lang
[Index
] = (CHAR8
) UnicodeLang
[Index
];
135 Status
= gRT
->SetVariable (
137 &gEfiGlobalVariableGuid
,
138 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
143 FreePool (LanguageString
);
163 // Boot Maintenance Manager
174 // FrontPage TimeOut Callback
176 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
177 if (TmpStr
!= NULL
) {
178 PlatformBdsShowProgress (
183 (UINTN
) (((EFI_IFR_DATA_ENTRY
*) (DataArray
+1))->Data
),
199 InitializeFrontPage (
200 BOOLEAN ReInitializeStrings
206 Initialize HII information for the FrontPage
212 EFI_SUCCESS - The operation is successful.
213 EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
218 EFI_HII_PACKAGES
*PackageList
;
219 EFI_HII_UPDATE_DATA
*UpdateData
;
220 IFR_OPTION
*OptionList
;
221 CHAR16
*LanguageString
;
227 CHAR16 UnicodeLang
[4];
229 CHAR16
*StringBuffer
;
236 if (ReInitializeStrings
) {
238 // BugBug: Dont' use a goto
243 // Go ahead and initialize the Device Manager
245 InitializeDeviceManager ();
248 // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
250 TempBuffer
= (UINT8
*) FrontPageVfrBin
;
251 TempBuffer
= TempBuffer
+ sizeof (EFI_HII_PACK_HEADER
);
252 TempBuffer
= (UINT8
*) &((EFI_IFR_FORM_SET
*) TempBuffer
)->NvDataSize
;
257 PackageList
= PreparePackages (1, &gEfiCallerIdGuid
, FrontPageVfrBin
);
259 Status
= gHii
->NewPack (gHii
, PackageList
, &gFrontPageHandle
);
261 FreePool (PackageList
);
264 // There will be only one FormConfig in the system
265 // If there is another out there, someone is trying to install us
266 // again. Fail that scenario.
268 Status
= gBS
->LocateProtocol (
269 &gEfiFormBrowserProtocolGuid
,
275 // This example does not implement worker functions
276 // for the NV accessor functions. Only a callback evaluator
278 FrontPageCallback
.NvRead
= NULL
;
279 FrontPageCallback
.NvWrite
= NULL
;
280 FrontPageCallback
.Callback
= FrontPageCallbackRoutine
;
283 // Install protocol interface
285 FrontPageCallbackHandle
= NULL
;
286 Status
= gBS
->InstallProtocolInterface (
287 &FrontPageCallbackHandle
,
288 &gEfiFormCallbackProtocolGuid
,
289 EFI_NATIVE_INTERFACE
,
292 ASSERT_EFI_ERROR (Status
);
296 // BugBug: This logic is in BdsInitLanguage. It should not be in two places!
299 Status
= gRT
->GetVariable (
301 &gEfiGlobalVariableGuid
,
307 for (Index
= 0; Index
< 3; Index
++) {
308 UnicodeLang
[Index
] = (CHAR16
) AsciiLang
[Index
];
314 // Allocate space for creation of UpdateData Buffer
316 UpdateData
= AllocateZeroPool (0x1000);
317 ASSERT (UpdateData
!= NULL
);
319 OptionList
= AllocateZeroPool (0x1000);
320 ASSERT (OptionList
!= NULL
);
323 // Flag update pending in FormSet
325 UpdateData
->FormSetUpdate
= TRUE
;
327 // Register CallbackHandle data for FormSet
329 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FrontPageCallbackHandle
;
330 UpdateData
->FormUpdate
= FALSE
;
331 UpdateData
->FormTitle
= 0;
332 UpdateData
->DataCount
= 1;
335 // Collect the languages from what our current Language support is based on our VFR
337 gHii
->GetPrimaryLanguages (gHii
, gFrontPageHandle
, &LanguageString
);
342 // Try for a 512 byte Buffer
347 // Allocate memory for our Form binary
349 StringBuffer
= AllocateZeroPool (BufferSize
);
350 ASSERT (StringBuffer
!= NULL
);
352 for (Index
= 0; LanguageString
[Index
] != 0; Index
+= 3) {
354 CopyMem (Lang
, &LanguageString
[Index
], 6);
357 if (!StrCmp (Lang
, UnicodeLang
)) {
358 mLastSelection
= (UINT16
) OptionCount
;
361 Status
= gHii
->GetString (gHii
, gStringPackHandle
, 1, TRUE
, Lang
, &BufferSize
, StringBuffer
);
362 gHii
->NewString (gHii
, NULL
, gStringPackHandle
, &Token
, StringBuffer
);
363 CopyMem (&OptionList
[OptionCount
].StringToken
, &Token
, sizeof (UINT16
));
364 CopyMem (&OptionList
[OptionCount
].Value
, &OptionCount
, sizeof (UINT16
));
366 CopyMem (&OptionList
[OptionCount
].Key
, &Key
, sizeof (UINT16
));
367 OptionList
[OptionCount
].Flags
= EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_NV_ACCESS
;
371 FreePool (LanguageString
);
373 if (ReInitializeStrings
) {
374 FreePool (StringBuffer
);
375 FreePool (OptionList
);
379 Status
= CreateOneOfOpCode (
380 FRONT_PAGE_QUESTION_ID
, // Question ID
381 FRONT_PAGE_DATA_WIDTH
, // Data Width
382 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT
), // Prompt Token
383 (STRING_REF
) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
), // Help Token
384 OptionList
, // List of Options
385 OptionCount
, // Number of Options
386 &UpdateData
->Data
// Data Buffer
390 // Assign the number of options and the oneof and endoneof op-codes to count
392 UpdateData
->DataCount
= (UINT8
) (OptionCount
+ 2);
394 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0x0002, TRUE
, UpdateData
);
396 FreePool (UpdateData
);
398 // FreePool (OptionList);
400 FreePool (StringBuffer
);
412 Call the browser and display the front page
423 UINT8 FakeNvRamMap
[1];
424 BOOLEAN FrontPageMenuResetRequired
;
427 // Begin waiting for USER INPUT
431 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
434 FakeNvRamMap
[0] = (UINT8
) mLastSelection
;
435 FrontPageMenuResetRequired
= FALSE
;
436 Status
= gBrowser
->SendForm (
438 TRUE
, // Use the database
439 &gFrontPageHandle
, // The HII Handle
442 FrontPageCallbackHandle
, // This is the handle that the interface to the callback was installed on
445 &FrontPageMenuResetRequired
448 // Check whether user change any option setting which needs a reset to be effective
450 if (FrontPageMenuResetRequired
) {
451 EnableResetRequired ();
454 gHii
->ResetStrings (gHii
, gFrontPageHandle
);
461 IN EFI_GUID
*ProducerGuid
,
469 Acquire the string associated with the ProducerGuid and return it.
473 ProducerGuid - The Guid to search the HII database for
474 Token - The token value of the string to extract
475 String - The string that is extracted
479 EFI_SUCCESS - The function returns EFI_SUCCESS always.
484 UINT16 HandleBufferLength
;
485 EFI_HII_HANDLE
*HiiHandleBuffer
;
486 UINTN StringBufferLength
;
487 UINTN NumberOfHiiHandles
;
493 // Initialize params.
495 HandleBufferLength
= 0;
496 HiiHandleBuffer
= NULL
;
499 // Get all the Hii handles
501 Status
= BdsLibGetHiiHandles (gHii
, &HandleBufferLength
, &HiiHandleBuffer
);
502 ASSERT_EFI_ERROR (Status
);
505 // Get the gHii Handle that matches the StructureNode->ProducerName
507 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
508 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
510 Status
= ExtractDataFromHiiHandle (
511 HiiHandleBuffer
[Index
],
516 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
521 // Find the string based on the current language
523 StringBufferLength
= 0x100;
524 *String
= AllocateZeroPool (0x100);
525 Status
= gHii
->GetString (
527 HiiHandleBuffer
[Index
],
535 if (EFI_ERROR (Status
)) {
537 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
540 FreePool (HiiHandleBuffer
);
545 ConvertProcessorToString (
546 IN EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
,
553 Convert Processor Frequency Data to a string
557 ProcessorFrequency - The frequency data to process
558 String - The string that is created
564 CHAR16
*StringBuffer
;
568 if (ProcessorFrequency
->Exponent
>= 6) {
569 FreqMhz
= ProcessorFrequency
->Value
;
570 for (Index
= 0; Index
< (UINTN
) (ProcessorFrequency
->Exponent
- 6); Index
++) {
577 StringBuffer
= AllocateZeroPool (0x20);
578 ASSERT (StringBuffer
!= NULL
);
579 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
580 StrCat (StringBuffer
, L
".");
581 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
582 StrCat (StringBuffer
, L
" GHz");
584 *String
= (CHAR16
*) StringBuffer
;
590 ConvertMemorySizeToString (
591 IN UINT32 MemorySize
,
598 Convert Memory Size to a string
602 MemorySize - The size of the memory to process
603 String - The string that is created
609 CHAR16
*StringBuffer
;
611 StringBuffer
= AllocateZeroPool (0x20);
612 ASSERT (StringBuffer
!= NULL
);
613 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
614 StrCat (StringBuffer
, L
" MB RAM");
616 *String
= (CHAR16
*) StringBuffer
;
622 UpdateFrontPageStrings (
629 Update the banner information for the Front Page based on DataHub information
640 STRING_REF TokenToUpdate
;
642 UINT64 MonotonicCount
;
643 EFI_DATA_HUB_PROTOCOL
*DataHub
;
644 EFI_DATA_RECORD_HEADER
*Record
;
645 EFI_SUBCLASS_TYPE1_HEADER
*DataHeader
;
646 EFI_MISC_BIOS_VENDOR_DATA
*BiosVendor
;
647 EFI_MISC_SYSTEM_MANUFACTURER_DATA
*SystemManufacturer
;
648 EFI_PROCESSOR_VERSION_DATA
*ProcessorVersion
;
649 EFI_PROCESSOR_CORE_FREQUENCY_DATA
*ProcessorFrequency
;
650 EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*MemoryArray
;
657 ZeroMem (Find
, sizeof (Find
));
660 // Update Front Page strings
662 Status
= gBS
->LocateProtocol (
663 &gEfiDataHubProtocolGuid
,
667 ASSERT_EFI_ERROR (Status
);
671 Status
= gRT
->GetVariable (
673 &gEfiGlobalVariableGuid
,
679 for (Index
= 0; Index
< 3; Index
++) {
680 Lang
[Index
] = (CHAR16
) LangCode
[Index
];
686 Status
= DataHub
->GetNextRecord (DataHub
, &MonotonicCount
, NULL
, &Record
);
687 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
) {
688 DataHeader
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
689 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
690 (DataHeader
->RecordType
== EFI_MISC_BIOS_VENDOR_RECORD_NUMBER
)
692 BiosVendor
= (EFI_MISC_BIOS_VENDOR_DATA
*) (DataHeader
+ 1);
693 GetStringFromToken (&Record
->ProducerName
, BiosVendor
->BiosVersion
, &NewString
);
694 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_BIOS_VERSION
;
695 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
696 FreePool (NewString
);
700 if (CompareGuid (&Record
->DataRecordGuid
, &mMiscSubClass
) &&
701 (DataHeader
->RecordType
== EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER
)
703 SystemManufacturer
= (EFI_MISC_SYSTEM_MANUFACTURER_DATA
*) (DataHeader
+ 1);
704 GetStringFromToken (&Record
->ProducerName
, SystemManufacturer
->SystemProductName
, &NewString
);
705 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_COMPUTER_MODEL
;
706 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
707 FreePool (NewString
);
711 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
712 (DataHeader
->RecordType
== ProcessorVersionRecordType
)
714 ProcessorVersion
= (EFI_PROCESSOR_VERSION_DATA
*) (DataHeader
+ 1);
715 GetStringFromToken (&Record
->ProducerName
, *ProcessorVersion
, &NewString
);
716 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_MODEL
;
717 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
718 FreePool (NewString
);
722 if (CompareGuid (&Record
->DataRecordGuid
, &mProcessorSubClass
) &&
723 (DataHeader
->RecordType
== ProcessorCoreFrequencyRecordType
)
725 ProcessorFrequency
= (EFI_PROCESSOR_CORE_FREQUENCY_DATA
*) (DataHeader
+ 1);
726 ConvertProcessorToString (ProcessorFrequency
, &NewString
);
727 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_CPU_SPEED
;
728 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
729 FreePool (NewString
);
733 if (CompareGuid (&Record
->DataRecordGuid
, &mMemorySubClass
) &&
734 (DataHeader
->RecordType
== EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER
)
736 MemoryArray
= (EFI_MEMORY_ARRAY_START_ADDRESS_DATA
*) (DataHeader
+ 1);
737 ConvertMemorySizeToString((UINT32
)(RShiftU64((MemoryArray
->MemoryArrayEndAddress
-
738 MemoryArray
->MemoryArrayStartAddress
+ 1), 20)),
740 TokenToUpdate
= (STRING_REF
) STR_FRONT_PAGE_MEMORY_SIZE
;
741 gHii
->NewString (gHii
, Lang
, gFrontPageHandle
, &TokenToUpdate
, NewString
);
742 FreePool (NewString
);
746 } while (!EFI_ERROR (Status
) && (MonotonicCount
!= 0) && !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
752 PlatformBdsEnterFrontPage (
753 IN UINT16 TimeoutDefault
,
754 IN BOOLEAN ConnectAllHappened
759 This function is the main entry of the platform setup entry.
760 The function will present the main menu of the system setup,
761 this is the platform reference part and can be customize.
764 TimeoutDefault - The fault time out value before the system
766 ConnectAllHappened - The indicater to check if the connect all have
775 EFI_HII_UPDATE_DATA
*UpdateData
;
776 EFI_CONSOLE_CONTROL_PROTOCOL
*ConsoleControl
;
779 // Indicate if we need connect all in the platform setup
781 if (ConnectAllHappened
) {
782 gConnectAllHappened
= TRUE
;
785 // Allocate space for creation of Buffer
787 UpdateData
= AllocateZeroPool (0x1000);
788 ASSERT (UpdateData
!= NULL
);
790 UpdateData
->FormSetUpdate
= FALSE
;
791 UpdateData
->FormCallbackHandle
= 0;
792 UpdateData
->FormUpdate
= FALSE
;
793 UpdateData
->FormTitle
= 0;
794 UpdateData
->DataCount
= 1;
797 // Remove Banner Op-code if any at this label
799 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, FALSE
, UpdateData
);
802 // Create Banner Op-code which reflects correct timeout value
805 STRING_TOKEN (STR_TIME_OUT_PROMPT
),
807 (UINT8
) EFI_IFR_BANNER_TIMEOUT
,
812 // Add Banner Op-code at this label
814 gHii
->UpdateForm (gHii
, gFrontPageHandle
, (EFI_FORM_LABEL
) 0xFFFF, TRUE
, UpdateData
);
818 InitializeFrontPage (TRUE
);
821 // Update Front Page strings
823 UpdateFrontPageStrings ();
826 PERF_START (0, "BdsTimeOut", "BDS", 0);
827 Status
= CallFrontPage ();
828 PERF_END (0, "BdsTimeOut", "BDS", 0);
831 // If gCallbackKey is greater than 1 and less or equal to 5,
832 // it will lauch configuration utilities.
835 // 4 = device manager
836 // 5 = boot maintainenance manager
838 if ((gCallbackKey
> 0x0001) && (gCallbackKey
<= 0x0005)) {
841 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
845 // Based on the key that was set, we can determine what to do
847 switch (gCallbackKey
) {
849 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
850 // describe to their customers in documentation how to find their setup information (namely
851 // under the device manager and specific buckets)
853 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
863 // User made a language setting change - display front page again
869 // User chose to run the Boot Manager
876 // Display the Device Manager
880 } while (gCallbackKey
== 4);
885 // Display the Boot Maintenance Manager
887 BdsStartBootMaint ();
891 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= 1));
894 //Will leave browser, check any reset required change is applied? if yes, reset system
896 SetupResetReminder ();
899 // Automatically load current entry
900 // Note: The following lines of code only execute when Auto boot
903 Status
= gBS
->LocateProtocol (&gEfiConsoleControlProtocolGuid
, NULL
, &ConsoleControl
);
904 ConsoleControl
->SetMode (ConsoleControl
, EfiConsoleControlScreenText
);