]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/UiApp/FrontPage.c
MdeModulePkg: Refine the UI code
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / FrontPage.c
CommitLineData
143f0b1d
ED
1/** @file\r
2 FrontPage routines to handle the callbacks and browser calls\r
3\r
c7d310dd 4Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
143f0b1d
ED
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "FrontPage.h"\r
16#include "Language.h"\r
17#define MAX_STRING_LEN 200\r
18\r
ce7690e2 19EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;\r
143f0b1d
ED
20\r
21BOOLEAN gConnectAllHappened = FALSE;\r
22BOOLEAN mFeaturerSwitch = TRUE;\r
23BOOLEAN mResetRequired = FALSE;\r
143f0b1d
ED
24\r
25EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
26CHAR8 *mLanguageString;\r
27BOOLEAN mModeInitialized = FALSE;\r
28//\r
29// Boot video resolution and text mode.\r
30//\r
31UINT32 mBootHorizontalResolution = 0;\r
32UINT32 mBootVerticalResolution = 0;\r
33UINT32 mBootTextModeColumn = 0;\r
34UINT32 mBootTextModeRow = 0;\r
35//\r
36// BIOS setup video resolution and text mode.\r
37//\r
38UINT32 mSetupTextModeColumn = 0;\r
39UINT32 mSetupTextModeRow = 0;\r
40UINT32 mSetupHorizontalResolution = 0;\r
41UINT32 mSetupVerticalResolution = 0;\r
42\r
43FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {\r
44 FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
45 NULL,\r
46 NULL,\r
47 NULL,\r
48 {\r
49 FakeExtractConfig,\r
50 FakeRouteConfig,\r
51 FrontPageCallback\r
52 }\r
53};\r
54\r
55HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {\r
56 {\r
57 {\r
58 HARDWARE_DEVICE_PATH,\r
59 HW_VENDOR_DP,\r
60 {\r
61 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
62 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
63 }\r
64 },\r
65 //\r
66 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}\r
67 //\r
68 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }\r
69 },\r
70 {\r
71 END_DEVICE_PATH_TYPE,\r
72 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
73 {\r
74 (UINT8) (END_DEVICE_PATH_LENGTH),\r
75 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
76 }\r
77 }\r
78};\r
79\r
80/**\r
81 Update the banner information for the Front Page based on Smbios information.\r
82\r
83**/\r
84VOID\r
85UpdateFrontPageStrings (\r
86 VOID\r
87 );\r
88\r
89/**\r
90 This function allows a caller to extract the current configuration for one\r
91 or more named elements from the target driver.\r
92\r
93\r
94 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
95 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
96 @param Progress On return, points to a character in the Request string.\r
97 Points to the string's null terminator if request was successful.\r
98 Points to the most recent '&' before the first failing name/value\r
99 pair (or the beginning of the string if the failure is in the\r
100 first name/value pair) if the request was not successful.\r
101 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
102 has all values filled in for the names in the Request string.\r
103 String to be allocated by the called function.\r
104\r
105 @retval EFI_SUCCESS The Results is filled with the requested values.\r
106 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
107 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
108 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
109\r
110**/\r
111EFI_STATUS\r
112EFIAPI\r
113FakeExtractConfig (\r
114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
115 IN CONST EFI_STRING Request,\r
116 OUT EFI_STRING *Progress,\r
117 OUT EFI_STRING *Results\r
118 )\r
119{\r
120 if (Progress == NULL || Results == NULL) {\r
121 return EFI_INVALID_PARAMETER;\r
122 }\r
123 *Progress = Request;\r
124 return EFI_NOT_FOUND;\r
125}\r
126\r
127/**\r
128 This function processes the results of changes in configuration.\r
129\r
130\r
131 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
132 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
133 @param Progress A pointer to a string filled in with the offset of the most\r
134 recent '&' before the first failing name/value pair (or the\r
135 beginning of the string if the failure is in the first\r
136 name/value pair) or the terminating NULL if all was successful.\r
137\r
138 @retval EFI_SUCCESS The Results is processed successfully.\r
139 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
140 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
141\r
142**/\r
143EFI_STATUS\r
144EFIAPI\r
145FakeRouteConfig (\r
146 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
147 IN CONST EFI_STRING Configuration,\r
148 OUT EFI_STRING *Progress\r
149 )\r
150{\r
151 if (Configuration == NULL || Progress == NULL) {\r
152 return EFI_INVALID_PARAMETER;\r
153 }\r
154\r
ce7690e2 155 return EFI_NOT_FOUND;\r
143f0b1d
ED
156}\r
157\r
158/**\r
159 Create oneof options for language.\r
160\r
161**/\r
162VOID\r
163InitializeLanguage (\r
164 VOID\r
165 )\r
166{\r
167 EFI_STATUS Status;\r
168 CHAR8 *LangCode;\r
169 CHAR8 *Lang;\r
170 CHAR8 *CurrentLang;\r
171 UINTN OptionCount;\r
172 CHAR16 *StringBuffer;\r
173 EFI_HII_HANDLE HiiHandle;\r
174 VOID *OptionsOpCodeHandle;\r
175 VOID *StartOpCodeHandle;\r
176 VOID *EndOpCodeHandle;\r
177 EFI_IFR_GUID_LABEL *StartLabel;\r
178 EFI_IFR_GUID_LABEL *EndLabel; \r
179 EFI_HII_STRING_PROTOCOL *HiiString;\r
180 UINTN StringSize;\r
181\r
182 Lang = NULL;\r
183 StringBuffer = NULL;\r
184\r
185 //\r
186 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
187 //\r
188 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
189 ASSERT (StartOpCodeHandle != NULL);\r
190\r
191 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
192 ASSERT (EndOpCodeHandle != NULL);\r
193\r
194 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
195 ASSERT (OptionsOpCodeHandle != NULL);\r
196 //\r
197 // Create Hii Extend Label OpCode as the start opcode\r
198 //\r
199 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
200 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
201 StartLabel->Number = LABEL_SELECT_LANGUAGE;\r
202\r
203 //\r
204 // Create Hii Extend Label OpCode as the end opcode\r
205 //\r
206 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
207 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
208 EndLabel->Number = LABEL_END;\r
209 //\r
210 // Collect the languages from what our current Language support is based on our VFR\r
211 //\r
212 HiiHandle = gFrontPagePrivate.HiiHandle;\r
213\r
cf34f86b 214 GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);\r
143f0b1d
ED
215\r
216 if (mLanguageString == NULL) {\r
217 //\r
218 // Get Support language list from variable.\r
219 //\r
cf34f86b 220 GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL);\r
143f0b1d
ED
221 if (mLanguageString == NULL) {\r
222 mLanguageString = AllocateCopyPool (\r
223 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
224 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
225 );\r
226 ASSERT (mLanguageString != NULL);\r
227 }\r
228 }\r
229\r
230 if (gFrontPagePrivate.LanguageToken == NULL) {\r
231 //\r
232 // Count the language list number.\r
233 // \r
234 LangCode = mLanguageString;\r
235 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
236 ASSERT (Lang != NULL);\r
237 OptionCount = 0;\r
238 while (*LangCode != 0) {\r
239 GetNextLanguage (&LangCode, Lang);\r
240 OptionCount ++;\r
241 }\r
242\r
243 //\r
244 // Allocate extra 1 as the end tag.\r
245 //\r
246 gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));\r
247 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
248\r
249 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
250 ASSERT_EFI_ERROR (Status);\r
251\r
252 LangCode = mLanguageString;\r
253 OptionCount = 0;\r
254 while (*LangCode != 0) {\r
255 GetNextLanguage (&LangCode, Lang);\r
256\r
257 StringSize = 0;\r
258 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
259 if (Status == EFI_BUFFER_TOO_SMALL) {\r
260 StringBuffer = AllocateZeroPool (StringSize);\r
261 ASSERT (StringBuffer != NULL);\r
262 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
263 ASSERT_EFI_ERROR (Status);\r
264 }\r
265\r
266 if (EFI_ERROR (Status)) {\r
267 StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16));\r
268 ASSERT (StringBuffer != NULL);\r
269 AsciiStrToUnicodeStr (Lang, StringBuffer);\r
270 }\r
271\r
272 ASSERT (StringBuffer != NULL);\r
273 gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
274 FreePool (StringBuffer);\r
275\r
276 OptionCount++;\r
277 }\r
278 }\r
279\r
280 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
281 LangCode = mLanguageString;\r
282 OptionCount = 0;\r
283 if (Lang == NULL) {\r
284 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
285 ASSERT (Lang != NULL);\r
286 }\r
287 while (*LangCode != 0) {\r
288 GetNextLanguage (&LangCode, Lang);\r
289\r
290 if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {\r
291 HiiCreateOneOfOptionOpCode (\r
292 OptionsOpCodeHandle,\r
293 gFrontPagePrivate.LanguageToken[OptionCount],\r
294 EFI_IFR_OPTION_DEFAULT,\r
295 EFI_IFR_NUMERIC_SIZE_1,\r
296 (UINT8) OptionCount\r
297 );\r
298 } else {\r
299 HiiCreateOneOfOptionOpCode (\r
300 OptionsOpCodeHandle,\r
301 gFrontPagePrivate.LanguageToken[OptionCount],\r
302 0,\r
303 EFI_IFR_NUMERIC_SIZE_1,\r
304 (UINT8) OptionCount\r
305 );\r
306 }\r
307\r
308 OptionCount++;\r
309 }\r
310\r
311 if (CurrentLang != NULL) {\r
312 FreePool (CurrentLang);\r
313 }\r
314 FreePool (Lang);\r
315\r
316 HiiCreateOneOfOpCode (\r
317 StartOpCodeHandle,\r
318 FRONT_PAGE_KEY_LANGUAGE,\r
319 0,\r
320 0,\r
321 STRING_TOKEN (STR_LANGUAGE_SELECT),\r
322 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
323 EFI_IFR_FLAG_CALLBACK,\r
324 EFI_IFR_NUMERIC_SIZE_1,\r
325 OptionsOpCodeHandle,\r
326 NULL\r
327 );\r
328\r
329 Status = HiiUpdateForm (\r
330 HiiHandle,\r
331 &mFrontPageGuid,\r
332 FRONT_PAGE_FORM_ID,\r
333 StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
334 EndOpCodeHandle // LABEL_END\r
335 );\r
336\r
337 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
338 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
339 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
340}\r
341\r
342/**\r
343 This function processes the results of changes in configuration.\r
344\r
345\r
346 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
347 @param Action Specifies the type of action taken by the browser.\r
348 @param QuestionId A unique value which is sent to the original exporting driver\r
349 so that it can identify the type of data to expect.\r
350 @param Type The type of value for the question.\r
351 @param Value A pointer to the data being sent to the original exporting driver.\r
352 @param ActionRequest On return, points to the action requested by the callback function.\r
353\r
354 @retval EFI_SUCCESS The callback successfully handled the action.\r
355 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
356 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
357 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
358\r
359**/\r
360EFI_STATUS\r
361EFIAPI\r
362FrontPageCallback (\r
363 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
364 IN EFI_BROWSER_ACTION Action,\r
365 IN EFI_QUESTION_ID QuestionId,\r
366 IN UINT8 Type,\r
367 IN EFI_IFR_TYPE_VALUE *Value,\r
368 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
369 )\r
370{\r
371 CHAR8 *LangCode;\r
372 CHAR8 *Lang;\r
373 UINTN Index;\r
374 EFI_STATUS Status;\r
375\r
ce7690e2 376 if (Action != EFI_BROWSER_ACTION_CHANGED) {\r
143f0b1d
ED
377 //\r
378 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
379 //\r
380 return EFI_UNSUPPORTED;\r
381 }\r
382\r
383 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
384 if ((Value == NULL) || (ActionRequest == NULL)) {\r
385 return EFI_INVALID_PARAMETER;\r
386 }\r
387\r
388 switch (QuestionId) {\r
389 case FRONT_PAGE_KEY_CONTINUE:\r
390 //\r
391 // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
392 //\r
393 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
394 break;\r
395\r
396 case FRONT_PAGE_KEY_LANGUAGE:\r
397 //\r
398 // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
399 //\r
400 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
401 ASSERT (Lang != NULL); \r
402\r
403 Index = 0;\r
404 LangCode = mLanguageString;\r
405 while (*LangCode != 0) {\r
406 GetNextLanguage (&LangCode, Lang);\r
407\r
408 if (Index == Value->u8) {\r
409 break;\r
410 }\r
411\r
412 Index++;\r
413 }\r
414\r
415 if (Index == Value->u8) {\r
416 Status = gRT->SetVariable (\r
417 L"PlatformLang",\r
418 &gEfiGlobalVariableGuid,\r
419 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
420 AsciiStrSize (Lang),\r
421 Lang\r
422 );\r
c7d310dd
DB
423 if (EFI_ERROR (Status)) {\r
424 FreePool (Lang);\r
425 return EFI_DEVICE_ERROR;\r
426 }\r
143f0b1d
ED
427 } else {\r
428 ASSERT (FALSE);\r
429 }\r
430 FreePool (Lang);\r
431 //\r
432 //Current language of platform is changed,recreate oneof options for language.\r
433 //\r
434 InitializeLanguage();\r
435 break;\r
436\r
143f0b1d
ED
437 default:\r
438 break;\r
439 }\r
ce7690e2
DB
440 }\r
441\r
442 return EFI_SUCCESS;\r
443}\r
444\r
445/**\r
446Update front page form base on the ClassGuid in the formset in other modules.\r
447\r
448**/\r
449VOID\r
450UpdateFrontPageForm (\r
451 VOID\r
452 )\r
453{\r
454 EFI_STATUS Status;\r
455 EFI_HII_HANDLE HiiHandle;\r
456 VOID *StartOpCodeHandle;\r
457 VOID *EndOpCodeHandle;\r
458 EFI_IFR_GUID_LABEL *StartLabel;\r
459 EFI_IFR_GUID_LABEL *EndLabel;\r
460 UINTN Index;\r
461 EFI_STRING String;\r
462 EFI_STRING_ID Token;\r
463 EFI_STRING_ID TokenHelp;\r
464 EFI_HII_HANDLE *HiiHandles;\r
465 EFI_GUID FormSetGuid;\r
466 CHAR16 *DevicePathStr;\r
467 EFI_STRING_ID DevicePathId;\r
468 EFI_IFR_FORM_SET *Buffer;\r
469 UINTN BufferSize;\r
470 UINT8 ClassGuidNum;\r
471 EFI_GUID *ClassGuid;\r
472 UINTN TempSize;\r
473 UINT8 *Ptr;\r
474\r
475 TempSize =0;\r
476 BufferSize = 0;\r
477 Buffer = NULL;\r
478\r
479 HiiHandle = gFrontPagePrivate.HiiHandle;\r
480\r
481 //\r
482 // Allocate space for creation of UpdateData Buffer\r
483 //\r
484 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
485 ASSERT (StartOpCodeHandle != NULL);\r
486\r
487 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
488 ASSERT (EndOpCodeHandle != NULL);\r
489 //\r
490 // Create Hii Extend Label OpCode as the start opcode\r
491 //\r
492 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
493 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
494 StartLabel->Number = LABEL_PLATFORM_INFORMATION;\r
495 //\r
496 // Create Hii Extend Label OpCode as the end opcode\r
497 //\r
498 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
499 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
500 EndLabel->Number = LABEL_END;\r
501\r
502 //\r
503 // Get all the Hii handles\r
504 //\r
505 HiiHandles = HiiGetHiiHandles (NULL);\r
506 ASSERT (HiiHandles != NULL);\r
507 //\r
508 // Search for formset of each class type\r
509 //\r
510 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
511 Status = HiiGetFormSetFromHiiHandle(HiiHandles[Index], &Buffer,&BufferSize);\r
512 if (EFI_ERROR (Status)) {\r
513 continue;\r
143f0b1d
ED
514 }\r
515\r
ce7690e2
DB
516 Ptr = (UINT8 *)Buffer;\r
517 while(TempSize < BufferSize) {\r
518 TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
143f0b1d 519\r
ce7690e2
DB
520 if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){\r
521 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
522 continue;\r
523 }\r
143f0b1d 524\r
143f0b1d 525 //\r
ce7690e2 526 // Find Class Guid\r
143f0b1d 527 //\r
ce7690e2
DB
528 ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);\r
529 ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));\r
530 while (ClassGuidNum-- > 0) {\r
531 if (CompareGuid (&gEfiIfrFrontPageGuid, ClassGuid) == 0){\r
532 ClassGuid ++;\r
533 continue;\r
534 }\r
143f0b1d 535\r
ce7690e2
DB
536 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);\r
537 if (String == NULL) {\r
538 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
539 ASSERT (String != NULL);\r
540 }\r
541 Token = HiiSetString (HiiHandle, 0, String, NULL);\r
542 FreePool (String);\r
543\r
544 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);\r
545\r
546 if (String == NULL) {\r
547 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
548 ASSERT (String != NULL);\r
549 }\r
550 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);\r
551 FreePool (String);\r
552\r
553 FormSetGuid = ((EFI_IFR_FORM_SET *)Ptr)->Guid;\r
554\r
555 DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);\r
556 DevicePathId = 0;\r
557 if (DevicePathStr != NULL){\r
558 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
559 FreePool (DevicePathStr);\r
560 }\r
561 HiiCreateGotoExOpCode (\r
562 StartOpCodeHandle,\r
563 0,\r
564 Token,\r
565 TokenHelp,\r
566 0,\r
567 (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET),\r
568 0,\r
569 &FormSetGuid,\r
570 DevicePathId\r
571 );\r
572 break;\r
573 }\r
574 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
143f0b1d 575 }\r
ce7690e2
DB
576\r
577 FreePool(Buffer);\r
578 Buffer = NULL;\r
579 TempSize = 0;\r
580 BufferSize = 0;\r
143f0b1d
ED
581 }\r
582\r
ce7690e2
DB
583 HiiUpdateForm (\r
584 HiiHandle,\r
585 &mFrontPageGuid,\r
586 FRONT_PAGE_FORM_ID,\r
587 StartOpCodeHandle,\r
588 EndOpCodeHandle\r
589 );\r
590\r
591 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
592 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
593 FreePool (HiiHandles);\r
143f0b1d
ED
594}\r
595\r
596/**\r
597 Initialize HII information for the FrontPage\r
598\r
599\r
600 @retval EFI_SUCCESS The operation is successful.\r
601 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.\r
602\r
603**/\r
604EFI_STATUS\r
605InitializeFrontPage (\r
606 VOID\r
607 )\r
608{\r
609 EFI_STATUS Status;\r
143f0b1d
ED
610 //\r
611 // Locate Hii relative protocols\r
612 //\r
613 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
614 if (EFI_ERROR (Status)) {\r
615 return Status;\r
616 }\r
617\r
618 //\r
619 // Install Device Path Protocol and Config Access protocol to driver handle\r
620 //\r
621 gFrontPagePrivate.DriverHandle = NULL;\r
622 Status = gBS->InstallMultipleProtocolInterfaces (\r
623 &gFrontPagePrivate.DriverHandle,\r
624 &gEfiDevicePathProtocolGuid,\r
625 &mFrontPageHiiVendorDevicePath,\r
626 &gEfiHiiConfigAccessProtocolGuid,\r
627 &gFrontPagePrivate.ConfigAccess,\r
628 NULL\r
629 );\r
630 ASSERT_EFI_ERROR (Status);\r
631\r
632 //\r
633 // Publish our HII data\r
634 //\r
635 gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
636 &mFrontPageGuid,\r
637 gFrontPagePrivate.DriverHandle,\r
638 FrontPageVfrBin,\r
639 UiAppStrings,\r
640 NULL\r
641 );\r
642 ASSERT (gFrontPagePrivate.HiiHandle != NULL);\r
643\r
644 //\r
645 //Updata Front Page strings\r
646 //\r
647 UpdateFrontPageStrings ();\r
648\r
649 //\r
650 // Initialize laguage options\r
651 //\r
652 InitializeLanguage ();\r
653\r
ce7690e2
DB
654 //\r
655 //Updata Front Page form\r
656 //\r
657 UpdateFrontPageForm();\r
658\r
143f0b1d
ED
659 return Status;\r
660}\r
661\r
662/**\r
663 Call the browser and display the front page\r
664\r
665 @return Status code that will be returned by\r
666 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().\r
667\r
668**/\r
669EFI_STATUS\r
670CallFrontPage (\r
671 VOID\r
672 )\r
673{\r
674 EFI_STATUS Status;\r
675 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
676\r
677 //\r
678 // Begin waiting for USER INPUT\r
679 //\r
680 REPORT_STATUS_CODE (\r
681 EFI_PROGRESS_CODE,\r
682 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
683 );\r
684\r
685 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
686 Status = gFormBrowser2->SendForm (\r
687 gFormBrowser2,\r
688 &gFrontPagePrivate.HiiHandle,\r
689 1,\r
690 &mFrontPageGuid,\r
691 0,\r
692 NULL,\r
693 &ActionRequest\r
694 );\r
695 //\r
696 // Check whether user change any option setting which needs a reset to be effective\r
697 //\r
698 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
699 EnableResetRequired ();\r
700 }\r
701\r
702 return Status;\r
703}\r
704\r
3194d76f
DB
705/**\r
706 Remove the installed packages from the HiiDatabase.\r
707\r
708**/\r
143f0b1d
ED
709VOID\r
710FreeFrontPage(\r
711 VOID\r
712 )\r
713{\r
714 EFI_STATUS Status;\r
715 Status = gBS->UninstallMultipleProtocolInterfaces (\r
716 gFrontPagePrivate.DriverHandle,\r
717 &gEfiDevicePathProtocolGuid,\r
718 &mFrontPageHiiVendorDevicePath,\r
719 &gEfiHiiConfigAccessProtocolGuid,\r
720 &gFrontPagePrivate.ConfigAccess,\r
721 NULL\r
722 );\r
723 ASSERT_EFI_ERROR (Status);\r
724\r
725 //\r
726 // Publish our HII data\r
727 //\r
728 HiiRemovePackages (gFrontPagePrivate.HiiHandle);\r
729 if (gFrontPagePrivate.LanguageToken != NULL) {\r
730 FreePool (gFrontPagePrivate.LanguageToken);\r
731 gFrontPagePrivate.LanguageToken = NULL;\r
732 }\r
733}\r
734\r
735/**\r
736 Convert Processor Frequency Data to a string.\r
737\r
738 @param ProcessorFrequency The frequency data to process\r
739 @param Base10Exponent The exponent based on 10\r
740 @param String The string that is created\r
741\r
742**/\r
743VOID\r
744ConvertProcessorToString (\r
745 IN UINT16 ProcessorFrequency,\r
746 IN UINT16 Base10Exponent,\r
747 OUT CHAR16 **String\r
748 )\r
749{\r
750 CHAR16 *StringBuffer;\r
751 UINTN Index;\r
d91cb870 752 UINTN DestMax;\r
143f0b1d
ED
753 UINT32 FreqMhz;\r
754\r
755 if (Base10Exponent >= 6) {\r
756 FreqMhz = ProcessorFrequency;\r
757 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) {\r
758 FreqMhz *= 10;\r
759 }\r
760 } else {\r
761 FreqMhz = 0;\r
762 }\r
d91cb870 763 DestMax = 0x20 / sizeof (CHAR16);\r
143f0b1d
ED
764 StringBuffer = AllocateZeroPool (0x20);\r
765 ASSERT (StringBuffer != NULL);\r
766 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
d91cb870 767 StrCatS (StringBuffer, DestMax, L".");\r
143f0b1d 768 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
d91cb870 769 StrCatS (StringBuffer, DestMax, L" GHz");\r
143f0b1d
ED
770 *String = (CHAR16 *) StringBuffer;\r
771 return ;\r
772}\r
773\r
774\r
775/**\r
776 Convert Memory Size to a string.\r
777\r
778 @param MemorySize The size of the memory to process\r
779 @param String The string that is created\r
780\r
781**/\r
782VOID\r
783ConvertMemorySizeToString (\r
784 IN UINT32 MemorySize,\r
785 OUT CHAR16 **String\r
786 )\r
787{\r
788 CHAR16 *StringBuffer;\r
789\r
790 StringBuffer = AllocateZeroPool (0x24);\r
791 ASSERT (StringBuffer != NULL);\r
792 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 10);\r
d91cb870 793 StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM");\r
143f0b1d
ED
794\r
795 *String = (CHAR16 *) StringBuffer;\r
796\r
797 return ;\r
798}\r
799\r
800/**\r
801\r
802 Acquire the string associated with the Index from smbios structure and return it.\r
803 The caller is responsible for free the string buffer.\r
804\r
805 @param OptionalStrStart The start position to search the string\r
806 @param Index The index of the string to extract\r
807 @param String The string that is extracted\r
808\r
809 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.\r
810\r
811**/\r
812EFI_STATUS\r
813GetOptionalStringByIndex (\r
814 IN CHAR8 *OptionalStrStart,\r
815 IN UINT8 Index,\r
816 OUT CHAR16 **String\r
817 )\r
818{\r
819 UINTN StrSize;\r
820\r
821 if (Index == 0) {\r
822 *String = AllocateZeroPool (sizeof (CHAR16));\r
823 return EFI_SUCCESS;\r
824 }\r
825\r
826 StrSize = 0;\r
827 do {\r
828 Index--;\r
829 OptionalStrStart += StrSize;\r
830 StrSize = AsciiStrSize (OptionalStrStart);\r
831 } while (OptionalStrStart[StrSize] != 0 && Index != 0);\r
832\r
833 if ((Index != 0) || (StrSize == 1)) {\r
834 //\r
835 // Meet the end of strings set but Index is non-zero, or\r
836 // Find an empty string\r
837 //\r
838 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
839 } else {\r
840 *String = AllocatePool (StrSize * sizeof (CHAR16));\r
841 AsciiStrToUnicodeStr (OptionalStrStart, *String);\r
842 }\r
843\r
844 return EFI_SUCCESS;\r
845}\r
846\r
847\r
848/**\r
849 Update the banner information for the Front Page based on Smbios information.\r
850**/\r
851VOID\r
852UpdateFrontPageStrings (\r
853 VOID\r
854 )\r
855{\r
856 UINT8 StrIndex;\r
857 CHAR16 *NewString;\r
858 CHAR16 *FirmwareVersionString;\r
859 BOOLEAN Find[5];\r
860 EFI_STATUS Status;\r
861 EFI_STRING_ID TokenToUpdate;\r
862 EFI_SMBIOS_HANDLE SmbiosHandle;\r
863 EFI_SMBIOS_PROTOCOL *Smbios;\r
864 SMBIOS_TABLE_TYPE0 *Type0Record;\r
865 SMBIOS_TABLE_TYPE1 *Type1Record;\r
866 SMBIOS_TABLE_TYPE4 *Type4Record;\r
867 SMBIOS_TABLE_TYPE19 *Type19Record;\r
868 EFI_SMBIOS_TABLE_HEADER *Record;\r
869\r
870 ZeroMem (Find, sizeof (Find));\r
871\r
872 //\r
873 // Update Front Page strings\r
874 //\r
875 Status = gBS->LocateProtocol (\r
876 &gEfiSmbiosProtocolGuid,\r
877 NULL,\r
878 (VOID **) &Smbios\r
879 );\r
880 if (EFI_ERROR (Status)) {\r
881 return ;\r
882 }\r
883\r
884 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
885 do {\r
886 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
887 if (EFI_ERROR(Status)) {\r
888 break;\r
889 }\r
890\r
891 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {\r
892 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
893 StrIndex = Type0Record->BiosVersion;\r
894 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
895 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
896 FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);\r
897 if (*FirmwareVersionString != 0x0000 ) {\r
898 FreePool (NewString);\r
899 NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);\r
900 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
901 } else {\r
902 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
903 FreePool (NewString);\r
904 }\r
905 Find[0] = TRUE;\r
906 } \r
907\r
908 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
909 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
910 StrIndex = Type1Record->ProductName;\r
911 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
912 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
913 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
914 FreePool (NewString);\r
915 Find[1] = TRUE;\r
916 }\r
917\r
918 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[2]) {\r
919 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
920 //\r
921 // The information in the record should be only valid when the CPU Socket is populated. \r
922 //\r
923 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {\r
924 StrIndex = Type4Record->ProcessorVersion;\r
925 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
926 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
927 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
928 FreePool (NewString);\r
929 Find[2] = TRUE;\r
930 }\r
931 } \r
932\r
933 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[3]) {\r
934 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
935 //\r
936 // The information in the record should be only valid when the CPU Socket is populated. \r
937 //\r
938 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {\r
939 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
940 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
941 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
942 FreePool (NewString);\r
943 Find[3] = TRUE;\r
944 }\r
945 } \r
946\r
947 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
948 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
949 ConvertMemorySizeToString (\r
950 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),\r
951 &NewString\r
952 );\r
953 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
954 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
955 FreePool (NewString);\r
956 Find[4] = TRUE; \r
957 }\r
958 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
959 return ;\r
960}\r
961\r
962/**\r
963 This function will change video resolution and text mode\r
964 according to defined setup mode or defined boot mode \r
965\r
966 @param IsSetupMode Indicate mode is changed to setup mode or boot mode. \r
967\r
968 @retval EFI_SUCCESS Mode is changed successfully.\r
969 @retval Others Mode failed to be changed.\r
970\r
971**/\r
972EFI_STATUS\r
973EFIAPI\r
974BdsSetConsoleMode (\r
975 BOOLEAN IsSetupMode\r
976 )\r
977{\r
978 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
979 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
980 UINTN SizeOfInfo;\r
981 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
982 UINT32 MaxGopMode;\r
983 UINT32 MaxTextMode;\r
984 UINT32 ModeNumber;\r
985 UINT32 NewHorizontalResolution;\r
986 UINT32 NewVerticalResolution;\r
987 UINT32 NewColumns;\r
988 UINT32 NewRows;\r
989 UINTN HandleCount;\r
990 EFI_HANDLE *HandleBuffer;\r
991 EFI_STATUS Status;\r
992 UINTN Index;\r
993 UINTN CurrentColumn;\r
994 UINTN CurrentRow; \r
995\r
996 MaxGopMode = 0;\r
997 MaxTextMode = 0;\r
998\r
999 //\r
1000 // Get current video resolution and text mode \r
1001 //\r
1002 Status = gBS->HandleProtocol (\r
1003 gST->ConsoleOutHandle,\r
1004 &gEfiGraphicsOutputProtocolGuid,\r
1005 (VOID**)&GraphicsOutput\r
1006 );\r
1007 if (EFI_ERROR (Status)) {\r
1008 GraphicsOutput = NULL;\r
1009 }\r
1010\r
1011 Status = gBS->HandleProtocol (\r
1012 gST->ConsoleOutHandle,\r
1013 &gEfiSimpleTextOutProtocolGuid,\r
1014 (VOID**)&SimpleTextOut\r
1015 );\r
1016 if (EFI_ERROR (Status)) {\r
1017 SimpleTextOut = NULL;\r
1018 } \r
1019\r
1020 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {\r
1021 return EFI_UNSUPPORTED;\r
1022 }\r
1023\r
1024 if (IsSetupMode) {\r
1025 //\r
1026 // The requried resolution and text mode is setup mode.\r
1027 //\r
1028 NewHorizontalResolution = mSetupHorizontalResolution;\r
1029 NewVerticalResolution = mSetupVerticalResolution;\r
1030 NewColumns = mSetupTextModeColumn;\r
1031 NewRows = mSetupTextModeRow;\r
1032 } else {\r
1033 //\r
1034 // The required resolution and text mode is boot mode.\r
1035 //\r
1036 NewHorizontalResolution = mBootHorizontalResolution;\r
1037 NewVerticalResolution = mBootVerticalResolution;\r
1038 NewColumns = mBootTextModeColumn;\r
1039 NewRows = mBootTextModeRow; \r
1040 }\r
1041 \r
1042 if (GraphicsOutput != NULL) {\r
1043 MaxGopMode = GraphicsOutput->Mode->MaxMode;\r
1044 } \r
1045\r
1046 if (SimpleTextOut != NULL) {\r
1047 MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
1048 }\r
1049\r
1050 //\r
1051 // 1. If current video resolution is same with required video resolution,\r
1052 // video resolution need not be changed.\r
1053 // 1.1. If current text mode is same with required text mode, text mode need not be changed.\r
1054 // 1.2. If current text mode is different from required text mode, text mode need be changed.\r
1055 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
1056 //\r
1057 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
1058 Status = GraphicsOutput->QueryMode (\r
1059 GraphicsOutput,\r
1060 ModeNumber,\r
1061 &SizeOfInfo,\r
1062 &Info\r
1063 );\r
1064 if (!EFI_ERROR (Status)) {\r
1065 if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
1066 (Info->VerticalResolution == NewVerticalResolution)) {\r
1067 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
1068 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
1069 //\r
1070 // Current resolution is same with required resolution, check if text mode need be set\r
1071 //\r
1072 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
1073 ASSERT_EFI_ERROR (Status);\r
1074 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
1075 //\r
1076 // If current text mode is same with required text mode. Do nothing\r
1077 //\r
1078 FreePool (Info);\r
1079 return EFI_SUCCESS;\r
1080 } else {\r
1081 //\r
1082 // If current text mode is different from requried text mode. Set new video mode\r
1083 //\r
1084 for (Index = 0; Index < MaxTextMode; Index++) {\r
1085 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
1086 if (!EFI_ERROR(Status)) {\r
1087 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
1088 //\r
1089 // Required text mode is supported, set it.\r
1090 //\r
1091 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
1092 ASSERT_EFI_ERROR (Status);\r
1093 //\r
1094 // Update text mode PCD.\r
1095 //\r
377680ae
ED
1096 Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);\r
1097 ASSERT_EFI_ERROR (Status);\r
1098 Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);\r
1099 ASSERT_EFI_ERROR (Status);\r
143f0b1d
ED
1100 FreePool (Info);\r
1101 return EFI_SUCCESS;\r
1102 }\r
1103 }\r
1104 }\r
1105 if (Index == MaxTextMode) {\r
1106 //\r
1107 // If requried text mode is not supported, return error.\r
1108 //\r
1109 FreePool (Info);\r
1110 return EFI_UNSUPPORTED;\r
1111 }\r
1112 }\r
1113 } else {\r
1114 //\r
1115 // If current video resolution is not same with the new one, set new video resolution.\r
1116 // In this case, the driver which produces simple text out need be restarted.\r
1117 //\r
1118 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
1119 if (!EFI_ERROR (Status)) {\r
1120 FreePool (Info);\r
1121 break;\r
1122 }\r
1123 }\r
1124 }\r
1125 FreePool (Info);\r
1126 }\r
1127 }\r
1128\r
1129 if (ModeNumber == MaxGopMode) {\r
1130 //\r
1131 // If the resolution is not supported, return error.\r
1132 //\r
1133 return EFI_UNSUPPORTED;\r
1134 }\r
1135\r
1136 //\r
1137 // Set PCD to Inform GraphicsConsole to change video resolution.\r
1138 // Set PCD to Inform Consplitter to change text mode.\r
1139 //\r
377680ae
ED
1140 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
1141 ASSERT_EFI_ERROR (Status);\r
1142 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);\r
1143 ASSERT_EFI_ERROR (Status);\r
1144 Status = PcdSet32S (PcdConOutColumn, NewColumns);\r
1145 ASSERT_EFI_ERROR (Status);\r
1146 Status = PcdSet32S (PcdConOutRow, NewRows);\r
1147 ASSERT_EFI_ERROR (Status);\r
143f0b1d
ED
1148 \r
1149 \r
1150 //\r
1151 // Video mode is changed, so restart graphics console driver and higher level driver.\r
1152 // Reconnect graphics console driver and higher level driver.\r
1153 // Locate all the handles with GOP protocol and reconnect it.\r
1154 //\r
1155 Status = gBS->LocateHandleBuffer (\r
1156 ByProtocol,\r
1157 &gEfiSimpleTextOutProtocolGuid,\r
1158 NULL,\r
1159 &HandleCount,\r
1160 &HandleBuffer\r
1161 );\r
1162 if (!EFI_ERROR (Status)) {\r
1163 for (Index = 0; Index < HandleCount; Index++) {\r
1164 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
1165 }\r
1166 for (Index = 0; Index < HandleCount; Index++) {\r
1167 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
1168 }\r
1169 if (HandleBuffer != NULL) {\r
1170 FreePool (HandleBuffer);\r
1171 }\r
1172 }\r
1173\r
1174 return EFI_SUCCESS;\r
1175}\r
1176\r
1177/**\r
1178 The user Entry Point for Application. The user code starts with this function\r
1179 as the real entry point for the image goes into a library that calls this \r
1180 function.\r
1181\r
1182 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1183 @param[in] SystemTable A pointer to the EFI System Table.\r
1184 \r
1185 @retval EFI_SUCCESS The entry point is executed successfully.\r
1186 @retval other Some error occurs when executing this entry point.\r
1187\r
1188**/\r
1189EFI_STATUS\r
1190EFIAPI\r
1191InitializeUserInterface (\r
1192 IN EFI_HANDLE ImageHandle,\r
1193 IN EFI_SYSTEM_TABLE *SystemTable\r
1194 )\r
1195{\r
1196 EFI_HII_HANDLE HiiHandle;\r
1197 EFI_STATUS Status;\r
1198 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1199 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
1200 UINTN BootTextColumn;\r
1201 UINTN BootTextRow;\r
1202\r
1203 if (!mModeInitialized) {\r
1204 //\r
1205 // After the console is ready, get current video resolution \r
1206 // and text mode before launching setup at first time.\r
1207 //\r
1208 Status = gBS->HandleProtocol (\r
1209 gST->ConsoleOutHandle,\r
1210 &gEfiGraphicsOutputProtocolGuid,\r
1211 (VOID**)&GraphicsOutput\r
1212 );\r
1213 if (EFI_ERROR (Status)) {\r
1214 GraphicsOutput = NULL;\r
1215 }\r
1216 \r
1217 Status = gBS->HandleProtocol (\r
1218 gST->ConsoleOutHandle,\r
1219 &gEfiSimpleTextOutProtocolGuid,\r
1220 (VOID**)&SimpleTextOut\r
1221 );\r
1222 if (EFI_ERROR (Status)) {\r
1223 SimpleTextOut = NULL;\r
1224 } \r
1225\r
1226 if (GraphicsOutput != NULL) {\r
1227 //\r
1228 // Get current video resolution and text mode.\r
1229 //\r
1230 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1231 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
1232 }\r
1233\r
1234 if (SimpleTextOut != NULL) {\r
1235 Status = SimpleTextOut->QueryMode (\r
1236 SimpleTextOut,\r
1237 SimpleTextOut->Mode->Mode,\r
1238 &BootTextColumn,\r
1239 &BootTextRow\r
1240 );\r
1241 mBootTextModeColumn = (UINT32)BootTextColumn;\r
1242 mBootTextModeRow = (UINT32)BootTextRow;\r
1243 }\r
1244\r
1245 //\r
1246 // Get user defined text mode for setup.\r
1247 // \r
1248 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
1249 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); \r
1250 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
1251 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
1252\r
1253 mModeInitialized = TRUE;\r
1254 }\r
1255\r
1256 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
1257 gST->ConOut->ClearScreen (gST->ConOut);\r
1258 \r
1259 //\r
1260 // Install customized fonts needed by Front Page\r
1261 //\r
1262 \r
1263 HiiHandle = ExportFonts ();\r
1264 ASSERT (HiiHandle != NULL);\r
1265\r
1266 InitializeStringSupport ();\r
1267\r
1268 BdsSetConsoleMode (TRUE);\r
1269 UiEntry (FALSE);\r
1270 BdsSetConsoleMode (FALSE);\r
1271\r
1272 UninitializeStringSupport ();\r
1273 HiiRemovePackages (HiiHandle);\r
1274\r
1275 return EFI_SUCCESS;\r
1276}\r
1277\r
1278/**\r
1279 This function is the main entry of the UI entry.\r
1280 The function will present the main menu of the system UI.\r
1281\r
1282 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.\r
1283\r
1284**/\r
1285VOID\r
1286EFIAPI\r
1287UiEntry (\r
1288 IN BOOLEAN ConnectAllHappened\r
1289 )\r
1290{\r
1291 EFI_STATUS Status;\r
1292 EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
1293\r
1294 //\r
1295 // Indicate if the connect all has been performed before.\r
1296 //\r
1297 if (ConnectAllHappened) {\r
1298 gConnectAllHappened = TRUE;\r
1299 }\r
1300\r
1301 //\r
1302 // The boot option enumeration time is acceptable in Ui driver\r
1303 //\r
1304 EfiBootManagerRefreshAllBootOption ();\r
1305\r
1306 //\r
1307 // Boot Logo is corrupted, report it using Boot Logo protocol.\r
1308 //\r
1309 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
1310 if (!EFI_ERROR (Status) && (BootLogo != NULL)) {\r
1311 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);\r
1312 }\r
1313\r
1314 InitializeFrontPage ();\r
143f0b1d
ED
1315\r
1316 CallFrontPage ();\r
1317\r
143f0b1d
ED
1318 FreeFrontPage ();\r
1319\r
1320 if (mLanguageString != NULL) {\r
1321 FreePool (mLanguageString);\r
1322 mLanguageString = NULL;\r
1323 }\r
1324\r
1325 //\r
1326 //Will leave browser, check any reset required change is applied? if yes, reset system\r
1327 //\r
1328 SetupResetReminder ();\r
1329}\r
1330\r
1331/**\r
1332 Extract device path for given HII handle and class guid.\r
1333\r
1334 @param Handle The HII handle.\r
1335\r
1336 @retval NULL Fail to get the device path string.\r
1337 @return PathString Get the device path string.\r
1338\r
1339**/\r
1340CHAR16 *\r
1341ExtractDevicePathFromHiiHandle (\r
1342 IN EFI_HII_HANDLE Handle\r
1343 )\r
1344{\r
1345 EFI_STATUS Status;\r
1346 EFI_HANDLE DriverHandle;\r
ce7690e2 1347 \r
143f0b1d
ED
1348 ASSERT (Handle != NULL);\r
1349\r
1350 if (Handle == NULL) {\r
1351 return NULL;\r
1352 }\r
1353\r
1354 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
143f0b1d
ED
1355 if (EFI_ERROR (Status)) {\r
1356 return NULL;\r
1357 }\r
1358\r
ce7690e2 1359 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);\r
143f0b1d 1360\r
143f0b1d
ED
1361}\r
1362\r
1363//\r
1364// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.\r
1365// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if\r
1366// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.\r
1367//\r
1368\r
1369\r
1370/**\r
1371 Enable the setup browser reset reminder feature.\r
1372 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.\r
1373\r
1374**/\r
1375VOID\r
1376EFIAPI\r
1377EnableResetReminderFeature (\r
1378 VOID\r
1379 )\r
1380{\r
1381 mFeaturerSwitch = TRUE;\r
1382}\r
1383\r
1384\r
1385/**\r
1386 Disable the setup browser reset reminder feature.\r
1387 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.\r
1388\r
1389**/\r
1390VOID\r
1391EFIAPI\r
1392DisableResetReminderFeature (\r
1393 VOID\r
1394 )\r
1395{\r
1396 mFeaturerSwitch = FALSE;\r
1397}\r
1398\r
1399\r
1400/**\r
1401 Record the info that a reset is required.\r
1402 A module boolean variable is used to record whether a reset is required.\r
1403\r
1404**/\r
1405VOID\r
1406EFIAPI\r
1407EnableResetRequired (\r
1408 VOID\r
1409 )\r
1410{\r
1411 mResetRequired = TRUE;\r
1412}\r
1413\r
1414\r
1415/**\r
1416 Record the info that no reset is required.\r
1417 A module boolean variable is used to record whether a reset is required.\r
1418\r
1419**/\r
1420VOID\r
1421EFIAPI\r
1422DisableResetRequired (\r
1423 VOID\r
1424 )\r
1425{\r
1426 mResetRequired = FALSE;\r
1427}\r
1428\r
1429\r
1430/**\r
1431 Check whether platform policy enable the reset reminder feature. The default is enabled.\r
1432\r
1433**/\r
1434BOOLEAN\r
1435EFIAPI\r
1436IsResetReminderFeatureEnable (\r
1437 VOID\r
1438 )\r
1439{\r
1440 return mFeaturerSwitch;\r
1441}\r
1442\r
1443\r
1444/**\r
1445 Check if user changed any option setting which needs a system reset to be effective.\r
1446\r
1447**/\r
1448BOOLEAN\r
1449EFIAPI\r
1450IsResetRequired (\r
1451 VOID\r
1452 )\r
1453{\r
1454 return mResetRequired;\r
1455}\r
1456\r
1457\r
1458/**\r
1459 Check whether a reset is needed, and finish the reset reminder feature.\r
1460 If a reset is needed, Popup a menu to notice user, and finish the feature\r
1461 according to the user selection.\r
1462\r
1463**/\r
1464VOID\r
1465EFIAPI\r
1466SetupResetReminder (\r
1467 VOID\r
1468 )\r
1469{\r
1470 EFI_INPUT_KEY Key;\r
1471 CHAR16 *StringBuffer1;\r
1472 CHAR16 *StringBuffer2;\r
1473\r
1474\r
1475 //\r
1476 //check any reset required change is applied? if yes, reset system\r
1477 //\r
1478 if (IsResetReminderFeatureEnable ()) {\r
1479 if (IsResetRequired ()) {\r
1480\r
1481 StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
1482 ASSERT (StringBuffer1 != NULL);\r
1483 StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
1484 ASSERT (StringBuffer2 != NULL);\r
d91cb870
DB
1485 StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now.");\r
1486 StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset");\r
143f0b1d
ED
1487 //\r
1488 // Popup a menu to notice user\r
1489 //\r
1490 do {\r
1491 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);\r
1492 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1493\r
1494 FreePool (StringBuffer1);\r
1495 FreePool (StringBuffer2);\r
1496\r
1497 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1498 }\r
1499 }\r
1500}\r
1501\r