1 /** @file
2 The functions for Boot Maintainence Main menu.
3
4 Copyright (c) 2004 - 2015, 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
InitializeBmmConfig(IN BMM_CALLBACK_DATA * CallbackData)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
CreateMenuStringToken(IN BMM_CALLBACK_DATA * CallbackData,IN EFI_HII_HANDLE HiiHandle,IN BM_MENU_OPTION * MenuOption)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
BootMaintExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Request,OUT EFI_STRING * Progress,OUT EFI_STRING * Results)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
BootMaintRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Configuration,OUT EFI_STRING * Progress)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 (VOID**) &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 // Change for "delete boot option" page need update NewBmmData->BootOptionOrder, so process
433 // NewBmmData->BootOptionOrder before NewBmmData->BootOptionDel
434 //
435 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
436 Status = Var_UpdateBootOrder (Private);
437 }
438
439 //
440 // Change for "delete driver option" page need update NewBmmData->DriverOptionOrder, so process
441 // NewBmmData->DriverOptionOrder before NewBmmData->DriverOptionDel
442 //
443 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
444 Status = Var_UpdateDriverOrder (Private);
445 }
446
447 //
448 // Check data which located in Boot Options Menu and save the settings if need
449 //
450 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
451 for (Index = 0;
452 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
453 Index ++) {
454 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
455 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
456 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
457 NewBmmData->BootOptionDel[Index] = FALSE;
458 NewBmmData->BootOptionDelMark[Index] = FALSE;
459 }
460
461 Var_DelBootOption ();
462 }
463
464 //
465 // Check data which located in Driver Options Menu and save the settings if need
466 //
467 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
468 for (Index = 0;
469 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
470 Index++) {
471 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
472 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
473 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
474 NewBmmData->DriverOptionDel[Index] = FALSE;
475 NewBmmData->DriverOptionDelMark[Index] = FALSE;
476 }
477 Var_DelDriverOption ();
478 }
479
480 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {
481 Status = gRT->SetVariable (
482 L"Timeout",
483 &gEfiGlobalVariableGuid,
484 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
485 sizeof (UINT16),
486 &(NewBmmData->BootTimeOut)
487 );
488 ASSERT_EFI_ERROR(Status);
489
490 //
491 // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.
492 //
493 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
494 }
495
496 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
497 Status = Var_UpdateBootNext (Private);
498 }
499
500 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {
501 Var_UpdateConMode (Private);
502 }
503
504 TerminalAttChange = FALSE;
505 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
506
507 //
508 // only need update modified items
509 //
510 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&
511 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&
512 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&
513 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&
514 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&
515 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {
516 continue;
517 }
518
519 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
520 ASSERT (NewMenuEntry != NULL);
521 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
522 NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];
523 ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));
524 NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;
525 NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];
526 ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));
527 NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;
528 NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];
529 ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));
530 NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;
531 NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];
532 ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));
533 NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;
534 NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];
535 NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];
536 ChangeTerminalDevicePath (
537 &(NewTerminalContext->DevicePath),
538 FALSE
539 );
540 TerminalAttChange = TRUE;
541 }
542 if (TerminalAttChange) {
543 Var_UpdateConsoleInpOption ();
544 Var_UpdateConsoleOutOption ();
545 Var_UpdateErrorOutOption ();
546 }
547
548 //
549 // Check data which located in Console Options Menu and save the settings if need
550 //
551 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {
552 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
553 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
554 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
555 ASSERT (Index < MAX_MENU_NUMBER);
556 NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];
557 }
558
559 Var_UpdateConsoleInpOption ();
560 }
561
562 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {
563 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
564 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
565 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
566 ASSERT (Index < MAX_MENU_NUMBER);
567 NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];
568 }
569
570 Var_UpdateConsoleOutOption ();
571 }
572
573 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {
574 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
575 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
576 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
577 ASSERT (Index < MAX_MENU_NUMBER);
578 NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];
579 }
580
581 Var_UpdateErrorOutOption ();
582 }
583
584 //
585 // After user do the save action, need to update OldBmmData.
586 //
587 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
588
589 return EFI_SUCCESS;
590 }
591
592 /**
593 Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.
594
595 **/
596 EFI_STATUS
InitializeLegacyBootOption(VOID)597 InitializeLegacyBootOption (
598 VOID
599 )
600 {
601 RefreshUpdateData ();
602 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;
603
604 //
605 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
606 // in BootOption form: legacy FD/HD/CD/NET/BEV
607 //
608 HiiCreateGotoOpCode (
609 mStartOpCodeHandle,
610 FORM_SET_FD_ORDER_ID,
611 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
612 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
613 EFI_IFR_FLAG_CALLBACK,
614 FORM_SET_FD_ORDER_ID
615 );
616
617 HiiCreateGotoOpCode (
618 mStartOpCodeHandle,
619 FORM_SET_HD_ORDER_ID,
620 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
621 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
622 EFI_IFR_FLAG_CALLBACK,
623 FORM_SET_HD_ORDER_ID
624 );
625
626 HiiCreateGotoOpCode (
627 mStartOpCodeHandle,
628 FORM_SET_CD_ORDER_ID,
629 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
630 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
631 EFI_IFR_FLAG_CALLBACK,
632 FORM_SET_CD_ORDER_ID
633 );
634
635 HiiCreateGotoOpCode (
636 mStartOpCodeHandle,
637 FORM_SET_NET_ORDER_ID,
638 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
639 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
640 EFI_IFR_FLAG_CALLBACK,
641 FORM_SET_NET_ORDER_ID
642 );
643
644 HiiCreateGotoOpCode (
645 mStartOpCodeHandle,
646 FORM_SET_BEV_ORDER_ID,
647 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
648 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
649 EFI_IFR_FLAG_CALLBACK,
650 FORM_SET_BEV_ORDER_ID
651 );
652
653 HiiUpdateForm (
654 mBmmCallbackInfo->BmmHiiHandle,
655 &gBootMaintFormSetGuid,
656 FORM_BOOT_SETUP_ID,
657 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID
658 mEndOpCodeHandle // LABEL_END
659 );
660
661 return EFI_SUCCESS;
662 }
663
664 /**
665 This function processes the results of changes in configuration.
666
667
668 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
669 @param Action Specifies the type of action taken by the browser.
670 @param QuestionId A unique value which is sent to the original exporting driver
671 so that it can identify the type of data to expect.
672 @param Type The type of value for the question.
673 @param Value A pointer to the data being sent to the original exporting driver.
674 @param ActionRequest On return, points to the action requested by the callback function.
675
676 @retval EFI_SUCCESS The callback successfully handled the action.
677 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
678 @retval EFI_DEVICE_ERROR The variable could not be saved.
679 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
680 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
681 **/
682 EFI_STATUS
683 EFIAPI
BootMaintCallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN EFI_BROWSER_ACTION Action,IN EFI_QUESTION_ID QuestionId,IN UINT8 Type,IN EFI_IFR_TYPE_VALUE * Value,OUT EFI_BROWSER_ACTION_REQUEST * ActionRequest)684 BootMaintCallback (
685 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
686 IN EFI_BROWSER_ACTION Action,
687 IN EFI_QUESTION_ID QuestionId,
688 IN UINT8 Type,
689 IN EFI_IFR_TYPE_VALUE *Value,
690 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
691 )
692 {
693 BMM_CALLBACK_DATA *Private;
694 BM_MENU_ENTRY *NewMenuEntry;
695 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
696 EFI_STATUS Status;
697 UINTN OldValue;
698 UINTN NewValue;
699 UINTN Number;
700 UINTN Pos;
701 UINTN Bit;
702 UINT16 NewValuePos;
703 UINT16 Index3;
704 UINT16 Index2;
705 UINT16 Index;
706 UINT8 *OldLegacyDev;
707 UINT8 *NewLegacyDev;
708 UINT8 *DisMap;
709 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
710
711 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
712 if (Action == EFI_BROWSER_ACTION_FORM_OPEN && QuestionId == FORM_BOOT_SETUP_ID) {
713 //
714 // Initilize Form for legacy boot option.
715 //
716 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
717 if (!EFI_ERROR (Status)) {
718 InitializeLegacyBootOption ();
719 }
720
721 return EFI_SUCCESS;
722 }
723
724 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
725 //
726 // All other action return unsupported.
727 //
728 return EFI_UNSUPPORTED;
729 }
730
731 Status = EFI_SUCCESS;
732 OldValue = 0;
733 NewValue = 0;
734 Number = 0;
735 OldLegacyDev = NULL;
736 NewLegacyDev = NULL;
737 NewValuePos = 0;
738 DisMap = NULL;
739
740 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
741 //
742 // Retrive uncommitted data from Form Browser
743 //
744 CurrentFakeNVMap = &Private->BmmFakeNvData;
745 HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
746 if (Action == EFI_BROWSER_ACTION_CHANGING) {
747 if (Value == NULL) {
748 return EFI_INVALID_PARAMETER;
749 }
750
751 UpdatePageId (Private, QuestionId);
752
753 if (QuestionId < FILE_OPTION_OFFSET) {
754 if (QuestionId < CONFIG_OPTION_OFFSET) {
755 switch (QuestionId) {
756 case KEY_VALUE_BOOT_FROM_FILE:
757 Private->FeCurrentState = FileExplorerStateBootFromFile;
758 break;
759
760 case FORM_BOOT_ADD_ID:
761 Private->FeCurrentState = FileExplorerStateAddBootOption;
762 break;
763
764 case FORM_DRV_ADD_FILE_ID:
765 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;
766 break;
767
768 case FORM_DRV_ADD_HANDLE_ID:
769 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
770 UpdateDrvAddHandlePage (Private);
771 break;
772
773 case FORM_BOOT_DEL_ID:
774 CleanUpPage (FORM_BOOT_DEL_ID, Private);
775 UpdateBootDelPage (Private);
776 break;
777
778 case FORM_BOOT_CHG_ID:
779 case FORM_DRV_CHG_ID:
780 UpdatePageBody (QuestionId, Private);
781 break;
782
783 case FORM_DRV_DEL_ID:
784 CleanUpPage (FORM_DRV_DEL_ID, Private);
785 UpdateDrvDelPage (Private);
786 break;
787
788 case FORM_BOOT_NEXT_ID:
789 CleanUpPage (FORM_BOOT_NEXT_ID, Private);
790 UpdateBootNextPage (Private);
791 break;
792
793 case FORM_TIME_OUT_ID:
794 CleanUpPage (FORM_TIME_OUT_ID, Private);
795 UpdateTimeOutPage (Private);
796 break;
797
798 case FORM_CON_IN_ID:
799 case FORM_CON_OUT_ID:
800 case FORM_CON_ERR_ID:
801 UpdatePageBody (QuestionId, Private);
802 break;
803
804 case FORM_CON_MODE_ID:
805 CleanUpPage (FORM_CON_MODE_ID, Private);
806 UpdateConModePage (Private);
807 break;
808
809 case FORM_CON_COM_ID:
810 CleanUpPage (FORM_CON_COM_ID, Private);
811 UpdateConCOMPage (Private);
812 break;
813
814 case FORM_SET_FD_ORDER_ID:
815 case FORM_SET_HD_ORDER_ID:
816 case FORM_SET_CD_ORDER_ID:
817 case FORM_SET_NET_ORDER_ID:
818 case FORM_SET_BEV_ORDER_ID:
819 CleanUpPage (QuestionId, Private);
820 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
821 break;
822
823 default:
824 break;
825 }
826 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
827 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
828 Private->CurrentTerminal = Index2;
829
830 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
831 UpdateTerminalPage (Private);
832
833 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
834 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
835
836 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);
837 ASSERT (NewMenuEntry != NULL);
838 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
839
840 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
841
842 Private->MenuEntry = NewMenuEntry;
843 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
844
845 UpdateDriverAddHandleDescPage (Private);
846 }
847 }
848 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
849 if ((Value == NULL) || (ActionRequest == NULL)) {
850 return EFI_INVALID_PARAMETER;
851 }
852 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
853 if (Value->b){
854 //
855 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
856 //
857 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
858 } else {
859 //
860 // Means user remove the old check status.
861 //
862 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
863 }
864 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
865 if (Value->b){
866 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
867 } else {
868 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
869 }
870 } else if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {
871 //
872 // Update Select FD/HD/CD/NET/BEV Order Form
873 //
874
875 DisMap = Private->BmmOldFakeNVData.DisableMap;
876
877 if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {
878 Number = (UINT16) LegacyFDMenu.MenuNumber;
879 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
880 NewLegacyDev = CurrentFakeNVMap->LegacyFD;
881 } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {
882 Number = (UINT16) LegacyHDMenu.MenuNumber;
883 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
884 NewLegacyDev = CurrentFakeNVMap->LegacyHD;
885 } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {
886 Number = (UINT16) LegacyCDMenu.MenuNumber;
887 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
888 NewLegacyDev = CurrentFakeNVMap->LegacyCD;
889 } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {
890 Number = (UINT16) LegacyNETMenu.MenuNumber;
891 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
892 NewLegacyDev = CurrentFakeNVMap->LegacyNET;
893 } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {
894 Number = (UINT16) LegacyBEVMenu.MenuNumber;
895 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
896 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
897 }
898 //
899 // First, find the different position
900 // if there is change, it should be only one
901 //
902 for (Index = 0; Index < Number; Index++) {
903 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
904 OldValue = OldLegacyDev[Index];
905 NewValue = NewLegacyDev[Index];
906 break;
907 }
908 }
909
910 if (Index != Number) {
911 //
912 // there is change, now process
913 //
914 if (0xFF == NewValue) {
915 //
916 // This item will be disable
917 // Just move the items behind this forward to overlap it
918 //
919 Pos = OldValue / 8;
920 Bit = 7 - (OldValue % 8);
921 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
922 for (Index2 = Index; Index2 < Number - 1; Index2++) {
923 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
924 }
925
926 NewLegacyDev[Index2] = 0xFF;
927 } else {
928 for (Index2 = 0; Index2 < Number; Index2++) {
929 if (Index2 == Index) {
930 continue;
931 }
932
933 if (OldLegacyDev[Index2] == NewValue) {
934 //
935 // If NewValue is in OldLegacyDev array
936 // remember its old position
937 //
938 NewValuePos = Index2;
939 break;
940 }
941 }
942
943 if (Index2 != Number) {
944 //
945 // We will change current item to an existing item
946 // (It's hard to describe here, please read code, it's like a cycle-moving)
947 //
948 for (Index2 = NewValuePos; Index2 != Index;) {
949 if (NewValuePos < Index) {
950 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
951 Index2++;
952 } else {
953 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
954 Index2--;
955 }
956 }
957 } else {
958 //
959 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
960 // so we should modify DisMap to reflect the change
961 //
962 Pos = NewValue / 8;
963 Bit = 7 - (NewValue % 8);
964 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
965 if (0xFF != OldValue) {
966 //
967 // Because NewValue is a item that was disabled before
968 // so after changing the OldValue should be disabled
969 // actually we are doing a swap of enable-disable states of two items
970 //
971 Pos = OldValue / 8;
972 Bit = 7 - (OldValue % 8);
973 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
974 }
975 }
976 }
977 //
978 // To prevent DISABLE appears in the middle of the list
979 // we should perform a re-ordering
980 //
981 Index3 = Index;
982 Index = 0;
983 while (Index < Number) {
984 if (0xFF != NewLegacyDev[Index]) {
985 Index++;
986 continue;
987 }
988
989 Index2 = Index;
990 Index2++;
991 while (Index2 < Number) {
992 if (0xFF != NewLegacyDev[Index2]) {
993 break;
994 }
995
996 Index2++;
997 }
998
999 if (Index2 < Number) {
1000 NewLegacyDev[Index] = NewLegacyDev[Index2];
1001 NewLegacyDev[Index2] = 0xFF;
1002 }
1003
1004 Index++;
1005 }
1006
1007 //
1008 // Return correct question value.
1009 //
1010 Value->u8 = NewLegacyDev[Index3];
1011 }
1012 } else {
1013 switch (QuestionId) {
1014 case KEY_VALUE_SAVE_AND_EXIT:
1015 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1016 break;
1017
1018 case KEY_VALUE_NO_SAVE_AND_EXIT:
1019 //
1020 // Restore local maintain data.
1021 //
1022 DiscardChangeHandler (Private, CurrentFakeNVMap);
1023 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1024 break;
1025
1026 case FORM_RESET:
1027 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1028 return EFI_UNSUPPORTED;
1029
1030 default:
1031 break;
1032 }
1033 }
1034 }
1035
1036 //
1037 // Pass changed uncommitted data back to Form Browser
1038 //
1039 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
1040 return EFI_SUCCESS;
1041 }
1042
1043 /**
1044 Discard all changes done to the BMM pages such as Boot Order change,
1045 Driver order change.
1046
1047 @param Private The BMM context data.
1048 @param CurrentFakeNVMap The current Fack NV Map.
1049
1050 **/
1051 VOID
DiscardChangeHandler(IN BMM_CALLBACK_DATA * Private,IN BMM_FAKE_NV_DATA * CurrentFakeNVMap)1052 DiscardChangeHandler (
1053 IN BMM_CALLBACK_DATA *Private,
1054 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
1055 )
1056 {
1057 UINT16 Index;
1058
1059 switch (Private->BmmPreviousPageId) {
1060 case FORM_BOOT_CHG_ID:
1061 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
1062 break;
1063
1064 case FORM_DRV_CHG_ID:
1065 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
1066 break;
1067
1068 case FORM_BOOT_DEL_ID:
1069 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
1070 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
1071 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
1072 CurrentFakeNVMap->BootOptionDelMark[Index] = FALSE;
1073 }
1074 break;
1075
1076 case FORM_DRV_DEL_ID:
1077 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
1078 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1079 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
1080 CurrentFakeNVMap->DriverOptionDelMark[Index] = FALSE;
1081 }
1082 break;
1083
1084 case FORM_BOOT_NEXT_ID:
1085 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
1086 break;
1087
1088 case FORM_TIME_OUT_ID:
1089 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
1090 break;
1091
1092 case FORM_DRV_ADD_HANDLE_DESC_ID:
1093 case FORM_DRV_ADD_FILE_ID:
1094 case FORM_DRV_ADD_HANDLE_ID:
1095 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
1096 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
1097 break;
1098
1099 default:
1100 break;
1101 }
1102 }
1103
1104 /**
1105 Initialize the Boot Maintenance Utitliy.
1106
1107
1108 @retval EFI_SUCCESS utility ended successfully
1109 @retval others contain some errors
1110
1111 **/
1112 EFI_STATUS
InitializeBM(VOID)1113 InitializeBM (
1114 VOID
1115 )
1116 {
1117 BMM_CALLBACK_DATA *BmmCallbackInfo;
1118 EFI_STATUS Status;
1119 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
1120 UINT32 Length;
1121 UINT8 *Data;
1122
1123 Status = EFI_SUCCESS;
1124 BmmCallbackInfo = mBmmCallbackInfo;
1125
1126 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
1127 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
1128 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;
1129 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;
1130
1131 //
1132 // Reinstall String packages to include more new strings.
1133 //
1134
1135 //
1136 // String package size
1137 //
1138 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);
1139
1140 //
1141 // Add the length of the Package List Header and the terminating Package Header
1142 //
1143 Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER);
1144
1145 //
1146 // Allocate the storage for the entire Package List
1147 //
1148 PackageListHeader = AllocateZeroPool (Length);
1149
1150 //
1151 // If the Package List can not be allocated, then return a NULL HII Handle
1152 //
1153 if (PackageListHeader == NULL) {
1154 return EFI_OUT_OF_RESOURCES;
1155 }
1156
1157 //
1158 // Fill in the GUID and Length of the Package List Header
1159 //
1160 PackageListHeader->PackageLength = Length;
1161
1162 //
1163 // Copy String Data into Package list.
1164 //
1165 Data = (UINT8 *)(PackageListHeader + 1);
1166 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);
1167 CopyMem (Data, (UINT8 *) BdsDxeStrings + sizeof (UINT32), Length);
1168
1169 //
1170 // Add End type HII package.
1171 //
1172 Data += Length;
1173 ((EFI_HII_PACKAGE_HEADER *) Data)->Type = EFI_HII_PACKAGE_END;
1174 ((EFI_HII_PACKAGE_HEADER *) Data)->Length = sizeof (EFI_HII_PACKAGE_HEADER);
1175
1176 //
1177 // Update String package for BM
1178 //
1179 CopyGuid (&PackageListHeader->PackageListGuid, &gBootMaintFormSetGuid);
1180 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle, PackageListHeader);
1181
1182 //
1183 // Update String package for FE.
1184 //
1185 CopyGuid (&PackageListHeader->PackageListGuid, &gFileExploreFormSetGuid);
1186 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle, PackageListHeader);
1187
1188 FreePool (PackageListHeader);
1189
1190 //
1191 // Init OpCode Handle and Allocate space for creation of Buffer
1192 //
1193 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
1194 if (mStartOpCodeHandle == NULL) {
1195 Status = EFI_OUT_OF_RESOURCES;
1196 goto Exit;
1197 }
1198
1199 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
1200 if (mEndOpCodeHandle == NULL) {
1201 Status = EFI_OUT_OF_RESOURCES;
1202 goto Exit;
1203 }
1204
1205 //
1206 // Create Hii Extend Label OpCode as the start opcode
1207 //
1208 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1209 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1210
1211 //
1212 // Create Hii Extend Label OpCode as the end opcode
1213 //
1214 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1215 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1216 mEndLabel->Number = LABEL_END;
1217
1218 InitializeStringDepository ();
1219
1220 InitAllMenu (BmmCallbackInfo);
1221
1222 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
1223 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
1224 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
1225 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
1226 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
1227 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
1228 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
1229
1230 InitializeBmmConfig (BmmCallbackInfo);
1231
1232 //
1233 // Dispatch BMM main formset and File Explorer formset.
1234 //
1235 FormSetDispatcher (BmmCallbackInfo);
1236
1237 //
1238 // Clean up.
1239 //
1240 CleanUpStringDepository ();
1241
1242 FreeAllMenu ();
1243
1244 Exit:
1245 if (mStartOpCodeHandle != NULL) {
1246 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1247 }
1248
1249 if (mEndOpCodeHandle != NULL) {
1250 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1251 }
1252
1253 return Status;
1254 }
1255
1256
1257 /**
1258 Initialized all Menu Option List.
1259
1260 @param CallbackData The BMM context data.
1261
1262 **/
1263 VOID
InitAllMenu(IN BMM_CALLBACK_DATA * CallbackData)1264 InitAllMenu (
1265 IN BMM_CALLBACK_DATA *CallbackData
1266 )
1267 {
1268 InitializeListHead (&BootOptionMenu.Head);
1269 InitializeListHead (&DriverOptionMenu.Head);
1270 BOpt_GetBootOptions (CallbackData);
1271 BOpt_GetDriverOptions (CallbackData);
1272 BOpt_GetLegacyOptions ();
1273 InitializeListHead (&FsOptionMenu.Head);
1274 BOpt_FindDrivers ();
1275 InitializeListHead (&DirectoryMenu.Head);
1276 InitializeListHead (&ConsoleInpMenu.Head);
1277 InitializeListHead (&ConsoleOutMenu.Head);
1278 InitializeListHead (&ConsoleErrMenu.Head);
1279 InitializeListHead (&TerminalMenu.Head);
1280 LocateSerialIo ();
1281 GetAllConsoles ();
1282 }
1283
1284 /**
1285 Free up all Menu Option list.
1286
1287 **/
1288 VOID
FreeAllMenu(VOID)1289 FreeAllMenu (
1290 VOID
1291 )
1292 {
1293 BOpt_FreeMenu (&DirectoryMenu);
1294 BOpt_FreeMenu (&FsOptionMenu);
1295 BOpt_FreeMenu (&BootOptionMenu);
1296 BOpt_FreeMenu (&DriverOptionMenu);
1297 BOpt_FreeMenu (&DriverMenu);
1298 BOpt_FreeLegacyOptions ();
1299 FreeAllConsoles ();
1300 }
1301
1302 /**
1303 Initialize all the string depositories.
1304
1305 **/
1306 VOID
InitializeStringDepository(VOID)1307 InitializeStringDepository (
1308 VOID
1309 )
1310 {
1311 STRING_DEPOSITORY *StringDepository;
1312 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1313 FileOptionStrDepository = StringDepository++;
1314 ConsoleOptionStrDepository = StringDepository++;
1315 BootOptionStrDepository = StringDepository++;
1316 BootOptionHelpStrDepository = StringDepository++;
1317 DriverOptionStrDepository = StringDepository++;
1318 DriverOptionHelpStrDepository = StringDepository++;
1319 TerminalStrDepository = StringDepository;
1320 }
1321
1322 /**
1323 Fetch a usable string node from the string depository and return the string token.
1324
1325 @param CallbackData The BMM context data.
1326 @param StringDepository The string repository.
1327
1328 @retval EFI_STRING_ID String token.
1329
1330 **/
1331 EFI_STRING_ID
GetStringTokenFromDepository(IN BMM_CALLBACK_DATA * CallbackData,IN STRING_DEPOSITORY * StringDepository)1332 GetStringTokenFromDepository (
1333 IN BMM_CALLBACK_DATA *CallbackData,
1334 IN STRING_DEPOSITORY *StringDepository
1335 )
1336 {
1337 STRING_LIST_NODE *CurrentListNode;
1338 STRING_LIST_NODE *NextListNode;
1339
1340 CurrentListNode = StringDepository->CurrentNode;
1341
1342 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1343 //
1344 // Fetch one reclaimed node from the list.
1345 //
1346 NextListNode = StringDepository->CurrentNode->Next;
1347 } else {
1348 //
1349 // If there is no usable node in the list, update the list.
1350 //
1351 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1352 ASSERT (NextListNode != NULL);
1353 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);
1354 ASSERT (NextListNode->StringToken != 0);
1355
1356 StringDepository->TotalNodeNumber++;
1357
1358 if (NULL == CurrentListNode) {
1359 StringDepository->ListHead = NextListNode;
1360 } else {
1361 CurrentListNode->Next = NextListNode;
1362 }
1363 }
1364
1365 StringDepository->CurrentNode = NextListNode;
1366
1367 return StringDepository->CurrentNode->StringToken;
1368 }
1369
1370 /**
1371 Reclaim string depositories by moving the current node pointer to list head..
1372
1373 **/
1374 VOID
ReclaimStringDepository(VOID)1375 ReclaimStringDepository (
1376 VOID
1377 )
1378 {
1379 UINTN DepositoryIndex;
1380 STRING_DEPOSITORY *StringDepository;
1381
1382 StringDepository = FileOptionStrDepository;
1383 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1384 StringDepository->CurrentNode = StringDepository->ListHead;
1385 StringDepository++;
1386 }
1387 }
1388
1389 /**
1390 Release resource for all the string depositories.
1391
1392 **/
1393 VOID
CleanUpStringDepository(VOID)1394 CleanUpStringDepository (
1395 VOID
1396 )
1397 {
1398 UINTN NodeIndex;
1399 UINTN DepositoryIndex;
1400 STRING_LIST_NODE *CurrentListNode;
1401 STRING_LIST_NODE *NextListNode;
1402 STRING_DEPOSITORY *StringDepository;
1403
1404 //
1405 // Release string list nodes.
1406 //
1407 StringDepository = FileOptionStrDepository;
1408 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1409 CurrentListNode = StringDepository->ListHead;
1410 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1411 NextListNode = CurrentListNode->Next;
1412 FreePool (CurrentListNode);
1413 CurrentListNode = NextListNode;
1414 }
1415
1416 StringDepository++;
1417 }
1418 //
1419 // Release string depository.
1420 //
1421 FreePool (FileOptionStrDepository);
1422 }
1423
1424 /**
1425 Start boot maintenance manager
1426
1427 @retval EFI_SUCCESS If BMM is invoked successfully.
1428 @return Other value if BMM return unsuccessfully.
1429
1430 **/
1431 EFI_STATUS
BdsStartBootMaint(VOID)1432 BdsStartBootMaint (
1433 VOID
1434 )
1435 {
1436 EFI_STATUS Status;
1437 LIST_ENTRY BdsBootOptionList;
1438
1439 InitializeListHead (&BdsBootOptionList);
1440
1441 //
1442 // Connect all prior to entering the platform setup menu.
1443 //
1444 if (!gConnectAllHappened) {
1445 BdsLibConnectAllDriversToAllControllers ();
1446 gConnectAllHappened = TRUE;
1447 }
1448 //
1449 // Have chance to enumerate boot device
1450 //
1451 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1452
1453 //
1454 // Group the legacy boot options for the same device type
1455 //
1456 GroupMultipleLegacyBootOption4SameType ();
1457
1458 //
1459 // Init the BMM
1460 //
1461 Status = InitializeBM ();
1462
1463 return Status;
1464 }
1465
1466 /**
1467 Dispatch BMM formset and FileExplorer formset.
1468
1469
1470 @param CallbackData The BMM context data.
1471
1472 @retval EFI_SUCCESS If function complete successfully.
1473 @return Other value if the Setup Browser process BMM's pages and
1474 return unsuccessfully.
1475
1476 **/
1477 EFI_STATUS
FormSetDispatcher(IN BMM_CALLBACK_DATA * CallbackData)1478 FormSetDispatcher (
1479 IN BMM_CALLBACK_DATA *CallbackData
1480 )
1481 {
1482 EFI_STATUS Status;
1483 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1484
1485 while (TRUE) {
1486 UpdatePageId (CallbackData, FORM_MAIN_ID);
1487
1488 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1489 Status = gFormBrowser2->SendForm (
1490 gFormBrowser2,
1491 &CallbackData->BmmHiiHandle,
1492 1,
1493 &gBootMaintFormSetGuid,
1494 0,
1495 NULL,
1496 &ActionRequest
1497 );
1498 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1499 EnableResetRequired ();
1500 }
1501
1502 ReclaimStringDepository ();
1503
1504 //
1505 // When this Formset returns, check if we are going to explore files.
1506 //
1507 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {
1508 UpdateFileExplorer (CallbackData, 0);
1509
1510 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1511 Status = gFormBrowser2->SendForm (
1512 gFormBrowser2,
1513 &CallbackData->FeHiiHandle,
1514 1,
1515 &gFileExploreFormSetGuid,
1516 0,
1517 NULL,
1518 &ActionRequest
1519 );
1520 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1521 EnableResetRequired ();
1522 }
1523
1524 CallbackData->FeCurrentState = FileExplorerStateInActive;
1525 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;
1526 ReclaimStringDepository ();
1527 } else {
1528 break;
1529 }
1530 }
1531
1532 return Status;
1533 }
1534
1535 /**
1536 Intall BootMaint and FileExplorer HiiPackages.
1537
1538 **/
1539 EFI_STATUS
InitBMPackage(VOID)1540 InitBMPackage (
1541 VOID
1542 )
1543 {
1544 BMM_CALLBACK_DATA *BmmCallbackInfo;
1545 EFI_STATUS Status;
1546 UINT8 *Ptr;
1547
1548 //
1549 // Create CallbackData structures for Driver Callback
1550 //
1551 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
1552 if (BmmCallbackInfo == NULL) {
1553 return EFI_OUT_OF_RESOURCES;
1554 }
1555
1556 //
1557 // Create LoadOption in BmmCallbackInfo for Driver Callback
1558 //
1559 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
1560 if (Ptr == NULL) {
1561 FreePool (BmmCallbackInfo);
1562 BmmCallbackInfo = NULL;
1563 return EFI_OUT_OF_RESOURCES;
1564 }
1565 //
1566 // Initialize Bmm callback data.
1567 //
1568 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
1569 Ptr += sizeof (BM_LOAD_CONTEXT);
1570
1571 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
1572 Ptr += sizeof (BM_FILE_CONTEXT);
1573
1574 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
1575 Ptr += sizeof (BM_HANDLE_CONTEXT);
1576
1577 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
1578
1579 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
1580 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
1581 BmmCallbackInfo->BmmConfigAccess.RouteConfig = BootMaintRouteConfig;
1582 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
1583 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
1584 BmmCallbackInfo->FeConfigAccess.RouteConfig = FileExplorerRouteConfig;
1585 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
1586
1587 //
1588 // Install Device Path Protocol and Config Access protocol to driver handle
1589 //
1590 Status = gBS->InstallMultipleProtocolInterfaces (
1591 &BmmCallbackInfo->BmmDriverHandle,
1592 &gEfiDevicePathProtocolGuid,
1593 &mBmmHiiVendorDevicePath,
1594 &gEfiHiiConfigAccessProtocolGuid,
1595 &BmmCallbackInfo->BmmConfigAccess,
1596 NULL
1597 );
1598 ASSERT_EFI_ERROR (Status);
1599
1600 //
1601 // Install Device Path Protocol and Config Access protocol to driver handle
1602 //
1603 Status = gBS->InstallMultipleProtocolInterfaces (
1604 &BmmCallbackInfo->FeDriverHandle,
1605 &gEfiDevicePathProtocolGuid,
1606 &mFeHiiVendorDevicePath,
1607 &gEfiHiiConfigAccessProtocolGuid,
1608 &BmmCallbackInfo->FeConfigAccess,
1609 NULL
1610 );
1611 ASSERT_EFI_ERROR (Status);
1612
1613 //
1614 // Post our Boot Maint VFR binary to the HII database.
1615 //
1616 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
1617 &gBootMaintFormSetGuid,
1618 BmmCallbackInfo->BmmDriverHandle,
1619 BmBin,
1620 BdsDxeStrings,
1621 NULL
1622 );
1623 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);
1624
1625 //
1626 // Post our File Explorer VFR binary to the HII database.
1627 //
1628 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (
1629 &gFileExploreFormSetGuid,
1630 BmmCallbackInfo->FeDriverHandle,
1631 FEBin,
1632 BdsDxeStrings,
1633 NULL
1634 );
1635 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);
1636
1637 mBmmCallbackInfo = BmmCallbackInfo;
1638
1639 return EFI_SUCCESS;
1640 }
1641
1642 /**
1643 Remvoe the intalled BootMaint and FileExplorer HiiPackages.
1644
1645 **/
1646 VOID
FreeBMPackage(VOID)1647 FreeBMPackage (
1648 VOID
1649 )
1650 {
1651 BMM_CALLBACK_DATA *BmmCallbackInfo;
1652
1653 BmmCallbackInfo = mBmmCallbackInfo;
1654
1655 //
1656 // Remove our IFR data from HII database
1657 //
1658 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);
1659 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);
1660
1661 if (BmmCallbackInfo->FeDriverHandle != NULL) {
1662 gBS->UninstallMultipleProtocolInterfaces (
1663 BmmCallbackInfo->FeDriverHandle,
1664 &gEfiDevicePathProtocolGuid,
1665 &mFeHiiVendorDevicePath,
1666 &gEfiHiiConfigAccessProtocolGuid,
1667 &BmmCallbackInfo->FeConfigAccess,
1668 NULL
1669 );
1670 }
1671
1672 if (BmmCallbackInfo->BmmDriverHandle != NULL) {
1673 gBS->UninstallMultipleProtocolInterfaces (
1674 BmmCallbackInfo->BmmDriverHandle,
1675 &gEfiDevicePathProtocolGuid,
1676 &mBmmHiiVendorDevicePath,
1677 &gEfiHiiConfigAccessProtocolGuid,
1678 &BmmCallbackInfo->BmmConfigAccess,
1679 NULL
1680 );
1681 }
1682
1683 FreePool (BmmCallbackInfo->LoadContext);
1684 FreePool (BmmCallbackInfo);
1685
1686 mBmmCallbackInfo = NULL;
1687
1688 return;
1689 }
1690
1691