| /** @file | |
| Var Check Hii generation from Hii Database. | |
| Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "VarCheckHiiGen.h" | |
| /** | |
| Generate from Hii Database. | |
| **/ | |
| VOID | |
| VarCheckHiiGenFromHiiDatabase ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN BufferSize; | |
| VOID *Buffer; | |
| EFI_PHYSICAL_ADDRESS BufferAddress; | |
| EFI_HII_DATABASE_PROTOCOL *HiiDatabase; | |
| // | |
| // Locate HII Database protocol | |
| // | |
| Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase); | |
| if (EFI_ERROR (Status)) { | |
| return; | |
| } | |
| // | |
| // Call first time with zero buffer length. | |
| // Should fail with EFI_BUFFER_TOO_SMALL. | |
| // | |
| BufferSize = 0; | |
| Buffer = NULL; | |
| Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| // | |
| // Allocate buffer to hold the HII Database. | |
| // | |
| Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (BufferSize), &BufferAddress); | |
| ASSERT_EFI_ERROR (Status); | |
| Buffer = (VOID *)(UINTN)BufferAddress; | |
| // | |
| // Export HII Database into the buffer. | |
| // | |
| Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer); | |
| ASSERT_EFI_ERROR (Status); | |
| DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromHii - HII Database exported at 0x%x, size = 0x%x\n", Buffer, BufferSize)); | |
| #ifdef DUMP_HII_DATA | |
| DEBUG_CODE ( | |
| DumpHiiDatabase (Buffer, BufferSize); | |
| ); | |
| #endif | |
| VarCheckParseHiiDatabase (Buffer, BufferSize); | |
| gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize)); | |
| } | |
| } | |
| #ifdef DUMP_VAR_CHECK_HII | |
| GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = { | |
| { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" }, | |
| { EFI_IFR_ONE_OF_OP, "OneOf" }, | |
| { EFI_IFR_CHECKBOX_OP, "CheckBox" }, | |
| { EFI_IFR_NUMERIC_OP, "Numeric" }, | |
| { EFI_IFR_ORDERED_LIST_OP, "OrderedList" }, | |
| }; | |
| /** | |
| HII opcode to string. | |
| @param[in] HiiOpCode Hii OpCode. | |
| @return Pointer to string. | |
| **/ | |
| CHAR8 * | |
| HiiOpCodeToStr ( | |
| IN UINT8 HiiOpCode | |
| ) | |
| { | |
| UINTN Index; | |
| for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) { | |
| if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) { | |
| return mHiiOpCodeStringTable[Index].HiiOpCodeStr; | |
| } | |
| } | |
| return "<UnknownHiiOpCode>"; | |
| } | |
| /** | |
| Dump Hii Question. | |
| @param[in] HiiQuestion Pointer to Hii Question. | |
| **/ | |
| VOID | |
| DumpHiiQuestion ( | |
| IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion | |
| ) | |
| { | |
| UINT64 Minimum; | |
| UINT64 Maximum; | |
| UINT64 OneValue; | |
| UINT8 *Ptr; | |
| DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n")); | |
| DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); | |
| DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length)); | |
| DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); | |
| DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); | |
| switch (HiiQuestion->OpCode) { | |
| case EFI_IFR_ONE_OF_OP: | |
| Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); | |
| while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { | |
| OneValue = 0; | |
| if (HiiQuestion->BitFieldStore) { | |
| // | |
| // For OneOf stored in bit field, the value of options are saved as UINT32 type. | |
| // | |
| CopyMem (&OneValue, Ptr, sizeof (UINT32)); | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); | |
| } else { | |
| CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); | |
| switch (HiiQuestion->StorageWidth) { | |
| case sizeof (UINT8): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); | |
| break; | |
| case sizeof (UINT16): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); | |
| break; | |
| case sizeof (UINT32): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); | |
| break; | |
| case sizeof (UINT64): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); | |
| break; | |
| default: | |
| ASSERT (FALSE); | |
| break; | |
| } | |
| } | |
| if (HiiQuestion->BitFieldStore) { | |
| Ptr += sizeof (UINT32); | |
| } else { | |
| Ptr += HiiQuestion->StorageWidth; | |
| } | |
| } | |
| break; | |
| case EFI_IFR_CHECKBOX_OP: | |
| break; | |
| case EFI_IFR_NUMERIC_OP: | |
| Minimum = 0; | |
| Maximum = 0; | |
| Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); | |
| if (HiiQuestion->BitFieldStore) { | |
| // | |
| // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. | |
| // | |
| CopyMem (&Minimum, Ptr, sizeof (UINT32)); | |
| Ptr += sizeof (UINT32); | |
| CopyMem (&Maximum, Ptr, sizeof (UINT32)); | |
| Ptr += sizeof (UINT32); | |
| DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); | |
| DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); | |
| } else { | |
| CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); | |
| Ptr += HiiQuestion->StorageWidth; | |
| CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); | |
| Ptr += HiiQuestion->StorageWidth; | |
| switch (HiiQuestion->StorageWidth) { | |
| case sizeof (UINT8): | |
| DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum)); | |
| DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum)); | |
| break; | |
| case sizeof (UINT16): | |
| DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum)); | |
| DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum)); | |
| break; | |
| case sizeof (UINT32): | |
| DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); | |
| DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); | |
| break; | |
| case sizeof (UINT64): | |
| DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum)); | |
| DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum)); | |
| break; | |
| default: | |
| ASSERT (FALSE); | |
| break; | |
| } | |
| } | |
| break; | |
| case EFI_IFR_ORDERED_LIST_OP: | |
| DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers)); | |
| Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); | |
| while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { | |
| OneValue = 0; | |
| CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); | |
| switch (HiiQuestion->StorageWidth) { | |
| case sizeof (UINT8): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); | |
| break; | |
| case sizeof (UINT16): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); | |
| break; | |
| case sizeof (UINT32): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); | |
| break; | |
| case sizeof (UINT64): | |
| DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); | |
| break; | |
| default: | |
| ASSERT (FALSE); | |
| break; | |
| } | |
| Ptr += HiiQuestion->StorageWidth; | |
| } | |
| break; | |
| default: | |
| ASSERT (FALSE); | |
| break; | |
| } | |
| } | |
| /** | |
| Dump Hii Variable. | |
| @param[in] HiiVariable Pointer to Hii Variable. | |
| **/ | |
| VOID | |
| DumpHiiVariable ( | |
| IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable | |
| ) | |
| { | |
| VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; | |
| DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n")); | |
| DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision)); | |
| DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength)); | |
| DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length)); | |
| DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode))); | |
| DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size)); | |
| DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes)); | |
| DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid)); | |
| DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1)); | |
| // | |
| // For Hii Question header align. | |
| // | |
| HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); | |
| while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { | |
| // | |
| // Dump Hii Question related to the Hii Variable. | |
| // | |
| DumpHiiQuestion (HiiQuestion); | |
| // | |
| // For Hii Question header align. | |
| // | |
| HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); | |
| } | |
| } | |
| /** | |
| Dump Var Check HII. | |
| @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin. | |
| @param[in] VarCheckHiiBinSize VarCheckHiiBin size. | |
| **/ | |
| VOID | |
| DumpVarCheckHii ( | |
| IN VOID *VarCheckHiiBin, | |
| IN UINTN VarCheckHiiBinSize | |
| ) | |
| { | |
| VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; | |
| DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n")); | |
| // | |
| // For Hii Variable header align. | |
| // | |
| HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin); | |
| while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) { | |
| DumpHiiVariable (HiiVariable); | |
| // | |
| // For Hii Variable header align. | |
| // | |
| HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); | |
| } | |
| } | |
| #endif |