]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
1. fixed one bug to construct config request string header used child handle instead...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / FrontPage.c
CommitLineData
5c08e117 1/** @file\r
2 FrontPage routines to handle the callbacks and browser calls\r
3\r
4548fc2a 4Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 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 "Bds.h"\r
16#include "FrontPage.h"\r
ad5a96ab 17#include "Language.h"\r
5c08e117 18\r
19EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;\r
20\r
21BOOLEAN gConnectAllHappened = FALSE;\r
22UINTN gCallbackKey;\r
23\r
5c08e117 24EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
5c08e117 25\r
26FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {\r
27 FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
28 NULL,\r
29 NULL,\r
30 NULL,\r
31 {\r
32 FakeExtractConfig,\r
33 FakeRouteConfig,\r
34 FrontPageCallback\r
35 }\r
36};\r
37\r
f6f910dd 38HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {\r
39 {\r
40 {\r
41 HARDWARE_DEVICE_PATH,\r
42 HW_VENDOR_DP,\r
43 {\r
44 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
45 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
46 }\r
47 },\r
48 //\r
49 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}\r
50 //\r
51 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }\r
52 },\r
53 {\r
54 END_DEVICE_PATH_TYPE,\r
55 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
128efbbc 56 {\r
f6f910dd 57 (UINT8) (END_DEVICE_PATH_LENGTH),\r
58 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
59 }\r
60 }\r
61};\r
62\r
5c08e117 63/**\r
64 This function allows a caller to extract the current configuration for one\r
65 or more named elements from the target driver.\r
66\r
67\r
68 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
69 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
70 @param Progress On return, points to a character in the Request string.\r
71 Points to the string's null terminator if request was successful.\r
72 Points to the most recent '&' before the first failing name/value\r
73 pair (or the beginning of the string if the failure is in the\r
74 first name/value pair) if the request was not successful.\r
75 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
76 has all values filled in for the names in the Request string.\r
77 String to be allocated by the called function.\r
78\r
79 @retval EFI_SUCCESS The Results is filled with the requested values.\r
80 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
59aefb7e 81 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
5c08e117 82 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
83\r
84**/\r
85EFI_STATUS\r
86EFIAPI\r
87FakeExtractConfig (\r
88 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
89 IN CONST EFI_STRING Request,\r
90 OUT EFI_STRING *Progress,\r
91 OUT EFI_STRING *Results\r
92 )\r
93{\r
59aefb7e 94 if (Progress == NULL || Results == NULL) {\r
dedfc3bb
LG
95 return EFI_INVALID_PARAMETER;\r
96 }\r
cdcc36ae 97 *Progress = Request;\r
5c08e117 98 return EFI_NOT_FOUND;\r
99}\r
100\r
101/**\r
102 This function processes the results of changes in configuration.\r
103\r
104\r
105 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
106 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
107 @param Progress A pointer to a string filled in with the offset of the most\r
108 recent '&' before the first failing name/value pair (or the\r
109 beginning of the string if the failure is in the first\r
110 name/value pair) or the terminating NULL if all was successful.\r
111\r
112 @retval EFI_SUCCESS The Results is processed successfully.\r
113 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
114 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
115\r
116**/\r
117EFI_STATUS\r
118EFIAPI\r
119FakeRouteConfig (\r
120 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
121 IN CONST EFI_STRING Configuration,\r
122 OUT EFI_STRING *Progress\r
123 )\r
124{\r
dedfc3bb 125 if (Configuration == NULL || Progress == NULL) {\r
cdcc36ae
LG
126 return EFI_INVALID_PARAMETER;\r
127 }\r
128\r
dedfc3bb
LG
129 *Progress = Configuration;\r
130 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)\r
131 && !HiiIsConfigHdrMatch (Configuration, &mFileExplorerGuid, mFileExplorerStorageName)) {\r
132 return EFI_NOT_FOUND;\r
cdcc36ae
LG
133 }\r
134\r
dedfc3bb
LG
135 *Progress = Configuration + StrLen (Configuration);\r
136 return EFI_SUCCESS;\r
5c08e117 137}\r
138\r
139/**\r
140 This function processes the results of changes in configuration.\r
141\r
142\r
143 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
144 @param Action Specifies the type of action taken by the browser.\r
145 @param QuestionId A unique value which is sent to the original exporting driver\r
146 so that it can identify the type of data to expect.\r
147 @param Type The type of value for the question.\r
148 @param Value A pointer to the data being sent to the original exporting driver.\r
149 @param ActionRequest On return, points to the action requested by the callback function.\r
150\r
151 @retval EFI_SUCCESS The callback successfully handled the action.\r
152 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
153 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
154 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
155\r
156**/\r
157EFI_STATUS\r
158EFIAPI\r
159FrontPageCallback (\r
160 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
161 IN EFI_BROWSER_ACTION Action,\r
162 IN EFI_QUESTION_ID QuestionId,\r
163 IN UINT8 Type,\r
164 IN EFI_IFR_TYPE_VALUE *Value,\r
165 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
166 )\r
167{\r
168 CHAR8 *LanguageString;\r
169 CHAR8 *LangCode;\r
a3a795af 170 CHAR8 *Lang;\r
5c08e117 171 UINTN Index;\r
172 EFI_STATUS Status;\r
a3a795af 173 CHAR8 *PlatformSupportedLanguages;\r
174 CHAR8 *BestLanguage;\r
5c08e117 175\r
4548fc2a
LG
176 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {\r
177 //\r
178 // Do nothing for UEFI OPEN/CLOSE Action\r
179 //\r
180 return EFI_SUCCESS;\r
181 }\r
182\r
5c08e117 183 if ((Value == NULL) || (ActionRequest == NULL)) {\r
184 return EFI_INVALID_PARAMETER;\r
185 }\r
186\r
187 gCallbackKey = QuestionId;\r
188\r
189 //\r
190 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
191 // describe to their customers in documentation how to find their setup information (namely\r
192 // under the device manager and specific buckets)\r
193 //\r
194 switch (QuestionId) {\r
195 case FRONT_PAGE_KEY_CONTINUE:\r
196 //\r
197 // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
198 //\r
199 break;\r
200\r
201 case FRONT_PAGE_KEY_LANGUAGE:\r
202 //\r
203 // Collect the languages from what our current Language support is based on our VFR\r
204 //\r
cb7d01c0 205 LanguageString = HiiGetSupportedLanguages (gFrontPagePrivate.HiiHandle);\r
5c08e117 206 ASSERT (LanguageString != NULL);\r
a3a795af 207 //\r
208 // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
209 //\r
210 Lang = AllocatePool (AsciiStrSize (LanguageString));\r
211 ASSERT (Lang != NULL);\r
128efbbc 212\r
5c08e117 213 Index = 0;\r
214 LangCode = LanguageString;\r
215 while (*LangCode != 0) {\r
0f268521 216 GetNextLanguage (&LangCode, Lang);\r
5c08e117 217\r
218 if (Index == Value->u8) {\r
219 break;\r
220 }\r
221\r
222 Index++;\r
223 }\r
224\r
a3a795af 225 PlatformSupportedLanguages = GetEfiGlobalVariable (L"PlatformLangCodes");\r
226 if (PlatformSupportedLanguages == NULL) {\r
227 PlatformSupportedLanguages = AllocateCopyPool (\r
228 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
229 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
230 );\r
231 ASSERT (PlatformSupportedLanguages != NULL);\r
232 }\r
128efbbc 233\r
a3a795af 234 //\r
235 // Select the best language in platform supported Language.\r
236 //\r
237 BestLanguage = GetBestLanguage (\r
238 PlatformSupportedLanguages,\r
239 FALSE,\r
240 Lang,\r
241 NULL\r
242 );\r
243 if (BestLanguage != NULL) {\r
244 Status = gRT->SetVariable (\r
245 L"PlatformLang",\r
246 &gEfiGlobalVariableGuid,\r
247 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
248 AsciiStrSize (BestLanguage),\r
249 Lang\r
250 );\r
b96c2106 251 ASSERT_EFI_ERROR(Status);\r
a3a795af 252 FreePool (BestLanguage);\r
d357145f 253 } else {\r
254 ASSERT (FALSE);\r
5c08e117 255 }\r
d357145f 256\r
a3a795af 257 FreePool (PlatformSupportedLanguages);\r
258 FreePool (Lang);\r
5c08e117 259 FreePool (LanguageString);\r
260 break;\r
261\r
262 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
263 //\r
264 // Boot Manager\r
265 //\r
266 break;\r
267\r
268 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
269 //\r
270 // Device Manager\r
271 //\r
272 break;\r
273\r
274 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
275 //\r
276 // Boot Maintenance Manager\r
277 //\r
278 break;\r
279\r
280 default:\r
281 gCallbackKey = 0;\r
282 break;\r
283 }\r
284\r
285 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
286\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290/**\r
291 Initialize HII information for the FrontPage\r
292\r
293\r
294 @param InitializeHiiData TRUE if HII elements need to be initialized.\r
295\r
296 @retval EFI_SUCCESS The operation is successful.\r
297 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.\r
298\r
299**/\r
300EFI_STATUS\r
301InitializeFrontPage (\r
302 IN BOOLEAN InitializeHiiData\r
303 )\r
304{\r
305 EFI_STATUS Status;\r
5c08e117 306 CHAR8 *LanguageString;\r
307 CHAR8 *LangCode;\r
a3a795af 308 CHAR8 *Lang;\r
309 CHAR8 *CurrentLang;\r
310 CHAR8 *BestLanguage;\r
5c08e117 311 UINTN OptionCount;\r
5c08e117 312 CHAR16 *StringBuffer;\r
5c08e117 313 EFI_HII_HANDLE HiiHandle;\r
75bf9d0e
LG
314 VOID *OptionsOpCodeHandle;\r
315 VOID *StartOpCodeHandle;\r
316 VOID *EndOpCodeHandle;\r
317 EFI_IFR_GUID_LABEL *StartLabel;\r
318 EFI_IFR_GUID_LABEL *EndLabel;\r
319 BOOLEAN FirstFlag;\r
5c08e117 320\r
321 if (InitializeHiiData) {\r
322 //\r
323 // Initialize the Device Manager\r
324 //\r
325 InitializeDeviceManager ();\r
326\r
327 //\r
328 // Initialize the Device Manager\r
329 //\r
330 InitializeBootManager ();\r
331\r
332 gCallbackKey = 0;\r
333\r
334 //\r
335 // Locate Hii relative protocols\r
336 //\r
5c08e117 337 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
338 if (EFI_ERROR (Status)) {\r
339 return Status;\r
340 }\r
341\r
5c08e117 342 //\r
f6f910dd 343 // Install Device Path Protocol and Config Access protocol to driver handle\r
5c08e117 344 //\r
f6f910dd 345 Status = gBS->InstallMultipleProtocolInterfaces (\r
5c08e117 346 &gFrontPagePrivate.DriverHandle,\r
f6f910dd 347 &gEfiDevicePathProtocolGuid,\r
348 &mFrontPageHiiVendorDevicePath,\r
5c08e117 349 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 350 &gFrontPagePrivate.ConfigAccess,\r
351 NULL\r
5c08e117 352 );\r
353 ASSERT_EFI_ERROR (Status);\r
354\r
355 //\r
356 // Publish our HII data\r
357 //\r
cb7d01c0 358 gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
359 &mFrontPageGuid,\r
360 gFrontPagePrivate.DriverHandle,\r
361 FrontPageVfrBin,\r
362 BdsDxeStrings,\r
363 NULL\r
364 );\r
365 if (gFrontPagePrivate.HiiHandle == NULL) {\r
366 return EFI_OUT_OF_RESOURCES;\r
5c08e117 367 }\r
368 }\r
369\r
5c08e117 370\r
371 //\r
75bf9d0e 372 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
5c08e117 373 //\r
75bf9d0e
LG
374 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
375 ASSERT (StartOpCodeHandle != NULL);\r
5c08e117 376\r
75bf9d0e
LG
377 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
378 ASSERT (EndOpCodeHandle != NULL);\r
379\r
380 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
381 ASSERT (OptionsOpCodeHandle != NULL);\r
382 //\r
383 // Create Hii Extend Label OpCode as the start opcode\r
384 //\r
385 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
386 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
387 StartLabel->Number = LABEL_SELECT_LANGUAGE;\r
388\r
389 //\r
390 // Create Hii Extend Label OpCode as the end opcode\r
391 //\r
392 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
393 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
394 EndLabel->Number = LABEL_END;\r
5c08e117 395\r
396 //\r
397 // Collect the languages from what our current Language support is based on our VFR\r
398 //\r
399 HiiHandle = gFrontPagePrivate.HiiHandle;\r
cb7d01c0 400 LanguageString = HiiGetSupportedLanguages (HiiHandle);\r
5c08e117 401 ASSERT (LanguageString != NULL);\r
a3a795af 402 //\r
403 // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
404 //\r
405 Lang = AllocatePool (AsciiStrSize (LanguageString));\r
406 ASSERT (Lang != NULL);\r
407\r
408 CurrentLang = GetEfiGlobalVariable (L"PlatformLang");\r
409 //\r
410 // Select the best language in LanguageString as the default one.\r
411 //\r
412 BestLanguage = GetBestLanguage (\r
413 LanguageString,\r
414 FALSE,\r
415 (CurrentLang != NULL) ? CurrentLang : "",\r
416 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
417 LanguageString,\r
418 NULL\r
419 );\r
420 //\r
421 // BestLanguage must be selected as it is the first language in LanguageString by default\r
422 //\r
423 ASSERT (BestLanguage != NULL);\r
5c08e117 424\r
75bf9d0e
LG
425 OptionCount = 0;\r
426 LangCode = LanguageString;\r
427 FirstFlag = FALSE;\r
128efbbc 428\r
75bf9d0e
LG
429 if (gFrontPagePrivate.LanguageToken == NULL) {\r
430 while (*LangCode != 0) {\r
0b3f5a4d 431 GetNextLanguage (&LangCode, Lang);\r
75bf9d0e
LG
432 OptionCount ++;\r
433 }\r
8df1634c 434 gFrontPagePrivate.LanguageToken = AllocatePool (OptionCount * sizeof (EFI_STRING_ID));\r
75bf9d0e
LG
435 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
436 FirstFlag = TRUE;\r
437 }\r
438\r
5c08e117 439 OptionCount = 0;\r
440 LangCode = LanguageString;\r
441 while (*LangCode != 0) {\r
0f268521 442 GetNextLanguage (&LangCode, Lang);\r
5c08e117 443\r
75bf9d0e 444 if (FirstFlag) {\r
33bb6326 445 StringBuffer = HiiGetString (HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, Lang);\r
446 ASSERT_EFI_ERROR (StringBuffer != NULL);\r
5c08e117 447\r
75bf9d0e
LG
448 //\r
449 // Save the string Id for each language\r
450 //\r
451 gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
5c08e117 452 FreePool (StringBuffer);\r
5c08e117 453 }\r
454\r
a3a795af 455 if (AsciiStrCmp (Lang, BestLanguage) == 0) {\r
75bf9d0e
LG
456 HiiCreateOneOfOptionOpCode (\r
457 OptionsOpCodeHandle,\r
458 gFrontPagePrivate.LanguageToken[OptionCount],\r
459 EFI_IFR_OPTION_DEFAULT,\r
460 EFI_IFR_NUMERIC_SIZE_1,\r
461 (UINT8) OptionCount\r
462 );\r
5c08e117 463 } else {\r
75bf9d0e
LG
464 HiiCreateOneOfOptionOpCode (\r
465 OptionsOpCodeHandle,\r
466 gFrontPagePrivate.LanguageToken[OptionCount],\r
467 0,\r
468 EFI_IFR_NUMERIC_SIZE_1,\r
469 (UINT8) OptionCount\r
470 );\r
5c08e117 471 }\r
5c08e117 472\r
473 OptionCount++;\r
474 }\r
475\r
a3a795af 476 if (CurrentLang != NULL) {\r
477 FreePool (CurrentLang);\r
478 }\r
479 FreePool (BestLanguage);\r
480 FreePool (Lang);\r
5c08e117 481 FreePool (LanguageString);\r
482\r
75bf9d0e
LG
483 HiiCreateOneOfOpCode (\r
484 StartOpCodeHandle,\r
5c08e117 485 FRONT_PAGE_KEY_LANGUAGE,\r
486 0,\r
487 0,\r
488 STRING_TOKEN (STR_LANGUAGE_SELECT),\r
489 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
490 EFI_IFR_FLAG_CALLBACK,\r
491 EFI_IFR_NUMERIC_SIZE_1,\r
75bf9d0e
LG
492 OptionsOpCodeHandle,\r
493 NULL\r
5c08e117 494 );\r
495\r
75bf9d0e 496 Status = HiiUpdateForm (\r
5c08e117 497 HiiHandle,\r
498 &mFrontPageGuid,\r
499 FRONT_PAGE_FORM_ID,\r
75bf9d0e
LG
500 StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
501 EndOpCodeHandle // LABEL_END\r
5c08e117 502 );\r
503\r
75bf9d0e
LG
504 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
505 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
506 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
5c08e117 507 return Status;\r
508}\r
509\r
510/**\r
511 Call the browser and display the front page\r
512\r
513 @return Status code that will be returned by\r
514 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().\r
515\r
516**/\r
517EFI_STATUS\r
518CallFrontPage (\r
519 VOID\r
520 )\r
521{\r
522 EFI_STATUS Status;\r
523 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
524\r
525 //\r
526 // Begin waiting for USER INPUT\r
527 //\r
528 REPORT_STATUS_CODE (\r
529 EFI_PROGRESS_CODE,\r
530 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
531 );\r
532\r
533 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
534 Status = gFormBrowser2->SendForm (\r
535 gFormBrowser2,\r
536 &gFrontPagePrivate.HiiHandle,\r
537 1,\r
f0da9ffb 538 &mFrontPageGuid,\r
5c08e117 539 0,\r
540 NULL,\r
541 &ActionRequest\r
542 );\r
543 //\r
baf46e70 544 // Check whether user change any option setting which needs a reset to be effective\r
5c08e117 545 //\r
546 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
547 EnableResetRequired ();\r
548 }\r
549\r
550 return Status;\r
551}\r
552\r
553/**\r
554 Acquire the string associated with the ProducerGuid and return it.\r
555\r
556\r
557 @param ProducerGuid The Guid to search the HII database for\r
558 @param Token The token value of the string to extract\r
559 @param String The string that is extracted\r
560\r
561 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.\r
562\r
563**/\r
564EFI_STATUS\r
565GetProducerString (\r
566 IN EFI_GUID *ProducerGuid,\r
567 IN EFI_STRING_ID Token,\r
568 OUT CHAR16 **String\r
569 )\r
570{\r
cb7d01c0 571 EFI_STRING TmpString;\r
5c08e117 572\r
cb7d01c0 573 TmpString = HiiGetPackageString (ProducerGuid, Token, NULL);\r
574 if (TmpString == NULL) {\r
5c08e117 575 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
cb7d01c0 576 } else {\r
577 *String = TmpString;\r
5c08e117 578 }\r
579\r
580 return EFI_SUCCESS;\r
581}\r
582\r
583/**\r
13078b3f 584 Convert Processor Frequency Data to a string.\r
5c08e117 585\r
586 @param ProcessorFrequency The frequency data to process\r
6cfbf7ad 587 @param Base10Exponent The exponent based on 10\r
5c08e117 588 @param String The string that is created\r
589\r
590**/\r
591VOID\r
592ConvertProcessorToString (\r
6cfbf7ad 593 IN UINT16 ProcessorFrequency,\r
594 IN UINT16 Base10Exponent,\r
595 OUT CHAR16 **String\r
5c08e117 596 )\r
597{\r
598 CHAR16 *StringBuffer;\r
599 UINTN Index;\r
600 UINT32 FreqMhz;\r
601\r
6cfbf7ad 602 if (Base10Exponent >= 6) {\r
603 FreqMhz = ProcessorFrequency;\r
604 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) {\r
5c08e117 605 FreqMhz *= 10;\r
606 }\r
607 } else {\r
608 FreqMhz = 0;\r
609 }\r
610\r
611 StringBuffer = AllocateZeroPool (0x20);\r
612 ASSERT (StringBuffer != NULL);\r
613 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
614 StrCat (StringBuffer, L".");\r
615 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
616 StrCat (StringBuffer, L" GHz");\r
5c08e117 617 *String = (CHAR16 *) StringBuffer;\r
5c08e117 618 return ;\r
619}\r
620\r
6cfbf7ad 621\r
5c08e117 622/**\r
623 Convert Memory Size to a string.\r
624\r
625 @param MemorySize The size of the memory to process\r
626 @param String The string that is created\r
627\r
628**/\r
629VOID\r
630ConvertMemorySizeToString (\r
631 IN UINT32 MemorySize,\r
632 OUT CHAR16 **String\r
633 )\r
634{\r
635 CHAR16 *StringBuffer;\r
636\r
637 StringBuffer = AllocateZeroPool (0x20);\r
638 ASSERT (StringBuffer != NULL);\r
639 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);\r
640 StrCat (StringBuffer, L" MB RAM");\r
641\r
642 *String = (CHAR16 *) StringBuffer;\r
643\r
644 return ;\r
645}\r
646\r
6cfbf7ad 647/**\r
648\r
649 Acquire the string associated with the Index from smbios structure and return it.\r
650 The caller is responsible for free the string buffer.\r
651\r
652 @param OptionalStrStart The start position to search the string\r
653 @param Index The index of the string to extract\r
654 @param String The string that is extracted\r
655\r
656 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.\r
657\r
658**/\r
659EFI_STATUS\r
660GetOptionalStringByIndex (\r
661 IN CHAR8 *OptionalStrStart,\r
662 IN UINT8 Index,\r
663 OUT CHAR16 **String\r
664 )\r
665{\r
666 UINT8 StrNum;\r
667 UINTN CurrentStrLen;\r
668 CHAR8* CharInStr;\r
669 EFI_STATUS Status;\r
670\r
671 StrNum = 0;\r
672 Status = EFI_NOT_FOUND;\r
673 CharInStr = OptionalStrStart;\r
674\r
675 if (Index != 1) {\r
676 CurrentStrLen = 0;\r
677 //\r
678 // look for the two consecutive zeros, check the string limit by the way.\r
679 //\r
680 while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
681 if (*CharInStr == 0) {\r
682 StrNum += 1;\r
683 CharInStr++;\r
684 }\r
685 \r
686 if (StrNum == Index) {\r
687 Status = EFI_SUCCESS;\r
688 break;\r
689 }\r
690 \r
691 CurrentStrLen = AsciiStrLen(CharInStr);\r
692 \r
693 //\r
694 // forward the pointer\r
695 //\r
696 OptionalStrStart = CharInStr;\r
697 CharInStr += CurrentStrLen;\r
698 }\r
699 \r
700 if (EFI_ERROR (Status)) {\r
701 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
702 return Status;\r
703 }\r
704 } else {\r
705 CurrentStrLen = AsciiStrLen(CharInStr);\r
706 }\r
707\r
708 *String = AllocatePool((CurrentStrLen + 1)*sizeof(CHAR16));\r
709 AsciiStrToUnicodeStr(OptionalStrStart, *String);\r
710\r
711 return EFI_SUCCESS;\r
712}\r
713\r
714\r
5c08e117 715/**\r
716 Update the banner information for the Front Page based on DataHub information.\r
717\r
718**/\r
719VOID\r
720UpdateFrontPageStrings (\r
721 VOID\r
722 )\r
723{\r
6cfbf7ad 724 UINT8 StrIndex;\r
5c08e117 725 CHAR16 *NewString;\r
5c08e117 726 BOOLEAN Find[5];\r
6cfbf7ad 727 EFI_STATUS Status;\r
728 EFI_STRING_ID TokenToUpdate;\r
729 EFI_SMBIOS_HANDLE SmbiosHandle;\r
730 EFI_SMBIOS_PROTOCOL *Smbios;\r
731 SMBIOS_TABLE_TYPE0 *Type0Record;\r
732 SMBIOS_TABLE_TYPE1 *Type1Record;\r
733 SMBIOS_TABLE_TYPE4 *Type4Record;\r
734 SMBIOS_TABLE_TYPE19 *Type19Record;\r
735 EFI_SMBIOS_TABLE_HEADER *Record;\r
5c08e117 736\r
737 ZeroMem (Find, sizeof (Find));\r
738\r
739 //\r
740 // Update Front Page strings\r
741 //\r
742 Status = gBS->LocateProtocol (\r
6cfbf7ad 743 &gEfiSmbiosProtocolGuid,\r
5c08e117 744 NULL,\r
6cfbf7ad 745 (VOID **) &Smbios\r
5c08e117 746 );\r
747 ASSERT_EFI_ERROR (Status);\r
748\r
6cfbf7ad 749 SmbiosHandle = 0;\r
5c08e117 750 do {\r
6cfbf7ad 751 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
752 if (EFI_ERROR(Status)) {\r
b55f8b01
LG
753 break;\r
754 }\r
5c08e117 755\r
6cfbf7ad 756 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {\r
757 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
758 StrIndex = Type0Record->BiosVersion;\r
ed79462b 759 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
6cfbf7ad 760 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
761 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
762 FreePool (NewString);\r
763 Find[0] = TRUE;\r
764 } \r
765\r
766 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
767 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
768 StrIndex = Type1Record->ProductName;\r
ed79462b 769 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
6cfbf7ad 770 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
771 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
772 FreePool (NewString);\r
773 Find[1] = TRUE;\r
5c08e117 774 }\r
6cfbf7ad 775 \r
776 if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
777 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
778 StrIndex = Type4Record->ProcessorVersion;\r
ed79462b 779 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
6cfbf7ad 780 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
781 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
782 FreePool (NewString);\r
783 Find[2] = TRUE;\r
784 } \r
785\r
786 if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
787 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
788 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
789 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
790 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
791 FreePool (NewString);\r
792 Find[3] = TRUE;\r
793 } \r
794\r
795 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
796 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
797 ConvertMemorySizeToString (\r
798 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),\r
799 &NewString\r
800 );\r
801 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
802 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
803 FreePool (NewString);\r
804 Find[4] = TRUE; \r
805 }\r
806 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
5c08e117 807 return ;\r
808}\r
809\r
6cfbf7ad 810\r
5c08e117 811/**\r
812 Function waits for a given event to fire, or for an optional timeout to expire.\r
813\r
6cfbf7ad 814 @param Event The event to wait for\r
815 @param Timeout An optional timeout value in 100 ns units.\r
5c08e117 816\r
817 @retval EFI_SUCCESS Event fired before Timeout expired.\r
818 @retval EFI_TIME_OUT Timout expired before Event fired..\r
819\r
820**/\r
821EFI_STATUS\r
822WaitForSingleEvent (\r
823 IN EFI_EVENT Event,\r
824 IN UINT64 Timeout OPTIONAL\r
825 )\r
826{\r
5c08e117 827 UINTN Index;\r
6cfbf7ad 828 EFI_STATUS Status;\r
5c08e117 829 EFI_EVENT TimerEvent;\r
830 EFI_EVENT WaitList[2];\r
831\r
832 if (Timeout != 0) {\r
833 //\r
834 // Create a timer event\r
835 //\r
836 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
837 if (!EFI_ERROR (Status)) {\r
838 //\r
839 // Set the timer event\r
840 //\r
841 gBS->SetTimer (\r
6cfbf7ad 842 TimerEvent,\r
843 TimerRelative,\r
844 Timeout\r
845 );\r
5c08e117 846\r
847 //\r
848 // Wait for the original event or the timer\r
849 //\r
850 WaitList[0] = Event;\r
851 WaitList[1] = TimerEvent;\r
852 Status = gBS->WaitForEvent (2, WaitList, &Index);\r
853 gBS->CloseEvent (TimerEvent);\r
854\r
855 //\r
856 // If the timer expired, change the return to timed out\r
857 //\r
858 if (!EFI_ERROR (Status) && Index == 1) {\r
859 Status = EFI_TIMEOUT;\r
860 }\r
861 }\r
862 } else {\r
863 //\r
864 // No timeout... just wait on the event\r
865 //\r
866 Status = gBS->WaitForEvent (1, &Event, &Index);\r
867 ASSERT (!EFI_ERROR (Status));\r
868 ASSERT (Index == 0);\r
869 }\r
870\r
871 return Status;\r
872}\r
873\r
874/**\r
875 Function show progress bar to wait for user input.\r
876\r
877\r
6cfbf7ad 878 @param TimeoutDefault The fault time out value before the system continue to boot.\r
5c08e117 879\r
880 @retval EFI_SUCCESS User pressed some key except "Enter"\r
baf46e70 881 @retval EFI_TIME_OUT Timeout expired or user press "Enter"\r
5c08e117 882\r
883**/\r
884EFI_STATUS\r
885ShowProgress (\r
886 IN UINT16 TimeoutDefault\r
887 )\r
888{\r
5c08e117 889 CHAR16 *TmpStr;\r
6cfbf7ad 890 UINT16 TimeoutRemain;\r
891 EFI_STATUS Status;\r
892 EFI_INPUT_KEY Key;\r
5c08e117 893 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
894 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
895 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
5c08e117 896\r
897 if (TimeoutDefault == 0) {\r
898 return EFI_TIMEOUT;\r
899 }\r
900\r
901 DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
128efbbc 902\r
5c08e117 903 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
904 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
905 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
906\r
907 //\r
908 // Clear the progress status bar first\r
909 //\r
910 TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
911 if (TmpStr != NULL) {\r
912 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
913 }\r
914\r
915 TimeoutRemain = TimeoutDefault;\r
916 while (TimeoutRemain != 0) {\r
917 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
128efbbc 918\r
5c08e117 919 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
920 if (Status != EFI_TIMEOUT) {\r
921 break;\r
922 }\r
923 TimeoutRemain--;\r
924\r
925 //\r
926 // Show progress\r
927 //\r
928 if (TmpStr != NULL) {\r
929 PlatformBdsShowProgress (\r
930 Foreground,\r
931 Background,\r
932 TmpStr,\r
933 Color,\r
934 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
935 0\r
936 );\r
937 }\r
938 }\r
939 gBS->FreePool (TmpStr);\r
940\r
941 //\r
942 // Timeout expired\r
943 //\r
944 if (TimeoutRemain == 0) {\r
945 return EFI_TIMEOUT;\r
946 }\r
947\r
948 //\r
949 // User pressed some key\r
950 //\r
951 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
952 if (EFI_ERROR (Status)) {\r
953 return Status;\r
954 }\r
955\r
956 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
957 //\r
958 // User pressed enter, equivalent to select "continue"\r
959 //\r
960 return EFI_TIMEOUT;\r
961 }\r
962\r
963 return EFI_SUCCESS;\r
964}\r
965\r
966/**\r
967 This function is the main entry of the platform setup entry.\r
968 The function will present the main menu of the system setup,\r
969 this is the platform reference part and can be customize.\r
970\r
971\r
972 @param TimeoutDefault The fault time out value before the system\r
973 continue to boot.\r
974 @param ConnectAllHappened The indicater to check if the connect all have\r
baf46e70 975 already happened.\r
5c08e117 976\r
977**/\r
978VOID\r
979PlatformBdsEnterFrontPage (\r
980 IN UINT16 TimeoutDefault,\r
981 IN BOOLEAN ConnectAllHappened\r
982 )\r
983{\r
984 EFI_STATUS Status;\r
5c08e117 985\r
128efbbc 986 PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
5c08e117 987 //\r
988 // Indicate if we need connect all in the platform setup\r
989 //\r
990 if (ConnectAllHappened) {\r
991 gConnectAllHappened = TRUE;\r
992 }\r
993\r
994 if (TimeoutDefault != 0xffff) {\r
995 Status = ShowProgress (TimeoutDefault);\r
996\r
997 //\r
998 // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
999 //\r
1000 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1001 gST->ConOut->ClearScreen (gST->ConOut);\r
1002\r
1003 if (EFI_ERROR (Status)) {\r
1004 //\r
1005 // Timeout or user press enter to continue\r
1006 //\r
1007 goto Exit;\r
1008 }\r
1009 }\r
1010\r
1011 do {\r
1012\r
1013 InitializeFrontPage (FALSE);\r
1014\r
1015 //\r
1016 // Update Front Page strings\r
1017 //\r
1018 UpdateFrontPageStrings ();\r
1019\r
1020 gCallbackKey = 0;\r
1021 Status = CallFrontPage ();\r
1022\r
1023 //\r
1024 // If gCallbackKey is greater than 1 and less or equal to 5,\r
baf46e70 1025 // it will launch configuration utilities.\r
5c08e117 1026 // 2 = set language\r
1027 // 3 = boot manager\r
1028 // 4 = device manager\r
baf46e70 1029 // 5 = boot maintenance manager\r
5c08e117 1030 //\r
1031 if (gCallbackKey != 0) {\r
1032 REPORT_STATUS_CODE (\r
1033 EFI_PROGRESS_CODE,\r
1034 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
1035 );\r
1036 }\r
1037 //\r
1038 // Based on the key that was set, we can determine what to do\r
1039 //\r
1040 switch (gCallbackKey) {\r
1041 //\r
1042 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
1043 // describe to their customers in documentation how to find their setup information (namely\r
1044 // under the device manager and specific buckets)\r
1045 //\r
1046 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
1047 //\r
1048 case FRONT_PAGE_KEY_CONTINUE:\r
1049 //\r
1050 // User hit continue\r
1051 //\r
1052 break;\r
1053\r
1054 case FRONT_PAGE_KEY_LANGUAGE:\r
1055 //\r
1056 // User made a language setting change - display front page again\r
1057 //\r
1058 break;\r
1059\r
1060 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
1061 //\r
1062 // User chose to run the Boot Manager\r
1063 //\r
bd2057a8 1064 CallBootManager ();\r
5c08e117 1065 break;\r
1066\r
1067 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
1068 //\r
1069 // Display the Device Manager\r
1070 //\r
1071 do {\r
bd2057a8 1072 CallDeviceManager ();\r
5c08e117 1073 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
1074 break;\r
1075\r
1076 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
1077 //\r
1078 // Display the Boot Maintenance Manager\r
1079 //\r
1080 BdsStartBootMaint ();\r
1081 break;\r
1082 }\r
1083\r
1084 } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));\r
1085\r
1086 //\r
1087 //Will leave browser, check any reset required change is applied? if yes, reset system\r
1088 //\r
1089 SetupResetReminder ();\r
1090\r
1091Exit:\r
1092 //\r
1093 // Automatically load current entry\r
1094 // Note: The following lines of code only execute when Auto boot\r
1095 // takes affect\r
1096 //\r
128efbbc 1097 PERF_END (NULL, "BdsTimeOut", "BDS", 0);\r
5c08e117 1098}\r