+/**\r
+ This function applies changes in a driver's configuration.\r
+ Input is a Configuration, which has the routing data for this\r
+ driver followed by name / value configuration pairs. The driver\r
+ must apply those pairs to its configurable storage. If the\r
+ driver's configuration is stored in a linear block of data\r
+ and the driver's name / value pairs are in <BlockConfig>\r
+ format, it may use the ConfigToBlock helper function (above) to\r
+ simplify the job. Currently not implemented.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Configuration A null-terminated Unicode string in\r
+ <ConfigString> format. \r
+ @param[out] Progress A pointer to a string filled in with the\r
+ offset of the most recent '&' before the\r
+ first failing name / value pair (or the\r
+ beginn ing of the string if the failure\r
+ is in the first name / value pair) or\r
+ the terminating NULL if all was\r
+ successful.\r
+\r
+ @retval EFI_SUCCESS The results have been distributed or are\r
+ awaiting distribution. \r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
+ parts of the results that must be\r
+ stored awaiting possible future\r
+ protocols.\r
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
+ Results parameter would result\r
+ in this type of error.\r
+ @retval EFI_NOT_FOUND Target for the specified routing data\r
+ was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootMaintRouteConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Configuration,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
+ BMM_FAKE_NV_DATA *NewBmmData;\r
+ BMM_FAKE_NV_DATA *OldBmmData;\r
+ BM_CONSOLE_CONTEXT *NewConsoleContext;\r
+ BM_TERMINAL_CONTEXT *NewTerminalContext;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_LOAD_CONTEXT *NewLoadContext;\r
+ UINT16 Index; \r
+ BOOLEAN TerminalAttChange;\r
+ BMM_CALLBACK_DATA *Private; \r
+\r
+ if (Progress == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ *Progress = Configuration;\r
+\r
+ if (Configuration == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check routing data in <ConfigHdr>.\r
+ // Note: there is no name for Name/Value storage, only GUID will be checked\r
+ //\r
+ if (!HiiIsConfigHdrMatch (Configuration, &gBootMaintFormSetGuid, mBootMaintStorageName)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiConfigRoutingProtocolGuid, \r
+ NULL, \r
+ (VOID**) &ConfigRouting\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
+ //\r
+ // Get Buffer Storage data from EFI variable\r
+ //\r
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
+ OldBmmData = &Private->BmmOldFakeNVData;\r
+ NewBmmData = &Private->BmmFakeNvData;\r
+ //\r
+ // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
+ //\r
+ Status = ConfigRouting->ConfigToBlock (\r
+ ConfigRouting,\r
+ Configuration,\r
+ (UINT8 *) NewBmmData,\r
+ &BufferSize,\r
+ Progress\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Compare new and old BMM configuration data and only do action for modified item to \r
+ // avoid setting unnecessary non-volatile variable\r
+ //\r
+\r
+ //\r
+ // Check data which located in BMM main page and save the settings if need\r
+ //\r
+ if (CompareMem (NewBmmData->LegacyFD, OldBmmData->LegacyFD, sizeof (NewBmmData->LegacyFD)) != 0) {\r
+ Var_UpdateBBSOption (Private, FORM_SET_FD_ORDER_ID);\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->LegacyHD, OldBmmData->LegacyHD, sizeof (NewBmmData->LegacyHD)) != 0) {\r
+ Var_UpdateBBSOption (Private, FORM_SET_HD_ORDER_ID);\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->LegacyCD, OldBmmData->LegacyCD, sizeof (NewBmmData->LegacyCD)) != 0) {\r
+ Var_UpdateBBSOption (Private, FORM_SET_CD_ORDER_ID);\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->LegacyNET, OldBmmData->LegacyNET, sizeof (NewBmmData->LegacyNET)) != 0) {\r
+ Var_UpdateBBSOption (Private, FORM_SET_NET_ORDER_ID);\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->LegacyBEV, OldBmmData->LegacyBEV, sizeof (NewBmmData->LegacyBEV)) != 0) {\r
+ Var_UpdateBBSOption (Private, FORM_SET_BEV_ORDER_ID);\r
+ }\r
+\r
+ //\r
+ // Change for "delete boot option" page need update NewBmmData->BootOptionOrder, so process \r
+ // NewBmmData->BootOptionOrder before NewBmmData->BootOptionDel\r
+ //\r
+ if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) { \r
+ Status = Var_UpdateBootOrder (Private);\r
+ }\r
+\r
+ //\r
+ // Change for "delete driver option" page need update NewBmmData->DriverOptionOrder, so process \r
+ // NewBmmData->DriverOptionOrder before NewBmmData->DriverOptionDel\r
+ //\r
+ if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
+ Status = Var_UpdateDriverOrder (Private);\r
+ }\r
+\r
+ //\r
+ // Check data which located in Boot Options Menu and save the settings if need\r
+ //\r
+ if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
+ for (Index = 0; \r
+ ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
+ Index ++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+ NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
+ NewBmmData->BootOptionDel[Index] = FALSE;\r
+ NewBmmData->BootOptionDelMark[Index] = FALSE;\r
+ }\r
+\r
+ Var_DelBootOption ();\r
+ }\r
+\r
+ //\r
+ // Check data which located in Driver Options Menu and save the settings if need\r
+ //\r
+ if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
+ for (Index = 0; \r
+ ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
+ Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+ NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
+ NewBmmData->DriverOptionDel[Index] = FALSE;\r
+ NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
+ }\r
+ Var_DelDriverOption ();\r
+ }\r
+\r
+ if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {\r
+ Status = gRT->SetVariable (\r
+ L"Timeout",\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ sizeof (UINT16),\r
+ &(NewBmmData->BootTimeOut)\r
+ );\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ //\r
+ // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.\r
+ //\r
+ Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut; \r
+ }\r
+\r
+ if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
+ Status = Var_UpdateBootNext (Private);\r
+ }\r
+\r
+ if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) { \r
+ Var_UpdateConMode (Private);\r
+ }\r
+\r
+ TerminalAttChange = FALSE;\r
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
+\r
+ //\r
+ // only need update modified items\r
+ //\r
+ if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
+ CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
+ CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
+ CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
+ CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
+ CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
+ continue;\r
+ }\r
+\r
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
+ ASSERT (NewMenuEntry != NULL);\r
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+ NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];\r
+ ASSERT (NewBmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));\r
+ NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;\r
+ NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];\r
+ ASSERT (NewBmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));\r
+ NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;\r
+ NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];\r
+ ASSERT (NewBmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));\r
+ NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;\r
+ NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];\r
+ ASSERT (NewBmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));\r
+ NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;\r
+ NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];\r
+ NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];\r
+ ChangeTerminalDevicePath (\r
+ &(NewTerminalContext->DevicePath),\r
+ FALSE\r
+ );\r
+ TerminalAttChange = TRUE;\r
+ }\r
+ if (TerminalAttChange) {\r
+ Var_UpdateConsoleInpOption ();\r
+ Var_UpdateConsoleOutOption ();\r
+ Var_UpdateErrorOutOption ();\r
+ }\r
+\r
+ //\r
+ // Check data which located in Console Options Menu and save the settings if need\r
+ //\r
+ if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {\r
+ for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ASSERT (Index < MAX_MENU_NUMBER);\r
+ NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];\r
+ }\r
+\r
+ Var_UpdateConsoleInpOption ();\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {\r
+ for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ASSERT (Index < MAX_MENU_NUMBER);\r
+ NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];\r
+ }\r
+\r
+ Var_UpdateConsoleOutOption ();\r
+ }\r
+\r
+ if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) { \r
+ for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+ ASSERT (Index < MAX_MENU_NUMBER);\r
+ NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];\r
+ }\r
+\r
+ Var_UpdateErrorOutOption ();\r
+ }\r
+\r
+ //\r
+ // After user do the save action, need to update OldBmmData.\r
+ //\r
+ CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeLegacyBootOption (\r
+ VOID\r
+ )\r
+{\r
+ RefreshUpdateData ();\r
+ mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
+ \r
+ //\r
+ // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
+ // in BootOption form: legacy FD/HD/CD/NET/BEV\r
+ //\r
+ HiiCreateGotoOpCode (\r
+ mStartOpCodeHandle,\r
+ FORM_SET_FD_ORDER_ID,\r
+ STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
+ STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ FORM_SET_FD_ORDER_ID\r
+ );\r
+\r
+ HiiCreateGotoOpCode (\r
+ mStartOpCodeHandle,\r
+ FORM_SET_HD_ORDER_ID,\r
+ STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
+ STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ FORM_SET_HD_ORDER_ID\r
+ );\r
+\r
+ HiiCreateGotoOpCode (\r
+ mStartOpCodeHandle,\r
+ FORM_SET_CD_ORDER_ID,\r
+ STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
+ STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ FORM_SET_CD_ORDER_ID\r
+ );\r
+\r
+ HiiCreateGotoOpCode (\r
+ mStartOpCodeHandle,\r
+ FORM_SET_NET_ORDER_ID,\r
+ STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
+ STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ FORM_SET_NET_ORDER_ID\r
+ );\r
+\r
+ HiiCreateGotoOpCode (\r
+ mStartOpCodeHandle,\r
+ FORM_SET_BEV_ORDER_ID,\r
+ STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
+ STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ FORM_SET_BEV_ORDER_ID\r
+ );\r
+ \r
+ HiiUpdateForm (\r
+ mBmmCallbackInfo->BmmHiiHandle,\r
+ &gBootMaintFormSetGuid,\r
+ FORM_BOOT_SETUP_ID,\r
+ mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID\r
+ mEndOpCodeHandle // LABEL_END\r
+ );\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r