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