newline added at end
[people/mcb30/edk2.git] / edk2 / EdkUnixPkg / Dxe / PlatformBds / Generic / FrontPage.c
1 /*++\r
2 \r
3 Copyright (c) 2006, Intel Corporation                                                         \r
4 All rights reserved. This program and the accompanying materials                          \r
5 are licensed and made available under the terms and conditions of the BSD License         \r
6 which accompanies this distribution.  The full text of the license may be found at        \r
7 http://opensource.org/licenses/bsd-license.php                                            \r
8                                                                                           \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
11 \r
12 Module Name:\r
13 \r
14   FrontPage.c\r
15 \r
16 Abstract:\r
17 \r
18   FrontPage routines to handle the callbacks and browser calls\r
19   \r
20 --*/\r
21 \r
22 #include "Bds.h"\r
23 #include "BdsPlatform.h"\r
24 #include "FrontPage.h"\r
25 #include "String.h"\r
26 \r
27 EFI_GUID                    mProcessorSubClass  = EFI_PROCESSOR_SUBCLASS_GUID;\r
28 EFI_GUID                    mMemorySubClass     = EFI_MEMORY_SUBCLASS_GUID;\r
29 EFI_GUID                    mMiscSubClass       = EFI_MISC_SUBCLASS_GUID;\r
30 \r
31 UINT16                      mLastSelection;\r
32 EFI_HII_HANDLE              gFrontPageHandle;\r
33 EFI_HANDLE                  FrontPageCallbackHandle;\r
34 EFI_FORM_CALLBACK_PROTOCOL  FrontPageCallback;\r
35 EFI_FORM_BROWSER_PROTOCOL   *gBrowser;\r
36 UINTN                       gCallbackKey;\r
37 BOOLEAN                     gConnectAllHappened = FALSE;\r
38 \r
39 extern EFI_HII_HANDLE       gFrontPageHandle;\r
40 extern EFI_GUID             gBdsStringPackGuid;\r
41 \r
42 EFI_STATUS\r
43 EFIAPI\r
44 FrontPageCallbackRoutine (\r
45   IN EFI_FORM_CALLBACK_PROTOCOL       *This,\r
46   IN UINT16                           KeyValue,\r
47   IN EFI_IFR_DATA_ARRAY               *DataArray,\r
48   OUT EFI_HII_CALLBACK_PACKET         **Packet\r
49   )\r
50 /*++\r
51 \r
52 Routine Description:\r
53 \r
54   This is the function that is called to provide results data to the driver.  This data\r
55   consists of a unique key which is used to identify what data is either being passed back\r
56   or being asked for. \r
57 \r
58 Arguments:\r
59 \r
60   KeyValue -        A unique value which is sent to the original exporting driver so that it\r
61                     can identify the type of data to expect.  The format of the data tends to\r
62                     vary based on the op-code that geerated the callback.\r
63 \r
64   Data -            A pointer to the data being sent to the original exporting driver.\r
65 \r
66 Returns: \r
67 \r
68 --*/\r
69 {\r
70   CHAR16        *LanguageString;\r
71   UINTN         Count;\r
72   CHAR16        UnicodeLang[3];\r
73   CHAR8         Lang[3];\r
74   EFI_STATUS    Status;\r
75   UINTN         Index;\r
76   CHAR16        *TmpStr;\r
77   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
78   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
79   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
80 \r
81   SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
82   SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
83   SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
84 \r
85   Count = 0;\r
86 \r
87   //\r
88   // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
89   // describe to their customers in documentation how to find their setup information (namely\r
90   // under the device manager and specific buckets)\r
91   //\r
92   switch (KeyValue) {\r
93   case 0x0001:\r
94     //\r
95     // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
96     //\r
97     gCallbackKey = 1;\r
98     break;\r
99 \r
100   case 0x1234:\r
101     //\r
102     // Collect the languages from what our current Language support is based on our VFR\r
103     //\r
104     Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);\r
105 \r
106     //\r
107     // Based on the DataArray->Data->Data value, we can determine\r
108     // which language was chosen by the user\r
109     //\r
110     for (Index = 0; Count != (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray + 1))->Data); Index += 3) {\r
111       Count++;\r
112     }\r
113     //\r
114     // Preserve the choice the user made\r
115     //\r
116     mLastSelection = (UINT16) Count;\r
117 \r
118     //\r
119     // The Language (in Unicode format) the user chose\r
120     //\r
121     CopyMem (UnicodeLang, &LanguageString[Index], 6);\r
122 \r
123     //\r
124     // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations\r
125     // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.\r
126     //\r
127     for (Index = 0; Index < 3; Index++) {\r
128       Lang[Index] = (CHAR8) UnicodeLang[Index];\r
129     }\r
130 \r
131     Status = gRT->SetVariable (\r
132                     L"Lang",\r
133                     &gEfiGlobalVariableGuid,\r
134                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
135                     3,\r
136                     Lang\r
137                     );\r
138 \r
139     gBS->FreePool (LanguageString);\r
140     gCallbackKey = 2;\r
141     break;\r
142 \r
143   case 0x1064:\r
144     //\r
145     // Boot Manager\r
146     //\r
147     gCallbackKey = 3;\r
148     break;\r
149 \r
150   case 0x8567:\r
151     //\r
152     // Device Manager\r
153     //\r
154     gCallbackKey = 4;\r
155     break;\r
156 \r
157   case 0x9876:\r
158     //\r
159     // Boot Maintenance Manager\r
160     //\r
161     gCallbackKey = 5;\r
162     break;\r
163 \r
164   case 0xFFFE:\r
165 \r
166     break;\r
167 \r
168   case 0xFFFF:\r
169     //\r
170     // FrontPage TimeOut Callback\r
171     //\r
172     TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
173     if (TmpStr != NULL) {\r
174       PlatformBdsShowProgress (\r
175         Foreground,\r
176         Background,\r
177         TmpStr,\r
178         Color,\r
179         (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray+1))->Data),\r
180         0\r
181         );\r
182       gBS->FreePool (TmpStr);\r
183     }\r
184     break;\r
185 \r
186   default:\r
187     gCallbackKey = 0;\r
188     break;\r
189   }\r
190 \r
191   return EFI_SUCCESS;\r
192 }\r
193 \r
194 EFI_STATUS\r
195 InitializeFrontPage (\r
196   BOOLEAN                         ReInitializeStrings\r
197   )\r
198 /*++\r
199 \r
200 Routine Description:\r
201   \r
202   Initialize HII information for the FrontPage\r
203 \r
204 Arguments:\r
205   None\r
206             \r
207 Returns:\r
208   EFI_SUCCESS       - The operation is successful.\r
209   EFI_DEVICE_ERROR  - If the dynamic opcode creation failed.\r
210 \r
211 --*/\r
212 {\r
213   EFI_STATUS          Status;\r
214   EFI_HII_PACKAGES    *PackageList;\r
215   EFI_HII_UPDATE_DATA *UpdateData;\r
216   IFR_OPTION          *OptionList;\r
217   CHAR16              *LanguageString;\r
218   UINTN               OptionCount;\r
219   UINTN               Index;\r
220   STRING_REF          Token;\r
221   UINT16              Key;\r
222   CHAR8               AsciiLang[4];\r
223   CHAR16              UnicodeLang[4];\r
224   CHAR16              Lang[4];\r
225   CHAR16              *StringBuffer;\r
226   UINTN               BufferSize;\r
227   UINT8               *TempBuffer;\r
228 \r
229   UpdateData  = NULL;\r
230   OptionList  = NULL;\r
231 \r
232   if (ReInitializeStrings) {\r
233     //\r
234     // BugBug: Dont' use a goto\r
235     //\r
236     goto ReInitStrings;\r
237   }\r
238   //\r
239   // Go ahead and initialize the Device Manager\r
240   //\r
241   InitializeDeviceManager ();\r
242 \r
243   //\r
244   // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here\r
245   //\r
246   TempBuffer    = (UINT8 *) FrontPageVfrBin;\r
247   TempBuffer    = TempBuffer + sizeof (EFI_HII_PACK_HEADER);\r
248   TempBuffer    = (UINT8 *) &((EFI_IFR_FORM_SET *) TempBuffer)->NvDataSize;\r
249   *TempBuffer   = 1;\r
250 \r
251   gCallbackKey  = 0;\r
252 \r
253   PackageList   = PreparePackages (1, &gBdsStringPackGuid, FrontPageVfrBin);\r
254 \r
255   Status        = Hii->NewPack (Hii, PackageList, &gFrontPageHandle);\r
256 \r
257   gBS->FreePool (PackageList);\r
258 \r
259   //\r
260   // There will be only one FormConfig in the system\r
261   // If there is another out there, someone is trying to install us\r
262   // again.  Fail that scenario.\r
263   //\r
264   Status = gBS->LocateProtocol (\r
265                   &gEfiFormBrowserProtocolGuid,\r
266                   NULL,\r
267                   (VOID**)&gBrowser\r
268                   );\r
269 \r
270   //\r
271   // This example does not implement worker functions\r
272   // for the NV accessor functions.  Only a callback evaluator\r
273   //\r
274   FrontPageCallback.NvRead    = NULL;\r
275   FrontPageCallback.NvWrite   = NULL;\r
276   FrontPageCallback.Callback  = FrontPageCallbackRoutine;\r
277 \r
278   //\r
279   // Install protocol interface\r
280   //\r
281   FrontPageCallbackHandle = NULL;\r
282   Status = gBS->InstallProtocolInterface (\r
283                   &FrontPageCallbackHandle,\r
284                   &gEfiFormCallbackProtocolGuid,\r
285                   EFI_NATIVE_INTERFACE,\r
286                   &FrontPageCallback\r
287                   );\r
288   ASSERT_EFI_ERROR (Status);\r
289 \r
290 ReInitStrings:\r
291   //\r
292   // BugBug: This logic is in BdsInitLanguage. It should not be in two places!\r
293   //\r
294   BufferSize = 4;\r
295   Status = gRT->GetVariable (\r
296                   L"Lang",\r
297                   &gEfiGlobalVariableGuid,\r
298                   NULL,\r
299                   &BufferSize,\r
300                   AsciiLang\r
301                   );\r
302 \r
303   for (Index = 0; Index < 3; Index++) {\r
304     UnicodeLang[Index] = (CHAR16) AsciiLang[Index];\r
305   }\r
306 \r
307   UnicodeLang[3] = 0;\r
308 \r
309   //\r
310   // Allocate space for creation of UpdateData Buffer\r
311   //\r
312   UpdateData = AllocateZeroPool (0x1000);\r
313   ASSERT (UpdateData != NULL);\r
314 \r
315   OptionList = AllocateZeroPool (0x1000);\r
316   ASSERT (OptionList != NULL);\r
317 \r
318   //\r
319   // Flag update pending in FormSet\r
320   //\r
321   UpdateData->FormSetUpdate = TRUE;\r
322   //\r
323   // Register CallbackHandle data for FormSet\r
324   //\r
325   UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FrontPageCallbackHandle;\r
326   UpdateData->FormUpdate  = FALSE;\r
327   UpdateData->FormTitle   = 0;\r
328   UpdateData->DataCount   = 1;\r
329 \r
330   //\r
331   // Collect the languages from what our current Language support is based on our VFR\r
332   //\r
333   Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);\r
334 \r
335   OptionCount = 0;\r
336 \r
337   //\r
338   // Try for a 512 byte Buffer\r
339   //\r
340   BufferSize = 0x200;\r
341 \r
342   //\r
343   // Allocate memory for our Form binary\r
344   //\r
345   StringBuffer = AllocateZeroPool (BufferSize);\r
346   ASSERT (StringBuffer != NULL);\r
347 \r
348   for (Index = 0; LanguageString[Index] != 0; Index += 3) {\r
349     Token = 0;\r
350     CopyMem (Lang, &LanguageString[Index], 6);\r
351     Lang[3] = 0;\r
352 \r
353     if (!StrCmp (Lang, UnicodeLang)) {\r
354       mLastSelection = (UINT16) OptionCount;\r
355     }\r
356 \r
357     Status = Hii->GetString (Hii, gStringPackHandle, 1, TRUE, Lang, &BufferSize, StringBuffer);\r
358     Hii->NewString (Hii, NULL, gStringPackHandle, &Token, StringBuffer);\r
359     CopyMem (&OptionList[OptionCount].StringToken, &Token, sizeof (UINT16));\r
360     CopyMem (&OptionList[OptionCount].Value, &OptionCount, sizeof (UINT16));\r
361     Key = 0x1234;\r
362     CopyMem (&OptionList[OptionCount].Key, &Key, sizeof (UINT16));\r
363     OptionList[OptionCount].Flags = EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS;\r
364     OptionCount++;\r
365   }\r
366 \r
367   gBS->FreePool (LanguageString);\r
368 \r
369   if (ReInitializeStrings) {\r
370     gBS->FreePool (StringBuffer);\r
371     gBS->FreePool (OptionList);\r
372     return EFI_SUCCESS;\r
373   }\r
374 \r
375   Status = CreateOneOfOpCode (\r
376             FRONT_PAGE_QUESTION_ID,                               // Question ID\r
377             FRONT_PAGE_DATA_WIDTH,                                // Data Width\r
378             (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT),      // Prompt Token\r
379             (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), // Help Token\r
380             OptionList,       // List of Options\r
381             OptionCount,      // Number of Options\r
382             &UpdateData->Data // Data Buffer\r
383             );\r
384 \r
385   //\r
386   // Assign the number of options and the oneof and endoneof op-codes to count\r
387   //\r
388   UpdateData->DataCount = (UINT8) (OptionCount + 2);\r
389 \r
390   Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
391 \r
392   gBS->FreePool (UpdateData);\r
393   //\r
394   // gBS->FreePool (OptionList);\r
395   //\r
396   gBS->FreePool (StringBuffer);\r
397   return Status;\r
398 }\r
399 \r
400 EFI_STATUS\r
401 CallFrontPage (\r
402   VOID\r
403   )\r
404 /*++\r
405 \r
406 Routine Description:\r
407   \r
408   Call the browser and display the front page\r
409 \r
410 Arguments:\r
411   \r
412   None\r
413   \r
414 Returns:\r
415 \r
416 --*/\r
417 {\r
418   EFI_STATUS  Status;\r
419   UINT8       FakeNvRamMap[1];\r
420   BOOLEAN     FrontPageMenuResetRequired;\r
421 \r
422   //\r
423   // Begin waiting for USER INPUT\r
424   //\r
425   REPORT_STATUS_CODE (\r
426         EFI_PROGRESS_CODE,\r
427         (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
428         );\r
429 \r
430   FakeNvRamMap[0] = (UINT8) mLastSelection;\r
431   FrontPageMenuResetRequired = FALSE;\r
432   Status = gBrowser->SendForm (\r
433                       gBrowser,\r
434                       TRUE,                     // Use the database\r
435                       &gFrontPageHandle,        // The HII Handle\r
436                       1,\r
437                       NULL,\r
438                       FrontPageCallbackHandle,  // This is the handle that the interface to the callback was installed on\r
439                       FakeNvRamMap,\r
440                       NULL,\r
441                       &FrontPageMenuResetRequired\r
442                       );\r
443   //\r
444   // Check whether user change any option setting which needs a reset to be effective\r
445   //                      \r
446   if (FrontPageMenuResetRequired) {\r
447     EnableResetRequired ();\r
448   }\r
449 \r
450   Hii->ResetStrings (Hii, gFrontPageHandle);\r
451 \r
452   return Status;\r
453 }\r
454 \r
455 EFI_STATUS\r
456 GetStringFromToken (\r
457   IN      EFI_GUID                  *ProducerGuid,\r
458   IN      STRING_REF                Token,\r
459   OUT     CHAR16                    **String\r
460   )\r
461 /*++\r
462 \r
463 Routine Description:\r
464   \r
465   Acquire the string associated with the ProducerGuid and return it.\r
466 \r
467 Arguments:\r
468   \r
469   ProducerGuid - The Guid to search the HII database for\r
470   Token - The token value of the string to extract\r
471   String - The string that is extracted\r
472   \r
473 Returns:\r
474 \r
475   EFI_SUCCESS - The function returns EFI_SUCCESS always.\r
476 \r
477 --*/\r
478 {\r
479   EFI_STATUS      Status;\r
480   UINT16          HandleBufferLength;\r
481   EFI_HII_HANDLE  *HiiHandleBuffer;\r
482   UINTN           StringBufferLength;\r
483   UINTN           NumberOfHiiHandles;\r
484   UINTN           Index;\r
485   UINT16          Length;\r
486   EFI_GUID        HiiGuid;\r
487 \r
488   //\r
489   // Initialize params.\r
490   //\r
491   HandleBufferLength  = 0;\r
492   HiiHandleBuffer     = NULL;\r
493 \r
494   //\r
495   // Get all the Hii handles\r
496   //\r
497   Status = BdsLibGetHiiHandles (Hii, &HandleBufferLength, &HiiHandleBuffer);\r
498   ASSERT_EFI_ERROR (Status);\r
499 \r
500   //\r
501   // Get the Hii Handle that matches the StructureNode->ProducerName\r
502   //\r
503   NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);\r
504   for (Index = 0; Index < NumberOfHiiHandles; Index++) {\r
505     Length = 0;\r
506     Status = ExtractDataFromHiiHandle (\r
507               HiiHandleBuffer[Index],\r
508               &Length,\r
509               NULL,\r
510               &HiiGuid\r
511               );\r
512     if (CompareGuid (ProducerGuid, &HiiGuid)) {\r
513       break;\r
514     }\r
515   }\r
516   //\r
517   // Find the string based on the current language\r
518   //\r
519   StringBufferLength  = 0x100;\r
520   *String             = AllocateZeroPool (0x100);\r
521   Status = Hii->GetString (\r
522                   Hii,\r
523                   HiiHandleBuffer[Index],\r
524                   Token,\r
525                   FALSE,\r
526                   NULL,\r
527                   &StringBufferLength,\r
528                   *String\r
529                   );\r
530 \r
531   if (EFI_ERROR (Status)) {\r
532     gBS->FreePool (*String);\r
533     *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
534   }\r
535 \r
536   gBS->FreePool (HiiHandleBuffer);\r
537   return EFI_SUCCESS;\r
538 }\r
539 \r
540 VOID\r
541 ConvertProcessorToString (\r
542   IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,\r
543   OUT CHAR16                            **String\r
544   )\r
545 /*++\r
546 \r
547 Routine Description:\r
548   \r
549   Convert Processor Frequency Data to a string\r
550 \r
551 Arguments:\r
552   \r
553   ProcessorFrequency - The frequency data to process\r
554   String - The string that is created\r
555   \r
556 Returns:\r
557 \r
558 --*/\r
559 {\r
560   CHAR16  *StringBuffer;\r
561   UINTN   Index;\r
562   UINT32  FreqMhz;\r
563 \r
564   if (ProcessorFrequency->Exponent >= 6) {\r
565     FreqMhz = ProcessorFrequency->Value;\r
566     for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {\r
567       FreqMhz *= 10;\r
568     }\r
569   } else {\r
570     FreqMhz = 0;\r
571   }\r
572 \r
573   StringBuffer = AllocateZeroPool (0x20);\r
574   ASSERT (StringBuffer != NULL);\r
575   Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
576   StrCat (StringBuffer, L".");\r
577   UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
578   StrCat (StringBuffer, L" GHz");\r
579 \r
580   *String = (CHAR16 *) StringBuffer;\r
581 \r
582   return ;\r
583 }\r
584 \r
585 VOID\r
586 ConvertMemorySizeToString (\r
587   IN  UINT32          MemorySize,\r
588   OUT CHAR16          **String\r
589   )\r
590 /*++\r
591 \r
592 Routine Description:\r
593   \r
594   Convert Memory Size to a string\r
595 \r
596 Arguments:\r
597   \r
598   MemorySize - The size of the memory to process\r
599   String - The string that is created\r
600   \r
601 Returns:\r
602 \r
603 --*/\r
604 {\r
605   CHAR16  *StringBuffer;\r
606 \r
607   StringBuffer = AllocateZeroPool (0x20);\r
608   ASSERT (StringBuffer != NULL);\r
609   UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);\r
610   StrCat (StringBuffer, L" MB RAM");\r
611 \r
612   *String = (CHAR16 *) StringBuffer;\r
613 \r
614   return ;\r
615 }\r
616 \r
617 VOID\r
618 UpdateFrontPageStrings (\r
619   VOID\r
620   )\r
621 /*++\r
622 \r
623 Routine Description:\r
624   \r
625   Update the banner information for the Front Page based on DataHub information\r
626 \r
627 Arguments:\r
628   \r
629   None\r
630   \r
631 Returns:\r
632 \r
633 --*/\r
634 {\r
635   EFI_STATUS                        Status;\r
636   STRING_REF                        TokenToUpdate;\r
637   CHAR16                            *NewString;\r
638   UINT64                            MonotonicCount;\r
639   EFI_DATA_HUB_PROTOCOL             *DataHub;\r
640   EFI_DATA_RECORD_HEADER            *Record;\r
641   EFI_SUBCLASS_TYPE1_HEADER         *DataHeader;\r
642   EFI_MISC_BIOS_VENDOR_DATA         *BiosVendor;\r
643   EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;\r
644   EFI_PROCESSOR_VERSION_DATA        *ProcessorVersion;\r
645   EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;\r
646   EFI_MEMORY_ARRAY_START_ADDRESS_DATA *MemoryArray;\r
647   CHAR8                             LangCode[3];\r
648   CHAR16                            Lang[3];\r
649   UINTN                             Size;\r
650   UINTN                             Index;\r
651   BOOLEAN                           Find[5];\r
652 \r
653   ZeroMem (Find, sizeof (Find));\r
654 \r
655   //\r
656   // Update Front Page strings\r
657   //\r
658   Status = gBS->LocateProtocol (\r
659                   &gEfiDataHubProtocolGuid,\r
660                   NULL,\r
661                   (VOID**)&DataHub\r
662                   );\r
663   ASSERT_EFI_ERROR (Status);\r
664 \r
665   Size = 3;\r
666 \r
667   Status = gRT->GetVariable (\r
668                   L"Lang",\r
669                   &gEfiGlobalVariableGuid,\r
670                   NULL,\r
671                   &Size,\r
672                   LangCode\r
673                   );\r
674 \r
675   for (Index = 0; Index < 3; Index++) {\r
676     Lang[Index] = (CHAR16) LangCode[Index];\r
677   }\r
678 \r
679   MonotonicCount  = 0;\r
680   Record          = NULL;\r
681   do {\r
682     Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);\r
683     if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {\r
684       DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);\r
685       if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&\r
686           (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)\r
687           ) {\r
688         BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);\r
689         GetStringFromToken (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);\r
690         TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_BIOS_VERSION;\r
691         Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
692         gBS->FreePool (NewString);\r
693         Find[0] = TRUE;\r
694       }\r
695 \r
696       if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&\r
697           (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)\r
698           ) {\r
699         SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);\r
700         GetStringFromToken (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);\r
701         TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_COMPUTER_MODEL;\r
702         Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
703         gBS->FreePool (NewString);\r
704         Find[1] = TRUE;\r
705       }\r
706 \r
707       if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&\r
708           (DataHeader->RecordType == ProcessorVersionRecordType)\r
709           ) {\r
710         ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);\r
711         GetStringFromToken (&Record->ProducerName, *ProcessorVersion, &NewString);\r
712         TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_MODEL;\r
713         Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
714         gBS->FreePool (NewString);\r
715         Find[2] = TRUE;\r
716       }\r
717 \r
718       if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&\r
719           (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)\r
720           ) {\r
721         ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);\r
722         ConvertProcessorToString (ProcessorFrequency, &NewString);\r
723         TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_SPEED;\r
724         Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
725         gBS->FreePool (NewString);\r
726         Find[3] = TRUE;\r
727       }\r
728 \r
729       if (CompareGuid (&Record->DataRecordGuid, &mMemorySubClass) &&\r
730           (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)\r
731           ) {\r
732         MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);\r
733         ConvertMemorySizeToString((UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - \r
734                                   MemoryArray->MemoryArrayStartAddress + 1), 20)),\r
735                                   &NewString);\r
736         TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_MEMORY_SIZE;\r
737         Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
738         gBS->FreePool (NewString);\r
739         Find[4] = TRUE;\r
740       }\r
741     }\r
742   } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
743 \r
744   return ;\r
745 }\r
746 \r
747 VOID\r
748 PlatformBdsEnterFrontPage (\r
749   IN UINT16                       TimeoutDefault,\r
750   IN BOOLEAN                      ConnectAllHappened\r
751   )\r
752 /*++\r
753 \r
754 Routine Description:\r
755   This function is the main entry of the platform setup entry.\r
756   The function will present the main menu of the system setup, \r
757   this is the platform reference part and can be customize.\r
758   \r
759 Arguments:\r
760   TimeoutDefault     - The fault time out value before the system\r
761                        continue to boot.\r
762   ConnectAllHappened - The indicater to check if the connect all have\r
763                        already happended.\r
764   \r
765 Returns:\r
766   None\r
767 \r
768 --*/\r
769 {\r
770   EFI_STATUS                    Status;\r
771   EFI_HII_UPDATE_DATA           *UpdateData;\r
772   EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
773 \r
774   //\r
775   // Indicate if we need connect all in the platform setup\r
776   //\r
777   if (ConnectAllHappened) {\r
778     gConnectAllHappened = TRUE;\r
779   }\r
780   //\r
781   // Allocate space for creation of Buffer\r
782   //\r
783   UpdateData = AllocateZeroPool (0x1000);\r
784   ASSERT (UpdateData != NULL);\r
785 \r
786   UpdateData->FormSetUpdate       = FALSE;\r
787   UpdateData->FormCallbackHandle  = 0;\r
788   UpdateData->FormUpdate          = FALSE;\r
789   UpdateData->FormTitle           = 0;\r
790   UpdateData->DataCount           = 1;\r
791 \r
792   //\r
793   // Remove Banner Op-code if any at this label\r
794   //\r
795   Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, FALSE, UpdateData);\r
796 \r
797   //\r
798   // Create Banner Op-code which reflects correct timeout value\r
799   //\r
800   CreateBannerOpCode (\r
801     STRING_TOKEN (STR_TIME_OUT_PROMPT),\r
802     TimeoutDefault,\r
803     (UINT8) EFI_IFR_BANNER_TIMEOUT,\r
804     &UpdateData->Data\r
805     );\r
806 \r
807   //\r
808   // Add Banner Op-code at this label\r
809   //\r
810   Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, TRUE, UpdateData);\r
811 \r
812   do {\r
813 \r
814     InitializeFrontPage (TRUE);\r
815 \r
816     //\r
817     // Update Front Page strings\r
818     //\r
819     UpdateFrontPageStrings ();\r
820 \r
821     gCallbackKey = 0;\r
822     PERF_START (0, "BdsTimeOut", "BDS", 0);\r
823     Status = CallFrontPage ();\r
824     PERF_END (0, "BdsTimeOut", "BDS", 0);\r
825 \r
826     //\r
827     // If gCallbackKey is greater than 1 and less or equal to 5,\r
828     // it will lauch configuration utilities.\r
829     // 2 = set language\r
830     // 3 = boot manager\r
831     // 4 = device manager\r
832     // 5 = boot maintainenance manager\r
833     //\r
834     if ((gCallbackKey > 0x0001) && (gCallbackKey <= 0x0005)) {\r
835       REPORT_STATUS_CODE (\r
836             EFI_PROGRESS_CODE,\r
837             (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
838             );\r
839     }\r
840     //\r
841     // Based on the key that was set, we can determine what to do\r
842     //\r
843     switch (gCallbackKey) {\r
844     //\r
845     // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
846     // describe to their customers in documentation how to find their setup information (namely\r
847     // under the device manager and specific buckets)\r
848     //\r
849     // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
850     //\r
851     case 0x0001:\r
852       //\r
853       // User hit continue\r
854       //\r
855       break;\r
856 \r
857     case 0x0002:\r
858       //\r
859       // User made a language setting change - display front page again\r
860       //\r
861       break;\r
862 \r
863     case 0x0003:\r
864       //\r
865       // User chose to run the Boot Manager\r
866       //\r
867       CallBootManager ();\r
868       break;\r
869 \r
870     case 0x0004:\r
871       //\r
872       // Display the Device Manager\r
873       //\r
874       do {\r
875         CallDeviceManager();\r
876       } while (gCallbackKey == 4);\r
877       break;\r
878 \r
879     case 0x0005:\r
880       //\r
881       // Display the Boot Maintenance Manager\r
882       //\r
883       BdsStartBootMaint ();\r
884       break;\r
885     }\r
886 \r
887   } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1));\r
888 \r
889   //\r
890   //Will leave browser, check any reset required change is applied? if yes, reset system\r
891   //\r
892   SetupResetReminder ();\r
893   \r
894   //\r
895   // Automatically load current entry\r
896   // Note: The following lines of code only execute when Auto boot\r
897   // takes affect\r
898   //\r
899   Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
900   ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
901 \r
902 }\r