]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Report the setting variable failure to platform through the status code when core...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
CommitLineData
5c08e117 1/** @file\r
2 The functions for Boot Maintainence Main menu.\r
3\r
69fc8f08 4Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BootMaint.h"\r
16#include "FormGuid.h"\r
17#include "Bds.h"\r
18#include "FrontPage.h"\r
19\r
20EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
21 {\r
22 END_DEVICE_PATH_TYPE,\r
23 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
24 {\r
25 END_DEVICE_PATH_LENGTH,\r
26 0\r
27 }\r
28 }\r
29};\r
30\r
f6f910dd 31HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {\r
32 {\r
33 {\r
34 HARDWARE_DEVICE_PATH,\r
35 HW_VENDOR_DP,\r
36 {\r
37 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
38 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
39 }\r
40 },\r
e24fc103 41 BOOT_MAINT_FORMSET_GUID\r
f6f910dd 42 },\r
43 {\r
44 END_DEVICE_PATH_TYPE,\r
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
46 { \r
47 (UINT8) (END_DEVICE_PATH_LENGTH),\r
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49 }\r
50 }\r
51};\r
52\r
53HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath = {\r
54 {\r
55 {\r
56 HARDWARE_DEVICE_PATH,\r
57 HW_VENDOR_DP,\r
58 {\r
59 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
60 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
61 }\r
62 },\r
e24fc103 63 FILE_EXPLORE_FORMSET_GUID\r
f6f910dd 64 },\r
65 {\r
66 END_DEVICE_PATH_TYPE,\r
67 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
68 { \r
69 (UINT8) (END_DEVICE_PATH_LENGTH),\r
70 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
71 }\r
72 }\r
73};\r
5c08e117 74\r
75bf9d0e 75CHAR16 mBootMaintStorageName[] = L"BmmData";\r
5c08e117 76CHAR16 mFileExplorerStorageName[] = L"FeData";\r
77\r
78/**\r
79 Init all memu.\r
80\r
81 @param CallbackData The BMM context data.\r
82\r
83**/\r
84VOID\r
85InitAllMenu (\r
86 IN BMM_CALLBACK_DATA *CallbackData\r
87 );\r
88\r
89/**\r
90 Free up all Menu Option list.\r
91\r
92**/\r
93VOID\r
94FreeAllMenu (\r
95 VOID\r
96 );\r
97\r
98/**\r
99 Create string tokens for a menu from its help strings and display strings\r
100\r
101 @param CallbackData The BMM context data.\r
102 @param HiiHandle Hii Handle of the package to be updated.\r
103 @param MenuOption The Menu whose string tokens need to be created\r
104\r
105 @retval EFI_SUCCESS String tokens created successfully\r
106 @retval others contain some errors\r
107**/\r
108EFI_STATUS\r
109CreateMenuStringToken (\r
110 IN BMM_CALLBACK_DATA *CallbackData,\r
111 IN EFI_HII_HANDLE HiiHandle,\r
112 IN BM_MENU_OPTION *MenuOption\r
113 )\r
114{\r
115 BM_MENU_ENTRY *NewMenuEntry;\r
116 UINTN Index;\r
117\r
118 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
119 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
120\r
cb7d01c0 121 NewMenuEntry->DisplayStringToken = HiiSetString (\r
122 HiiHandle,\r
123 0,\r
124 NewMenuEntry->DisplayString,\r
125 NULL\r
126 );\r
5c08e117 127\r
128 if (NULL == NewMenuEntry->HelpString) {\r
129 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
130 } else {\r
cb7d01c0 131 NewMenuEntry->HelpStringToken = HiiSetString (\r
132 HiiHandle,\r
133 0,\r
134 NewMenuEntry->HelpString,\r
135 NULL\r
136 );\r
5c08e117 137 }\r
138 }\r
139\r
140 return EFI_SUCCESS;\r
141}\r
142\r
143/**\r
144 This function allows a caller to extract the current configuration for one\r
145 or more named elements from the target driver.\r
146\r
147\r
148 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
149 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
150 @param Progress On return, points to a character in the Request string.\r
151 Points to the string's null terminator if request was successful.\r
152 Points to the most recent '&' before the first failing name/value\r
153 pair (or the beginning of the string if the failure is in the\r
154 first name/value pair) if the request was not successful.\r
155 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
156 has all values filled in for the names in the Request string.\r
157 String to be allocated by the called function.\r
158\r
159 @retval EFI_SUCCESS The Results is filled with the requested values.\r
160 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
161 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
162 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
163\r
164**/\r
165EFI_STATUS\r
166EFIAPI\r
167BootMaintExtractConfig (\r
168 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
169 IN CONST EFI_STRING Request,\r
170 OUT EFI_STRING *Progress,\r
171 OUT EFI_STRING *Results\r
172 )\r
173{\r
174 EFI_STATUS Status;\r
175 UINTN BufferSize;\r
176 BMM_CALLBACK_DATA *Private;\r
59aefb7e
LG
177 EFI_STRING ConfigRequestHdr;\r
178 EFI_STRING ConfigRequest;\r
179 BOOLEAN AllocatedRequest;\r
180 UINTN Size;\r
5c08e117 181\r
59aefb7e 182 if (Progress == NULL || Results == NULL) {\r
5c08e117 183 return EFI_INVALID_PARAMETER;\r
184 }\r
185\r
59aefb7e 186 *Progress = Request;\r
e24fc103 187 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gBootMaintFormSetGuid, mBootMaintStorageName)) {\r
59aefb7e
LG
188 return EFI_NOT_FOUND;\r
189 }\r
5c08e117 190\r
59aefb7e
LG
191 ConfigRequestHdr = NULL;\r
192 ConfigRequest = NULL;\r
193 AllocatedRequest = FALSE;\r
194 Size = 0;\r
195\r
196 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
5c08e117 197 //\r
198 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
199 //\r
200 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
59aefb7e
LG
201 ConfigRequest = Request;\r
202 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
203 //\r
204 // Request has no request element, construct full request string.\r
205 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
206 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
207 //\r
e24fc103 208 ConfigRequestHdr = HiiConstructConfigHdr (&gBootMaintFormSetGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
59aefb7e
LG
209 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
210 ConfigRequest = AllocateZeroPool (Size);\r
211 ASSERT (ConfigRequest != NULL);\r
212 AllocatedRequest = TRUE;\r
213 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
214 FreePool (ConfigRequestHdr);\r
215 }\r
216\r
5c08e117 217 Status = gHiiConfigRouting->BlockToConfig (\r
218 gHiiConfigRouting,\r
59aefb7e 219 ConfigRequest,\r
5c08e117 220 (UINT8 *) &Private->BmmFakeNvData,\r
221 BufferSize,\r
222 Results,\r
223 Progress\r
224 );\r
59aefb7e
LG
225 //\r
226 // Free the allocated config request string.\r
227 //\r
228 if (AllocatedRequest) {\r
229 FreePool (ConfigRequest);\r
230 ConfigRequest = NULL;\r
231 }\r
232 //\r
233 // Set Progress string to the original request string.\r
234 //\r
235 if (Request == NULL) {\r
236 *Progress = NULL;\r
237 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
238 *Progress = Request + StrLen (Request);\r
239 }\r
240\r
5c08e117 241 return Status;\r
242}\r
243\r
244/**\r
245 This function processes the results of changes in configuration.\r
246\r
247\r
248 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
249 @param Action Specifies the type of action taken by the browser.\r
250 @param QuestionId A unique value which is sent to the original exporting driver\r
251 so that it can identify the type of data to expect.\r
252 @param Type The type of value for the question.\r
253 @param Value A pointer to the data being sent to the original exporting driver.\r
254 @param ActionRequest On return, points to the action requested by the callback function.\r
255\r
256 @retval EFI_SUCCESS The callback successfully handled the action.\r
257 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
258 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
259 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
260 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
261**/\r
262EFI_STATUS\r
263EFIAPI\r
264BootMaintCallback (\r
265 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
266 IN EFI_BROWSER_ACTION Action,\r
267 IN EFI_QUESTION_ID QuestionId,\r
268 IN UINT8 Type,\r
269 IN EFI_IFR_TYPE_VALUE *Value,\r
270 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
271 )\r
272{\r
273 BMM_CALLBACK_DATA *Private;\r
274 BM_MENU_ENTRY *NewMenuEntry;\r
275 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
276 EFI_STATUS Status;\r
277 UINTN OldValue;\r
278 UINTN NewValue;\r
279 UINTN Number;\r
280 UINTN Pos;\r
281 UINTN Bit;\r
282 UINT16 NewValuePos;\r
98ba35a4 283 UINT16 Index3; \r
5c08e117 284 UINT16 Index2;\r
285 UINT16 Index;\r
286 UINT8 *OldLegacyDev;\r
287 UINT8 *NewLegacyDev;\r
288 UINT8 *DisMap;\r
d88f86f1 289\r
84724077
ED
290 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { \r
291 //\r
292 // All other action return unsupported.\r
293 //\r
294 return EFI_UNSUPPORTED;\r
295 }\r
296 \r
297 Status = EFI_SUCCESS;\r
298 OldValue = 0;\r
299 NewValue = 0;\r
300 Number = 0;\r
301 OldLegacyDev = NULL;\r
302 NewLegacyDev = NULL;\r
303 NewValuePos = 0;\r
304 DisMap = NULL;\r
305\r
306 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
307 //\r
308 // Retrive uncommitted data from Form Browser\r
309 //\r
310 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
311 HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
d88f86f1 312 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
84724077 313 if (Value == NULL) {\r
d88f86f1
ED
314 return EFI_INVALID_PARAMETER;\r
315 }\r
84724077 316 \r
d88f86f1
ED
317 UpdatePageId (Private, QuestionId);\r
318\r
dc840773
ED
319 if (QuestionId < FILE_OPTION_OFFSET) {\r
320 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
321 switch (QuestionId) {\r
322 case KEY_VALUE_BOOT_FROM_FILE:\r
323 Private->FeCurrentState = FileExplorerStateBootFromFile;\r
324 break;\r
325\r
326 case FORM_BOOT_ADD_ID:\r
327 Private->FeCurrentState = FileExplorerStateAddBootOption;\r
328 break;\r
329\r
330 case FORM_DRV_ADD_FILE_ID:\r
331 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;\r
332 break;\r
333\r
334 case FORM_DRV_ADD_HANDLE_ID:\r
335 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
336 UpdateDrvAddHandlePage (Private);\r
337 break;\r
338\r
339 case FORM_BOOT_DEL_ID:\r
340 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
341 UpdateBootDelPage (Private);\r
342 break;\r
343\r
344 case FORM_BOOT_CHG_ID:\r
345 case FORM_DRV_CHG_ID:\r
346 UpdatePageBody (QuestionId, Private);\r
347 break;\r
348\r
349 case FORM_DRV_DEL_ID:\r
350 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
351 UpdateDrvDelPage (Private);\r
352 break;\r
353\r
354 case FORM_BOOT_NEXT_ID:\r
355 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
356 UpdateBootNextPage (Private);\r
357 break;\r
358\r
359 case FORM_TIME_OUT_ID:\r
360 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
361 UpdateTimeOutPage (Private);\r
362 break;\r
363\r
364 case FORM_CON_IN_ID:\r
365 case FORM_CON_OUT_ID:\r
366 case FORM_CON_ERR_ID:\r
367 UpdatePageBody (QuestionId, Private);\r
368 break;\r
369\r
370 case FORM_CON_MODE_ID:\r
371 CleanUpPage (FORM_CON_MODE_ID, Private);\r
372 UpdateConModePage (Private);\r
373 break;\r
374\r
375 case FORM_CON_COM_ID:\r
376 CleanUpPage (FORM_CON_COM_ID, Private);\r
377 UpdateConCOMPage (Private);\r
378 break;\r
379\r
380 case FORM_SET_FD_ORDER_ID:\r
381 case FORM_SET_HD_ORDER_ID:\r
382 case FORM_SET_CD_ORDER_ID:\r
383 case FORM_SET_NET_ORDER_ID:\r
384 case FORM_SET_BEV_ORDER_ID:\r
385 CleanUpPage (QuestionId, Private);\r
386 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);\r
387 break;\r
388\r
389 default:\r
390 break;\r
391 }\r
392 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
393 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
394 Private->CurrentTerminal = Index2;\r
395\r
396 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
397 UpdateTerminalPage (Private);\r
398\r
399 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
400 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
401\r
402 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);\r
403 ASSERT (NewMenuEntry != NULL);\r
404 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
405\r
406 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
407\r
408 Private->MenuEntry = NewMenuEntry;\r
409 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
410\r
411 UpdateDriverAddHandleDescPage (Private);\r
412 }\r
413 }\r
414 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
415 if ((Value == NULL) || (ActionRequest == NULL)) {\r
416 return EFI_INVALID_PARAMETER;\r
417 }\r
418 \r
d88f86f1
ED
419 //\r
420 // need to be subtituded.\r
421 //\r
422 // Update Select FD/HD/CD/NET/BEV Order Form\r
423 //\r
98ba35a4 424 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {\r
d88f86f1
ED
425\r
426 DisMap = Private->BmmOldFakeNVData.DisableMap;\r
427\r
98ba35a4 428 if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
429 Number = (UINT16) LegacyFDMenu.MenuNumber;\r
430 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;\r
431 NewLegacyDev = CurrentFakeNVMap->LegacyFD;\r
98ba35a4 432 } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
433 Number = (UINT16) LegacyHDMenu.MenuNumber;\r
434 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;\r
435 NewLegacyDev = CurrentFakeNVMap->LegacyHD;\r
98ba35a4 436 } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
437 Number = (UINT16) LegacyCDMenu.MenuNumber;\r
438 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;\r
439 NewLegacyDev = CurrentFakeNVMap->LegacyCD;\r
98ba35a4 440 } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
441 Number = (UINT16) LegacyNETMenu.MenuNumber;\r
442 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;\r
443 NewLegacyDev = CurrentFakeNVMap->LegacyNET;\r
98ba35a4 444 } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
445 Number = (UINT16) LegacyBEVMenu.MenuNumber;\r
446 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;\r
447 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;\r
d88f86f1 448 }\r
5c08e117 449 //\r
d88f86f1
ED
450 // First, find the different position\r
451 // if there is change, it should be only one\r
5c08e117 452 //\r
d88f86f1
ED
453 for (Index = 0; Index < Number; Index++) {\r
454 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {\r
455 OldValue = OldLegacyDev[Index];\r
456 NewValue = NewLegacyDev[Index];\r
457 break;\r
458 }\r
459 }\r
460\r
461 if (Index != Number) {\r
5c08e117 462 //\r
d88f86f1 463 // there is change, now process\r
5c08e117 464 //\r
d88f86f1
ED
465 if (0xFF == NewValue) {\r
466 //\r
467 // This item will be disable\r
468 // Just move the items behind this forward to overlap it\r
469 //\r
470 Pos = OldValue / 8;\r
471 Bit = 7 - (OldValue % 8);\r
472 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
473 for (Index2 = Index; Index2 < Number - 1; Index2++) {\r
474 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];\r
475 }\r
5c08e117 476\r
d88f86f1
ED
477 NewLegacyDev[Index2] = 0xFF;\r
478 } else {\r
479 for (Index2 = 0; Index2 < Number; Index2++) {\r
480 if (Index2 == Index) {\r
481 continue;\r
482 }\r
483\r
484 if (OldLegacyDev[Index2] == NewValue) {\r
485 //\r
486 // If NewValue is in OldLegacyDev array\r
487 // remember its old position\r
488 //\r
489 NewValuePos = Index2;\r
490 break;\r
491 }\r
5c08e117 492 }\r
493\r
d88f86f1 494 if (Index2 != Number) {\r
5c08e117 495 //\r
d88f86f1
ED
496 // We will change current item to an existing item\r
497 // (It's hard to describe here, please read code, it's like a cycle-moving)\r
5c08e117 498 //\r
d88f86f1
ED
499 for (Index2 = NewValuePos; Index2 != Index;) {\r
500 if (NewValuePos < Index) {\r
501 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];\r
502 Index2++;\r
503 } else {\r
504 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];\r
505 Index2--;\r
506 }\r
5c08e117 507 }\r
d88f86f1 508 } else {\r
5c08e117 509 //\r
d88f86f1
ED
510 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item\r
511 // so we should modify DisMap to reflect the change\r
5c08e117 512 //\r
d88f86f1
ED
513 Pos = NewValue / 8;\r
514 Bit = 7 - (NewValue % 8);\r
515 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));\r
516 if (0xFF != OldValue) {\r
517 //\r
518 // Because NewValue is a item that was disabled before\r
519 // so after changing the OldValue should be disabled\r
520 // actually we are doing a swap of enable-disable states of two items\r
521 //\r
522 Pos = OldValue / 8;\r
523 Bit = 7 - (OldValue % 8);\r
524 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
525 }\r
5c08e117 526 }\r
527 }\r
d88f86f1
ED
528 //\r
529 // To prevent DISABLE appears in the middle of the list\r
530 // we should perform a re-ordering\r
531 //\r
98ba35a4 532 Index3 = Index;\r
d88f86f1
ED
533 Index = 0;\r
534 while (Index < Number) {\r
535 if (0xFF != NewLegacyDev[Index]) {\r
536 Index++;\r
537 continue;\r
5c08e117 538 }\r
539\r
d88f86f1 540 Index2 = Index;\r
5c08e117 541 Index2++;\r
d88f86f1
ED
542 while (Index2 < Number) {\r
543 if (0xFF != NewLegacyDev[Index2]) {\r
544 break;\r
545 }\r
5c08e117 546\r
d88f86f1
ED
547 Index2++;\r
548 }\r
549\r
550 if (Index2 < Number) {\r
551 NewLegacyDev[Index] = NewLegacyDev[Index2];\r
552 NewLegacyDev[Index2] = 0xFF;\r
553 }\r
554\r
555 Index++;\r
5c08e117 556 }\r
557\r
d88f86f1
ED
558 CopyMem (\r
559 OldLegacyDev,\r
560 NewLegacyDev,\r
561 Number\r
562 );\r
98ba35a4
ED
563\r
564 //\r
565 // Return correct question value.\r
566 //\r
567 Value->u8 = NewLegacyDev[Index3];\r
5c08e117 568 }\r
dc840773
ED
569 } else {\r
570 switch (QuestionId) {\r
571 case KEY_VALUE_SAVE_AND_EXIT:\r
572 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
573 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
574 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);\r
575 if (EFI_ERROR (Status)) {\r
576 return Status;\r
577 }\r
578 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
579 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
d88f86f1 580 }\r
5c08e117 581\r
dc840773
ED
582 //\r
583 // Tell browser not to ask for confirmation of changes,\r
584 // since we have already applied or discarded.\r
585 //\r
586 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
587 break; \r
5c08e117 588\r
dc840773
ED
589 case FORM_RESET:\r
590 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
591 return EFI_UNSUPPORTED;\r
5c08e117 592\r
dc840773
ED
593 default:\r
594 break;\r
d88f86f1 595 }\r
5c08e117 596 }\r
597 }\r
598\r
599 //\r
84724077 600 // Pass changed uncommitted data back to Form Browser\r
5c08e117 601 //\r
84724077
ED
602 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
603 return EFI_SUCCESS;\r
5c08e117 604}\r
605\r
606/**\r
607 Function handling request to apply changes for BMM pages.\r
608\r
609 @param Private Pointer to callback data buffer.\r
610 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM\r
611 @param FormId ID of the form which has sent the request to apply change.\r
612\r
613 @retval EFI_SUCCESS Change successfully applied.\r
614 @retval Other Error occurs while trying to apply changes.\r
615\r
616**/\r
617EFI_STATUS\r
618ApplyChangeHandler (\r
619 IN BMM_CALLBACK_DATA *Private,\r
620 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
621 IN EFI_FORM_ID FormId\r
622 )\r
623{\r
624 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
625 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
626 BM_LOAD_CONTEXT *NewLoadContext;\r
627 BM_MENU_ENTRY *NewMenuEntry;\r
628 EFI_STATUS Status;\r
629 UINT16 Index;\r
630\r
631 Status = EFI_SUCCESS;\r
632\r
633 switch (FormId) {\r
634 case FORM_SET_FD_ORDER_ID:\r
635 case FORM_SET_HD_ORDER_ID:\r
636 case FORM_SET_CD_ORDER_ID:\r
637 case FORM_SET_NET_ORDER_ID:\r
638 case FORM_SET_BEV_ORDER_ID:\r
639 Var_UpdateBBSOption (Private);\r
640 break;\r
641\r
642 case FORM_BOOT_DEL_ID:\r
bd828c8e 643 for (Index = 0; \r
b452ca89 644 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])))); \r
bd828c8e 645 Index ++) {\r
5c08e117 646 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
647 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 648 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];\r
5c08e117 649 }\r
650\r
651 Var_DelBootOption ();\r
652 break;\r
653\r
654 case FORM_DRV_DEL_ID:\r
bd828c8e 655 for (Index = 0; \r
b452ca89 656 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])))); \r
bd828c8e 657 Index++) {\r
5c08e117 658 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
659 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 660 NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];\r
5c08e117 661 }\r
662\r
663 Var_DelDriverOption ();\r
664 break;\r
665\r
666 case FORM_BOOT_CHG_ID:\r
667 Status = Var_UpdateBootOrder (Private);\r
668 break;\r
669\r
670 case FORM_DRV_CHG_ID:\r
671 Status = Var_UpdateDriverOrder (Private);\r
672 break;\r
673\r
674 case FORM_TIME_OUT_ID:\r
69fc8f08
RN
675 BdsDxeSetVariableAndReportStatusCodeOnError (\r
676 L"Timeout",\r
677 &gEfiGlobalVariableGuid,\r
678 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
679 sizeof (UINT16),\r
680 &(CurrentFakeNVMap->BootTimeOut)\r
681 );\r
5c08e117 682\r
683 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
684 break;\r
685\r
686 case FORM_BOOT_NEXT_ID:\r
687 Status = Var_UpdateBootNext (Private);\r
688 break;\r
689\r
690 case FORM_CON_MODE_ID:\r
691 Status = Var_UpdateConMode (Private);\r
692 break;\r
693\r
694 case FORM_CON_COM_SETUP_ID:\r
695 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
696\r
697 ASSERT (NewMenuEntry != NULL);\r
698\r
699 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
700\r
701 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
702 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
703 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
704 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
705 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
706 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
707 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
708 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
709 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
710 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
711 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));\r
712 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
713 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
8e491a81 714 NewTerminalContext->FlowControl = CurrentFakeNVMap->COMFlowControl;\r
5c08e117 715\r
716 ChangeTerminalDevicePath (\r
8e491a81 717 &(NewTerminalContext->DevicePath),\r
5c08e117 718 FALSE\r
719 );\r
720\r
721 Var_UpdateConsoleInpOption ();\r
722 Var_UpdateConsoleOutOption ();\r
723 Var_UpdateErrorOutOption ();\r
724 break;\r
725\r
726 case FORM_CON_IN_ID:\r
b7b0dca2 727 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
5c08e117 728 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
729 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 730 ASSERT (Index < MAX_MENU_NUMBER);\r
5c08e117 731 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
732 }\r
733\r
b7b0dca2 734 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 735 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
736 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 737 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
5c08e117 738 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
739 }\r
740\r
741 Var_UpdateConsoleInpOption ();\r
742 break;\r
743\r
744 case FORM_CON_OUT_ID:\r
b7b0dca2 745 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
5c08e117 746 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
747 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 748 ASSERT (Index < MAX_MENU_NUMBER);\r
5c08e117 749 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
750 }\r
751\r
b7b0dca2 752 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 753 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
754 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 755 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
5c08e117 756 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
757 }\r
758\r
759 Var_UpdateConsoleOutOption ();\r
760 break;\r
761\r
762 case FORM_CON_ERR_ID:\r
b7b0dca2 763 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
5c08e117 764 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
765 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 766 ASSERT (Index < MAX_MENU_NUMBER);\r
5c08e117 767 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
768 }\r
769\r
b7b0dca2 770 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 771 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
772 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 773 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
5c08e117 774 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
775 }\r
776\r
777 Var_UpdateErrorOutOption ();\r
778 break;\r
779\r
780 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
781 Status = Var_UpdateDriverOption (\r
782 Private,\r
783 Private->BmmHiiHandle,\r
784 CurrentFakeNVMap->DriverAddHandleDesc,\r
785 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
786 CurrentFakeNVMap->DriverAddForceReconnect\r
787 );\r
788 if (EFI_ERROR (Status)) {\r
789 goto Error;\r
790 }\r
791\r
792 BOpt_GetDriverOptions (Private);\r
793 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
794 break;\r
795\r
796 default:\r
797 break;\r
798 }\r
799\r
800Error:\r
801 return Status;\r
802}\r
803\r
804/**\r
805 Discard all changes done to the BMM pages such as Boot Order change,\r
806 Driver order change.\r
807\r
808 @param Private The BMM context data.\r
809 @param CurrentFakeNVMap The current Fack NV Map.\r
810\r
811**/\r
812VOID\r
813DiscardChangeHandler (\r
814 IN BMM_CALLBACK_DATA *Private,\r
815 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
816 )\r
817{\r
818 UINT16 Index;\r
819\r
820 switch (Private->BmmPreviousPageId) {\r
821 case FORM_BOOT_CHG_ID:\r
822 case FORM_DRV_CHG_ID:\r
b452ca89 823 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, sizeof (CurrentFakeNVMap->OptionOrder));\r
5c08e117 824 break;\r
825\r
826 case FORM_BOOT_DEL_ID:\r
b452ca89 827 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));\r
5c08e117 828 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
b452ca89 829 CurrentFakeNVMap->OptionDel[Index] = FALSE;\r
5c08e117 830 }\r
831 break;\r
832\r
833 case FORM_DRV_DEL_ID:\r
b452ca89 834 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));\r
5c08e117 835 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
b452ca89 836 CurrentFakeNVMap->OptionDel[Index] = FALSE;\r
5c08e117 837 }\r
838 break;\r
839\r
840 case FORM_BOOT_NEXT_ID:\r
841 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
842 break;\r
843\r
844 case FORM_TIME_OUT_ID:\r
845 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
846 break;\r
847\r
848 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
849 case FORM_DRV_ADD_FILE_ID:\r
850 case FORM_DRV_ADD_HANDLE_ID:\r
851 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
852 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
853 break;\r
854\r
855 default:\r
856 break;\r
857 }\r
858}\r
859\r
860/**\r
861 Initialize the Boot Maintenance Utitliy.\r
862\r
863\r
864 @retval EFI_SUCCESS utility ended successfully\r
865 @retval others contain some errors\r
866\r
867**/\r
868EFI_STATUS\r
869InitializeBM (\r
870 VOID\r
871 )\r
872{\r
873 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
5c08e117 874 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
875 EFI_STATUS Status;\r
876 UINT8 *Ptr;\r
877\r
878 Status = EFI_SUCCESS;\r
879\r
880 //\r
881 // Create CallbackData structures for Driver Callback\r
882 //\r
883 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
884 if (BmmCallbackInfo == NULL) {\r
885 return EFI_OUT_OF_RESOURCES;\r
886 }\r
887\r
888 //\r
889 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
890 //\r
891 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
892 if (Ptr == NULL) {\r
893 FreePool (BmmCallbackInfo);\r
894 return EFI_OUT_OF_RESOURCES;\r
895 }\r
896\r
897 //\r
898 // Initialize Bmm callback data.\r
899 //\r
900 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
901 Ptr += sizeof (BM_LOAD_CONTEXT);\r
902\r
903 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
904 Ptr += sizeof (BM_FILE_CONTEXT);\r
905\r
906 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
907 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
908\r
909 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
910\r
911 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
912 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
913 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;\r
914 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
915 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
916 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
917 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
918 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;\r
919 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
13078b3f 920 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
921 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
5c08e117 922\r
923 //\r
f6f910dd 924 // Install Device Path Protocol and Config Access protocol to driver handle\r
5c08e117 925 //\r
f6f910dd 926 Status = gBS->InstallMultipleProtocolInterfaces (\r
5c08e117 927 &BmmCallbackInfo->BmmDriverHandle,\r
f6f910dd 928 &gEfiDevicePathProtocolGuid,\r
929 &mBmmHiiVendorDevicePath,\r
5c08e117 930 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 931 &BmmCallbackInfo->BmmConfigAccess,\r
932 NULL\r
5c08e117 933 );\r
934 if (EFI_ERROR (Status)) {\r
4376a6f2 935 goto Exit;\r
5c08e117 936 }\r
937\r
938 //\r
f6f910dd 939 // Install Device Path Protocol and Config Access protocol to driver handle\r
5c08e117 940 //\r
f6f910dd 941 Status = gBS->InstallMultipleProtocolInterfaces (\r
5c08e117 942 &BmmCallbackInfo->FeDriverHandle,\r
f6f910dd 943 &gEfiDevicePathProtocolGuid,\r
944 &mFeHiiVendorDevicePath,\r
5c08e117 945 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 946 &BmmCallbackInfo->FeConfigAccess,\r
947 NULL\r
5c08e117 948 );\r
949 if (EFI_ERROR (Status)) {\r
4376a6f2 950 goto Exit;\r
5c08e117 951 }\r
952\r
953 //\r
baf46e70 954 // Post our Boot Maint VFR binary to the HII database.\r
5c08e117 955 //\r
cb7d01c0 956 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
e24fc103 957 &gBootMaintFormSetGuid,\r
cb7d01c0 958 BmmCallbackInfo->BmmDriverHandle,\r
959 BmBin,\r
960 BdsDxeStrings,\r
961 NULL\r
962 );\r
963 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
5c08e117 964\r
965 //\r
966 // Post our File Explorer VFR binary to the HII database.\r
967 //\r
cb7d01c0 968 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
e24fc103 969 &gFileExploreFormSetGuid,\r
cb7d01c0 970 BmmCallbackInfo->FeDriverHandle,\r
971 FEBin,\r
972 BdsDxeStrings,\r
973 NULL\r
974 );\r
975 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
5c08e117 976\r
977 //\r
75bf9d0e 978 // Init OpCode Handle and Allocate space for creation of Buffer\r
5c08e117 979 //\r
75bf9d0e
LG
980 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
981 if (mStartOpCodeHandle == NULL) {\r
4376a6f2 982 Status = EFI_OUT_OF_RESOURCES;\r
983 goto Exit;\r
5c08e117 984 }\r
985\r
75bf9d0e
LG
986 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
987 if (mEndOpCodeHandle == NULL) {\r
988 Status = EFI_OUT_OF_RESOURCES;\r
989 goto Exit;\r
990 }\r
991\r
992 //\r
993 // Create Hii Extend Label OpCode as the start opcode\r
994 //\r
995 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
996 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
997\r
998 //\r
999 // Create Hii Extend Label OpCode as the end opcode\r
1000 //\r
1001 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1002 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1003 mEndLabel->Number = LABEL_END;\r
1004\r
5c08e117 1005 InitializeStringDepository ();\r
1006\r
1007 InitAllMenu (BmmCallbackInfo);\r
1008\r
1009 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
1010 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
1011 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
1012 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
1013 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
1014 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
1015 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
1016\r
1017 UpdateBootDelPage (BmmCallbackInfo);\r
1018 UpdateDrvDelPage (BmmCallbackInfo);\r
1019\r
1020 if (TerminalMenu.MenuNumber > 0) {\r
1021 BmmCallbackInfo->CurrentTerminal = 0;\r
1022 UpdateTerminalPage (BmmCallbackInfo);\r
1023 }\r
1024\r
16e5944a 1025 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
5c08e117 1026 if (!EFI_ERROR (Status)) {\r
1027 RefreshUpdateData ();\r
75bf9d0e 1028 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
5c08e117 1029\r
1030 //\r
1031 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
1032 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
1033 //\r
75bf9d0e
LG
1034 HiiCreateGotoOpCode (\r
1035 mStartOpCodeHandle,\r
5c08e117 1036 FORM_SET_FD_ORDER_ID,\r
1037 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
1038 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
1039 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 1040 FORM_SET_FD_ORDER_ID\r
5c08e117 1041 );\r
1042\r
75bf9d0e
LG
1043 HiiCreateGotoOpCode (\r
1044 mStartOpCodeHandle,\r
5c08e117 1045 FORM_SET_HD_ORDER_ID,\r
1046 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
1047 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
1048 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 1049 FORM_SET_HD_ORDER_ID\r
5c08e117 1050 );\r
1051\r
75bf9d0e
LG
1052 HiiCreateGotoOpCode (\r
1053 mStartOpCodeHandle,\r
5c08e117 1054 FORM_SET_CD_ORDER_ID,\r
1055 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
1056 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
1057 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 1058 FORM_SET_CD_ORDER_ID\r
5c08e117 1059 );\r
1060\r
75bf9d0e
LG
1061 HiiCreateGotoOpCode (\r
1062 mStartOpCodeHandle,\r
5c08e117 1063 FORM_SET_NET_ORDER_ID,\r
1064 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
1065 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
1066 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 1067 FORM_SET_NET_ORDER_ID\r
5c08e117 1068 );\r
1069\r
75bf9d0e
LG
1070 HiiCreateGotoOpCode (\r
1071 mStartOpCodeHandle,\r
5c08e117 1072 FORM_SET_BEV_ORDER_ID,\r
1073 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1074 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1075 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 1076 FORM_SET_BEV_ORDER_ID\r
5c08e117 1077 );\r
75bf9d0e
LG
1078 \r
1079 HiiUpdateForm (\r
5c08e117 1080 BmmCallbackInfo->BmmHiiHandle,\r
e24fc103 1081 &gBootMaintFormSetGuid,\r
3cdcfa85 1082 FORM_BOOT_SETUP_ID,\r
75bf9d0e
LG
1083 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID\r
1084 mEndOpCodeHandle // LABEL_END\r
5c08e117 1085 );\r
1086 }\r
1087\r
1088 //\r
1089 // Dispatch BMM main formset and File Explorer formset.\r
1090 //\r
1091 FormSetDispatcher (BmmCallbackInfo);\r
1092\r
1093 //\r
1094 // Remove our IFR data from HII database\r
1095 //\r
cb7d01c0 1096 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
1097 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
5c08e117 1098\r
1099 CleanUpStringDepository ();\r
1100\r
1101 FreeAllMenu ();\r
1102\r
4376a6f2 1103Exit:\r
75bf9d0e
LG
1104 if (mStartOpCodeHandle != NULL) {\r
1105 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1106 }\r
1107\r
1108 if (mEndOpCodeHandle != NULL) {\r
1109 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1110 }\r
1111\r
4376a6f2 1112 if (BmmCallbackInfo->FeDriverHandle != NULL) {\r
1113 gBS->UninstallMultipleProtocolInterfaces (\r
1114 BmmCallbackInfo->FeDriverHandle,\r
1115 &gEfiDevicePathProtocolGuid,\r
1116 &mFeHiiVendorDevicePath,\r
1117 &gEfiHiiConfigAccessProtocolGuid,\r
1118 &BmmCallbackInfo->FeConfigAccess,\r
1119 NULL\r
1120 );\r
1121 }\r
1122\r
1123 if (BmmCallbackInfo->BmmDriverHandle != NULL) {\r
1124 gBS->UninstallMultipleProtocolInterfaces (\r
1125 BmmCallbackInfo->BmmDriverHandle,\r
1126 &gEfiDevicePathProtocolGuid,\r
1127 &mBmmHiiVendorDevicePath,\r
1128 &gEfiHiiConfigAccessProtocolGuid,\r
1129 &BmmCallbackInfo->BmmConfigAccess,\r
1130 NULL\r
1131 );\r
1132 }\r
1133\r
1134 FreePool (BmmCallbackInfo->LoadContext);\r
1135 FreePool (BmmCallbackInfo);\r
1136\r
5c08e117 1137 return Status;\r
1138}\r
1139\r
1140/**\r
1141 Initialized all Menu Option List.\r
1142\r
1143 @param CallbackData The BMM context data.\r
1144\r
1145**/\r
1146VOID\r
1147InitAllMenu (\r
1148 IN BMM_CALLBACK_DATA *CallbackData\r
1149 )\r
1150{\r
1151 InitializeListHead (&BootOptionMenu.Head);\r
1152 InitializeListHead (&DriverOptionMenu.Head);\r
1153 BOpt_GetBootOptions (CallbackData);\r
1154 BOpt_GetDriverOptions (CallbackData);\r
1155 BOpt_GetLegacyOptions ();\r
1156 InitializeListHead (&FsOptionMenu.Head);\r
1157 BOpt_FindDrivers ();\r
1158 InitializeListHead (&DirectoryMenu.Head);\r
1159 InitializeListHead (&ConsoleInpMenu.Head);\r
1160 InitializeListHead (&ConsoleOutMenu.Head);\r
1161 InitializeListHead (&ConsoleErrMenu.Head);\r
1162 InitializeListHead (&TerminalMenu.Head);\r
1163 LocateSerialIo ();\r
1164 GetAllConsoles ();\r
1165}\r
1166\r
1167/**\r
1168 Free up all Menu Option list.\r
1169\r
1170**/\r
1171VOID\r
1172FreeAllMenu (\r
1173 VOID\r
1174 )\r
1175{\r
1176 BOpt_FreeMenu (&DirectoryMenu);\r
1177 BOpt_FreeMenu (&FsOptionMenu);\r
1178 BOpt_FreeMenu (&BootOptionMenu);\r
1179 BOpt_FreeMenu (&DriverOptionMenu);\r
1180 BOpt_FreeMenu (&DriverMenu);\r
1181 BOpt_FreeLegacyOptions ();\r
1182 FreeAllConsoles ();\r
1183}\r
1184\r
1185/**\r
baf46e70 1186 Initialize all the string depositories.\r
5c08e117 1187\r
1188**/\r
1189VOID\r
1190InitializeStringDepository (\r
1191 VOID\r
1192 )\r
1193{\r
1194 STRING_DEPOSITORY *StringDepository;\r
1195 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
1196 FileOptionStrDepository = StringDepository++;\r
1197 ConsoleOptionStrDepository = StringDepository++;\r
1198 BootOptionStrDepository = StringDepository++;\r
1199 BootOptionHelpStrDepository = StringDepository++;\r
1200 DriverOptionStrDepository = StringDepository++;\r
1201 DriverOptionHelpStrDepository = StringDepository++;\r
1202 TerminalStrDepository = StringDepository;\r
1203}\r
1204\r
1205/**\r
1206 Fetch a usable string node from the string depository and return the string token.\r
1207\r
1208 @param CallbackData The BMM context data.\r
1209 @param StringDepository The string repository.\r
1210\r
1211 @retval EFI_STRING_ID String token.\r
1212\r
1213**/\r
1214EFI_STRING_ID\r
1215GetStringTokenFromDepository (\r
1216 IN BMM_CALLBACK_DATA *CallbackData,\r
1217 IN STRING_DEPOSITORY *StringDepository\r
1218 )\r
1219{\r
1220 STRING_LIST_NODE *CurrentListNode;\r
1221 STRING_LIST_NODE *NextListNode;\r
1222\r
1223 CurrentListNode = StringDepository->CurrentNode;\r
1224\r
1225 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1226 //\r
1227 // Fetch one reclaimed node from the list.\r
1228 //\r
1229 NextListNode = StringDepository->CurrentNode->Next;\r
1230 } else {\r
1231 //\r
1232 // If there is no usable node in the list, update the list.\r
1233 //\r
1234 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
1235 ASSERT (NextListNode != NULL);\r
cb7d01c0 1236 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);\r
5c08e117 1237 ASSERT (NextListNode->StringToken != 0);\r
1238\r
1239 StringDepository->TotalNodeNumber++;\r
1240\r
1241 if (NULL == CurrentListNode) {\r
1242 StringDepository->ListHead = NextListNode;\r
1243 } else {\r
1244 CurrentListNode->Next = NextListNode;\r
1245 }\r
1246 }\r
1247\r
1248 StringDepository->CurrentNode = NextListNode;\r
1249\r
1250 return StringDepository->CurrentNode->StringToken;\r
1251}\r
1252\r
1253/**\r
1254 Reclaim string depositories by moving the current node pointer to list head..\r
1255\r
1256**/\r
1257VOID\r
1258ReclaimStringDepository (\r
1259 VOID\r
1260 )\r
1261{\r
1262 UINTN DepositoryIndex;\r
1263 STRING_DEPOSITORY *StringDepository;\r
1264\r
1265 StringDepository = FileOptionStrDepository;\r
1266 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1267 StringDepository->CurrentNode = StringDepository->ListHead;\r
1268 StringDepository++;\r
1269 }\r
1270}\r
1271\r
1272/**\r
1273 Release resource for all the string depositories.\r
1274\r
1275**/\r
1276VOID\r
1277CleanUpStringDepository (\r
1278 VOID\r
1279 )\r
1280{\r
1281 UINTN NodeIndex;\r
1282 UINTN DepositoryIndex;\r
1283 STRING_LIST_NODE *CurrentListNode;\r
1284 STRING_LIST_NODE *NextListNode;\r
1285 STRING_DEPOSITORY *StringDepository;\r
1286\r
1287 //\r
1288 // Release string list nodes.\r
1289 //\r
1290 StringDepository = FileOptionStrDepository;\r
1291 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1292 CurrentListNode = StringDepository->ListHead;\r
1293 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1294 NextListNode = CurrentListNode->Next;\r
1295 FreePool (CurrentListNode);\r
1296 CurrentListNode = NextListNode;\r
1297 }\r
1298\r
1299 StringDepository++;\r
1300 }\r
1301 //\r
1302 // Release string depository.\r
1303 //\r
1304 FreePool (FileOptionStrDepository);\r
1305}\r
1306\r
1307/**\r
1308 Start boot maintenance manager\r
1309\r
1310 @retval EFI_SUCCESS If BMM is invoked successfully.\r
1311 @return Other value if BMM return unsuccessfully.\r
1312\r
1313**/\r
1314EFI_STATUS\r
1315BdsStartBootMaint (\r
1316 VOID\r
1317 )\r
1318{\r
1319 EFI_STATUS Status;\r
1320 LIST_ENTRY BdsBootOptionList;\r
1321\r
1322 InitializeListHead (&BdsBootOptionList);\r
1323\r
1324 //\r
1325 // Connect all prior to entering the platform setup menu.\r
1326 //\r
1327 if (!gConnectAllHappened) {\r
1328 BdsLibConnectAllDriversToAllControllers ();\r
1329 gConnectAllHappened = TRUE;\r
1330 }\r
1331 //\r
1332 // Have chance to enumerate boot device\r
1333 //\r
1334 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1335\r
16e5944a
RN
1336 //\r
1337 // Group the legacy boot options for the same device type\r
1338 //\r
1339 GroupMultipleLegacyBootOption4SameType ();\r
1340\r
5c08e117 1341 //\r
1342 // Init the BMM\r
1343 //\r
1344 Status = InitializeBM ();\r
1345\r
1346 return Status;\r
1347}\r
1348\r
1349/**\r
1350 Dispatch BMM formset and FileExplorer formset.\r
1351\r
1352\r
1353 @param CallbackData The BMM context data.\r
1354\r
1355 @retval EFI_SUCCESS If function complete successfully.\r
1356 @return Other value if the Setup Browser process BMM's pages and\r
1357 return unsuccessfully.\r
1358\r
1359**/\r
1360EFI_STATUS\r
1361FormSetDispatcher (\r
1362 IN BMM_CALLBACK_DATA *CallbackData\r
1363 )\r
1364{\r
1365 EFI_STATUS Status;\r
1366 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1367\r
1368 while (TRUE) {\r
1369 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1370\r
1371 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1372 Status = gFormBrowser2->SendForm (\r
1373 gFormBrowser2,\r
1374 &CallbackData->BmmHiiHandle,\r
1375 1,\r
e24fc103 1376 &gBootMaintFormSetGuid,\r
5c08e117 1377 0,\r
1378 NULL,\r
1379 &ActionRequest\r
1380 );\r
1381 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1382 EnableResetRequired ();\r
1383 }\r
1384\r
1385 ReclaimStringDepository ();\r
1386\r
1387 //\r
1388 // When this Formset returns, check if we are going to explore files.\r
1389 //\r
13078b3f 1390 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {\r
5c08e117 1391 UpdateFileExplorer (CallbackData, 0);\r
1392\r
1393 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1394 Status = gFormBrowser2->SendForm (\r
1395 gFormBrowser2,\r
1396 &CallbackData->FeHiiHandle,\r
1397 1,\r
e24fc103 1398 &gFileExploreFormSetGuid,\r
5c08e117 1399 0,\r
1400 NULL,\r
1401 &ActionRequest\r
1402 );\r
1403 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1404 EnableResetRequired ();\r
1405 }\r
1406\r
13078b3f 1407 CallbackData->FeCurrentState = FileExplorerStateInActive;\r
1408 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;\r
5c08e117 1409 ReclaimStringDepository ();\r
1410 } else {\r
1411 break;\r
1412 }\r
1413 }\r
1414\r
1415 return Status;\r
1416}\r
1417\r