]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Support RouteConfig function for BdsDxe driver.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
1 /** @file
2 The functions for Boot Maintainence Main menu.
3
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BootMaint.h"
16 #include "FormGuid.h"
17 #include "Bds.h"
18 #include "FrontPage.h"
19
20 EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
21 {
22 END_DEVICE_PATH_TYPE,
23 END_ENTIRE_DEVICE_PATH_SUBTYPE,
24 {
25 END_DEVICE_PATH_LENGTH,
26 0
27 }
28 }
29 };
30
31 HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {
32 {
33 {
34 HARDWARE_DEVICE_PATH,
35 HW_VENDOR_DP,
36 {
37 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
38 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
39 }
40 },
41 BOOT_MAINT_FORMSET_GUID
42 },
43 {
44 END_DEVICE_PATH_TYPE,
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,
46 {
47 (UINT8) (END_DEVICE_PATH_LENGTH),
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
49 }
50 }
51 };
52
53 HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath = {
54 {
55 {
56 HARDWARE_DEVICE_PATH,
57 HW_VENDOR_DP,
58 {
59 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
60 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
61 }
62 },
63 FILE_EXPLORE_FORMSET_GUID
64 },
65 {
66 END_DEVICE_PATH_TYPE,
67 END_ENTIRE_DEVICE_PATH_SUBTYPE,
68 {
69 (UINT8) (END_DEVICE_PATH_LENGTH),
70 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
71 }
72 }
73 };
74
75 CHAR16 mBootMaintStorageName[] = L"BmmData";
76 CHAR16 mFileExplorerStorageName[] = L"FeData";
77 BMM_CALLBACK_DATA *mBmmCallbackInfo = NULL;
78
79 /**
80 Init all memu.
81
82 @param CallbackData The BMM context data.
83
84 **/
85 VOID
86 InitAllMenu (
87 IN BMM_CALLBACK_DATA *CallbackData
88 );
89
90 /**
91 Free up all Menu Option list.
92
93 **/
94 VOID
95 FreeAllMenu (
96 VOID
97 );
98
99 /**
100 Initialize all of BMM configuration data in BmmFakeNvData and BmmOldFakeNVData member
101 in BMM context data and create all of dynamic OP code for BMM.
102
103 @param CallbackData The BMM context data.
104
105 **/
106 VOID
107 InitializeBmmConfig (
108 IN BMM_CALLBACK_DATA *CallbackData
109 )
110 {
111 BM_MENU_ENTRY *NewMenuEntry;
112 BM_LOAD_CONTEXT *NewLoadContext;
113 UINT16 Index;
114
115 ASSERT (CallbackData != NULL);
116
117 //
118 // Initialize data which located in BMM main page
119 //
120 CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);
121 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
122 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
123 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
124
125 if (NewLoadContext->IsBootNext) {
126 CallbackData->BmmFakeNvData.BootNext = Index;
127 break;
128 }
129 }
130
131 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
132
133 //
134 // Initialize data which located in Boot Options Menu
135 //
136 GetBootOrder (CallbackData);
137 GetLegacyDeviceOrder (CallbackData);
138
139 //
140 // Initialize data which located in Driver Options Menu
141 //
142 GetDriverOrder (CallbackData);
143
144 //
145 // Initialize data which located in Console Options Menu
146 //
147 GetConsoleOutMode (CallbackData);
148 GetConsoleInCheck (CallbackData);
149 GetConsoleOutCheck (CallbackData);
150 GetConsoleErrCheck (CallbackData);
151 GetTerminalAttribute (CallbackData);
152
153 //
154 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
155 //
156 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
157 }
158
159 /**
160 Create string tokens for a menu from its help strings and display strings
161
162 @param CallbackData The BMM context data.
163 @param HiiHandle Hii Handle of the package to be updated.
164 @param MenuOption The Menu whose string tokens need to be created
165
166 @retval EFI_SUCCESS String tokens created successfully
167 @retval others contain some errors
168 **/
169 EFI_STATUS
170 CreateMenuStringToken (
171 IN BMM_CALLBACK_DATA *CallbackData,
172 IN EFI_HII_HANDLE HiiHandle,
173 IN BM_MENU_OPTION *MenuOption
174 )
175 {
176 BM_MENU_ENTRY *NewMenuEntry;
177 UINTN Index;
178
179 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
180 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
181
182 NewMenuEntry->DisplayStringToken = HiiSetString (
183 HiiHandle,
184 0,
185 NewMenuEntry->DisplayString,
186 NULL
187 );
188
189 if (NULL == NewMenuEntry->HelpString) {
190 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
191 } else {
192 NewMenuEntry->HelpStringToken = HiiSetString (
193 HiiHandle,
194 0,
195 NewMenuEntry->HelpString,
196 NULL
197 );
198 }
199 }
200
201 return EFI_SUCCESS;
202 }
203
204 /**
205 This function allows a caller to extract the current configuration for one
206 or more named elements from the target driver.
207
208
209 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
210 @param Request A null-terminated Unicode string in <ConfigRequest> format.
211 @param Progress On return, points to a character in the Request string.
212 Points to the string's null terminator if request was successful.
213 Points to the most recent '&' before the first failing name/value
214 pair (or the beginning of the string if the failure is in the
215 first name/value pair) if the request was not successful.
216 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
217 has all values filled in for the names in the Request string.
218 String to be allocated by the called function.
219
220 @retval EFI_SUCCESS The Results is filled with the requested values.
221 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
222 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
223 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
224
225 **/
226 EFI_STATUS
227 EFIAPI
228 BootMaintExtractConfig (
229 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
230 IN CONST EFI_STRING Request,
231 OUT EFI_STRING *Progress,
232 OUT EFI_STRING *Results
233 )
234 {
235 EFI_STATUS Status;
236 UINTN BufferSize;
237 BMM_CALLBACK_DATA *Private;
238 EFI_STRING ConfigRequestHdr;
239 EFI_STRING ConfigRequest;
240 BOOLEAN AllocatedRequest;
241 UINTN Size;
242
243 if (Progress == NULL || Results == NULL) {
244 return EFI_INVALID_PARAMETER;
245 }
246
247 *Progress = Request;
248 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gBootMaintFormSetGuid, mBootMaintStorageName)) {
249 return EFI_NOT_FOUND;
250 }
251
252 ConfigRequestHdr = NULL;
253 ConfigRequest = NULL;
254 AllocatedRequest = FALSE;
255 Size = 0;
256
257 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
258 //
259 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
260 //
261 BufferSize = sizeof (BMM_FAKE_NV_DATA);
262 ConfigRequest = Request;
263 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
264 //
265 // Request has no request element, construct full request string.
266 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
267 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
268 //
269 ConfigRequestHdr = HiiConstructConfigHdr (&gBootMaintFormSetGuid, mBootMaintStorageName, Private->BmmDriverHandle);
270 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
271 ConfigRequest = AllocateZeroPool (Size);
272 ASSERT (ConfigRequest != NULL);
273 AllocatedRequest = TRUE;
274 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
275 FreePool (ConfigRequestHdr);
276 }
277
278 Status = gHiiConfigRouting->BlockToConfig (
279 gHiiConfigRouting,
280 ConfigRequest,
281 (UINT8 *) &Private->BmmFakeNvData,
282 BufferSize,
283 Results,
284 Progress
285 );
286 //
287 // Free the allocated config request string.
288 //
289 if (AllocatedRequest) {
290 FreePool (ConfigRequest);
291 ConfigRequest = NULL;
292 }
293 //
294 // Set Progress string to the original request string.
295 //
296 if (Request == NULL) {
297 *Progress = NULL;
298 } else if (StrStr (Request, L"OFFSET") == NULL) {
299 *Progress = Request + StrLen (Request);
300 }
301
302 return Status;
303 }
304
305 /**
306 This function applies changes in a driver's configuration.
307 Input is a Configuration, which has the routing data for this
308 driver followed by name / value configuration pairs. The driver
309 must apply those pairs to its configurable storage. If the
310 driver's configuration is stored in a linear block of data
311 and the driver's name / value pairs are in <BlockConfig>
312 format, it may use the ConfigToBlock helper function (above) to
313 simplify the job. Currently not implemented.
314
315 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
316 @param[in] Configuration A null-terminated Unicode string in
317 <ConfigString> format.
318 @param[out] Progress A pointer to a string filled in with the
319 offset of the most recent '&' before the
320 first failing name / value pair (or the
321 beginn ing of the string if the failure
322 is in the first name / value pair) or
323 the terminating NULL if all was
324 successful.
325
326 @retval EFI_SUCCESS The results have been distributed or are
327 awaiting distribution.
328 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
329 parts of the results that must be
330 stored awaiting possible future
331 protocols.
332 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
333 Results parameter would result
334 in this type of error.
335 @retval EFI_NOT_FOUND Target for the specified routing data
336 was not found.
337 **/
338 EFI_STATUS
339 EFIAPI
340 BootMaintRouteConfig (
341 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
342 IN CONST EFI_STRING Configuration,
343 OUT EFI_STRING *Progress
344 )
345 {
346 EFI_STATUS Status;
347 UINTN BufferSize;
348 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
349 BMM_FAKE_NV_DATA *NewBmmData;
350 BMM_FAKE_NV_DATA *OldBmmData;
351 BM_CONSOLE_CONTEXT *NewConsoleContext;
352 BM_TERMINAL_CONTEXT *NewTerminalContext;
353 BM_MENU_ENTRY *NewMenuEntry;
354 BM_LOAD_CONTEXT *NewLoadContext;
355 UINT16 Index;
356 BOOLEAN TerminalAttChange;
357 BMM_CALLBACK_DATA *Private;
358
359 if (Progress == NULL) {
360 return EFI_INVALID_PARAMETER;
361 }
362 *Progress = Configuration;
363
364 if (Configuration == NULL) {
365 return EFI_INVALID_PARAMETER;
366 }
367
368 //
369 // Check routing data in <ConfigHdr>.
370 // Note: there is no name for Name/Value storage, only GUID will be checked
371 //
372 if (!HiiIsConfigHdrMatch (Configuration, &gBootMaintFormSetGuid, mBootMaintStorageName)) {
373 return EFI_NOT_FOUND;
374 }
375
376 Status = gBS->LocateProtocol (
377 &gEfiHiiConfigRoutingProtocolGuid,
378 NULL,
379 &ConfigRouting
380 );
381 if (EFI_ERROR (Status)) {
382 return Status;
383 }
384
385 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
386 //
387 // Get Buffer Storage data from EFI variable
388 //
389 BufferSize = sizeof (BMM_FAKE_NV_DATA);
390 OldBmmData = &Private->BmmOldFakeNVData;
391 NewBmmData = &Private->BmmFakeNvData;
392 //
393 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
394 //
395 Status = ConfigRouting->ConfigToBlock (
396 ConfigRouting,
397 Configuration,
398 (UINT8 *) NewBmmData,
399 &BufferSize,
400 Progress
401 );
402 ASSERT_EFI_ERROR (Status);
403 //
404 // Compare new and old BMM configuration data and only do action for modified item to
405 // avoid setting unnecessary non-volatile variable
406 //
407
408 //
409 // Check data which located in BMM main page and save the settings if need
410 //
411 if (CompareMem (NewBmmData->LegacyFD, OldBmmData->LegacyFD, sizeof (NewBmmData->LegacyFD)) != 0) {
412 Var_UpdateBBSOption (Private, FORM_SET_FD_ORDER_ID);
413 }
414
415 if (CompareMem (NewBmmData->LegacyHD, OldBmmData->LegacyHD, sizeof (NewBmmData->LegacyHD)) != 0) {
416 Var_UpdateBBSOption (Private, FORM_SET_HD_ORDER_ID);
417 }
418
419 if (CompareMem (NewBmmData->LegacyCD, OldBmmData->LegacyCD, sizeof (NewBmmData->LegacyCD)) != 0) {
420 Var_UpdateBBSOption (Private, FORM_SET_CD_ORDER_ID);
421 }
422
423 if (CompareMem (NewBmmData->LegacyNET, OldBmmData->LegacyNET, sizeof (NewBmmData->LegacyNET)) != 0) {
424 Var_UpdateBBSOption (Private, FORM_SET_NET_ORDER_ID);
425 }
426
427 if (CompareMem (NewBmmData->LegacyBEV, OldBmmData->LegacyBEV, sizeof (NewBmmData->LegacyBEV)) != 0) {
428 Var_UpdateBBSOption (Private, FORM_SET_BEV_ORDER_ID);
429 }
430
431 //
432 // Check data which located in Boot Options Menu and save the settings if need
433 //
434 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
435 for (Index = 0;
436 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
437 Index ++) {
438 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
439 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
440 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
441 }
442
443 Var_DelBootOption ();
444 }
445
446 //
447 // Check data which located in Driver Options Menu and save the settings if need
448 //
449 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
450 for (Index = 0;
451 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
452 Index++) {
453 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
454 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
455 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
456 }
457 Var_DelDriverOption ();
458 }
459
460 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
461 Status = Var_UpdateBootOrder (Private);
462 }
463
464 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
465 Status = Var_UpdateDriverOrder (Private);
466 }
467
468 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {
469 Status = gRT->SetVariable (
470 L"Timeout",
471 &gEfiGlobalVariableGuid,
472 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
473 sizeof (UINT16),
474 &(NewBmmData->BootTimeOut)
475 );
476 ASSERT_EFI_ERROR(Status);
477
478 //
479 // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.
480 //
481 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
482 }
483
484 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
485 Status = Var_UpdateBootNext (Private);
486 }
487
488 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {
489 Var_UpdateConMode (Private);
490 }
491
492 TerminalAttChange = FALSE;
493 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
494
495 //
496 // only need update modified items
497 //
498 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&
499 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&
500 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&
501 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&
502 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&
503 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {
504 continue;
505 }
506
507 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
508 ASSERT (NewMenuEntry != NULL);
509 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
510 NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];
511 ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
512 NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;
513 NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];
514 ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
515 NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;
516 NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];
517 ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
518 NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;
519 NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];
520 ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));
521 NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;
522 NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];
523 NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];
524 ChangeTerminalDevicePath (
525 &(NewTerminalContext->DevicePath),
526 FALSE
527 );
528 TerminalAttChange = TRUE;
529 }
530 if (TerminalAttChange) {
531 Var_UpdateConsoleInpOption ();
532 Var_UpdateConsoleOutOption ();
533 Var_UpdateErrorOutOption ();
534 }
535
536 //
537 // Check data which located in Console Options Menu and save the settings if need
538 //
539 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {
540 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
541 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
542 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
543 ASSERT (Index < MAX_MENU_NUMBER);
544 NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];
545 }
546
547 Var_UpdateConsoleInpOption ();
548 }
549
550 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {
551 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
552 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
553 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
554 ASSERT (Index < MAX_MENU_NUMBER);
555 NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];
556 }
557
558 Var_UpdateConsoleOutOption ();
559 }
560
561 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {
562 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
563 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
564 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
565 ASSERT (Index < MAX_MENU_NUMBER);
566 NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];
567 }
568
569 Var_UpdateErrorOutOption ();
570 }
571
572 //
573 // After user do the save action, need to update OldBmmData.
574 //
575 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
576
577 return EFI_SUCCESS;
578 }
579
580 /**
581 Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.
582
583 **/
584 EFI_STATUS
585 InitializeLegacyBootOption (
586 VOID
587 )
588 {
589 RefreshUpdateData ();
590 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;
591
592 //
593 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
594 // in BootOption form: legacy FD/HD/CD/NET/BEV
595 //
596 HiiCreateGotoOpCode (
597 mStartOpCodeHandle,
598 FORM_SET_FD_ORDER_ID,
599 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
600 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
601 EFI_IFR_FLAG_CALLBACK,
602 FORM_SET_FD_ORDER_ID
603 );
604
605 HiiCreateGotoOpCode (
606 mStartOpCodeHandle,
607 FORM_SET_HD_ORDER_ID,
608 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
609 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
610 EFI_IFR_FLAG_CALLBACK,
611 FORM_SET_HD_ORDER_ID
612 );
613
614 HiiCreateGotoOpCode (
615 mStartOpCodeHandle,
616 FORM_SET_CD_ORDER_ID,
617 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
618 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
619 EFI_IFR_FLAG_CALLBACK,
620 FORM_SET_CD_ORDER_ID
621 );
622
623 HiiCreateGotoOpCode (
624 mStartOpCodeHandle,
625 FORM_SET_NET_ORDER_ID,
626 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
627 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
628 EFI_IFR_FLAG_CALLBACK,
629 FORM_SET_NET_ORDER_ID
630 );
631
632 HiiCreateGotoOpCode (
633 mStartOpCodeHandle,
634 FORM_SET_BEV_ORDER_ID,
635 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
636 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
637 EFI_IFR_FLAG_CALLBACK,
638 FORM_SET_BEV_ORDER_ID
639 );
640
641 HiiUpdateForm (
642 mBmmCallbackInfo->BmmHiiHandle,
643 &gBootMaintFormSetGuid,
644 FORM_BOOT_SETUP_ID,
645 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID
646 mEndOpCodeHandle // LABEL_END
647 );
648
649 return EFI_SUCCESS;
650 }
651
652 /**
653 This function processes the results of changes in configuration.
654
655
656 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
657 @param Action Specifies the type of action taken by the browser.
658 @param QuestionId A unique value which is sent to the original exporting driver
659 so that it can identify the type of data to expect.
660 @param Type The type of value for the question.
661 @param Value A pointer to the data being sent to the original exporting driver.
662 @param ActionRequest On return, points to the action requested by the callback function.
663
664 @retval EFI_SUCCESS The callback successfully handled the action.
665 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
666 @retval EFI_DEVICE_ERROR The variable could not be saved.
667 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
668 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
669 **/
670 EFI_STATUS
671 EFIAPI
672 BootMaintCallback (
673 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
674 IN EFI_BROWSER_ACTION Action,
675 IN EFI_QUESTION_ID QuestionId,
676 IN UINT8 Type,
677 IN EFI_IFR_TYPE_VALUE *Value,
678 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
679 )
680 {
681 BMM_CALLBACK_DATA *Private;
682 BM_MENU_ENTRY *NewMenuEntry;
683 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
684 EFI_STATUS Status;
685 UINTN OldValue;
686 UINTN NewValue;
687 UINTN Number;
688 UINTN Pos;
689 UINTN Bit;
690 UINT16 NewValuePos;
691 UINT16 Index3;
692 UINT16 Index2;
693 UINT16 Index;
694 UINT8 *OldLegacyDev;
695 UINT8 *NewLegacyDev;
696 UINT8 *DisMap;
697 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
698
699 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
700 if (Action == EFI_BROWSER_ACTION_FORM_OPEN && QuestionId == FORM_BOOT_SETUP_ID) {
701 //
702 // Initilize Form for legacy boot option.
703 //
704 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
705 if (!EFI_ERROR (Status)) {
706 InitializeLegacyBootOption ();
707 }
708
709 return EFI_SUCCESS;
710 }
711
712 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
713 //
714 // All other action return unsupported.
715 //
716 return EFI_UNSUPPORTED;
717 }
718
719 Status = EFI_SUCCESS;
720 OldValue = 0;
721 NewValue = 0;
722 Number = 0;
723 OldLegacyDev = NULL;
724 NewLegacyDev = NULL;
725 NewValuePos = 0;
726 DisMap = NULL;
727
728 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
729 //
730 // Retrive uncommitted data from Form Browser
731 //
732 CurrentFakeNVMap = &Private->BmmFakeNvData;
733 HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
734 if (Action == EFI_BROWSER_ACTION_CHANGING) {
735 if (Value == NULL) {
736 return EFI_INVALID_PARAMETER;
737 }
738
739 UpdatePageId (Private, QuestionId);
740
741 if (QuestionId < FILE_OPTION_OFFSET) {
742 if (QuestionId < CONFIG_OPTION_OFFSET) {
743 switch (QuestionId) {
744 case KEY_VALUE_BOOT_FROM_FILE:
745 Private->FeCurrentState = FileExplorerStateBootFromFile;
746 break;
747
748 case FORM_BOOT_ADD_ID:
749 Private->FeCurrentState = FileExplorerStateAddBootOption;
750 break;
751
752 case FORM_DRV_ADD_FILE_ID:
753 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
754 break;
755
756 case FORM_DRV_ADD_HANDLE_ID:
757 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
758 UpdateDrvAddHandlePage (Private);
759 break;
760
761 case FORM_BOOT_DEL_ID:
762 CleanUpPage (FORM_BOOT_DEL_ID, Private);
763 UpdateBootDelPage (Private);
764 break;
765
766 case FORM_BOOT_CHG_ID:
767 case FORM_DRV_CHG_ID:
768 UpdatePageBody (QuestionId, Private);
769 break;
770
771 case FORM_DRV_DEL_ID:
772 CleanUpPage (FORM_DRV_DEL_ID, Private);
773 UpdateDrvDelPage (Private);
774 break;
775
776 case FORM_BOOT_NEXT_ID:
777 CleanUpPage (FORM_BOOT_NEXT_ID, Private);
778 UpdateBootNextPage (Private);
779 break;
780
781 case FORM_TIME_OUT_ID:
782 CleanUpPage (FORM_TIME_OUT_ID, Private);
783 UpdateTimeOutPage (Private);
784 break;
785
786 case FORM_CON_IN_ID:
787 case FORM_CON_OUT_ID:
788 case FORM_CON_ERR_ID:
789 UpdatePageBody (QuestionId, Private);
790 break;
791
792 case FORM_CON_MODE_ID:
793 CleanUpPage (FORM_CON_MODE_ID, Private);
794 UpdateConModePage (Private);
795 break;
796
797 case FORM_CON_COM_ID:
798 CleanUpPage (FORM_CON_COM_ID, Private);
799 UpdateConCOMPage (Private);
800 break;
801
802 case FORM_SET_FD_ORDER_ID:
803 case FORM_SET_HD_ORDER_ID:
804 case FORM_SET_CD_ORDER_ID:
805 case FORM_SET_NET_ORDER_ID:
806 case FORM_SET_BEV_ORDER_ID:
807 CleanUpPage (QuestionId, Private);
808 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
809 break;
810
811 default:
812 break;
813 }
814 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
815 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
816 Private->CurrentTerminal = Index2;
817
818 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
819 UpdateTerminalPage (Private);
820
821 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
822 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
823
824 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);
825 ASSERT (NewMenuEntry != NULL);
826 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
827
828 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
829
830 Private->MenuEntry = NewMenuEntry;
831 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
832
833 UpdateDriverAddHandleDescPage (Private);
834 }
835 }
836 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
837 if ((Value == NULL) || (ActionRequest == NULL)) {
838 return EFI_INVALID_PARAMETER;
839 }
840
841 //
842 // need to be subtituded.
843 //
844 // Update Select FD/HD/CD/NET/BEV Order Form
845 //
846 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {
847
848 DisMap = Private->BmmOldFakeNVData.DisableMap;
849
850 if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {
851 Number = (UINT16) LegacyFDMenu.MenuNumber;
852 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
853 NewLegacyDev = CurrentFakeNVMap->LegacyFD;
854 } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {
855 Number = (UINT16) LegacyHDMenu.MenuNumber;
856 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
857 NewLegacyDev = CurrentFakeNVMap->LegacyHD;
858 } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {
859 Number = (UINT16) LegacyCDMenu.MenuNumber;
860 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
861 NewLegacyDev = CurrentFakeNVMap->LegacyCD;
862 } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {
863 Number = (UINT16) LegacyNETMenu.MenuNumber;
864 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
865 NewLegacyDev = CurrentFakeNVMap->LegacyNET;
866 } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {
867 Number = (UINT16) LegacyBEVMenu.MenuNumber;
868 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
869 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
870 }
871 //
872 // First, find the different position
873 // if there is change, it should be only one
874 //
875 for (Index = 0; Index < Number; Index++) {
876 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
877 OldValue = OldLegacyDev[Index];
878 NewValue = NewLegacyDev[Index];
879 break;
880 }
881 }
882
883 if (Index != Number) {
884 //
885 // there is change, now process
886 //
887 if (0xFF == NewValue) {
888 //
889 // This item will be disable
890 // Just move the items behind this forward to overlap it
891 //
892 Pos = OldValue / 8;
893 Bit = 7 - (OldValue % 8);
894 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
895 for (Index2 = Index; Index2 < Number - 1; Index2++) {
896 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
897 }
898
899 NewLegacyDev[Index2] = 0xFF;
900 } else {
901 for (Index2 = 0; Index2 < Number; Index2++) {
902 if (Index2 == Index) {
903 continue;
904 }
905
906 if (OldLegacyDev[Index2] == NewValue) {
907 //
908 // If NewValue is in OldLegacyDev array
909 // remember its old position
910 //
911 NewValuePos = Index2;
912 break;
913 }
914 }
915
916 if (Index2 != Number) {
917 //
918 // We will change current item to an existing item
919 // (It's hard to describe here, please read code, it's like a cycle-moving)
920 //
921 for (Index2 = NewValuePos; Index2 != Index;) {
922 if (NewValuePos < Index) {
923 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
924 Index2++;
925 } else {
926 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
927 Index2--;
928 }
929 }
930 } else {
931 //
932 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
933 // so we should modify DisMap to reflect the change
934 //
935 Pos = NewValue / 8;
936 Bit = 7 - (NewValue % 8);
937 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
938 if (0xFF != OldValue) {
939 //
940 // Because NewValue is a item that was disabled before
941 // so after changing the OldValue should be disabled
942 // actually we are doing a swap of enable-disable states of two items
943 //
944 Pos = OldValue / 8;
945 Bit = 7 - (OldValue % 8);
946 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
947 }
948 }
949 }
950 //
951 // To prevent DISABLE appears in the middle of the list
952 // we should perform a re-ordering
953 //
954 Index3 = Index;
955 Index = 0;
956 while (Index < Number) {
957 if (0xFF != NewLegacyDev[Index]) {
958 Index++;
959 continue;
960 }
961
962 Index2 = Index;
963 Index2++;
964 while (Index2 < Number) {
965 if (0xFF != NewLegacyDev[Index2]) {
966 break;
967 }
968
969 Index2++;
970 }
971
972 if (Index2 < Number) {
973 NewLegacyDev[Index] = NewLegacyDev[Index2];
974 NewLegacyDev[Index2] = 0xFF;
975 }
976
977 Index++;
978 }
979
980 CopyMem (
981 OldLegacyDev,
982 NewLegacyDev,
983 Number
984 );
985
986 //
987 // Return correct question value.
988 //
989 Value->u8 = NewLegacyDev[Index3];
990 }
991 } else {
992 switch (QuestionId) {
993 case KEY_VALUE_SAVE_AND_EXIT:
994 case KEY_VALUE_NO_SAVE_AND_EXIT:
995 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
996 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
997 if (EFI_ERROR (Status)) {
998 return Status;
999 }
1000 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
1001 DiscardChangeHandler (Private, CurrentFakeNVMap);
1002 }
1003
1004 //
1005 // Tell browser not to ask for confirmation of changes,
1006 // since we have already applied or discarded.
1007 //
1008 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1009 break;
1010
1011 case FORM_RESET:
1012 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1013 return EFI_UNSUPPORTED;
1014
1015 default:
1016 break;
1017 }
1018 }
1019 }
1020
1021 //
1022 // Pass changed uncommitted data back to Form Browser
1023 //
1024 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
1025 return EFI_SUCCESS;
1026 }
1027
1028 /**
1029 Function handling request to apply changes for BMM pages.
1030
1031 @param Private Pointer to callback data buffer.
1032 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM
1033 @param FormId ID of the form which has sent the request to apply change.
1034
1035 @retval EFI_SUCCESS Change successfully applied.
1036 @retval Other Error occurs while trying to apply changes.
1037
1038 **/
1039 EFI_STATUS
1040 ApplyChangeHandler (
1041 IN BMM_CALLBACK_DATA *Private,
1042 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
1043 IN EFI_FORM_ID FormId
1044 )
1045 {
1046 BM_CONSOLE_CONTEXT *NewConsoleContext;
1047 BM_TERMINAL_CONTEXT *NewTerminalContext;
1048 BM_LOAD_CONTEXT *NewLoadContext;
1049 BM_MENU_ENTRY *NewMenuEntry;
1050 EFI_STATUS Status;
1051 UINT16 Index;
1052
1053 Status = EFI_SUCCESS;
1054
1055 switch (FormId) {
1056 case FORM_SET_FD_ORDER_ID:
1057 case FORM_SET_HD_ORDER_ID:
1058 case FORM_SET_CD_ORDER_ID:
1059 case FORM_SET_NET_ORDER_ID:
1060 case FORM_SET_BEV_ORDER_ID:
1061 Var_UpdateBBSOption (Private, FormId);
1062 break;
1063
1064 case FORM_BOOT_DEL_ID:
1065 for (Index = 0;
1066 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0]))));
1067 Index ++) {
1068 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
1069 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
1070 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];
1071 }
1072
1073 Var_DelBootOption ();
1074 break;
1075
1076 case FORM_DRV_DEL_ID:
1077 for (Index = 0;
1078 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0]))));
1079 Index++) {
1080 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
1081 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
1082 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];
1083 }
1084
1085 Var_DelDriverOption ();
1086 break;
1087
1088 case FORM_BOOT_CHG_ID:
1089 Status = Var_UpdateBootOrder (Private);
1090 break;
1091
1092 case FORM_DRV_CHG_ID:
1093 Status = Var_UpdateDriverOrder (Private);
1094 break;
1095
1096 case FORM_TIME_OUT_ID:
1097 BdsDxeSetVariableAndReportStatusCodeOnError (
1098 L"Timeout",
1099 &gEfiGlobalVariableGuid,
1100 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1101 sizeof (UINT16),
1102 &(CurrentFakeNVMap->BootTimeOut)
1103 );
1104
1105 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
1106 break;
1107
1108 case FORM_BOOT_NEXT_ID:
1109 Status = Var_UpdateBootNext (Private);
1110 break;
1111
1112 case FORM_CON_MODE_ID:
1113 Status = Var_UpdateConMode (Private);
1114 break;
1115
1116 case FORM_CON_COM_SETUP_ID:
1117 Index = (UINT16)Private->CurrentTerminal;
1118 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1119
1120 ASSERT (NewMenuEntry != NULL);
1121
1122 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1123
1124 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate[Index];
1125 ASSERT (CurrentFakeNVMap->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
1126 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate[Index]].Value;
1127 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate[Index];
1128 ASSERT (CurrentFakeNVMap->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
1129 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate[Index]].Value;
1130 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits[Index];
1131 ASSERT (CurrentFakeNVMap->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
1132 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits[Index]].Value;
1133 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity[Index];
1134 ASSERT (CurrentFakeNVMap->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));
1135 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity[Index]].Value;
1136 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType[Index];
1137 NewTerminalContext->FlowControl = CurrentFakeNVMap->COMFlowControl[Index];
1138
1139 ChangeTerminalDevicePath (
1140 &(NewTerminalContext->DevicePath),
1141 FALSE
1142 );
1143
1144 Var_UpdateConsoleInpOption ();
1145 Var_UpdateConsoleOutOption ();
1146 Var_UpdateErrorOutOption ();
1147 break;
1148
1149 case FORM_CON_IN_ID:
1150 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
1151 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
1152 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1153 ASSERT (Index < MAX_MENU_NUMBER);
1154 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleInCheck[Index];
1155 }
1156
1157 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1158 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1159 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1160 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
1161 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];
1162 }
1163
1164 Var_UpdateConsoleInpOption ();
1165 break;
1166
1167 case FORM_CON_OUT_ID:
1168 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
1169 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
1170 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1171 ASSERT (Index < MAX_MENU_NUMBER);
1172 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleOutCheck[Index];
1173 }
1174
1175 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1176 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1177 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1178 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
1179 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];
1180 }
1181
1182 Var_UpdateConsoleOutOption ();
1183 break;
1184
1185 case FORM_CON_ERR_ID:
1186 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
1187 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
1188 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1189 ASSERT (Index < MAX_MENU_NUMBER);
1190 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleErrCheck[Index];
1191 }
1192
1193 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1194 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1195 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1196 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
1197 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];
1198 }
1199
1200 Var_UpdateErrorOutOption ();
1201 break;
1202
1203 case FORM_DRV_ADD_HANDLE_DESC_ID:
1204 Status = Var_UpdateDriverOption (
1205 Private,
1206 Private->BmmHiiHandle,
1207 CurrentFakeNVMap->DriverAddHandleDesc,
1208 CurrentFakeNVMap->DriverAddHandleOptionalData,
1209 CurrentFakeNVMap->DriverAddForceReconnect
1210 );
1211 if (EFI_ERROR (Status)) {
1212 goto Error;
1213 }
1214
1215 BOpt_GetDriverOptions (Private);
1216 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
1217 break;
1218
1219 default:
1220 break;
1221 }
1222
1223 Error:
1224 return Status;
1225 }
1226
1227 /**
1228 Discard all changes done to the BMM pages such as Boot Order change,
1229 Driver order change.
1230
1231 @param Private The BMM context data.
1232 @param CurrentFakeNVMap The current Fack NV Map.
1233
1234 **/
1235 VOID
1236 DiscardChangeHandler (
1237 IN BMM_CALLBACK_DATA *Private,
1238 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
1239 )
1240 {
1241 UINT16 Index;
1242
1243 switch (Private->BmmPreviousPageId) {
1244 case FORM_BOOT_CHG_ID:
1245 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
1246 break;
1247
1248 case FORM_DRV_CHG_ID:
1249 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
1250 break;
1251
1252 case FORM_BOOT_DEL_ID:
1253 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
1254 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
1255 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
1256 }
1257 break;
1258
1259 case FORM_DRV_DEL_ID:
1260 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
1261 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1262 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
1263 }
1264 break;
1265
1266 case FORM_BOOT_NEXT_ID:
1267 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
1268 break;
1269
1270 case FORM_TIME_OUT_ID:
1271 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
1272 break;
1273
1274 case FORM_DRV_ADD_HANDLE_DESC_ID:
1275 case FORM_DRV_ADD_FILE_ID:
1276 case FORM_DRV_ADD_HANDLE_ID:
1277 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
1278 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
1279 break;
1280
1281 default:
1282 break;
1283 }
1284 }
1285
1286 /**
1287 Initialize the Boot Maintenance Utitliy.
1288
1289
1290 @retval EFI_SUCCESS utility ended successfully
1291 @retval others contain some errors
1292
1293 **/
1294 EFI_STATUS
1295 InitializeBM (
1296 VOID
1297 )
1298 {
1299 BMM_CALLBACK_DATA *BmmCallbackInfo;
1300 EFI_STATUS Status;
1301 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
1302 UINT32 Length;
1303 UINT8 *Data;
1304
1305 Status = EFI_SUCCESS;
1306 BmmCallbackInfo = mBmmCallbackInfo;
1307
1308 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
1309 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
1310 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;
1311 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;
1312
1313 //
1314 // Reinstall String packages to include more new strings.
1315 //
1316
1317 //
1318 // String package size
1319 //
1320 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);
1321
1322 //
1323 // Add the length of the Package List Header and the terminating Package Header
1324 //
1325 Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER);
1326
1327 //
1328 // Allocate the storage for the entire Package List
1329 //
1330 PackageListHeader = AllocateZeroPool (Length);
1331
1332 //
1333 // If the Package List can not be allocated, then return a NULL HII Handle
1334 //
1335 if (PackageListHeader == NULL) {
1336 return EFI_OUT_OF_RESOURCES;
1337 }
1338
1339 //
1340 // Fill in the GUID and Length of the Package List Header
1341 //
1342 PackageListHeader->PackageLength = Length;
1343
1344 //
1345 // Copy String Data into Package list.
1346 //
1347 Data = (UINT8 *)(PackageListHeader + 1);
1348 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);
1349 CopyMem (Data, (UINT8 *) BdsDxeStrings + sizeof (UINT32), Length);
1350
1351 //
1352 // Add End type HII package.
1353 //
1354 Data += Length;
1355 ((EFI_HII_PACKAGE_HEADER *) Data)->Type = EFI_HII_PACKAGE_END;
1356 ((EFI_HII_PACKAGE_HEADER *) Data)->Length = sizeof (EFI_HII_PACKAGE_HEADER);
1357
1358 //
1359 // Update String package for BM
1360 //
1361 CopyGuid (&PackageListHeader->PackageListGuid, &gBootMaintFormSetGuid);
1362 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle, PackageListHeader);
1363
1364 //
1365 // Update String package for FE.
1366 //
1367 CopyGuid (&PackageListHeader->PackageListGuid, &gFileExploreFormSetGuid);
1368 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle, PackageListHeader);
1369
1370 FreePool (PackageListHeader);
1371
1372 //
1373 // Init OpCode Handle and Allocate space for creation of Buffer
1374 //
1375 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
1376 if (mStartOpCodeHandle == NULL) {
1377 Status = EFI_OUT_OF_RESOURCES;
1378 goto Exit;
1379 }
1380
1381 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
1382 if (mEndOpCodeHandle == NULL) {
1383 Status = EFI_OUT_OF_RESOURCES;
1384 goto Exit;
1385 }
1386
1387 //
1388 // Create Hii Extend Label OpCode as the start opcode
1389 //
1390 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1391 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1392
1393 //
1394 // Create Hii Extend Label OpCode as the end opcode
1395 //
1396 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1397 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1398 mEndLabel->Number = LABEL_END;
1399
1400 InitializeStringDepository ();
1401
1402 InitAllMenu (BmmCallbackInfo);
1403
1404 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
1405 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
1406 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
1407 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
1408 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
1409 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
1410 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
1411
1412 InitializeBmmConfig (BmmCallbackInfo);
1413
1414 //
1415 // Dispatch BMM main formset and File Explorer formset.
1416 //
1417 FormSetDispatcher (BmmCallbackInfo);
1418
1419 //
1420 // Clean up.
1421 //
1422 CleanUpStringDepository ();
1423
1424 FreeAllMenu ();
1425
1426 Exit:
1427 if (mStartOpCodeHandle != NULL) {
1428 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1429 }
1430
1431 if (mEndOpCodeHandle != NULL) {
1432 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1433 }
1434
1435 return Status;
1436 }
1437
1438
1439 /**
1440 Initialized all Menu Option List.
1441
1442 @param CallbackData The BMM context data.
1443
1444 **/
1445 VOID
1446 InitAllMenu (
1447 IN BMM_CALLBACK_DATA *CallbackData
1448 )
1449 {
1450 InitializeListHead (&BootOptionMenu.Head);
1451 InitializeListHead (&DriverOptionMenu.Head);
1452 BOpt_GetBootOptions (CallbackData);
1453 BOpt_GetDriverOptions (CallbackData);
1454 BOpt_GetLegacyOptions ();
1455 InitializeListHead (&FsOptionMenu.Head);
1456 BOpt_FindDrivers ();
1457 InitializeListHead (&DirectoryMenu.Head);
1458 InitializeListHead (&ConsoleInpMenu.Head);
1459 InitializeListHead (&ConsoleOutMenu.Head);
1460 InitializeListHead (&ConsoleErrMenu.Head);
1461 InitializeListHead (&TerminalMenu.Head);
1462 LocateSerialIo ();
1463 GetAllConsoles ();
1464 }
1465
1466 /**
1467 Free up all Menu Option list.
1468
1469 **/
1470 VOID
1471 FreeAllMenu (
1472 VOID
1473 )
1474 {
1475 BOpt_FreeMenu (&DirectoryMenu);
1476 BOpt_FreeMenu (&FsOptionMenu);
1477 BOpt_FreeMenu (&BootOptionMenu);
1478 BOpt_FreeMenu (&DriverOptionMenu);
1479 BOpt_FreeMenu (&DriverMenu);
1480 BOpt_FreeLegacyOptions ();
1481 FreeAllConsoles ();
1482 }
1483
1484 /**
1485 Initialize all the string depositories.
1486
1487 **/
1488 VOID
1489 InitializeStringDepository (
1490 VOID
1491 )
1492 {
1493 STRING_DEPOSITORY *StringDepository;
1494 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1495 FileOptionStrDepository = StringDepository++;
1496 ConsoleOptionStrDepository = StringDepository++;
1497 BootOptionStrDepository = StringDepository++;
1498 BootOptionHelpStrDepository = StringDepository++;
1499 DriverOptionStrDepository = StringDepository++;
1500 DriverOptionHelpStrDepository = StringDepository++;
1501 TerminalStrDepository = StringDepository;
1502 }
1503
1504 /**
1505 Fetch a usable string node from the string depository and return the string token.
1506
1507 @param CallbackData The BMM context data.
1508 @param StringDepository The string repository.
1509
1510 @retval EFI_STRING_ID String token.
1511
1512 **/
1513 EFI_STRING_ID
1514 GetStringTokenFromDepository (
1515 IN BMM_CALLBACK_DATA *CallbackData,
1516 IN STRING_DEPOSITORY *StringDepository
1517 )
1518 {
1519 STRING_LIST_NODE *CurrentListNode;
1520 STRING_LIST_NODE *NextListNode;
1521
1522 CurrentListNode = StringDepository->CurrentNode;
1523
1524 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1525 //
1526 // Fetch one reclaimed node from the list.
1527 //
1528 NextListNode = StringDepository->CurrentNode->Next;
1529 } else {
1530 //
1531 // If there is no usable node in the list, update the list.
1532 //
1533 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1534 ASSERT (NextListNode != NULL);
1535 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);
1536 ASSERT (NextListNode->StringToken != 0);
1537
1538 StringDepository->TotalNodeNumber++;
1539
1540 if (NULL == CurrentListNode) {
1541 StringDepository->ListHead = NextListNode;
1542 } else {
1543 CurrentListNode->Next = NextListNode;
1544 }
1545 }
1546
1547 StringDepository->CurrentNode = NextListNode;
1548
1549 return StringDepository->CurrentNode->StringToken;
1550 }
1551
1552 /**
1553 Reclaim string depositories by moving the current node pointer to list head..
1554
1555 **/
1556 VOID
1557 ReclaimStringDepository (
1558 VOID
1559 )
1560 {
1561 UINTN DepositoryIndex;
1562 STRING_DEPOSITORY *StringDepository;
1563
1564 StringDepository = FileOptionStrDepository;
1565 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1566 StringDepository->CurrentNode = StringDepository->ListHead;
1567 StringDepository++;
1568 }
1569 }
1570
1571 /**
1572 Release resource for all the string depositories.
1573
1574 **/
1575 VOID
1576 CleanUpStringDepository (
1577 VOID
1578 )
1579 {
1580 UINTN NodeIndex;
1581 UINTN DepositoryIndex;
1582 STRING_LIST_NODE *CurrentListNode;
1583 STRING_LIST_NODE *NextListNode;
1584 STRING_DEPOSITORY *StringDepository;
1585
1586 //
1587 // Release string list nodes.
1588 //
1589 StringDepository = FileOptionStrDepository;
1590 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1591 CurrentListNode = StringDepository->ListHead;
1592 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1593 NextListNode = CurrentListNode->Next;
1594 FreePool (CurrentListNode);
1595 CurrentListNode = NextListNode;
1596 }
1597
1598 StringDepository++;
1599 }
1600 //
1601 // Release string depository.
1602 //
1603 FreePool (FileOptionStrDepository);
1604 }
1605
1606 /**
1607 Start boot maintenance manager
1608
1609 @retval EFI_SUCCESS If BMM is invoked successfully.
1610 @return Other value if BMM return unsuccessfully.
1611
1612 **/
1613 EFI_STATUS
1614 BdsStartBootMaint (
1615 VOID
1616 )
1617 {
1618 EFI_STATUS Status;
1619 LIST_ENTRY BdsBootOptionList;
1620
1621 InitializeListHead (&BdsBootOptionList);
1622
1623 //
1624 // Connect all prior to entering the platform setup menu.
1625 //
1626 if (!gConnectAllHappened) {
1627 BdsLibConnectAllDriversToAllControllers ();
1628 gConnectAllHappened = TRUE;
1629 }
1630 //
1631 // Have chance to enumerate boot device
1632 //
1633 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1634
1635 //
1636 // Group the legacy boot options for the same device type
1637 //
1638 GroupMultipleLegacyBootOption4SameType ();
1639
1640 //
1641 // Init the BMM
1642 //
1643 Status = InitializeBM ();
1644
1645 return Status;
1646 }
1647
1648 /**
1649 Dispatch BMM formset and FileExplorer formset.
1650
1651
1652 @param CallbackData The BMM context data.
1653
1654 @retval EFI_SUCCESS If function complete successfully.
1655 @return Other value if the Setup Browser process BMM's pages and
1656 return unsuccessfully.
1657
1658 **/
1659 EFI_STATUS
1660 FormSetDispatcher (
1661 IN BMM_CALLBACK_DATA *CallbackData
1662 )
1663 {
1664 EFI_STATUS Status;
1665 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1666
1667 while (TRUE) {
1668 UpdatePageId (CallbackData, FORM_MAIN_ID);
1669
1670 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1671 Status = gFormBrowser2->SendForm (
1672 gFormBrowser2,
1673 &CallbackData->BmmHiiHandle,
1674 1,
1675 &gBootMaintFormSetGuid,
1676 0,
1677 NULL,
1678 &ActionRequest
1679 );
1680 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1681 EnableResetRequired ();
1682 }
1683
1684 ReclaimStringDepository ();
1685
1686 //
1687 // When this Formset returns, check if we are going to explore files.
1688 //
1689 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {
1690 UpdateFileExplorer (CallbackData, 0);
1691
1692 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1693 Status = gFormBrowser2->SendForm (
1694 gFormBrowser2,
1695 &CallbackData->FeHiiHandle,
1696 1,
1697 &gFileExploreFormSetGuid,
1698 0,
1699 NULL,
1700 &ActionRequest
1701 );
1702 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1703 EnableResetRequired ();
1704 }
1705
1706 CallbackData->FeCurrentState = FileExplorerStateInActive;
1707 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;
1708 ReclaimStringDepository ();
1709 } else {
1710 break;
1711 }
1712 }
1713
1714 return Status;
1715 }
1716
1717 /**
1718 Intall BootMaint and FileExplorer HiiPackages.
1719
1720 **/
1721 EFI_STATUS
1722 InitBMPackage (
1723 VOID
1724 )
1725 {
1726 BMM_CALLBACK_DATA *BmmCallbackInfo;
1727 EFI_STATUS Status;
1728 UINT8 *Ptr;
1729
1730 //
1731 // Create CallbackData structures for Driver Callback
1732 //
1733 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
1734 if (BmmCallbackInfo == NULL) {
1735 return EFI_OUT_OF_RESOURCES;
1736 }
1737
1738 //
1739 // Create LoadOption in BmmCallbackInfo for Driver Callback
1740 //
1741 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
1742 if (Ptr == NULL) {
1743 FreePool (BmmCallbackInfo);
1744 BmmCallbackInfo = NULL;
1745 return EFI_OUT_OF_RESOURCES;
1746 }
1747 //
1748 // Initialize Bmm callback data.
1749 //
1750 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
1751 Ptr += sizeof (BM_LOAD_CONTEXT);
1752
1753 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
1754 Ptr += sizeof (BM_FILE_CONTEXT);
1755
1756 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
1757 Ptr += sizeof (BM_HANDLE_CONTEXT);
1758
1759 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
1760
1761 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
1762 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
1763 BmmCallbackInfo->BmmConfigAccess.RouteConfig = BootMaintRouteConfig;
1764 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
1765 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
1766 BmmCallbackInfo->FeConfigAccess.RouteConfig = FileExplorerRouteConfig;
1767 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
1768
1769 //
1770 // Install Device Path Protocol and Config Access protocol to driver handle
1771 //
1772 Status = gBS->InstallMultipleProtocolInterfaces (
1773 &BmmCallbackInfo->BmmDriverHandle,
1774 &gEfiDevicePathProtocolGuid,
1775 &mBmmHiiVendorDevicePath,
1776 &gEfiHiiConfigAccessProtocolGuid,
1777 &BmmCallbackInfo->BmmConfigAccess,
1778 NULL
1779 );
1780 ASSERT_EFI_ERROR (Status);
1781
1782 //
1783 // Install Device Path Protocol and Config Access protocol to driver handle
1784 //
1785 Status = gBS->InstallMultipleProtocolInterfaces (
1786 &BmmCallbackInfo->FeDriverHandle,
1787 &gEfiDevicePathProtocolGuid,
1788 &mFeHiiVendorDevicePath,
1789 &gEfiHiiConfigAccessProtocolGuid,
1790 &BmmCallbackInfo->FeConfigAccess,
1791 NULL
1792 );
1793 ASSERT_EFI_ERROR (Status);
1794
1795 //
1796 // Post our Boot Maint VFR binary to the HII database.
1797 //
1798 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
1799 &gBootMaintFormSetGuid,
1800 BmmCallbackInfo->BmmDriverHandle,
1801 BmBin,
1802 BdsDxeStrings,
1803 NULL
1804 );
1805 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);
1806
1807 //
1808 // Post our File Explorer VFR binary to the HII database.
1809 //
1810 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (
1811 &gFileExploreFormSetGuid,
1812 BmmCallbackInfo->FeDriverHandle,
1813 FEBin,
1814 BdsDxeStrings,
1815 NULL
1816 );
1817 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);
1818
1819 mBmmCallbackInfo = BmmCallbackInfo;
1820
1821 return EFI_SUCCESS;
1822 }
1823
1824 /**
1825 Remvoe the intalled BootMaint and FileExplorer HiiPackages.
1826
1827 **/
1828 VOID
1829 FreeBMPackage (
1830 VOID
1831 )
1832 {
1833 BMM_CALLBACK_DATA *BmmCallbackInfo;
1834
1835 BmmCallbackInfo = mBmmCallbackInfo;
1836
1837 //
1838 // Remove our IFR data from HII database
1839 //
1840 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);
1841 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);
1842
1843 if (BmmCallbackInfo->FeDriverHandle != NULL) {
1844 gBS->UninstallMultipleProtocolInterfaces (
1845 BmmCallbackInfo->FeDriverHandle,
1846 &gEfiDevicePathProtocolGuid,
1847 &mFeHiiVendorDevicePath,
1848 &gEfiHiiConfigAccessProtocolGuid,
1849 &BmmCallbackInfo->FeConfigAccess,
1850 NULL
1851 );
1852 }
1853
1854 if (BmmCallbackInfo->BmmDriverHandle != NULL) {
1855 gBS->UninstallMultipleProtocolInterfaces (
1856 BmmCallbackInfo->BmmDriverHandle,
1857 &gEfiDevicePathProtocolGuid,
1858 &mBmmHiiVendorDevicePath,
1859 &gEfiHiiConfigAccessProtocolGuid,
1860 &BmmCallbackInfo->BmmConfigAccess,
1861 NULL
1862 );
1863 }
1864
1865 FreePool (BmmCallbackInfo->LoadContext);
1866 FreePool (BmmCallbackInfo);
1867
1868 mBmmCallbackInfo = NULL;
1869
1870 return;
1871 }
1872