/** @file Var Check Hii generation from Hii Database. Copyright (c) 2015, Intel Corporation. All rights reserved.
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 ""; } /** 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