• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 Module Name:
24 
25 **/
26 
27 #include "PlatformSetupDxe.h"
28 #include "Guid/SetupVariable.h"
29 #include <Protocol/FormBrowserEx2.h>
30 
31 
32 #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
33 #define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
34 
35 typedef struct {
36   UINTN                           Signature;
37   EFI_HANDLE                      DriverHandle;
38   EFI_HII_HANDLE                  RegisteredHandle;
39   SYSTEM_CONFIGURATION            FakeNvData;
40   SYSTEM_CONFIGURATION            BackupNvData;
41   EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
42   EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;
43 } EFI_CALLBACK_INFO;
44 
45 #pragma pack(1)
46 
47 //
48 // HII specific Vendor Device Path definition.
49 //
50 typedef struct {
51   VENDOR_DEVICE_PATH             VendorDevicePath;
52   EFI_DEVICE_PATH_PROTOCOL       End;
53 } HII_VENDOR_DEVICE_PATH;
54 
55 #pragma pack()
56 
57 //
58 // uni string and Vfr Binary data.
59 //
60 extern UINT8  VfrBin[];
61 extern UINT8  PlatformSetupDxeStrings[];
62 
63 EFI_HANDLE            mImageHandle;
64 
65 //
66 // module global data
67 //
68 #define EFI_NORMAL_SETUP_GUID \
69   { 0xec87d643, 0xeba4, 0x4bb5, 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0xd, 0xa9 }
70 
71 EFI_GUID                     mNormalSetupGuid = EFI_NORMAL_SETUP_GUID;
72 
73 EFI_GUID                     mSystemConfigGuid = SYSTEM_CONFIGURATION_GUID;
74 CHAR16                       mVariableName[] = L"Setup";
75 CHAR16                       mSetupName[] = L"Setup";
76 EFI_CALLBACK_INFO           *mCallbackInfo;
77 BOOLEAN                      GlobalReset=FALSE;
78 
79 HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {
80   {
81     {
82       HARDWARE_DEVICE_PATH,
83       HW_VENDOR_DP,
84       {
85         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
86         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
87       }
88     },
89     EFI_CALLER_ID_GUID
90   },
91   {
92     END_DEVICE_PATH_TYPE,
93     END_ENTIRE_DEVICE_PATH_SUBTYPE,
94     {
95       (UINT8) (END_DEVICE_PATH_LENGTH),
96       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
97     }
98   }
99 };
100 
101 /**
102   This function allows a caller to extract the current configuration for one
103   or more named elements from the target driver.
104 
105   @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
106   @param  Request      A null-terminated Unicode string in <ConfigRequest> format.
107   @param  Progress     On return, points to a character in the Request string.
108                        Points to the string's null terminator if request was successful.
109                        Points to the most recent '&' before the first failing name/value
110                        pair (or the beginning of the string if the failure is in the
111                        first name/value pair) if the request was not successful.
112   @param  Results      A null-terminated Unicode string in <ConfigAltResp> format which
113                        has all values filled in for the names in the Request string.
114                        String to be allocated by the called function.
115 
116   @retval EFI_SUCCESS            The Results is filled with the requested values.
117   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
118   @retval EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.
119   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
120 
121 **/
122 
123 VOID
LoadLpssDefaultValues(IN EFI_CALLBACK_INFO * Private)124 CheckSystemConfigLoad(SYSTEM_CONFIGURATION *SystemConfigPtr);
125 
126 VOID
127 CheckSystemConfigSave(SYSTEM_CONFIGURATION *SystemConfigPtr);
128 
129 VOID
130 ConfirmSecureBootTest();
131 
132 VOID
133 LoadLpssDefaultValues (
134   IN EFI_CALLBACK_INFO                       *Private
135   )
136 {
137   //
138   // Load LPSS and SCC default configurations for Android
139   //
140   Private->FakeNvData.LpsseMMCEnabled            = FALSE;
141   Private->FakeNvData.LpssSdioEnabled            = TRUE;
142   Private->FakeNvData.LpssSdcardEnabled          = TRUE;
143   Private->FakeNvData.LpssSdCardSDR25Enabled     = FALSE;
144   Private->FakeNvData.LpssSdCardDDR50Enabled     = TRUE;
145   Private->FakeNvData.LpssMipiHsi                = FALSE;
146   Private->FakeNvData.LpsseMMC45Enabled          = TRUE;
147   Private->FakeNvData.LpsseMMC45DDR50Enabled     = TRUE;
148   Private->FakeNvData.LpsseMMC45HS200Enabled     = FALSE;
149   Private->FakeNvData.LpsseMMC45RetuneTimerValue = 8;
150   Private->FakeNvData.eMMCBootMode               = 1;     // Auto Detect
151 
152   Private->FakeNvData.GOPEnable = TRUE;
153   Private->FakeNvData.SecureBoot = TRUE;
154   Private->FakeNvData.UsbAutoMode = TRUE;
SystemConfigExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Request,OUT EFI_STRING * Progress,OUT EFI_STRING * Results)155   Private->FakeNvData.UsbXhciSupport = TRUE;
156   Private->FakeNvData.PchUsb30Mode = TRUE;
157   Private->FakeNvData.LegacyUSBBooting = FALSE;
158   Private->FakeNvData.PchUsb20 = FALSE;
159 }
160 
161 
162 EFI_STATUS
163 EFIAPI
164 SystemConfigExtractConfig (
165   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
166   IN  CONST EFI_STRING                       Request,
167   OUT EFI_STRING                             *Progress,
168   OUT EFI_STRING                             *Results
169   )
170 {
171   EFI_STATUS                       Status;
172   EFI_CALLBACK_INFO                *Private;
173   EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
174   EFI_STRING                       ConfigRequestHdr;
175   EFI_STRING                       ConfigRequest;
176   BOOLEAN                          AllocatedRequest;
177   UINTN                            Size;
178   UINTN                            BufferSize;
179   VOID                             *SystemConfigPtr;
180 
181 
182   if (Progress == NULL || Results == NULL) {
183     return EFI_INVALID_PARAMETER;
184   }
185 
186   *Progress = Request;
187   if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mSystemConfigGuid, mVariableName)) {
188     return EFI_NOT_FOUND;
189   }
190 
191   ConfigRequestHdr = NULL;
192   ConfigRequest    = NULL;
193   Size             = 0;
194   AllocatedRequest = FALSE;
195 
196   Private          = EFI_CALLBACK_INFO_FROM_THIS (This);
197 
198   SetupInfo();
199 
200   HiiConfigRouting = Private->HiiConfigRouting;
201   ConfigRequest = Request;
202   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
203     //
204     // Request has no request element, construct full request string.
205     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
206     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
207     //
208     ConfigRequestHdr = HiiConstructConfigHdr (&mSystemConfigGuid, mVariableName, Private->DriverHandle);
209     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
210     ConfigRequest = AllocateZeroPool (Size);
211     ASSERT (ConfigRequest != NULL);
212     AllocatedRequest = TRUE;
213     BufferSize = sizeof (SYSTEM_CONFIGURATION);
214     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
215     FreePool (ConfigRequestHdr);
216   }
217   SystemConfigPtr = GetVariable(mSetupName, &mNormalSetupGuid);
218 
219 
220   if (SystemConfigPtr == NULL) {
221     ZeroMem(&Private->FakeNvData, sizeof(SYSTEM_CONFIGURATION));
222     ZeroMem(&Private->BackupNvData, sizeof(SYSTEM_CONFIGURATION));
223   } else {
224     CheckSystemConfigLoad(SystemConfigPtr);
225     CopyMem(&Private->FakeNvData, SystemConfigPtr, sizeof(SYSTEM_CONFIGURATION));
226     CopyMem(&Private->BackupNvData, SystemConfigPtr, sizeof(SYSTEM_CONFIGURATION));
227     FreePool(SystemConfigPtr);
228   }
229 
230   //
231   // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
232   //
233   Status = HiiConfigRouting->BlockToConfig (
234                                HiiConfigRouting,
235                                ConfigRequest,
236                                (UINT8 *) &Private->FakeNvData,
237                                sizeof (SYSTEM_CONFIGURATION),
238                                Results,
239                                Progress
240                                );
241 
242   //
243   // Free the allocated config request string.
244   //
245   if (AllocatedRequest) {
246     FreePool (ConfigRequest);
247     ConfigRequest = NULL;
248   }
249 
250   //
251   // Set Progress string to the original request string.
252   //
253   if (Request == NULL) {
254     *Progress = NULL;
255   } else if (StrStr (Request, L"OFFSET") == NULL) {
256     *Progress = Request + StrLen (Request);
257   }
258 
259   return Status;
260 }
261 
262 /**
263   This function processes the results of changes in configuration.
264 
265   @param  This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
266   @param  Configuration   A null-terminated Unicode string in <ConfigRequest> format.
267   @param  Progress        A pointer to a string filled in with the offset of the most
268                           recent '&' before the first failing name/value pair (or the
269                           beginning of the string if the failure is in the first
SystemConfigRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Configuration,OUT EFI_STRING * Progress)270                           name/value pair) or the terminating NULL if all was successful.
271 
272   @retval EFI_SUCCESS            The Results is processed successfully.
273   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
274   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
275 
276 **/
277 EFI_STATUS
278 EFIAPI
279 SystemConfigRouteConfig (
280   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
281   IN  CONST EFI_STRING                       Configuration,
282   OUT EFI_STRING                             *Progress
283   )
284 {
285   EFI_CALLBACK_INFO                         *Private;
286   SYSTEM_CONFIGURATION                       *FakeNvData;
287 
288   if (Configuration == NULL || Progress == NULL) {
289     return EFI_INVALID_PARAMETER;
290   }
291   *Progress = Configuration;
292 
293   if (!HiiIsConfigHdrMatch (Configuration, &mSystemConfigGuid, mVariableName)) {
294     return EFI_NOT_FOUND;
295   }
296 
297   *Progress = Configuration + StrLen (Configuration);
298   Private    = EFI_CALLBACK_INFO_FROM_THIS (This);
299   FakeNvData = &Private->FakeNvData;
300   if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
301     //
302     // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
303     //
304     return EFI_SUCCESS;
305   }
306 
307   if (Private->FakeNvData.ReservedO != Private->BackupNvData.ReservedO) {
308     Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
309     LoadLpssDefaultValues (Private);
310 
311     //
312     // Pass changed uncommitted data back to Form Browser
313     //
314     HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
315   }
316 
317   gRT->SetVariable(
318          mSetupName,
319          &mNormalSetupGuid,
320          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
321          sizeof(SYSTEM_CONFIGURATION),
322          &Private->FakeNvData
323          );
324 
325   CheckSystemConfigSave(&Private->FakeNvData);
326   return EFI_SUCCESS;
327 }
328 
329 /**
330   This is the function that is called to provide results data to the driver.  This data
331   consists of a unique key which is used to identify what data is either being passed back
332   or being asked for.
333 
334   @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
335   @param  Action         A null-terminated Unicode string in <ConfigRequest> format.
336   @param  KeyValue       A unique Goto OpCode callback value which record user's selection.
337                          0x100 <= KeyValue <0x500 : user select a controller item in the first page;
338                          KeyValue == 0x1234       : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
339                          KeyValue == 0x1235       : user select 'Pci device filter' in first page
340                          KeyValue == 0x1500       : user select 'order ... priority' item in second page
341                          KeyValue == 0x1800       : user select 'commint changes' in third page
342                          KeyValue == 0x2000       : user select 'Go to Previous Menu' in third page
SystemConfigCallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN EFI_BROWSER_ACTION Action,IN EFI_QUESTION_ID KeyValue,IN UINT8 Type,IN EFI_IFR_TYPE_VALUE * Value,OUT EFI_BROWSER_ACTION_REQUEST * ActionRequest)343   @param  Type           The type of value for the question.
344   @param  Value          A pointer to the data being sent to the original exporting driver.
345   @param  ActionRequest  On return, points to the action requested by the callback function.
346 
347   @retval EFI_SUCCESS    Always returned.
348 
349 **/
350 EFI_STATUS
351 EFIAPI
352 SystemConfigCallback (
353   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
354   IN  EFI_BROWSER_ACTION                     Action,
355   IN  EFI_QUESTION_ID                        KeyValue,
356   IN  UINT8                                  Type,
357   IN  EFI_IFR_TYPE_VALUE                     *Value,
358   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
359   )
360 {
361   EFI_CALLBACK_INFO             *Private;
362   SYSTEM_CONFIGURATION          *FakeNvData;
363   SYSTEM_CONFIGURATION          *SetupData;
364   UINTN                         SizeOfNvStore;
365   EFI_INPUT_KEY                 Key;
366   CHAR16                        *StringBuffer1;
367   CHAR16                        *StringBuffer2;
368   CHAR16                        *StringBuffer3;
369   EFI_STATUS                    Status;
370   UINTN                         DataSize;
371   UINT8                         OsSelection;
372   EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
373 
374   StringBuffer1 = AllocateZeroPool (200 * sizeof (CHAR16));
375   ASSERT (StringBuffer1 != NULL);
376   StringBuffer2 = AllocateZeroPool (200 * sizeof (CHAR16));
377   ASSERT (StringBuffer2 != NULL);
378   StringBuffer3 = AllocateZeroPool (200 * sizeof (CHAR16));
379   ASSERT (StringBuffer3 != NULL);
380 
381   switch (Action) {
382   case EFI_BROWSER_ACTION_CHANGING:
383   {
384     if (KeyValue == 0x1235) {
385       StrCpy (StringBuffer1, L"Will you disable PTT ? ");
386       StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
387 
388       //
389       // Popup a menu to notice user
390       //
391       do {
392         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
393       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
394 
395       //
396       // If the user hits the YES Response key,
397       //
398       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
399 
400       }
401     } else if (KeyValue == 0x1236) {
402       StrCpy (StringBuffer1, L"Will you revoke trust ? ");
403       StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
404 
405       //
406       // Popup a menu to notice user
407       //
408       do {
409         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
410       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
411 
412       //
413       // If the user hits the YES Response key,
414       //
415       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
416 
417       }
418 	 } else if (KeyValue == 0x1239) {
419 	   if (Value->u8 == 0x00) {
420        StrCpy (StringBuffer1, L"WARNING: SOC may be damaged due to high temperature");
421        StrCpy (StringBuffer2, L"when DPTF is disabled and IGD turbo is enabled.");
422        StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
423 
424         //
425         // Popup a menu to notice user
426         //
427         do {
428           CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3, NULL);
429         } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
430     }
431     } else if (KeyValue == 0x1240) { // secure erase feature of eMMC
432 	    //
433       // Popup a menu to notice user
434       //
435       StrCpy (StringBuffer1, L"WARNING: All your data on the eMMC will be lost");
436       StrCpy (StringBuffer2, L"Do you really want to enable secure erase on eMMC?");
437       StrCpy (StringBuffer3, L"       Enter (YES)    /    Esc (NO)        ");
438 
439       do {
440         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3,NULL);
441       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
442 
443       //
444       // If the user hits the ESC Response key,
445       //
446       if (Key.ScanCode == SCAN_ESC) {
447         Private = EFI_CALLBACK_INFO_FROM_THIS (This);
448         FakeNvData = &Private->FakeNvData;
449 
450         Status = HiiGetBrowserData (
451 		               &mSystemConfigGuid,
452 				           mVariableName,
453 				           sizeof (SYSTEM_CONFIGURATION),
454 				           (UINT8 *) FakeNvData
455 				           );
456         if (!EFI_ERROR (Status)) {
457              FakeNvData->SecureErase = 0;
458              HiiSetBrowserData (
459                &mSystemConfigGuid,
460                mVariableName,
461                sizeof (SYSTEM_CONFIGURATION),
462                (UINT8 *) FakeNvData,
463                NULL
464                );
465         }
466         break;
467       }
468 
469       //
470       // If the user hits the YES Response key
471       //
472       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
473         //
474         // Save change
475         //
476         Private = EFI_CALLBACK_INFO_FROM_THIS (This);
477         FakeNvData = &Private->FakeNvData;
478 
479         Status = HiiGetBrowserData (
480 		               &mSystemConfigGuid,
481 				           mVariableName,
482 				           sizeof (SYSTEM_CONFIGURATION),
483 				          (UINT8 *) FakeNvData
484 				          );
485         if (!EFI_ERROR (Status)) {
486           Status = gRT->SetVariable (
487                           L"Setup",
488                           &mNormalSetupGuid,
489                           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
490                           sizeof(SYSTEM_CONFIGURATION),
491                           &Private->FakeNvData
492                           );
493         }
494 
495         //
496         // Reset system
497         //
498         gRT->ResetSystem(
499 		           EfiResetCold,
500 			         EFI_SUCCESS,
501 			         0,
502 			         NULL
503 			         );
504 
505     }
506 
507 
508     }
509     else if (KeyValue == 0xF001) {
510       //
511       // Popup a menu to notice user
512       //
513       StrCpy (StringBuffer1, L"Do you want to Commit Changes and Exit?");
514       StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)        ");
515 
516       do {
517         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
518       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
519 
520       //
521       // If the user hits the YES Response key
522       //
523       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
524         //
525         // Save change
526         //
527         Private = EFI_CALLBACK_INFO_FROM_THIS (This);
528         FakeNvData = &Private->FakeNvData;
529 
530         Status = HiiGetBrowserData (
531 		           &mSystemConfigGuid,
532 				   mVariableName,
533 				   sizeof (SYSTEM_CONFIGURATION),
534 				   (UINT8 *) FakeNvData
535 				   );
536         if (!EFI_ERROR (Status)) {
537           Status = gRT->SetVariable (
538                           L"Setup",
539                           &mNormalSetupGuid,
540                           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
541                           sizeof(SYSTEM_CONFIGURATION),
542                           &Private->FakeNvData
543                           );
544         }
545 
546 		//
547 		// Update Secure Boot configuration changes
548 		//
549         CheckSystemConfigSave(FakeNvData);
550 
551         //
552         // Reset system
553         //
554         if (GlobalReset == TRUE) {
555           //
556           // Issue full reset
557           //
558           IoWrite8 (
559             (UINTN) 0XCF9,
560             (UINT8) 0x02
561             );
562 
563           IoWrite8 (
564             (UINTN) 0xCF9,
565             (UINT8) 0x0E
566             );
567         } else {
568         	gRT->ResetSystem(
569 			       EfiResetCold,
570 				   EFI_SUCCESS,
571 				   0,
572 				   NULL
573 				   );
574         }
575       }
576     } else if (KeyValue == 0xF002) {
577       //
578       // Popup a menu to notice user
579       //
580       StrCpy (StringBuffer1, L"Do you want to Discard Changes and Exit?");
581       StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)         ");
582 
583       do {
584         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
585       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
586 
587       //
588       // If the user hits the YES Response key
589       //
590       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
591         //
592         // Reset system
593         //
594         gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
595       }
596     } else if (KeyValue == 0xF003) {
597       //
598       // Popup a menu to notice user
599       //
600       StrCpy (StringBuffer1, L"Do you want to load setup defaults and Exit?");
601       StrCpy (StringBuffer2, L"         Enter (YES) / Esc (NO)             ");
602 
603       do {
604         CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
605       } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
606 
607       //
608       // If the user hits the YES Response key
609       //
610       if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
611 
612         Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
613         FormBrowserEx2->ExecuteAction(BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD);
614 
615         FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
616 
617         if (FakeNvData == NULL) {
618           return EFI_OUT_OF_RESOURCES;
619         }
620 
621         Status = HiiGetBrowserData (
622 		           &mSystemConfigGuid,
623 				   mVariableName,
624 				   sizeof (SYSTEM_CONFIGURATION),
625 				   (UINT8 *) FakeNvData
626 				   );
627 
628         if (!EFI_ERROR (Status)) {
629           Status = gRT->SetVariable (
630                           L"Setup",
631                           &mNormalSetupGuid,
632                             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
633                           sizeof(SYSTEM_CONFIGURATION),
634                           FakeNvData
635                           );
636         }
637 
638         FreePool (FakeNvData);
639 
640         DataSize = sizeof(OsSelection);
641         Status = gRT->GetVariable(
642                         L"OsSelection",
643                         &gOsSelectionVariableGuid,
644                         NULL,
645                         &DataSize,
646                         &OsSelection
647                         );
648 
649         if (EFI_ERROR(Status) || (OsSelection != FakeNvData->ReservedO)) {
650           OsSelection = FakeNvData->ReservedO;
651           Status = gRT->SetVariable (
652                           L"OsSelection",
653                           &gOsSelectionVariableGuid,
654                           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
655                           sizeof(OsSelection),
656                           &OsSelection
657                           );
658         }
659 
660         //
661         // Reset system
662         //
663         gRT->ResetSystem(
664 		       EfiResetCold,
665 			   EFI_SUCCESS,
666 			   0,
667 			   NULL
668 			   );
669       }
670     } else if ((KeyValue == 0x123A) || (KeyValue == 0x123B) || (KeyValue == 0x123C)) {
671         StrCpy (StringBuffer1, L"WARNING: Enable or disable USB Controllers will ");
672         StrCpy (StringBuffer2, L"make global reset to restart system.");
673         StrCpy (StringBuffer3, L"Press Enter/ESC to continue...");
674         //
675         // Popup a menu to notice user
676         //
677         do {
678           CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, StringBuffer3, NULL);
679         } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
680 
681         FakeNvData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
682         Status = HiiGetBrowserData (
683 		           &mSystemConfigGuid,
684 				   mVariableName,
685 				   sizeof (SYSTEM_CONFIGURATION),
686 				   (UINT8 *) FakeNvData
687 				   );
688         //
689         // Get variable data
690         //
691         SizeOfNvStore = sizeof(SYSTEM_CONFIGURATION);
692         SetupData = AllocateZeroPool (sizeof(SYSTEM_CONFIGURATION));
693         Status = gRT->GetVariable(
694                         L"Setup",
695                         &mNormalSetupGuid,
696                         NULL,
697                         &SizeOfNvStore,
698                         SetupData
699                         );
700         if ((SetupData->UsbAutoMode != FakeNvData->UsbAutoMode) ||
701         	   (SetupData->UsbXhciSupport != FakeNvData->UsbXhciSupport) ||
702         	   (SetupData->PchUsb20 != FakeNvData->PchUsb20)) {
703           GlobalReset = TRUE;
704         } else {
705           GlobalReset = FALSE;
706         }
707 
708     }
709   }
710   break;
711 
712   default:
713     break;
714   }
715 
716   FreePool (StringBuffer1);
717   FreePool (StringBuffer2);
718   FreePool (StringBuffer3);
719 
720   //
721   // Workaround for Load Default for "DPTF Enable"
722   //
723   if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
724     if (KeyValue == 0x1239) {
725       return EFI_NOT_FOUND;
726     }
727   }
728 
729   if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
730     //
731     // Do nothing for UEFI OPEN/CLOSE Action
732     //
733     return EFI_SUCCESS;
734   }
735 
736   Private = EFI_CALLBACK_INFO_FROM_THIS (This);
737   FakeNvData = &Private->FakeNvData;
738   if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
739     return EFI_NOT_FOUND;
740   }
741 
742   if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) && (Private->FakeNvData.ReservedO != Private->BackupNvData.ReservedO)) {
743     Private->BackupNvData.ReservedO = Private->FakeNvData.ReservedO;
744     LoadLpssDefaultValues (Private);
745   }
746 
747   //
748   // When user selected the secure erase, set it to disable
749   //
750   if((KeyValue == 0x1240) && (Action == EFI_BROWSER_ACTION_CHANGED)) {
751     FakeNvData->SecureErase = 0;
752   }
753 
754   if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_CHANGED)) {
755     //
756     // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
757     //
758     if (Private->FakeNvData.LpssDma0Enabled == 0) {
759       Private->FakeNvData.LpssHsuart0Enabled = 0;
760       Private->FakeNvData.LpssHsuart1Enabled = 0;
761       Private->FakeNvData.LpssPwm0Enabled    = 0;
762       Private->FakeNvData.LpssPwm1Enabled    = 0;
763       Private->FakeNvData.LpssSpiEnabled     = 0;
764     }
765 
766 
767     //
768     // If function 0 is disabled, function 1 ~ 7 also required to be disabled.
769     //
770     if (Private->FakeNvData.LpssDma1Enabled == 0) {
771       Private->FakeNvData.LpssI2C0Enabled = 0;
772       Private->FakeNvData.LpssI2C1Enabled = 0;
773       Private->FakeNvData.LpssI2C2Enabled = 0;
774       Private->FakeNvData.LpssI2C3Enabled = 0;
775       Private->FakeNvData.LpssI2C4Enabled = 0;
776       Private->FakeNvData.LpssI2C5Enabled = 0;
777       Private->FakeNvData.LpssI2C6Enabled = 0;
778     }
779   }
780 
781 
782   //
783   // Pass changed uncommitted data back to Form Browser
784   //
785   HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
786 
787   return EFI_SUCCESS;
788 }
789 
790 
791 /**
792   The driver Entry Point. The function will export a disk device class formset and
793   its callback function to hii database.
794 
PlatformSetupDxeInit(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)795   @param  ImageHandle    The firmware allocated handle for the EFI image.
796   @param  SystemTable    A pointer to the EFI System Table.
797 
798   @retval EFI_SUCCESS    The entry point is executed successfully.
799   @retval other          Some error occurs when executing this entry point.
800 
801 **/
802 EFI_STATUS
803 EFIAPI
804 PlatformSetupDxeInit (
805   IN EFI_HANDLE                   ImageHandle,
806   IN EFI_SYSTEM_TABLE             *SystemTable
807   )
808 {
809   EFI_STATUS                  Status;
810   EFI_FORM_BROWSER2_PROTOCOL  *FormBrowser2;
811 
812   mImageHandle = ImageHandle;
813 
814   //
815   // There should only be one Form Configuration protocol
816   //
817   Status = gBS->LocateProtocol (
818                  &gEfiFormBrowser2ProtocolGuid,
819                  NULL,
820                  (VOID **) &FormBrowser2
821                  );
822   if (EFI_ERROR (Status)) {
823     return Status;
824   }
825 
826   mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
827   if (mCallbackInfo == NULL) {
828     return EFI_BAD_BUFFER_SIZE;
829   }
830 
831   mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
832   mCallbackInfo->ConfigAccess.ExtractConfig = SystemConfigExtractConfig;
833   mCallbackInfo->ConfigAccess.RouteConfig   = SystemConfigRouteConfig;
834   mCallbackInfo->ConfigAccess.Callback      = SystemConfigCallback;
835 
836   //
837   // Install Device Path Protocol and Config Access protocol to driver handle
838   // Install Platform Driver Override Protocol to driver handle
839   //
840   Status = gBS->InstallMultipleProtocolInterfaces (
841                   &mCallbackInfo->DriverHandle,
842                   &gEfiDevicePathProtocolGuid,
843                   &mHiiVendorDevicePath,
844                   &gEfiHiiConfigAccessProtocolGuid,
845                   &mCallbackInfo->ConfigAccess,
846                   NULL
847                   );
848   if (EFI_ERROR (Status)) {
849     goto Finish;
850   }
851 
852   //
853   // Publish our HII data
854   //
855   mCallbackInfo->RegisteredHandle = HiiAddPackages (
856                                       &mSystemConfigGuid,
857                                       mCallbackInfo->DriverHandle,
858                                       VfrBin,
859                                       PlatformSetupDxeStrings,
860                                       NULL
861                                       );
862   if (mCallbackInfo->RegisteredHandle == NULL) {
863     Status = EFI_OUT_OF_RESOURCES;
864     goto Finish;
865   }
866 
867   mHiiHandle = mCallbackInfo->RegisteredHandle;
868 
869   //
870   // Locate ConfigRouting protocol
871   //
872   Status = gBS->LocateProtocol (
873                   &gEfiHiiConfigRoutingProtocolGuid,
874                   NULL,
875                   (VOID **) &mCallbackInfo->HiiConfigRouting
876                   );
877   if (EFI_ERROR (Status)) {
878     goto Finish;
879   }
880 
881   //
882   // Clear all the globle variable
883   //
884   return EFI_SUCCESS;
885 
886 Finish:
887   if (mCallbackInfo->DriverHandle != NULL) {
888     gBS->UninstallMultipleProtocolInterfaces (
889            mCallbackInfo->DriverHandle,
890            &gEfiDevicePathProtocolGuid,
891            &mHiiVendorDevicePath,
892            &gEfiHiiConfigAccessProtocolGuid,
893            &mCallbackInfo->ConfigAccess,
894            NULL
895            );
896   }
897 
898   if (mCallbackInfo->RegisteredHandle != NULL) {
899     HiiRemovePackages (mCallbackInfo->RegisteredHandle);
900   }
901 
902   if (mCallbackInfo != NULL) {
903     FreePool (mCallbackInfo);
904   }
905 
906   return Status;
907 }
908 
PlatformSetupDxeUnload(IN EFI_HANDLE ImageHandle)909 /**
910   Unload its installed protocol.
911 
912   @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
913 
914   @retval EFI_SUCCESS           The image has been unloaded.
915 **/
916 EFI_STATUS
917 EFIAPI
918 PlatformSetupDxeUnload (
919   IN EFI_HANDLE  ImageHandle
920   )
921 {
922   if (mCallbackInfo != NULL) {
923     if (mCallbackInfo->DriverHandle != NULL) {
924       gBS->UninstallMultipleProtocolInterfaces (
925              mCallbackInfo->DriverHandle,
926              &gEfiDevicePathProtocolGuid,
927              &mHiiVendorDevicePath,
928              &gEfiHiiConfigAccessProtocolGuid,
929              &mCallbackInfo->ConfigAccess,
930              NULL
931              );
932     }
933 
934     if (mCallbackInfo->RegisteredHandle != NULL) {
935       HiiRemovePackages (mCallbackInfo->RegisteredHandle);
936     }
937 
938     FreePool (mCallbackInfo);
939   }
940 
941   return EFI_SUCCESS;
942 }
943 
944