]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
Fixed update file time error problem.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / FrontPage.c
... / ...
CommitLineData
1/** @file\r
2 FrontPage routines to handle the callbacks and browser calls\r
3\r
4Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
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 "Bds.h"\r
16#include "FrontPage.h"\r
17#include "Language.h"\r
18\r
19EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;\r
20\r
21BOOLEAN gConnectAllHappened = FALSE;\r
22UINTN gCallbackKey;\r
23\r
24EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
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
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
56 {\r
57 (UINT8) (END_DEVICE_PATH_LENGTH),\r
58 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
59 }\r
60 }\r
61};\r
62\r
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
81 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
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
94 if (Progress == NULL || Results == NULL) {\r
95 return EFI_INVALID_PARAMETER;\r
96 }\r
97 *Progress = Request;\r
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
125 if (Configuration == NULL || Progress == NULL) {\r
126 return EFI_INVALID_PARAMETER;\r
127 }\r
128\r
129 *Progress = Configuration;\r
130 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)\r
131 && !HiiIsConfigHdrMatch (Configuration, &mFileExplorerGuid, mFileExplorerStorageName)) {\r
132 return EFI_NOT_FOUND;\r
133 }\r
134\r
135 *Progress = Configuration + StrLen (Configuration);\r
136 return EFI_SUCCESS;\r
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
170 CHAR8 *Lang;\r
171 UINTN Index;\r
172 EFI_STATUS Status;\r
173 CHAR8 *PlatformSupportedLanguages;\r
174 CHAR8 *BestLanguage;\r
175\r
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
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
205 LanguageString = HiiGetSupportedLanguages (gFrontPagePrivate.HiiHandle);\r
206 ASSERT (LanguageString != NULL);\r
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
212\r
213 Index = 0;\r
214 LangCode = LanguageString;\r
215 while (*LangCode != 0) {\r
216 GetNextLanguage (&LangCode, Lang);\r
217\r
218 if (Index == Value->u8) {\r
219 break;\r
220 }\r
221\r
222 Index++;\r
223 }\r
224\r
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
233\r
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
251 ASSERT_EFI_ERROR(Status);\r
252 FreePool (BestLanguage);\r
253 } else {\r
254 ASSERT (FALSE);\r
255 }\r
256\r
257 FreePool (PlatformSupportedLanguages);\r
258 FreePool (Lang);\r
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
306 CHAR8 *LanguageString;\r
307 CHAR8 *LangCode;\r
308 CHAR8 *Lang;\r
309 CHAR8 *CurrentLang;\r
310 CHAR8 *BestLanguage;\r
311 UINTN OptionCount;\r
312 CHAR16 *StringBuffer;\r
313 EFI_HII_HANDLE HiiHandle;\r
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
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
337 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
338 if (EFI_ERROR (Status)) {\r
339 return Status;\r
340 }\r
341\r
342 //\r
343 // Install Device Path Protocol and Config Access protocol to driver handle\r
344 //\r
345 Status = gBS->InstallMultipleProtocolInterfaces (\r
346 &gFrontPagePrivate.DriverHandle,\r
347 &gEfiDevicePathProtocolGuid,\r
348 &mFrontPageHiiVendorDevicePath,\r
349 &gEfiHiiConfigAccessProtocolGuid,\r
350 &gFrontPagePrivate.ConfigAccess,\r
351 NULL\r
352 );\r
353 ASSERT_EFI_ERROR (Status);\r
354\r
355 //\r
356 // Publish our HII data\r
357 //\r
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
367 }\r
368 }\r
369\r
370\r
371 //\r
372 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
373 //\r
374 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
375 ASSERT (StartOpCodeHandle != NULL);\r
376\r
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
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
400 LanguageString = HiiGetSupportedLanguages (HiiHandle);\r
401 ASSERT (LanguageString != NULL);\r
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
424\r
425 OptionCount = 0;\r
426 LangCode = LanguageString;\r
427 FirstFlag = FALSE;\r
428\r
429 if (gFrontPagePrivate.LanguageToken == NULL) {\r
430 while (*LangCode != 0) {\r
431 GetNextLanguage (&LangCode, Lang);\r
432 OptionCount ++;\r
433 }\r
434 gFrontPagePrivate.LanguageToken = AllocatePool (OptionCount * sizeof (EFI_STRING_ID));\r
435 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
436 FirstFlag = TRUE;\r
437 }\r
438\r
439 OptionCount = 0;\r
440 LangCode = LanguageString;\r
441 while (*LangCode != 0) {\r
442 GetNextLanguage (&LangCode, Lang);\r
443\r
444 if (FirstFlag) {\r
445 StringBuffer = HiiGetString (HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, Lang);\r
446 ASSERT (StringBuffer != NULL);\r
447\r
448 //\r
449 // Save the string Id for each language\r
450 //\r
451 gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
452 FreePool (StringBuffer);\r
453 }\r
454\r
455 if (AsciiStrCmp (Lang, BestLanguage) == 0) {\r
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
463 } else {\r
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
471 }\r
472\r
473 OptionCount++;\r
474 }\r
475\r
476 if (CurrentLang != NULL) {\r
477 FreePool (CurrentLang);\r
478 }\r
479 FreePool (BestLanguage);\r
480 FreePool (Lang);\r
481 FreePool (LanguageString);\r
482\r
483 HiiCreateOneOfOpCode (\r
484 StartOpCodeHandle,\r
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
492 OptionsOpCodeHandle,\r
493 NULL\r
494 );\r
495\r
496 Status = HiiUpdateForm (\r
497 HiiHandle,\r
498 &mFrontPageGuid,\r
499 FRONT_PAGE_FORM_ID,\r
500 StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
501 EndOpCodeHandle // LABEL_END\r
502 );\r
503\r
504 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
505 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
506 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
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
538 &mFrontPageGuid,\r
539 0,\r
540 NULL,\r
541 &ActionRequest\r
542 );\r
543 //\r
544 // Check whether user change any option setting which needs a reset to be effective\r
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
571 EFI_STRING TmpString;\r
572\r
573 TmpString = HiiGetPackageString (ProducerGuid, Token, NULL);\r
574 if (TmpString == NULL) {\r
575 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
576 } else {\r
577 *String = TmpString;\r
578 }\r
579\r
580 return EFI_SUCCESS;\r
581}\r
582\r
583/**\r
584 Convert Processor Frequency Data to a string.\r
585\r
586 @param ProcessorFrequency The frequency data to process\r
587 @param Base10Exponent The exponent based on 10\r
588 @param String The string that is created\r
589\r
590**/\r
591VOID\r
592ConvertProcessorToString (\r
593 IN UINT16 ProcessorFrequency,\r
594 IN UINT16 Base10Exponent,\r
595 OUT CHAR16 **String\r
596 )\r
597{\r
598 CHAR16 *StringBuffer;\r
599 UINTN Index;\r
600 UINT32 FreqMhz;\r
601\r
602 if (Base10Exponent >= 6) {\r
603 FreqMhz = ProcessorFrequency;\r
604 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) {\r
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
617 *String = (CHAR16 *) StringBuffer;\r
618 return ;\r
619}\r
620\r
621\r
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
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 UINTN StrSize;\r
667\r
668 if (Index == 0) {\r
669 *String = AllocateZeroPool (sizeof (CHAR16));\r
670 return EFI_SUCCESS;\r
671 }\r
672\r
673 StrSize = 0;\r
674 do {\r
675 Index--;\r
676 OptionalStrStart += StrSize;\r
677 StrSize = AsciiStrSize (OptionalStrStart);\r
678 } while (OptionalStrStart[StrSize] != 0 && Index != 0);\r
679\r
680 if (Index != 0) {\r
681 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
682 } else {\r
683 *String = AllocatePool (StrSize * sizeof (CHAR16));\r
684 AsciiStrToUnicodeStr (OptionalStrStart, *String);\r
685 }\r
686\r
687 return EFI_SUCCESS;\r
688}\r
689\r
690\r
691/**\r
692 Update the banner information for the Front Page based on DataHub information.\r
693\r
694**/\r
695VOID\r
696UpdateFrontPageStrings (\r
697 VOID\r
698 )\r
699{\r
700 UINT8 StrIndex;\r
701 CHAR16 *NewString;\r
702 BOOLEAN Find[5];\r
703 EFI_STATUS Status;\r
704 EFI_STRING_ID TokenToUpdate;\r
705 EFI_SMBIOS_HANDLE SmbiosHandle;\r
706 EFI_SMBIOS_PROTOCOL *Smbios;\r
707 SMBIOS_TABLE_TYPE0 *Type0Record;\r
708 SMBIOS_TABLE_TYPE1 *Type1Record;\r
709 SMBIOS_TABLE_TYPE4 *Type4Record;\r
710 SMBIOS_TABLE_TYPE19 *Type19Record;\r
711 EFI_SMBIOS_TABLE_HEADER *Record;\r
712\r
713 ZeroMem (Find, sizeof (Find));\r
714\r
715 //\r
716 // Update Front Page strings\r
717 //\r
718 Status = gBS->LocateProtocol (\r
719 &gEfiSmbiosProtocolGuid,\r
720 NULL,\r
721 (VOID **) &Smbios\r
722 );\r
723 ASSERT_EFI_ERROR (Status);\r
724\r
725 SmbiosHandle = 0;\r
726 do {\r
727 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
728 if (EFI_ERROR(Status)) {\r
729 break;\r
730 }\r
731\r
732 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {\r
733 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
734 StrIndex = Type0Record->BiosVersion;\r
735 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
736 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
737 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
738 FreePool (NewString);\r
739 Find[0] = TRUE;\r
740 } \r
741\r
742 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
743 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
744 StrIndex = Type1Record->ProductName;\r
745 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
746 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
747 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
748 FreePool (NewString);\r
749 Find[1] = TRUE;\r
750 }\r
751 \r
752 if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
753 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
754 StrIndex = Type4Record->ProcessorVersion;\r
755 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
756 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
757 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
758 FreePool (NewString);\r
759 Find[2] = TRUE;\r
760 } \r
761\r
762 if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
763 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
764 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
765 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
766 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
767 FreePool (NewString);\r
768 Find[3] = TRUE;\r
769 } \r
770\r
771 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
772 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
773 ConvertMemorySizeToString (\r
774 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),\r
775 &NewString\r
776 );\r
777 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
778 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
779 FreePool (NewString);\r
780 Find[4] = TRUE; \r
781 }\r
782 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
783 return ;\r
784}\r
785\r
786\r
787/**\r
788 Function waits for a given event to fire, or for an optional timeout to expire.\r
789\r
790 @param Event The event to wait for\r
791 @param Timeout An optional timeout value in 100 ns units.\r
792\r
793 @retval EFI_SUCCESS Event fired before Timeout expired.\r
794 @retval EFI_TIME_OUT Timout expired before Event fired..\r
795\r
796**/\r
797EFI_STATUS\r
798WaitForSingleEvent (\r
799 IN EFI_EVENT Event,\r
800 IN UINT64 Timeout OPTIONAL\r
801 )\r
802{\r
803 UINTN Index;\r
804 EFI_STATUS Status;\r
805 EFI_EVENT TimerEvent;\r
806 EFI_EVENT WaitList[2];\r
807\r
808 if (Timeout != 0) {\r
809 //\r
810 // Create a timer event\r
811 //\r
812 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
813 if (!EFI_ERROR (Status)) {\r
814 //\r
815 // Set the timer event\r
816 //\r
817 gBS->SetTimer (\r
818 TimerEvent,\r
819 TimerRelative,\r
820 Timeout\r
821 );\r
822\r
823 //\r
824 // Wait for the original event or the timer\r
825 //\r
826 WaitList[0] = Event;\r
827 WaitList[1] = TimerEvent;\r
828 Status = gBS->WaitForEvent (2, WaitList, &Index);\r
829 gBS->CloseEvent (TimerEvent);\r
830\r
831 //\r
832 // If the timer expired, change the return to timed out\r
833 //\r
834 if (!EFI_ERROR (Status) && Index == 1) {\r
835 Status = EFI_TIMEOUT;\r
836 }\r
837 }\r
838 } else {\r
839 //\r
840 // No timeout... just wait on the event\r
841 //\r
842 Status = gBS->WaitForEvent (1, &Event, &Index);\r
843 ASSERT (!EFI_ERROR (Status));\r
844 ASSERT (Index == 0);\r
845 }\r
846\r
847 return Status;\r
848}\r
849\r
850/**\r
851 Function show progress bar to wait for user input.\r
852\r
853\r
854 @param TimeoutDefault The fault time out value before the system continue to boot.\r
855\r
856 @retval EFI_SUCCESS User pressed some key except "Enter"\r
857 @retval EFI_TIME_OUT Timeout expired or user press "Enter"\r
858\r
859**/\r
860EFI_STATUS\r
861ShowProgress (\r
862 IN UINT16 TimeoutDefault\r
863 )\r
864{\r
865 CHAR16 *TmpStr;\r
866 UINT16 TimeoutRemain;\r
867 EFI_STATUS Status;\r
868 EFI_INPUT_KEY Key;\r
869 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
870 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
871 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
872\r
873 if (TimeoutDefault == 0) {\r
874 return EFI_TIMEOUT;\r
875 }\r
876\r
877 DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
878\r
879 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
880 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
881 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
882\r
883 //\r
884 // Clear the progress status bar first\r
885 //\r
886 TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
887 if (TmpStr != NULL) {\r
888 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
889 }\r
890\r
891 TimeoutRemain = TimeoutDefault;\r
892 while (TimeoutRemain != 0) {\r
893 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
894\r
895 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
896 if (Status != EFI_TIMEOUT) {\r
897 break;\r
898 }\r
899 TimeoutRemain--;\r
900\r
901 //\r
902 // Show progress\r
903 //\r
904 if (TmpStr != NULL) {\r
905 PlatformBdsShowProgress (\r
906 Foreground,\r
907 Background,\r
908 TmpStr,\r
909 Color,\r
910 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
911 0\r
912 );\r
913 }\r
914 }\r
915 gBS->FreePool (TmpStr);\r
916\r
917 //\r
918 // Timeout expired\r
919 //\r
920 if (TimeoutRemain == 0) {\r
921 return EFI_TIMEOUT;\r
922 }\r
923\r
924 //\r
925 // User pressed some key\r
926 //\r
927 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
928 if (EFI_ERROR (Status)) {\r
929 return Status;\r
930 }\r
931\r
932 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
933 //\r
934 // User pressed enter, equivalent to select "continue"\r
935 //\r
936 return EFI_TIMEOUT;\r
937 }\r
938\r
939 return EFI_SUCCESS;\r
940}\r
941\r
942/**\r
943 This function is the main entry of the platform setup entry.\r
944 The function will present the main menu of the system setup,\r
945 this is the platform reference part and can be customize.\r
946\r
947\r
948 @param TimeoutDefault The fault time out value before the system\r
949 continue to boot.\r
950 @param ConnectAllHappened The indicater to check if the connect all have\r
951 already happened.\r
952\r
953**/\r
954VOID\r
955PlatformBdsEnterFrontPage (\r
956 IN UINT16 TimeoutDefault,\r
957 IN BOOLEAN ConnectAllHappened\r
958 )\r
959{\r
960 EFI_STATUS Status;\r
961\r
962 PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
963 //\r
964 // Indicate if we need connect all in the platform setup\r
965 //\r
966 if (ConnectAllHappened) {\r
967 gConnectAllHappened = TRUE;\r
968 }\r
969\r
970 if (TimeoutDefault != 0xffff) {\r
971 Status = ShowProgress (TimeoutDefault);\r
972\r
973 //\r
974 // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
975 //\r
976 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
977 gST->ConOut->ClearScreen (gST->ConOut);\r
978\r
979 if (EFI_ERROR (Status)) {\r
980 //\r
981 // Timeout or user press enter to continue\r
982 //\r
983 goto Exit;\r
984 }\r
985 }\r
986\r
987 do {\r
988\r
989 InitializeFrontPage (FALSE);\r
990\r
991 //\r
992 // Update Front Page strings\r
993 //\r
994 UpdateFrontPageStrings ();\r
995\r
996 gCallbackKey = 0;\r
997 Status = CallFrontPage ();\r
998\r
999 //\r
1000 // If gCallbackKey is greater than 1 and less or equal to 5,\r
1001 // it will launch configuration utilities.\r
1002 // 2 = set language\r
1003 // 3 = boot manager\r
1004 // 4 = device manager\r
1005 // 5 = boot maintenance manager\r
1006 //\r
1007 if (gCallbackKey != 0) {\r
1008 REPORT_STATUS_CODE (\r
1009 EFI_PROGRESS_CODE,\r
1010 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
1011 );\r
1012 }\r
1013 //\r
1014 // Based on the key that was set, we can determine what to do\r
1015 //\r
1016 switch (gCallbackKey) {\r
1017 //\r
1018 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
1019 // describe to their customers in documentation how to find their setup information (namely\r
1020 // under the device manager and specific buckets)\r
1021 //\r
1022 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
1023 //\r
1024 case FRONT_PAGE_KEY_CONTINUE:\r
1025 //\r
1026 // User hit continue\r
1027 //\r
1028 break;\r
1029\r
1030 case FRONT_PAGE_KEY_LANGUAGE:\r
1031 //\r
1032 // User made a language setting change - display front page again\r
1033 //\r
1034 break;\r
1035\r
1036 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
1037 //\r
1038 // User chose to run the Boot Manager\r
1039 //\r
1040 CallBootManager ();\r
1041 break;\r
1042\r
1043 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
1044 //\r
1045 // Display the Device Manager\r
1046 //\r
1047 do {\r
1048 CallDeviceManager ();\r
1049 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
1050 break;\r
1051\r
1052 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
1053 //\r
1054 // Display the Boot Maintenance Manager\r
1055 //\r
1056 BdsStartBootMaint ();\r
1057 break;\r
1058 }\r
1059\r
1060 } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));\r
1061\r
1062 //\r
1063 //Will leave browser, check any reset required change is applied? if yes, reset system\r
1064 //\r
1065 SetupResetReminder ();\r
1066\r
1067Exit:\r
1068 //\r
1069 // Automatically load current entry\r
1070 // Note: The following lines of code only execute when Auto boot\r
1071 // takes affect\r
1072 //\r
1073 PERF_END (NULL, "BdsTimeOut", "BDS", 0);\r
1074}\r