UINTN Index;\r
CHAR16 *QuestionName;\r
CHAR16 *StringPtr;\r
+ UINT16 BitOffset;\r
+ UINT16 BitWidth;\r
+ UINT16 TotalBits;\r
+ UINTN StartBit;\r
+ UINTN EndBit;\r
+ BOOLEAN QuestionReferBitField;\r
+ UINT32 BufferValue;\r
\r
//\r
// Initialize the local variables.\r
IfrEfiVarStore = NULL;\r
ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));\r
ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
+ BitOffset = 0;\r
+ BitWidth = 0;\r
+ QuestionReferBitField = FALSE;\r
\r
//\r
// Check IFR value is in block data, then Validate Value\r
//\r
// Get Offset by Question header and Width by DataType Flags\r
//\r
- Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the byte offset/width for bit field.\r
+ //\r
+ BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+ BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+ Offset = BitOffset / 8;\r
+ TotalBits = BitOffset % 8 + BitWidth;\r
+ Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+ } else {\r
+ Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ }\r
//\r
// Check whether this question is in current block array.\r
//\r
// Get the current value for oneof opcode\r
//\r
VarValue = 0;\r
- CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the value in bit fields.\r
+ //\r
+ StartBit = BitOffset % 8;\r
+ EndBit = StartBit + BitWidth - 1;\r
+ CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+ VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+ } else {\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ }\r
}\r
//\r
// Set Block Data, to be checked in the following Oneof option opcode.\r
//\r
// Get Offset by Question header and Width by DataType Flags\r
//\r
- Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the byte offset/width for bit field.\r
+ //\r
+ BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+ BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+ Offset = BitOffset / 8;\r
+ TotalBits = BitOffset % 8 + BitWidth;\r
+ Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+ } else {\r
+ Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ }\r
//\r
// Check whether this question is in current block array.\r
//\r
// Check the current value is in the numeric range.\r
//\r
VarValue = 0;\r
- CopyMem (&VarValue, VarBuffer + Offset, Width);\r
- }\r
- if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {\r
- switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
- case EFI_IFR_NUMERIC_SIZE_1:\r
- if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_2:\r
- if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_4:\r
- if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_8:\r
- if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the value in the bit fields.\r
+ //\r
+ StartBit = BitOffset % 8;\r
+ EndBit = StartBit + BitWidth - 1;\r
+ CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+ VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+ } else {\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
}\r
+ }\r
+ if ( QuestionReferBitField) {\r
+ //\r
+ // Value in bit fields was stored as UINt32 type.\r
+ //\r
+ if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) {\r
+ if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
+ if (VarValue < IfrNumeric->data.u32.MinValue || VarValue > IfrNumeric->data.u32.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
} else {\r
- switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
- case EFI_IFR_NUMERIC_SIZE_1:\r
- if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_2:\r
- if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_4:\r
- if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
+ if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {\r
+ switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
}\r
- break;\r
- case EFI_IFR_NUMERIC_SIZE_8:\r
- if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {\r
- //\r
- // Not in the valid range.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) {\r
+ //\r
+ // Not in the valid range.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
}\r
- break;\r
}\r
}\r
break;\r
//\r
// Get Offset by Question header\r
//\r
- Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) sizeof (BOOLEAN);\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the byte offset/width for bit field.\r
+ //\r
+ BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+ BitWidth = 1;\r
+ Offset = BitOffset / 8;\r
+ TotalBits = BitOffset % 8 + BitWidth;\r
+ Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+ } else {\r
+ Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) sizeof (BOOLEAN);\r
+ }\r
//\r
// Check whether this question is in current block array.\r
//\r
// Check the current value is in the numeric range.\r
//\r
VarValue = 0;\r
- CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the value in bit fields.\r
+ //\r
+ StartBit = BitOffset % 8;\r
+ EndBit = StartBit + BitWidth - 1;\r
+ CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);\r
+ VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+ } else {\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ }\r
}\r
//\r
// Boolean type, only 1 and 0 is valid.\r
}\r
break;\r
case EFI_IFR_END_OP:\r
+ QuestionReferBitField = FALSE;\r
//\r
// Decrease opcode scope for the validated opcode\r
//\r
return EFI_INVALID_PARAMETER;\r
}\r
break;\r
+ case EFI_IFR_GUID_OP:\r
+ if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+ QuestionReferBitField = TRUE;\r
+ }\r
+ break;\r
default:\r
//\r
// Increase Scope for the validated opcode\r