From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A25C721E3EA88 for ; Mon, 4 Sep 2017 00:14:14 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP; 04 Sep 2017 00:17:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,473,1498546800"; d="scan'208";a="145190966" Received: from shwdeopenpsi114.ccr.corp.intel.com ([10.239.157.135]) by orsmga005.jf.intel.com with ESMTP; 04 Sep 2017 00:17:00 -0700 From: Dandan Bi To: edk2-devel@lists.01.org Cc: Eric Dong , Liming Gao Date: Mon, 4 Sep 2017 15:16:26 +0800 Message-Id: <1504509388-369768-5-git-send-email-dandan.bi@intel.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1504509388-369768-1-git-send-email-dandan.bi@intel.com> References: <1504509388-369768-1-git-send-email-dandan.bi@intel.com> Subject: [patch 4/6] MdeModulePkg/HiiDatabase: Handle questions with Bit VarStore X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Sep 2017 07:14:14 -0000 https://bugzilla.tianocore.org/show_bug.cgi?id=545 For oneof/numeric/checkbox, their storage may be bit field. When generating string to get default value for these questions, we need to parse the Ifr data to get the bit Varstore info,and then generating the correct string. Cc: Eric Dong Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Dandan Bi --- .../Universal/HiiDatabaseDxe/ConfigRouting.c | 190 +++++++++++++++++++-- .../Universal/HiiDatabaseDxe/HiiDatabase.h | 6 +- .../Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf | 3 +- 3 files changed, 184 insertions(+), 15 deletions(-) diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c index c9ff1cf..19cb382 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c @@ -13,10 +13,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "HiiDatabase.h" extern HII_DATABASE_PRIVATE_DATA mPrivate; +BOOLEAN mQuestionReferBitVar = FALSE; /** Calculate the number of Unicode characters of the incoming Configuration string, not including NULL terminator. @@ -1223,19 +1224,19 @@ InsertBlockData ( // Insert block data in its Offset and Width order. // for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) { BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry); if (BlockArray->Offset == BlockSingleData->Offset) { - if (BlockArray->Width > BlockSingleData->Width) { + if ((BlockArray->Width > BlockSingleData->Width) || (BlockSingleData->IsBitVar && BlockArray->Width == BlockSingleData->Width)) { // // Insert this block data in the front of block array // InsertTailList (Link, &BlockSingleData->Entry); return; } - if (BlockArray->Width == BlockSingleData->Width) { + if ((!BlockSingleData->IsBitVar) && BlockArray->Width == BlockSingleData->Width) { // // The same block array has been added. // if (BlockSingleData != BlockArray) { FreePool (BlockSingleData); @@ -1978,10 +1979,11 @@ Done: @param HiiHandle The hii handle for this form package. @param VarStorageData The varstore data structure. @param IfrOpHdr Ifr opcode header for this opcode. @param VarWidth The buffer width for this opcode. @param ReturnData The data block added for this opcode. + @param IsBitVar Whether the the opcode refers to bit storage. @retval EFI_SUCCESS This opcode is required. @retval EFI_NOT_FOUND This opcode is not required. @retval Others Contain some error. @@ -1991,20 +1993,26 @@ IsThisOpcodeRequired ( IN IFR_BLOCK_DATA *RequestBlockArray, IN EFI_HII_HANDLE HiiHandle, IN OUT IFR_VARSTORAGE_DATA *VarStorageData, IN EFI_IFR_OP_HEADER *IfrOpHdr, IN UINT16 VarWidth, - OUT IFR_BLOCK_DATA **ReturnData + OUT IFR_BLOCK_DATA **ReturnData, + IN BOOLEAN IsBitVar ) { IFR_BLOCK_DATA *BlockData; UINT16 VarOffset; EFI_STRING_ID NameId; EFI_IFR_QUESTION_HEADER *IfrQuestionHdr; + UINT16 BitOffset; + UINT16 BitWidth; + UINT16 BitVarWidth; NameId = 0; VarOffset = 0; + BitOffset = 0; + BitVarWidth = 0; IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)); if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) { NameId = IfrQuestionHdr->VarStoreInfo.VarName; @@ -2016,11 +2024,21 @@ IsThisOpcodeRequired ( // This question is not in the requested string. Skip it. // return EFI_NOT_FOUND; } } else { - VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset; + if (IsBitVar) { + BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset; + VarOffset = BitOffset / 8; + BitVarWidth = VarWidth; + BitWidth = BitOffset - (VarOffset * 8) + BitVarWidth; + VarWidth = (BitWidth % 8 == 0 ? BitWidth / 8: BitWidth / 8 + 1); + } else { + VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset; + BitVarWidth = VarWidth; + BitOffset = VarOffset * 8; + } // // Check whether this question is in requested block array. // if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) { @@ -2051,10 +2069,13 @@ IsThisOpcodeRequired ( BlockData->Width = VarWidth; BlockData->QuestionId = IfrQuestionHdr->QuestionId; BlockData->OpCode = IfrOpHdr->OpCode; BlockData->Scope = IfrOpHdr->Scope; + BlockData->IsBitVar = IsBitVar; + BlockData->BitOffset = BitOffset; + BlockData->BitWidth = BitVarWidth; InitializeListHead (&BlockData->DefaultValueEntry); // // Add Block Data into VarStorageData BlockEntry // InsertBlockData (&VarStorageData->BlockEntry, &BlockData); @@ -2124,10 +2145,11 @@ ParseIfrData ( EFI_HII_PACKAGE_HEADER *PackageHeader; EFI_VARSTORE_ID VarStoreId; UINT16 SmallestDefaultId; BOOLEAN SmallestIdFromFlag; BOOLEAN FromOtherDefaultOpcode; + BOOLEAN IsBitVar; Status = EFI_SUCCESS; BlockData = NULL; DefaultDataPtr = NULL; FirstOneOfOption = FALSE; @@ -2135,10 +2157,11 @@ ParseIfrData ( FirstOrderedList = FALSE; VarStoreName = NULL; ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA)); SmallestDefaultId = 0xFFFF; FromOtherDefaultOpcode = FALSE; + IsBitVar = FALSE; // // Go through the form package to parse OpCode one by one. // PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER); @@ -2309,11 +2332,11 @@ ParseIfrData ( // if (BlockData != NULL){ BlockData = NULL; } - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2341,20 +2364,28 @@ ParseIfrData ( // IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpHdr; if (IfrOneOf->Question.VarStoreId != VarStoreId) { break; } - VarWidth = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + + if (mQuestionReferBitVar) { + mQuestionReferBitVar = FALSE; + VarWidth = IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE_BIT ; + IsBitVar = TRUE; + } else { + VarWidth = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + IsBitVar = FALSE; + } // // The BlockData may allocate by other opcode,need to clean. // if (BlockData != NULL){ BlockData = NULL; } - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, IsBitVar); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2439,11 +2470,11 @@ ParseIfrData ( // if (BlockData != NULL){ BlockData = NULL; } - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2484,11 +2515,19 @@ ParseIfrData ( // if (BlockData != NULL){ BlockData = NULL; } - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + if (mQuestionReferBitVar) { + mQuestionReferBitVar = FALSE; + VarWidth = 1; + IsBitVar = TRUE; + } else { + IsBitVar = FALSE; + } + + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, IsBitVar); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2612,11 +2651,11 @@ ParseIfrData ( if (BlockData != NULL){ BlockData = NULL; } VarWidth = (UINT16) sizeof (EFI_HII_DATE); - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2654,11 +2693,11 @@ ParseIfrData ( if (BlockData != NULL){ BlockData = NULL; } VarWidth = (UINT16) sizeof (EFI_HII_TIME); - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2696,11 +2735,11 @@ ParseIfrData ( if (BlockData != NULL){ BlockData = NULL; } VarWidth = (UINT16) (IfrString->MaxSize * sizeof (UINT16)); - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2738,11 +2777,11 @@ ParseIfrData ( if (BlockData != NULL){ BlockData = NULL; } VarWidth = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16)); - Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData); + Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND){ // //The opcode is not required,exit and parse other opcode. // @@ -2985,11 +3024,18 @@ ParseIfrData ( // SmallestDefaultId = 0xFFFF; FromOtherDefaultOpcode = FALSE; } } + mQuestionReferBitVar = FALSE; + + break; + case EFI_IFR_GUID_OP: + if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEfiIfrBitvarstoreGuid)) { + mQuestionReferBitVar = TRUE; + } break; default: if (BlockData != NULL) { if (BlockData->Scope > 0) { @@ -3567,10 +3613,126 @@ GetStorageWidth ( return StorageWidth; } /** + Update Block data. + For some question (oneof/numeric/checkbox),their storage may be bit filed, + their block data may have same byte OFFSET and WIDTH, this function merge the + same block data to one. + + @param BlockLink The Link of the block data. + +**/ +VOID +UpdateBlockDataArray( + IN LIST_ENTRY *BlockLink +) +{ + LIST_ENTRY *Link; + LIST_ENTRY *TempLink; + LIST_ENTRY *ListEntry; + LIST_ENTRY *NextListEntry; + LIST_ENTRY *LinkDefault; + LIST_ENTRY *NextLinkDefault; + IFR_BLOCK_DATA *BlockData; + IFR_BLOCK_DATA *NextBlockeData; + IFR_DEFAULT_DATA *DefaultValueData; + IFR_DEFAULT_DATA *NextDefaultValueData; + UINT32 Value; + UINT32 Mask; + UINT32 PreBits; + UINT32 *DefaultValue; + UINT8 *BufferValue; + BOOLEAN NextBlockChanged; + + Value = 0; + Link = BlockLink->ForwardLink; + NextBlockChanged = FALSE; + + while (Link != BlockLink) { + BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry); + TempLink = Link->ForwardLink; + if (!BlockData ->IsBitVar) { + Link = Link->ForwardLink; + continue; + } + // + // Find the block data for Bit VarStore. + // + while (TempLink != Link) { + NextBlockeData = BASE_CR (TempLink, IFR_BLOCK_DATA, Entry); + TempLink = TempLink->ForwardLink; + if (BlockData->Offset != NextBlockeData->Offset || BlockData->Width != NextBlockeData->Width) { + continue; + } + // + // Find two block data with same byte offset and width.Parse the default value in Block data and Next block data, + // and merge the default value with same default Id in next Block data to Block data. And then remove the next block data. + // + ListEntry = &BlockData->DefaultValueEntry; + for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) { + DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry); + NextListEntry = &NextBlockeData->DefaultValueEntry; + for (NextLinkDefault = NextListEntry->ForwardLink; NextLinkDefault != NextListEntry; NextLinkDefault = NextLinkDefault->ForwardLink) { + NextDefaultValueData = BASE_CR (NextLinkDefault, IFR_DEFAULT_DATA, Entry); + if (DefaultValueData->DefaultId != NextDefaultValueData->DefaultId) { + continue; + } + // + // Find two default data with same default Id. + // Get the default value in Block data. + // + if (NextBlockChanged) { + BufferValue = (UINT8*)&(DefaultValueData->Value); + Value = (UINTN)(*BufferValue); + } else { + Mask = (1 << BlockData->BitWidth) - 1; + PreBits = BlockData->BitOffset - BlockData->Offset * 8; + DefaultValue = (UINT32*)&(DefaultValueData->Value); + *DefaultValue <<= PreBits; + Mask <<= PreBits; + Value = (Value & (~Mask)) | *DefaultValue; + } + // + // Get the default value in Next Block data. + // And merge the value to the default value in Block data. + // + Mask = (1 << NextBlockeData->BitWidth) - 1; + PreBits = NextBlockeData->BitOffset - NextBlockeData->Offset * 8; + DefaultValue = (UINT32*) & (NextDefaultValueData->Value); + *DefaultValue <<= PreBits; + Mask <<= PreBits; + Value = (Value & (~Mask)) | *DefaultValue; + + CopyMem (&DefaultValueData->Value, &Value, sizeof (EFI_IFR_TYPE_VALUE)); + } + } + // + // Remove the block data from the block data list + // And free its sub-members and itself. + // + RemoveEntryList (&NextBlockeData->Entry); + if (NextBlockeData->Name != NULL) { + FreePool (NextBlockeData->Name); + } + while (!IsListEmpty (&NextBlockeData->DefaultValueEntry)) { + DefaultValueData = BASE_CR (NextBlockeData->DefaultValueEntry.ForwardLink, IFR_DEFAULT_DATA, Entry); + RemoveEntryList (&DefaultValueData->Entry); + FreePool (DefaultValueData); + } + FreePool (NextBlockeData); + Link->ForwardLink = TempLink; + NextBlockChanged = TRUE; + } + + Link = Link->ForwardLink; + NextBlockChanged = FALSE; + } +} + +/** Generate ConfigAltResp string base on the varstore info. @param HiiHandle Hii Handle for this hii package. @param ConfigHdr The config header for this varstore. @param VarStorageData The varstore info. @@ -3610,10 +3772,12 @@ GenerateAltConfigResp ( // // Add length for + '\0' // Length = StrLen (ConfigHdr) + 1; + UpdateBlockDataArray (&VarStorageData->BlockEntry); + for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) { DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry); // // Add length for "&&ALTCFG=XXXX" // |1| StrLen (ConfigHdr) | 8 | 4 | diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h index e6760c3..320754c 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h @@ -1,9 +1,9 @@ /** @file Private structures definitions in HiiDatabase. -Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -29,10 +29,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include #include +#include #include #include #include @@ -75,15 +76,18 @@ typedef struct { typedef struct { LIST_ENTRY Entry; // Link to Block array UINT16 Offset; UINT16 Width; + UINT16 BitOffset; + UINT16 BitWidth; EFI_QUESTION_ID QuestionId; UINT8 OpCode; UINT8 Scope; LIST_ENTRY DefaultValueEntry; // Link to its default value array CHAR16 *Name; + BOOLEAN IsBitVar; } IFR_BLOCK_DATA; // // Get default value from IFR data. // diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf index 6bb1d03..9f99c2c 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf @@ -2,11 +2,11 @@ # The DXE driver produces HII protocols defined in UEFI specification. # # This driver produces all required HII serivces that includes HiiDataBase, HiiString, # HiiFont, HiiConfigRouting. To support UEFI HII, this driver is required. # -# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php @@ -88,10 +88,11 @@ ## CONSUMES ## Event ## PRODUCES ## Event gEfiHiiKeyBoardLayoutGuid gEfiHiiImageDecoderNameJpegGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID gEfiHiiImageDecoderNamePngGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID + gEfiIfrBitvarstoreGuid ## SOMETIMES_CONSUMES ## GUID [Depex] TRUE [UserExtensions.TianoCore."ExtraFiles"] -- 1.9.5.msysgit.1