]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/UiApp/FrontPage.c
IntelSiliconPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / FrontPage.c
1 /** @file
2 FrontPage routines to handle the callbacks and browser calls
3
4 Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "FrontPage.h"
17 #include "FrontPageCustomizedUi.h"
18
19 #define MAX_STRING_LEN 200
20
21 EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;
22
23 BOOLEAN mResetRequired = FALSE;
24
25 EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
26 CHAR8 *mLanguageString;
27 BOOLEAN mModeInitialized = FALSE;
28 //
29 // Boot video resolution and text mode.
30 //
31 UINT32 mBootHorizontalResolution = 0;
32 UINT32 mBootVerticalResolution = 0;
33 UINT32 mBootTextModeColumn = 0;
34 UINT32 mBootTextModeRow = 0;
35 //
36 // BIOS setup video resolution and text mode.
37 //
38 UINT32 mSetupTextModeColumn = 0;
39 UINT32 mSetupTextModeRow = 0;
40 UINT32 mSetupHorizontalResolution = 0;
41 UINT32 mSetupVerticalResolution = 0;
42
43 FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {
44 FRONT_PAGE_CALLBACK_DATA_SIGNATURE,
45 NULL,
46 NULL,
47 NULL,
48 {
49 FakeExtractConfig,
50 FakeRouteConfig,
51 FrontPageCallback
52 }
53 };
54
55 HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {
56 {
57 {
58 HARDWARE_DEVICE_PATH,
59 HW_VENDOR_DP,
60 {
61 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
62 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
63 }
64 },
65 //
66 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}
67 //
68 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }
69 },
70 {
71 END_DEVICE_PATH_TYPE,
72 END_ENTIRE_DEVICE_PATH_SUBTYPE,
73 {
74 (UINT8) (END_DEVICE_PATH_LENGTH),
75 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
76 }
77 }
78 };
79
80 /**
81 Update the banner information for the Front Page based on Smbios information.
82
83 **/
84 VOID
85 UpdateFrontPageBannerStrings (
86 VOID
87 );
88
89 /**
90 This function allows a caller to extract the current configuration for one
91 or more named elements from the target driver.
92
93
94 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
95 @param Request A null-terminated Unicode string in <ConfigRequest> format.
96 @param Progress On return, points to a character in the Request string.
97 Points to the string's null terminator if request was successful.
98 Points to the most recent '&' before the first failing name/value
99 pair (or the beginning of the string if the failure is in the
100 first name/value pair) if the request was not successful.
101 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
102 has all values filled in for the names in the Request string.
103 String to be allocated by the called function.
104
105 @retval EFI_SUCCESS The Results is filled with the requested values.
106 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
107 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
108 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
109
110 **/
111 EFI_STATUS
112 EFIAPI
113 FakeExtractConfig (
114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
115 IN CONST EFI_STRING Request,
116 OUT EFI_STRING *Progress,
117 OUT EFI_STRING *Results
118 )
119 {
120 if (Progress == NULL || Results == NULL) {
121 return EFI_INVALID_PARAMETER;
122 }
123 *Progress = Request;
124 return EFI_NOT_FOUND;
125 }
126
127 /**
128 This function processes the results of changes in configuration.
129
130
131 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
132 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
133 @param Progress A pointer to a string filled in with the offset of the most
134 recent '&' before the first failing name/value pair (or the
135 beginning of the string if the failure is in the first
136 name/value pair) or the terminating NULL if all was successful.
137
138 @retval EFI_SUCCESS The Results is processed successfully.
139 @retval EFI_INVALID_PARAMETER Configuration is NULL.
140 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
141
142 **/
143 EFI_STATUS
144 EFIAPI
145 FakeRouteConfig (
146 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
147 IN CONST EFI_STRING Configuration,
148 OUT EFI_STRING *Progress
149 )
150 {
151 if (Configuration == NULL || Progress == NULL) {
152 return EFI_INVALID_PARAMETER;
153 }
154
155 *Progress = Configuration;
156
157 return EFI_NOT_FOUND;
158 }
159
160 /**
161 This function processes the results of changes in configuration.
162
163
164 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
165 @param Action Specifies the type of action taken by the browser.
166 @param QuestionId A unique value which is sent to the original exporting driver
167 so that it can identify the type of data to expect.
168 @param Type The type of value for the question.
169 @param Value A pointer to the data being sent to the original exporting driver.
170 @param ActionRequest On return, points to the action requested by the callback function.
171
172 @retval EFI_SUCCESS The callback successfully handled the action.
173 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
174 @retval EFI_DEVICE_ERROR The variable could not be saved.
175 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
176
177 **/
178 EFI_STATUS
179 EFIAPI
180 FrontPageCallback (
181 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
182 IN EFI_BROWSER_ACTION Action,
183 IN EFI_QUESTION_ID QuestionId,
184 IN UINT8 Type,
185 IN EFI_IFR_TYPE_VALUE *Value,
186 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
187 )
188 {
189 return UiFrontPageCallbackHandler (gFrontPagePrivate.HiiHandle, Action, QuestionId, Type, Value, ActionRequest);
190 }
191
192 /**
193
194 Update the menus in the front page.
195
196 **/
197 VOID
198 UpdateFrontPageForm (
199 VOID
200 )
201 {
202 VOID *StartOpCodeHandle;
203 VOID *EndOpCodeHandle;
204 EFI_IFR_GUID_LABEL *StartGuidLabel;
205 EFI_IFR_GUID_LABEL *EndGuidLabel;
206
207 //
208 // Allocate space for creation of UpdateData Buffer
209 //
210 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
211 ASSERT (StartOpCodeHandle != NULL);
212
213 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
214 ASSERT (EndOpCodeHandle != NULL);
215 //
216 // Create Hii Extend Label OpCode as the start opcode
217 //
218 StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
219 StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
220 StartGuidLabel->Number = LABEL_FRANTPAGE_INFORMATION;
221 //
222 // Create Hii Extend Label OpCode as the end opcode
223 //
224 EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
225 EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
226 EndGuidLabel->Number = LABEL_END;
227
228 //
229 //Updata Front Page form
230 //
231 UiCustomizeFrontPage (
232 gFrontPagePrivate.HiiHandle,
233 StartOpCodeHandle
234 );
235
236 HiiUpdateForm (
237 gFrontPagePrivate.HiiHandle,
238 &mFrontPageGuid,
239 FRONT_PAGE_FORM_ID,
240 StartOpCodeHandle,
241 EndOpCodeHandle
242 );
243
244 HiiFreeOpCodeHandle (StartOpCodeHandle);
245 HiiFreeOpCodeHandle (EndOpCodeHandle);
246 }
247
248 /**
249 Initialize HII information for the FrontPage
250
251
252 @retval EFI_SUCCESS The operation is successful.
253 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
254
255 **/
256 EFI_STATUS
257 InitializeFrontPage (
258 VOID
259 )
260 {
261 EFI_STATUS Status;
262 //
263 // Locate Hii relative protocols
264 //
265 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);
266 if (EFI_ERROR (Status)) {
267 return Status;
268 }
269
270 //
271 // Install Device Path Protocol and Config Access protocol to driver handle
272 //
273 gFrontPagePrivate.DriverHandle = NULL;
274 Status = gBS->InstallMultipleProtocolInterfaces (
275 &gFrontPagePrivate.DriverHandle,
276 &gEfiDevicePathProtocolGuid,
277 &mFrontPageHiiVendorDevicePath,
278 &gEfiHiiConfigAccessProtocolGuid,
279 &gFrontPagePrivate.ConfigAccess,
280 NULL
281 );
282 ASSERT_EFI_ERROR (Status);
283
284 //
285 // Publish our HII data
286 //
287 gFrontPagePrivate.HiiHandle = HiiAddPackages (
288 &mFrontPageGuid,
289 gFrontPagePrivate.DriverHandle,
290 FrontPageVfrBin,
291 UiAppStrings,
292 NULL
293 );
294 ASSERT (gFrontPagePrivate.HiiHandle != NULL);
295
296 //
297 //Updata Front Page banner strings
298 //
299 UpdateFrontPageBannerStrings ();
300
301 //
302 // Update front page menus.
303 //
304 UpdateFrontPageForm();
305
306 return Status;
307 }
308
309 /**
310 Call the browser and display the front page
311
312 @return Status code that will be returned by
313 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
314
315 **/
316 EFI_STATUS
317 CallFrontPage (
318 VOID
319 )
320 {
321 EFI_STATUS Status;
322 EFI_BROWSER_ACTION_REQUEST ActionRequest;
323
324 //
325 // Begin waiting for USER INPUT
326 //
327 REPORT_STATUS_CODE (
328 EFI_PROGRESS_CODE,
329 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
330 );
331
332 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
333 Status = gFormBrowser2->SendForm (
334 gFormBrowser2,
335 &gFrontPagePrivate.HiiHandle,
336 1,
337 &mFrontPageGuid,
338 0,
339 NULL,
340 &ActionRequest
341 );
342 //
343 // Check whether user change any option setting which needs a reset to be effective
344 //
345 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
346 EnableResetRequired ();
347 }
348
349 return Status;
350 }
351
352 /**
353 Remove the installed packages from the HiiDatabase.
354
355 **/
356 VOID
357 FreeFrontPage(
358 VOID
359 )
360 {
361 EFI_STATUS Status;
362 Status = gBS->UninstallMultipleProtocolInterfaces (
363 gFrontPagePrivate.DriverHandle,
364 &gEfiDevicePathProtocolGuid,
365 &mFrontPageHiiVendorDevicePath,
366 &gEfiHiiConfigAccessProtocolGuid,
367 &gFrontPagePrivate.ConfigAccess,
368 NULL
369 );
370 ASSERT_EFI_ERROR (Status);
371
372 //
373 // Publish our HII data
374 //
375 HiiRemovePackages (gFrontPagePrivate.HiiHandle);
376 if (gFrontPagePrivate.LanguageToken != NULL) {
377 FreePool (gFrontPagePrivate.LanguageToken);
378 gFrontPagePrivate.LanguageToken = NULL;
379 }
380 }
381
382 /**
383 Convert Processor Frequency Data to a string.
384
385 @param ProcessorFrequency The frequency data to process
386 @param Base10Exponent The exponent based on 10
387 @param String The string that is created
388
389 **/
390 VOID
391 ConvertProcessorToString (
392 IN UINT16 ProcessorFrequency,
393 IN UINT16 Base10Exponent,
394 OUT CHAR16 **String
395 )
396 {
397 CHAR16 *StringBuffer;
398 UINTN Index;
399 UINTN DestMax;
400 UINT32 FreqMhz;
401
402 if (Base10Exponent >= 6) {
403 FreqMhz = ProcessorFrequency;
404 for (Index = 0; Index < (UINT32) Base10Exponent - 6; Index++) {
405 FreqMhz *= 10;
406 }
407 } else {
408 FreqMhz = 0;
409 }
410 DestMax = 0x20 / sizeof (CHAR16);
411 StringBuffer = AllocateZeroPool (0x20);
412 ASSERT (StringBuffer != NULL);
413 UnicodeValueToStringS (StringBuffer, sizeof (CHAR16) * DestMax, LEFT_JUSTIFY, FreqMhz / 1000, 3);
414 Index = StrnLenS (StringBuffer, DestMax);
415 StrCatS (StringBuffer, DestMax, L".");
416 UnicodeValueToStringS (
417 StringBuffer + Index + 1,
418 sizeof (CHAR16) * (DestMax - (Index + 1)),
419 PREFIX_ZERO,
420 (FreqMhz % 1000) / 10,
421 2
422 );
423 StrCatS (StringBuffer, DestMax, L" GHz");
424 *String = (CHAR16 *) StringBuffer;
425 return ;
426 }
427
428
429 /**
430 Convert Memory Size to a string.
431
432 @param MemorySize The size of the memory to process
433 @param String The string that is created
434
435 **/
436 VOID
437 ConvertMemorySizeToString (
438 IN UINT32 MemorySize,
439 OUT CHAR16 **String
440 )
441 {
442 CHAR16 *StringBuffer;
443
444 StringBuffer = AllocateZeroPool (0x24);
445 ASSERT (StringBuffer != NULL);
446 UnicodeValueToStringS (StringBuffer, 0x24, LEFT_JUSTIFY, MemorySize, 10);
447 StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM");
448
449 *String = (CHAR16 *) StringBuffer;
450
451 return ;
452 }
453
454 /**
455
456 Acquire the string associated with the Index from smbios structure and return it.
457 The caller is responsible for free the string buffer.
458
459 @param OptionalStrStart The start position to search the string
460 @param Index The index of the string to extract
461 @param String The string that is extracted
462
463 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
464
465 **/
466 EFI_STATUS
467 GetOptionalStringByIndex (
468 IN CHAR8 *OptionalStrStart,
469 IN UINT8 Index,
470 OUT CHAR16 **String
471 )
472 {
473 UINTN StrSize;
474
475 if (Index == 0) {
476 *String = AllocateZeroPool (sizeof (CHAR16));
477 return EFI_SUCCESS;
478 }
479
480 StrSize = 0;
481 do {
482 Index--;
483 OptionalStrStart += StrSize;
484 StrSize = AsciiStrSize (OptionalStrStart);
485 } while (OptionalStrStart[StrSize] != 0 && Index != 0);
486
487 if ((Index != 0) || (StrSize == 1)) {
488 //
489 // Meet the end of strings set but Index is non-zero, or
490 // Find an empty string
491 //
492 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
493 } else {
494 *String = AllocatePool (StrSize * sizeof (CHAR16));
495 AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);
496 }
497
498 return EFI_SUCCESS;
499 }
500
501
502 /**
503
504 Update the banner information for the Front Page based on Smbios information.
505
506 **/
507 VOID
508 UpdateFrontPageBannerStrings (
509 VOID
510 )
511 {
512 UINT8 StrIndex;
513 CHAR16 *NewString;
514 CHAR16 *FirmwareVersionString;
515 EFI_STATUS Status;
516 EFI_SMBIOS_HANDLE SmbiosHandle;
517 EFI_SMBIOS_PROTOCOL *Smbios;
518 SMBIOS_TABLE_TYPE0 *Type0Record;
519 SMBIOS_TABLE_TYPE1 *Type1Record;
520 SMBIOS_TABLE_TYPE4 *Type4Record;
521 SMBIOS_TABLE_TYPE19 *Type19Record;
522 EFI_SMBIOS_TABLE_HEADER *Record;
523 UINT64 InstalledMemory;
524 BOOLEAN FoundCpu;
525
526 InstalledMemory = 0;
527 FoundCpu = 0;
528
529 //
530 // Update default banner string.
531 //
532 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NULL);
533 UiCustomizeFrontPageBanner (4, TRUE, &NewString);
534 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NewString, NULL);
535 FreePool (NewString);
536
537 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NULL);
538 UiCustomizeFrontPageBanner (4, FALSE, &NewString);
539 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NewString, NULL);
540 FreePool (NewString);
541
542 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NULL);
543 UiCustomizeFrontPageBanner (5, TRUE, &NewString);
544 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NewString, NULL);
545 FreePool (NewString);
546
547 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NULL);
548 UiCustomizeFrontPageBanner (5, FALSE, &NewString);
549 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NewString, NULL);
550 FreePool (NewString);
551
552 //
553 // Update Front Page banner strings base on SmBios Table.
554 //
555 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
556 if (EFI_ERROR (Status)) {
557 //
558 // Smbios protocol not found, get the default value.
559 //
560 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NULL);
561 UiCustomizeFrontPageBanner (1, TRUE, &NewString);
562 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
563 FreePool (NewString);
564
565 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NULL);
566 UiCustomizeFrontPageBanner (2, TRUE, &NewString);
567 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
568 FreePool (NewString);
569
570 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NULL);
571 UiCustomizeFrontPageBanner (2, FALSE, &NewString);
572 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
573 FreePool (NewString);
574
575 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NULL);
576 UiCustomizeFrontPageBanner (3, TRUE, &NewString);
577 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
578 FreePool (NewString);
579
580 NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NULL);
581 UiCustomizeFrontPageBanner (3, FALSE, &NewString);
582 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
583 FreePool (NewString);
584
585 return;
586 }
587
588 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
589 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
590 while (!EFI_ERROR(Status)) {
591 if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {
592 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
593 StrIndex = Type0Record->BiosVersion;
594 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);
595
596 FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
597 if (*FirmwareVersionString != 0x0000 ) {
598 FreePool (NewString);
599 NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
600 UiCustomizeFrontPageBanner (3, TRUE, &NewString);
601 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
602 } else {
603 UiCustomizeFrontPageBanner (3, TRUE, &NewString);
604 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
605 FreePool (NewString);
606 }
607 }
608
609 if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) {
610 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
611 StrIndex = Type1Record->ProductName;
612 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);
613 UiCustomizeFrontPageBanner (1, TRUE, &NewString);
614 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
615 FreePool (NewString);
616 }
617
618 if ((Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) && !FoundCpu) {
619 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
620 //
621 // The information in the record should be only valid when the CPU Socket is populated.
622 //
623 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
624 StrIndex = Type4Record->ProcessorVersion;
625 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);
626 UiCustomizeFrontPageBanner (2, TRUE, &NewString);
627 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
628 FreePool (NewString);
629
630 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);
631 UiCustomizeFrontPageBanner (2, FALSE, &NewString);
632 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
633 FreePool (NewString);
634
635 FoundCpu = TRUE;
636 }
637 }
638
639 if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {
640 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;
641 if (Type19Record->StartingAddress != 0xFFFFFFFF ) {
642 InstalledMemory += RShiftU64(Type19Record->EndingAddress -
643 Type19Record->StartingAddress + 1, 10);
644 } else {
645 InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress -
646 Type19Record->ExtendedStartingAddress + 1, 20);
647 }
648 }
649
650 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
651 }
652
653 //
654 // Now update the total installed RAM size
655 //
656 ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString );
657 UiCustomizeFrontPageBanner (3, FALSE, &NewString);
658 HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
659 FreePool (NewString);
660 }
661
662 /**
663 This function will change video resolution and text mode
664 according to defined setup mode or defined boot mode
665
666 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
667
668 @retval EFI_SUCCESS Mode is changed successfully.
669 @retval Others Mode failed to be changed.
670
671 **/
672 EFI_STATUS
673 UiSetConsoleMode (
674 BOOLEAN IsSetupMode
675 )
676 {
677 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
678 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
679 UINTN SizeOfInfo;
680 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
681 UINT32 MaxGopMode;
682 UINT32 MaxTextMode;
683 UINT32 ModeNumber;
684 UINT32 NewHorizontalResolution;
685 UINT32 NewVerticalResolution;
686 UINT32 NewColumns;
687 UINT32 NewRows;
688 UINTN HandleCount;
689 EFI_HANDLE *HandleBuffer;
690 EFI_STATUS Status;
691 UINTN Index;
692 UINTN CurrentColumn;
693 UINTN CurrentRow;
694
695 MaxGopMode = 0;
696 MaxTextMode = 0;
697
698 //
699 // Get current video resolution and text mode
700 //
701 Status = gBS->HandleProtocol (
702 gST->ConsoleOutHandle,
703 &gEfiGraphicsOutputProtocolGuid,
704 (VOID**)&GraphicsOutput
705 );
706 if (EFI_ERROR (Status)) {
707 GraphicsOutput = NULL;
708 }
709
710 Status = gBS->HandleProtocol (
711 gST->ConsoleOutHandle,
712 &gEfiSimpleTextOutProtocolGuid,
713 (VOID**)&SimpleTextOut
714 );
715 if (EFI_ERROR (Status)) {
716 SimpleTextOut = NULL;
717 }
718
719 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
720 return EFI_UNSUPPORTED;
721 }
722
723 if (IsSetupMode) {
724 //
725 // The required resolution and text mode is setup mode.
726 //
727 NewHorizontalResolution = mSetupHorizontalResolution;
728 NewVerticalResolution = mSetupVerticalResolution;
729 NewColumns = mSetupTextModeColumn;
730 NewRows = mSetupTextModeRow;
731 } else {
732 //
733 // The required resolution and text mode is boot mode.
734 //
735 NewHorizontalResolution = mBootHorizontalResolution;
736 NewVerticalResolution = mBootVerticalResolution;
737 NewColumns = mBootTextModeColumn;
738 NewRows = mBootTextModeRow;
739 }
740
741 if (GraphicsOutput != NULL) {
742 MaxGopMode = GraphicsOutput->Mode->MaxMode;
743 }
744
745 if (SimpleTextOut != NULL) {
746 MaxTextMode = SimpleTextOut->Mode->MaxMode;
747 }
748
749 //
750 // 1. If current video resolution is same with required video resolution,
751 // video resolution need not be changed.
752 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
753 // 1.2. If current text mode is different from required text mode, text mode need be changed.
754 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
755 //
756 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
757 Status = GraphicsOutput->QueryMode (
758 GraphicsOutput,
759 ModeNumber,
760 &SizeOfInfo,
761 &Info
762 );
763 if (!EFI_ERROR (Status)) {
764 if ((Info->HorizontalResolution == NewHorizontalResolution) &&
765 (Info->VerticalResolution == NewVerticalResolution)) {
766 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
767 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {
768 //
769 // Current resolution is same with required resolution, check if text mode need be set
770 //
771 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
772 ASSERT_EFI_ERROR (Status);
773 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
774 //
775 // If current text mode is same with required text mode. Do nothing
776 //
777 FreePool (Info);
778 return EFI_SUCCESS;
779 } else {
780 //
781 // If current text mode is different from required text mode. Set new video mode
782 //
783 for (Index = 0; Index < MaxTextMode; Index++) {
784 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
785 if (!EFI_ERROR(Status)) {
786 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
787 //
788 // Required text mode is supported, set it.
789 //
790 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
791 ASSERT_EFI_ERROR (Status);
792 //
793 // Update text mode PCD.
794 //
795 Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);
796 ASSERT_EFI_ERROR (Status);
797 Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);
798 ASSERT_EFI_ERROR (Status);
799 FreePool (Info);
800 return EFI_SUCCESS;
801 }
802 }
803 }
804 if (Index == MaxTextMode) {
805 //
806 // If required text mode is not supported, return error.
807 //
808 FreePool (Info);
809 return EFI_UNSUPPORTED;
810 }
811 }
812 } else {
813 //
814 // If current video resolution is not same with the new one, set new video resolution.
815 // In this case, the driver which produces simple text out need be restarted.
816 //
817 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
818 if (!EFI_ERROR (Status)) {
819 FreePool (Info);
820 break;
821 }
822 }
823 }
824 FreePool (Info);
825 }
826 }
827
828 if (ModeNumber == MaxGopMode) {
829 //
830 // If the resolution is not supported, return error.
831 //
832 return EFI_UNSUPPORTED;
833 }
834
835 //
836 // Set PCD to Inform GraphicsConsole to change video resolution.
837 // Set PCD to Inform Consplitter to change text mode.
838 //
839 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
840 ASSERT_EFI_ERROR (Status);
841 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
842 ASSERT_EFI_ERROR (Status);
843 Status = PcdSet32S (PcdConOutColumn, NewColumns);
844 ASSERT_EFI_ERROR (Status);
845 Status = PcdSet32S (PcdConOutRow, NewRows);
846 ASSERT_EFI_ERROR (Status);
847
848 //
849 // Video mode is changed, so restart graphics console driver and higher level driver.
850 // Reconnect graphics console driver and higher level driver.
851 // Locate all the handles with GOP protocol and reconnect it.
852 //
853 Status = gBS->LocateHandleBuffer (
854 ByProtocol,
855 &gEfiSimpleTextOutProtocolGuid,
856 NULL,
857 &HandleCount,
858 &HandleBuffer
859 );
860 if (!EFI_ERROR (Status)) {
861 for (Index = 0; Index < HandleCount; Index++) {
862 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
863 }
864 for (Index = 0; Index < HandleCount; Index++) {
865 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
866 }
867 if (HandleBuffer != NULL) {
868 FreePool (HandleBuffer);
869 }
870 }
871
872 return EFI_SUCCESS;
873 }
874
875 /**
876 The user Entry Point for Application. The user code starts with this function
877 as the real entry point for the image goes into a library that calls this
878 function.
879
880 @param[in] ImageHandle The firmware allocated handle for the EFI image.
881 @param[in] SystemTable A pointer to the EFI System Table.
882
883 @retval EFI_SUCCESS The entry point is executed successfully.
884 @retval other Some error occurs when executing this entry point.
885
886 **/
887 EFI_STATUS
888 EFIAPI
889 InitializeUserInterface (
890 IN EFI_HANDLE ImageHandle,
891 IN EFI_SYSTEM_TABLE *SystemTable
892 )
893 {
894 EFI_HII_HANDLE HiiHandle;
895 EFI_STATUS Status;
896 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
897 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
898 UINTN BootTextColumn;
899 UINTN BootTextRow;
900
901 if (!mModeInitialized) {
902 //
903 // After the console is ready, get current video resolution
904 // and text mode before launching setup at first time.
905 //
906 Status = gBS->HandleProtocol (
907 gST->ConsoleOutHandle,
908 &gEfiGraphicsOutputProtocolGuid,
909 (VOID**)&GraphicsOutput
910 );
911 if (EFI_ERROR (Status)) {
912 GraphicsOutput = NULL;
913 }
914
915 Status = gBS->HandleProtocol (
916 gST->ConsoleOutHandle,
917 &gEfiSimpleTextOutProtocolGuid,
918 (VOID**)&SimpleTextOut
919 );
920 if (EFI_ERROR (Status)) {
921 SimpleTextOut = NULL;
922 }
923
924 if (GraphicsOutput != NULL) {
925 //
926 // Get current video resolution and text mode.
927 //
928 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
929 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
930 }
931
932 if (SimpleTextOut != NULL) {
933 Status = SimpleTextOut->QueryMode (
934 SimpleTextOut,
935 SimpleTextOut->Mode->Mode,
936 &BootTextColumn,
937 &BootTextRow
938 );
939 mBootTextModeColumn = (UINT32)BootTextColumn;
940 mBootTextModeRow = (UINT32)BootTextRow;
941 }
942
943 //
944 // Get user defined text mode for setup.
945 //
946 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
947 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
948 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
949 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
950
951 mModeInitialized = TRUE;
952 }
953
954 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
955 gST->ConOut->ClearScreen (gST->ConOut);
956
957 //
958 // Install customized fonts needed by Front Page
959 //
960 HiiHandle = ExportFonts ();
961 ASSERT (HiiHandle != NULL);
962
963 InitializeStringSupport ();
964
965 UiSetConsoleMode (TRUE);
966 UiEntry (FALSE);
967 UiSetConsoleMode (FALSE);
968
969 UninitializeStringSupport ();
970 HiiRemovePackages (HiiHandle);
971
972 return EFI_SUCCESS;
973 }
974
975 /**
976 This function is the main entry of the UI entry.
977 The function will present the main menu of the system UI.
978
979 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.
980
981 **/
982 VOID
983 EFIAPI
984 UiEntry (
985 IN BOOLEAN ConnectAllHappened
986 )
987 {
988 EFI_STATUS Status;
989 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
990
991 //
992 // Enter Setup page.
993 //
994 REPORT_STATUS_CODE (
995 EFI_PROGRESS_CODE,
996 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
997 );
998
999 //
1000 // Indicate if the connect all has been performed before.
1001 // If has not been performed before, do here.
1002 //
1003 if (!ConnectAllHappened) {
1004 EfiBootManagerConnectAll ();
1005 }
1006
1007 //
1008 // The boot option enumeration time is acceptable in Ui driver
1009 //
1010 EfiBootManagerRefreshAllBootOption ();
1011
1012 //
1013 // Boot Logo is corrupted, report it using Boot Logo protocol.
1014 //
1015 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
1016 if (!EFI_ERROR (Status) && (BootLogo != NULL)) {
1017 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
1018 }
1019
1020 InitializeFrontPage ();
1021
1022 CallFrontPage ();
1023
1024 FreeFrontPage ();
1025
1026 if (mLanguageString != NULL) {
1027 FreePool (mLanguageString);
1028 mLanguageString = NULL;
1029 }
1030
1031 //
1032 //Will leave browser, check any reset required change is applied? if yes, reset system
1033 //
1034 SetupResetReminder ();
1035 }
1036
1037 //
1038 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
1039 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
1040 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
1041 //
1042
1043
1044
1045
1046
1047 /**
1048 Record the info that a reset is required.
1049 A module boolean variable is used to record whether a reset is required.
1050
1051 **/
1052 VOID
1053 EFIAPI
1054 EnableResetRequired (
1055 VOID
1056 )
1057 {
1058 mResetRequired = TRUE;
1059 }
1060
1061
1062
1063
1064
1065 /**
1066 Check if user changed any option setting which needs a system reset to be effective.
1067
1068 **/
1069 BOOLEAN
1070 EFIAPI
1071 IsResetRequired (
1072 VOID
1073 )
1074 {
1075 return mResetRequired;
1076 }
1077
1078
1079 /**
1080 Check whether a reset is needed, and finish the reset reminder feature.
1081 If a reset is needed, Popup a menu to notice user, and finish the feature
1082 according to the user selection.
1083
1084 **/
1085 VOID
1086 EFIAPI
1087 SetupResetReminder (
1088 VOID
1089 )
1090 {
1091 EFI_INPUT_KEY Key;
1092 CHAR16 *StringBuffer1;
1093 CHAR16 *StringBuffer2;
1094
1095 //
1096 //check any reset required change is applied? if yes, reset system
1097 //
1098 if (IsResetRequired ()) {
1099
1100 StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
1101 ASSERT (StringBuffer1 != NULL);
1102 StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
1103 ASSERT (StringBuffer2 != NULL);
1104 StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now.");
1105 StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset");
1106 //
1107 // Popup a menu to notice user
1108 //
1109 do {
1110 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
1111 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1112
1113 FreePool (StringBuffer1);
1114 FreePool (StringBuffer2);
1115
1116 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1117 }
1118 }
1119