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