VirtualBox

Ignore:
Timestamp:
Aug 14, 2024 1:16:30 PM (8 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164367
Message:

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c

    r101291 r105670  
    33
    44  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
    5   Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     5  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     6  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
    67
    78  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    205206
    206207/**
     208  Debug dump HII statement value.
     209
     210  @param[in]  ErrorLevel    DEBUG macro error level
     211  @param[in]  Value         HII statement value to dump
     212  @param[in]  Message       Debug message
     213
     214  @retval EFI_SUCCESS       Dump HII statement value successfully
     215  @retval Others            Errors occur
     216
     217**/
     218EFI_STATUS
     219DumpHiiStatementValue (
     220  IN UINTN                ErrorLevel,
     221  IN HII_STATEMENT_VALUE  *Value,
     222  IN CHAR8                *Message OPTIONAL
     223  )
     224{
     225  UINT64  Data;
     226
     227  if (Value == NULL) {
     228    return EFI_INVALID_PARAMETER;
     229  }
     230
     231  switch (Value->Type) {
     232    case EFI_IFR_TYPE_NUM_SIZE_8:
     233      Data = Value->Value.u8;
     234      break;
     235    case EFI_IFR_TYPE_NUM_SIZE_16:
     236      Data = Value->Value.u16;
     237      break;
     238    case EFI_IFR_TYPE_NUM_SIZE_32:
     239      Data = Value->Value.u32;
     240      break;
     241    case EFI_IFR_TYPE_NUM_SIZE_64:
     242      Data = Value->Value.u64;
     243      break;
     244    case EFI_IFR_TYPE_BOOLEAN:
     245      Data = (Value->Value.b ? 1 : 0);
     246      break;
     247    default:
     248      DEBUG ((ErrorLevel, "%a: unsupported type: 0x%x\n", __func__, Value->Type));
     249      return EFI_UNSUPPORTED;
     250  }
     251
     252  if (IS_EMPTY_STRING (Message)) {
     253    DEBUG ((ErrorLevel, "0x%lx\n", Data));
     254  } else {
     255    DEBUG ((ErrorLevel, "%a: 0x%lx\n", Message, Data));
     256  }
     257
     258  return EFI_SUCCESS;
     259}
     260
     261/**
     262  Debug dump HII statement prompt string.
     263
     264  @param[in]  ErrorLevel    DEBUG macro error level
     265  @param[in]  HiiHandle     HII handle instance
     266  @param[in]  HiiStatement  HII statement
     267  @param[in]  Message       Debug message
     268
     269  @retval EFI_SUCCESS       Dump HII statement string successfully
     270  @retval Others            Errors occur
     271
     272**/
     273EFI_STATUS
     274DumpHiiStatementPrompt (
     275  IN UINTN           ErrorLevel,
     276  IN EFI_HII_HANDLE  HiiHandle,
     277  IN HII_STATEMENT   *HiiStatement,
     278  IN CHAR8           *Message OPTIONAL
     279  )
     280{
     281  EFI_STRING  String;
     282
     283  if ((HiiHandle == NULL) || (HiiStatement == NULL)) {
     284    return EFI_INVALID_PARAMETER;
     285  }
     286
     287  if (HiiStatement->Prompt == 0) {
     288    return EFI_NOT_FOUND;
     289  }
     290
     291  String = HiiGetString (HiiHandle, HiiStatement->Prompt, NULL);
     292  if (String == NULL) {
     293    return EFI_NOT_FOUND;
     294  }
     295
     296  if (IS_EMPTY_STRING (Message)) {
     297    DEBUG ((ErrorLevel, "%s\n", String));
     298  } else {
     299    DEBUG ((ErrorLevel, "%a: %s\n", Message, String));
     300  }
     301
     302  FreePool (String);
     303
     304  return EFI_SUCCESS;
     305}
     306
     307/**
    207308  Build the menu path to given statement instance. It is caller's
    208309  responsibility to free returned string buffer.
     
    215316**/
    216317CHAR8 *
    217 BuildMenPath (
     318BuildMenuPath (
    218319  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *StatementPrivate
    219320  )
     
    245346
    246347  do {
    247     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "F(%d) <-", FormPrivate->Id));
     348    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "F(%d) <-", FormPrivate->Id));
    248349    FormPrivate = FindFormLinkToThis (FormPrivate);
    249350    if (FormPrivate == NULL) {
     
    287388      AsciiStrCatS (Buffer, OldBufferSize, FormTitle);
    288389      FreePool (FormTitle);
    289       DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " %a\n", Buffer));
     390      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " %a\n", Buffer));
    290391    }
    291392
     
    829930
    830931    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
     932    if (TmpString == NULL) {
     933      TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text);
     934    }
     935
    831936    if (TmpString != NULL) {
    832937      if (StrCmp (TmpString, HiiString) == 0) {
     
    891996    default:
    892997      RedfishValue->Type = RedfishValueTypeUnknown;
     998      DEBUG ((DEBUG_ERROR, "%a: Unsupported value type: 0x%x\n", __func__, Value->Type));
    893999      break;
    8941000  }
     
    9561062  }
    9571063
    958   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
    959   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
    960   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
    961   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
    962   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
    963   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
     1064  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
     1065  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
     1066  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
     1067  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
     1068  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
     1069  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
    9641070
    9651071  if (OrderedListStatement->Value.Buffer == NULL) {
     
    9781084      Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
    9791085      for (Index = 0; Index < Count; Index++) {
    980         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
     1086        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
    9811087      }
    9821088
     
    9861092      Count   = OrderedListStatement->StorageWidth / sizeof (UINT16);
    9871093      for (Index = 0; Index < Count; Index++) {
    988         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value16[Index]));
     1094        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value16[Index]));
    9891095      }
    9901096
     
    9941100      Count   = OrderedListStatement->StorageWidth / sizeof (UINT32);
    9951101      for (Index = 0; Index < Count; Index++) {
    996         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value32[Index]));
     1102        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value32[Index]));
    9971103      }
    9981104
     
    10021108      Count   = OrderedListStatement->StorageWidth / sizeof (UINT64);
    10031109      for (Index = 0; Index < Count; Index++) {
    1004         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value64[Index]));
     1110        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value64[Index]));
    10051111      }
    10061112
     
    10101116      Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
    10111117      for (Index = 0; Index < Count; Index++) {
    1012         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
    1013       }
    1014 
    1015       break;
    1016   }
    1017 
    1018   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
     1118        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
     1119      }
     1120
     1121      break;
     1122  }
     1123
     1124  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
    10191125}
    10201126
     
    11271233
    11281234    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
     1235    if (TmpString == NULL) {
     1236      TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text);
     1237    }
     1238
    11291239    if (TmpString != NULL) {
    11301240      if (StrCmp (TmpString, HiiString) == 0) {
     
    11881298      StringId = HiiValueToOneOfOptionStringId (HiiStatement, Value);
    11891299      if (StringId == 0) {
     1300        //
     1301        // Print prompt string of HII statement for ease of debugging
     1302        //
     1303        DumpHiiStatementPrompt (DEBUG_ERROR, HiiHandle, HiiStatement, "Can not find string ID");
     1304        DumpHiiStatementValue (DEBUG_ERROR, Value, "Current value");
    11901305        ASSERT (FALSE);
    11911306        Status = EFI_DEVICE_ERROR;
     
    12551370      StringIdArray = HiiValueToOrderedListOptionStringId (HiiStatement, &Count);
    12561371      if (StringIdArray == NULL) {
     1372        //
     1373        // Print prompt string of HII statement for ease of debugging
     1374        //
     1375        DumpHiiStatementPrompt (DEBUG_ERROR, HiiHandle, HiiStatement, "Can not get string ID array");
    12571376        ASSERT (FALSE);
    12581377        Status = EFI_DEVICE_ERROR;
     
    12621381      RedfishValue->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
    12631382      if (RedfishValue->Value.StringArray == NULL) {
     1383        //
     1384        // Print prompt string of HII statement for ease of debugging
     1385        //
     1386        DumpHiiStatementPrompt (DEBUG_ERROR, HiiHandle, HiiStatement, "Can not allocate memory");
    12641387        ASSERT (FALSE);
    12651388        Status = EFI_OUT_OF_RESOURCES;
     
    12681391
    12691392      for (Index = 0; Index < Count; Index++) {
    1270         ASSERT (StringIdArray[Index] != 0);
     1393        if (StringIdArray[Index] == 0) {
     1394          //
     1395          // Print prompt string of HII statement for ease of debugging
     1396          //
     1397          DumpHiiStatementPrompt (DEBUG_ERROR, HiiHandle, HiiStatement, "String ID in array is 0");
     1398          ASSERT (FALSE);
     1399        }
     1400
    12711401        RedfishValue->Value.StringArray[Index] = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringIdArray[Index]);
    12721402        ASSERT (RedfishValue->Value.StringArray[Index] != NULL);
     
    12901420      if (RedfishValue->Value.Buffer == NULL) {
    12911421        //
    1292         // No x-uefi-redfish string defined. Try to get string in English.
     1422        // No x-UEFI-redfish string defined. Try to get string in English.
    12931423        //
    12941424        RedfishValue->Value.Buffer = HiiGetEnglishAsciiString (HiiHandle, HiiStatement->ExtraData.TextTwo);
     
    13711501  }
    13721502
    1373   StringLen = StrLen (UnicodeString) + 1;
     1503  StringLen = HiiStrLen (UnicodeString) + 1;
    13741504  Buffer    = AllocatePool (StringLen * sizeof (CHAR8));
    13751505  if (Buffer == NULL) {
     
    16611791    //
    16621792    if ((TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP) && (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
    1663       TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
    1664       if (TempBuffer == NULL) {
    1665         return EFI_OUT_OF_RESOURCES;
    1666       }
    1667 
    1668       FreePool (StatementValue->Buffer);
     1793      //
     1794      // Keep input buffer to TempBuffer because StatementValue will be
     1795      // assigned in HiiStringToOneOfOptionValue().
     1796      //
     1797      TempBuffer                = (EFI_STRING)StatementValue->Buffer;
    16691798      StatementValue->Buffer    = NULL;
    16701799      StatementValue->BufferLen = 0;
     
    17451874  }
    17461875
    1747   if (StatementValue->Value.string != 0) {
    1748     HiiDeleteString (StatementValue->Value.string, TargetStatement->ParentForm->ParentFormset->HiiHandle);
     1876  if ((TargetStatement->HiiStatement->Operand == EFI_IFR_STRING_OP) && (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
     1877    if (StatementValue->Value.string != 0) {
     1878      // Delete HII string which was created for HII statement operand = EFI_IFR_STRING_OP and Type = EFI_IFR_TYPE_STRING.
     1879      HiiDeleteString (StatementValue->Value.string, TargetStatement->ParentForm->ParentFormset->HiiHandle);
     1880    }
    17491881  }
    17501882
     
    18812013  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF   *StatementRef;
    18822014  LIST_ENTRY                                      *NextLink;
    1883   EFI_STRING                                      TmpString;
    18842015  EFI_STRING                                      *TmpConfigureLangList;
    18852016  UINTN                                           Index;
    18862017  CHAR8                                           *FullSchema;
     2018
     2019  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Harvest config language of %a_%a (Regex: %s).\n", __func__, Schema, Version, RegexPattern));
    18872020
    18882021  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || (Count == NULL) || (ConfigureLangList == NULL) || IS_EMPTY_STRING (RegexPattern)) {
     
    19352068      ASSERT (StatementRef->Statement->Description != 0);
    19362069      if (StatementRef->Statement->Description != 0) {
    1937         TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
    1938         ASSERT (TmpString != NULL);
    1939         if (TmpString != NULL) {
    1940           TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
    1941           ASSERT (TmpConfigureLangList[Index] != NULL);
    1942           FreePool (TmpString);
    1943           ++Index;
    1944         }
     2070        ASSERT (StatementRef->Statement->XuefiRedfishStr != NULL);
     2071        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize (StatementRef->Statement->XuefiRedfishStr), (VOID *)StatementRef->Statement->XuefiRedfishStr);
     2072        ++Index;
    19452073      }
    19462074    }
     
    19502078  *ConfigureLangList = TmpConfigureLangList;
    19512079
     2080  DEBUG_REDFISH_THIS_MODULE (
     2081    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
     2082    "%a: Number of configure language strings harvested: %d\n",
     2083    __func__,
     2084    StatementList.Count
     2085    );
     2086
     2087  DEBUG_REDFISH_THIS_MODULE_CODE (
     2088    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
     2089    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, "%a: Number of configure language strings harvested: %d\n", __func__, StatementList.Count);
     2090    for (Index = 0; Index < *Count; Index++) {
     2091    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, "   (%d) %s\n", Index, TmpConfigureLangList[Index]);
     2092  }
     2093
     2094    );
     2095
    19522096RELEASE_RESOURCE:
    19532097
     
    19602104  }
    19612105
     2106  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: exit.\n", __func__));
    19622107  return Status;
    19632108}
     
    19682113  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
    19692114  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
    1970                                    For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
     2115                                   For example: "x-UEFI-redfish-Memory.v1_7_1;x-UEFI-redfish-Boot.v1_0_1"
    19712116                                   The SupportedSchema is allocated by the callee. It's caller's
    19722117                                   responsibility to free this buffer using FreePool().
     
    21742319  CHAR8                                      *Buffer;
    21752320
     2321  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Entry\n", __func__));
    21762322  if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
    21772323    return EFI_INVALID_PARAMETER;
     
    22152361  // Build up menu path
    22162362  //
    2217   AttributeValue->MenuPath = BuildMenPath (TargetStatement);
    2218   if (AttributeValue->MenuPath == NULL) {
    2219     DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n", __func__, AttributeValue->AttributeName));
     2363  if (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
     2364    AttributeValue->MenuPath = BuildMenuPath (TargetStatement);
     2365    if (AttributeValue->MenuPath == NULL) {
     2366      DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n", __func__, AttributeValue->AttributeName));
     2367    }
    22202368  }
    22212369
     
    22482396  }
    22492397
     2398  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Exit\n", __func__));
    22502399  return Status;
    22512400}
  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h

    r101291 r105670  
    33
    44  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
    5   Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     5  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     6  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
    67
    78  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    2122#include <Library/DebugLib.h>
    2223#include <Library/MemoryAllocationLib.h>
     24#include <Library/PcdLib.h>
    2325#include <Library/PrintLib.h>
     26#include <Library/RedfishDebugLib.h>
    2427#include <Library/UefiLib.h>
    2528#include <Library/UefiBootServicesTableLib.h>
     
    3740//
    3841#include <Protocol/EdkIIRedfishPlatformConfig.h>
     42
     43//
     44// Debug message in DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE scope.
     45// To enable the debug message for this module, below PCDs must be set.
     46//
     47// 1. DEBUG_MANAGEABILITY must be set PcdDebugPrintErrorLevel.
     48//
     49// 2  RedfishPlatformConfigDxe debug enablement must be set in
     50//    PcdRedfishDebugCategory (defined in RedfishPkg.dec)
     51//
     52// 3. The subordinate debug enablement for RedfishPlatformConfigDxe
     53//    must be set in PcdRedfishPlatformConfigDebugProperty (defined
     54//    in RedfishPkg.dec).
     55//
     56#define DEBUG_REDFISH_THIS_MODULE(DebugSubordinate, ...) \
     57  while (RedfishPlatformConfigDebugProp (DebugSubordinate)) { \
     58    DEBUG_REDFISH(DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, ##__VA_ARGS__); \
     59    break; \
     60  }
     61
     62#define DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
     63  if (RedfishPlatformConfigDebugProp (DebugSubordinate)) {
     64
     65#define DEBUG_REDFISH_THIS_MODULE_CODE_END()  }
     66
     67#define DEBUG_REDFISH_THIS_MODULE_CODE(DebugSubordinate, Expression) \
     68  DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
     69  Expression \
     70  DEBUG_REDFISH_THIS_MODULE_CODE_END()
     71
     72// Subordinate debug property for DEBUG_REDFISH_PLATFORM_CONFIG_DXE
     73#define REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE     0x00000001
     74#define REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET        0x00000002
     75#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH  0x00000004
     76#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX   0x00000008
    3977
    4078///
     
    74112#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
    75113#define REGULAR_EXPRESSION_INCLUDE_ALL   L".*"
    76 #define CONFIGURE_LANGUAGE_PREFIX        "x-uefi-redfish-"
     114#define CONFIGURE_LANGUAGE_PREFIX        "x-UEFI-redfish-"
    77115#define REDFISH_PLATFORM_CONFIG_VERSION  0x00010000
    78 #define REDFISH_PLATFORM_CONFIG_DEBUG    DEBUG_MANAGEABILITY
    79 #define REDFISH_MENU_PATH_SIZE           8
     116
     117#define REDFISH_MENU_PATH_SIZE  8
     118
     119// Definitions of Redfish platform config capability
     120#define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH   0x000000001
     121#define REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED  0x000000002
    80122
    81123/**
  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf

    r101291 r105670  
    44#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
    55#  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     6#  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
    67#
    78#  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    2425
    2526[Sources]
     27  RedfishPlatformConfigCapability.c
    2628  RedfishPlatformConfigDxe.h
    2729  RedfishPlatformConfigDxe.c
     
    3739  HiiUtilityLib
    3840  MemoryAllocationLib
     41  PcdLib
    3942  PrintLib
     43  RedfishDebugLib
    4044  UefiLib
    4145  UefiBootServicesTableLib
     
    5256  gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
    5357
     58[FixedPcd]
     59 gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty
     60 gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty
     61
    5462[Depex]
    5563  TRUE
  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c

    r101291 r105670  
    33
    44  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
    5   Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     5  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     6  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
    67
    78  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    3233
    3334  if ((HiiHandle == NULL) || (StringId == 0)) {
    34     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "???"));
     35    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "???"));
    3536    return EFI_INVALID_PARAMETER;
    3637  }
     
    4142  }
    4243
    43   DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%s", String));
     44  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%s", String));
    4445  FreePool (String);
    4546
     
    7980    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
    8081
    81     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
     82    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
    8283    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
    83     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
     84    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
    8485
    8586    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
     
    8889      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
    8990
    90       DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
     91      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
    9192      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
    92       DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
     93      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
    9394
    9495      HiiStatementLink = HiiNextStatementLink;
     
    125126
    126127  if (IsListEmpty (FormsetList)) {
    127     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: Empty formset list\n", __func__));
     128    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Empty formset list\n", __func__));
    128129    return EFI_SUCCESS;
    129130  }
     
    135136    HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
    136137
    137     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
     138    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
    138139    DumpFormset (HiiFormsetPrivate);
    139140
     
    142143
    143144  return EFI_SUCCESS;
     145}
     146
     147/**
     148  Return the HII string length. We don't check word alignment
     149  of the input string as same as the checking in StrLen
     150  function, because the HII string in the database is compact
     151  at the byte alignment.
     152
     153  @param[in]  String  Input UCS format string.
     154
     155  @retval Length of the string.
     156
     157**/
     158UINTN
     159EFIAPI
     160HiiStrLen (
     161  IN  CONST CHAR16  *String
     162  )
     163{
     164  UINTN  Length;
     165
     166  ASSERT (String != NULL);
     167
     168  for (Length = 0; *String != L'\0'; String++, Length++) {
     169  }
     170
     171  return Length;
     172}
     173
     174/**
     175  Return the HII string size. We don't check word alignment
     176  of the input string as same as the checking in StrLen
     177  function, because the HII string in the database is compact
     178  at the byte alignment.
     179
     180  @param[in]  String  Input UCS format string.
     181
     182  @retval Size of the string.
     183
     184**/
     185UINTN
     186EFIAPI
     187HiiStrSize (
     188  IN      CONST CHAR16  *String
     189  )
     190{
     191  return (HiiStrLen (String) + 1) * sizeof (*String);
     192}
     193
     194/**
     195  Compare two HII strings. We don't check word alignment
     196  of the input string as same as the checking in StrLen
     197  function, because the HII string in the database is compact
     198  at the byte alignment.
     199
     200  @param[in]  FirstString   Input UCS format of string to search.
     201  @param[in]  SecondString  Input UCS format of string to look for in
     202                            FirstString;
     203
     204  @retval 0   The strings are identical.
     205          !0  The strings are not identical.
     206
     207**/
     208INTN
     209EFIAPI
     210HiiStrCmp (
     211  IN      CONST CHAR16  *FirstString,
     212  IN      CONST CHAR16  *SecondString
     213  )
     214{
     215  //
     216  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
     217  //
     218  ASSERT (HiiStrSize (FirstString) != 0);
     219  ASSERT (HiiStrSize (SecondString) != 0);
     220
     221  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
     222    FirstString++;
     223    SecondString++;
     224  }
     225
     226  return *FirstString - *SecondString;
    144227}
    145228
     
    303386
    304387/**
    305   Get string from HII database in English language. The returned string is allocated
    306   using AllocatePool(). The caller is responsible for freeing the allocated buffer using
    307   FreePool().
    308 
    309   @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
    310   @param[in]  StringId          The identifier of the string to retrieved from the string
    311                                 package associated with HiiHandle.
    312 
    313   @retval NULL   The string specified by StringId is not present in the string package.
    314   @retval Other  The string was returned.
    315 
    316 **/
    317 EFI_STRING
    318 HiiGetEnglishString (
    319   IN EFI_HII_HANDLE  HiiHandle,
    320   IN EFI_STRING_ID   StringId
    321   )
    322 {
    323   return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId);
    324 }
    325 
    326 /**
    327388  Get ASCII string from HII database in English language. The returned string is allocated
    328389  using AllocatePool(). The caller is responsible for freeing the allocated buffer using
     
    562623        HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
    563624
    564         if ((HiiStatementPrivate->Description != 0) && !HiiStatementPrivate->Suppressed) {
    565           TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
     625        if ((HiiStatementPrivate->Description != 0) &&
     626            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
     627        {
     628          TmpString = HiiStatementPrivate->XuefiRedfishStr;
    566629          if (TmpString != NULL) {
    567630            Status = RegularExpressionProtocol->MatchString (
     
    593656              ++StatementList->Count;
    594657            }
    595 
    596             FreePool (TmpString);
     658          } else {
     659            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
     660              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
     661              ASSERT (FALSE);
     662            }
    597663          }
    598664        }
     
    637703  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
    638704  EFI_STRING                                 TmpString;
     705  UINTN                                      Index;
    639706
    640707  if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
     
    646713  }
    647714
     715  Index          = 0;
    648716  HiiFormsetLink = GetFirstNode (FormsetList);
    649717  while (!IsNull (FormsetList, HiiFormsetLink)) {
     
    670738        HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
    671739
    672         DEBUG_CODE (
    673           STATIC UINTN Index = 0;
    674           DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: [%d] search %s in QID: 0x%x form: 0x%x formset: %g\n", __func__, ++Index, ConfigureLang, HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid));
    675           );
    676 
    677         if (HiiStatementPrivate->Description != 0) {
    678           TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
     740        if ((HiiStatementPrivate->Description != 0) &&
     741            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
     742        {
     743          TmpString = HiiStatementPrivate->XuefiRedfishStr;
    679744          if (TmpString != NULL) {
    680             if (StrCmp (TmpString, ConfigureLang) == 0) {
    681               FreePool (TmpString);
     745            Index++;
     746            DEBUG_REDFISH_THIS_MODULE (
     747              REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH,
     748              "%a: [%d] check %s in QID: 0x%x form: 0x%x formset: %g\n",
     749              __func__,
     750              Index,
     751              ConfigureLang,
     752              HiiStatementPrivate->QuestionId,
     753              HiiFormPrivate->Id,
     754              &HiiFormsetPrivate->Guid
     755              );
     756            if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
    682757              return HiiStatementPrivate;
    683758            }
    684 
    685             FreePool (TmpString);
     759          } else {
     760            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
     761              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
     762              ASSERT (FALSE);
     763            }
    686764          }
    687765        }
     
    742820
    743821/**
     822  Release x-UEFI-string related information.
     823
     824  @param[in]      FormsetPrivate Pointer to HII form-set private instance.
     825
     826  @retval         EFI_STATUS
     827
     828**/
     829EFI_STATUS
     830ReleaseXuefiStringDatabase (
     831  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
     832  )
     833{
     834  REDFISH_X_UEFI_STRING_DATABASE  *ThisDatabase;
     835  REDFISH_X_UEFI_STRING_DATABASE  *PreDatabase;
     836  REDFISH_X_UEFI_STRINGS_ARRAY    *ThisStringArray;
     837  REDFISH_X_UEFI_STRINGS_ARRAY    *PreStringArray;
     838  BOOLEAN                         EndDatabase;
     839  BOOLEAN                         EndArray;
     840
     841  if (FormsetPrivate->HiiPackageListHeader != NULL) {
     842    FreePool (FormsetPrivate->HiiPackageListHeader);
     843  }
     844
     845  // Walk through x-UEFI-redfish string database.
     846  if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
     847    EndDatabase  = FALSE;
     848    ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
     849    while (!EndDatabase) {
     850      // Walk through string arrays.
     851      if (!IsListEmpty (&ThisDatabase->XuefiRedfishStringArrays)) {
     852        EndArray        = FALSE;
     853        ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&ThisDatabase->XuefiRedfishStringArrays);
     854        while (!EndArray) {
     855          // Remove this array
     856          FreePool (ThisStringArray->ArrayEntryAddress);
     857          EndArray       = IsNodeAtEnd (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
     858          PreStringArray = ThisStringArray;
     859          if (!EndArray) {
     860            ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
     861          }
     862
     863          RemoveEntryList (&PreStringArray->NextArray);
     864          FreePool (PreStringArray);
     865        }
     866      }
     867
     868      //
     869      // Remove this database
     870      //
     871      EndDatabase = IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
     872      PreDatabase = ThisDatabase;
     873      if (!EndDatabase) {
     874        ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
     875      }
     876
     877      RemoveEntryList (&PreDatabase->NextXuefiRedfishLanguage);
     878      FreePool (PreDatabase);
     879    }
     880  }
     881
     882  return EFI_SUCCESS;
     883}
     884
     885/**
    744886  Release formset and all the forms and statements that belong to this formset.
    745887
    746   @param[in]      FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
     888  @param[in]      FormsetPrivate Pointer to HII form-set private instance.
    747889
    748890  @retval         EFI_STATUS
     
    779921      // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
    780922      //
    781 
    782       if (HiiStatementPrivate->DesStringCache != NULL) {
    783         FreePool (HiiStatementPrivate->DesStringCache);
    784         HiiStatementPrivate->DesStringCache = NULL;
    785       }
    786 
    787923      RemoveEntryList (&HiiStatementPrivate->Link);
    788924      FreePool (HiiStatementPrivate);
     
    821957  }
    822958
     959  ReleaseXuefiStringDatabase (FormsetPrivate);
     960
    823961  return EFI_SUCCESS;
    824962}
     
    846984  //
    847985  InitializeListHead (&NewFormsetPrivate->HiiFormList);
     986  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
    848987
    849988  return NewFormsetPrivate;
     989}
     990
     991/**
     992  Create new x-UEFI-redfish string array.
     993
     994  @param[in]      XuefiRedfishStringDatabase  The x-UEFI-redfish string database.
     995
     996  @retval         EFI_OUT_OF_RESOURCES  Not enough memory for creating a new array.
     997                  EFI_SUCCESS           New array is created successfully.
     998
     999**/
     1000EFI_STATUS
     1001NewRedfishXuefiStringArray (
     1002  IN  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase
     1003  )
     1004{
     1005  REDFISH_X_UEFI_STRINGS_ARRAY  *ArrayAddress;
     1006
     1007  // Initial first REDFISH_X_UEFI_STRINGS_ARRAY memory.
     1008  ArrayAddress = (REDFISH_X_UEFI_STRINGS_ARRAY *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY));
     1009  if (ArrayAddress == NULL) {
     1010    DEBUG ((DEBUG_ERROR, "%a: Failed to allocate REDFISH_X_UEFI_STRINGS_ARRAY.\n", __func__));
     1011    return EFI_OUT_OF_RESOURCES;
     1012  }
     1013
     1014  InitializeListHead (&ArrayAddress->NextArray);
     1015
     1016  // Allocate memory buffer for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT elements.
     1017  ArrayAddress->ArrayEntryAddress = \
     1018    (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT) * X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER);
     1019  if (ArrayAddress->ArrayEntryAddress == NULL) {
     1020    FreePool (ArrayAddress);
     1021    DEBUG ((DEBUG_ERROR, "%a: Failed to allocate array for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENTs.\n", __func__));
     1022    return EFI_OUT_OF_RESOURCES;
     1023  }
     1024
     1025  XuefiRedfishStringDatabase->StringsArrayBlocks++;
     1026  InsertTailList (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ArrayAddress->NextArray);
     1027  return EFI_SUCCESS;
     1028}
     1029
     1030/**
     1031  Get the pointer of x-UEFI-redfish database or create a new database.
     1032
     1033  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.
     1034  @param[in]      HiiStringPackageHeader  HII string package header.
     1035
     1036  @retval         Pointer to REDFISH_X_UEFI_STRING_DATABASE.
     1037                  If NULL, it fails to obtain x-UEFI-redfish database.
     1038
     1039**/
     1040REDFISH_X_UEFI_STRING_DATABASE *
     1041GetExistOrCreateXuefiStringDatabase (
     1042  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
     1043  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
     1044  )
     1045{
     1046  EFI_STATUS                      Status;
     1047  BOOLEAN                         CreateNewOne;
     1048  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
     1049
     1050  CreateNewOne               = TRUE;
     1051  XuefiRedfishStringDatabase = NULL;
     1052  if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
     1053    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
     1054
     1055    while (TRUE) {
     1056      if (AsciiStriCmp (XuefiRedfishStringDatabase->XuefiRedfishLanguage, HiiStringPackageHeader->Language) == 0) {
     1057        CreateNewOne = FALSE;
     1058        break;
     1059      }
     1060
     1061      if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
     1062        break;
     1063      }
     1064
     1065      XuefiRedfishStringDatabase = \
     1066        (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
     1067    }
     1068  }
     1069
     1070  if (CreateNewOne) {
     1071    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Creating x-UEFI-redfish (%a) string database...\n", HiiStringPackageHeader->Language));
     1072    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRING_DATABASE));
     1073    if (XuefiRedfishStringDatabase == NULL) {
     1074      DEBUG ((DEBUG_ERROR, "  Failed to allocate REDFISH_X_UEFI_STRING_DATABASE.\n"));
     1075      return NULL;
     1076    }
     1077
     1078    InitializeListHead (&XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
     1079    InitializeListHead (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
     1080    XuefiRedfishStringDatabase->StringsArrayBlocks   = 0;
     1081    XuefiRedfishStringDatabase->XuefiRedfishLanguage = HiiStringPackageHeader->Language;
     1082
     1083    Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
     1084    if (EFI_ERROR (Status)) {
     1085      FreePool (XuefiRedfishStringDatabase);
     1086      return NULL;
     1087    }
     1088
     1089    DEBUG ((
     1090      DEBUG_REDFISH_PLATFORM_CONFIG,
     1091      "  x-UEFI-redfish (%a):\n    String array is added to XuefiRedfishStringDatabase, total %d arrays now.\n",
     1092      XuefiRedfishStringDatabase->XuefiRedfishLanguage,
     1093      XuefiRedfishStringDatabase->StringsArrayBlocks
     1094      ));
     1095
     1096    // Link string database to FormsetPrivate.
     1097    InsertTailList (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
     1098  }
     1099
     1100  return XuefiRedfishStringDatabase;
     1101}
     1102
     1103/**
     1104  Check and allocate a new x-UEFI-redfish array if it is insufficient for the
     1105  newly added x-UEFI-redfish string.
     1106
     1107  @param[in]      FormsetPrivate              Pointer to HII form-set private instance.
     1108  @param[in]      XuefiRedfishStringDatabase  Pointer to the x-UEFI-redfish database.
     1109  @param[in]      StringId                    String ID added to database.
     1110
     1111  @retval         EFI_SUCCESS                 The size of x-UEFI-string array is adjusted or
     1112                                              is not required to be adjusted.
     1113                  Otherwise, refer to the error code returned from NewRedfishXuefiStringArray().
     1114
     1115**/
     1116EFI_STATUS
     1117RedfishXuefiStringAdjustArrays (
     1118  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
     1119  IN  REDFISH_X_UEFI_STRING_DATABASE            *XuefiRedfishStringDatabase,
     1120  IN  EFI_STRING_ID                             StringId
     1121  )
     1122{
     1123  EFI_STATUS  Status;
     1124
     1125  while (((StringId + X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) / X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) > (UINT16)XuefiRedfishStringDatabase->StringsArrayBlocks) {
     1126    Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
     1127    if (EFI_ERROR (Status)) {
     1128      DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-string array", __func__));
     1129      return Status;
     1130    }
     1131  }
     1132
     1133  return EFI_SUCCESS;
     1134}
     1135
     1136/**
     1137  Insert a x-UEFI-redfish string to database.
     1138
     1139  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.
     1140  @param[in]      HiiStringPackageHeader  Pointer to HII string package.
     1141  @param[in]      StringId                The HII string ID
     1142  @param[in]      StringTextPtr           Pointer to HII string text.
     1143
     1144  @retval         EFI_SUCCESS             The HII string is added to database.
     1145                  EFI_LOAD_ERROR          Something wrong when insert an HII string
     1146                                          to database.
     1147
     1148**/
     1149EFI_STATUS
     1150RedfishXuefiStringInsertDatabase (
     1151  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
     1152  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
     1153  IN  EFI_STRING_ID                             StringId,
     1154  IN  CHAR16                                    *StringTextPtr
     1155  )
     1156{
     1157  EFI_STATUS                      Status;
     1158  UINTN                           StringIdOffset;
     1159  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
     1160  REDFISH_X_UEFI_STRINGS_ARRAY    *ThisArray;
     1161
     1162  XuefiRedfishStringDatabase = GetExistOrCreateXuefiStringDatabase (FormsetPrivate, HiiStringPackageHeader);
     1163  if (XuefiRedfishStringDatabase == NULL) {
     1164    DEBUG ((DEBUG_ERROR, "%a: Failed to get REDFISH_X_UEFI_STRING_DATABASE of x-UEFI-redfish language %a.\n", __func__, HiiStringPackageHeader->Language));
     1165    ReleaseXuefiStringDatabase (FormsetPrivate);
     1166    return EFI_LOAD_ERROR;
     1167  }
     1168
     1169  Status = RedfishXuefiStringAdjustArrays (FormsetPrivate, XuefiRedfishStringDatabase, StringId);
     1170  if (EFI_ERROR (Status)) {
     1171    DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-redfish string array.\n", __func__));
     1172    ReleaseXuefiStringDatabase (FormsetPrivate);
     1173    return EFI_LOAD_ERROR;
     1174  }
     1175
     1176  // Insert string to x-UEFI-redfish string array.
     1177  StringIdOffset = (UINTN)StringId;
     1178  ThisArray      = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
     1179  while (StringIdOffset >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
     1180    ThisArray       = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ThisArray->NextArray);
     1181    StringIdOffset -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
     1182  }
     1183
     1184  // Insert string
     1185  (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId  = StringId;
     1186  (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;
     1187
     1188  DEBUG_REDFISH_THIS_MODULE (
     1189    REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE,
     1190    "  Insert string ID: (%d) to database\n    x-UEFI-string: \"%s\"\n    Language: %a.\n",
     1191    StringId,
     1192    StringTextPtr,
     1193    HiiStringPackageHeader->Language
     1194    );
     1195  return EFI_SUCCESS;
     1196}
     1197
     1198/**
     1199  Get x-UEFI-redfish string and language by string ID.
     1200
     1201  @param[in]       FormsetPrivate          Pointer to HII form-set private instance.
     1202  @param[in]       HiiStringPackageHeader  HII string package header.
     1203  @param[out]      TotalStringAdded        Return the total strings added to database.
     1204
     1205  @retval  TRUE   x-UEFI-redfish string and ID map is inserted to database.
     1206           FALSE  Something is wrong when insert x-UEFI-redfish string and ID map.
     1207
     1208**/
     1209BOOLEAN
     1210CreateXuefiLanguageStringIdMap (
     1211  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
     1212  IN   EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
     1213  OUT  UINTN                                     *TotalStringAdded
     1214  )
     1215{
     1216  EFI_STATUS               Status;
     1217  UINT8                    *BlockHdr;
     1218  EFI_STRING_ID            CurrentStringId;
     1219  UINTN                    BlockSize;
     1220  UINTN                    Index;
     1221  UINT8                    *StringTextPtr;
     1222  UINTN                    Offset;
     1223  UINT16                   StringCount;
     1224  UINT16                   SkipCount;
     1225  UINT8                    Length8;
     1226  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
     1227  UINT32                   Length32;
     1228  UINT8                    *StringBlockInfo;
     1229  UINTN                    StringsAdded;
     1230
     1231  StringsAdded = 0;
     1232
     1233  //
     1234  // Parse the string blocks to get the string text and font.
     1235  //
     1236  StringBlockInfo = (UINT8 *)((UINTN)HiiStringPackageHeader + HiiStringPackageHeader->StringInfoOffset);
     1237  BlockHdr        = StringBlockInfo;
     1238  BlockSize       = 0;
     1239  Offset          = 0;
     1240  CurrentStringId = 1;
     1241  while (*BlockHdr != EFI_HII_SIBT_END) {
     1242    switch (*BlockHdr) {
     1243      case EFI_HII_SIBT_STRING_SCSU:
     1244        Offset        = sizeof (EFI_HII_STRING_BLOCK);
     1245        StringTextPtr = BlockHdr + Offset;
     1246        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
     1247        CurrentStringId++;
     1248        break;
     1249
     1250      case EFI_HII_SIBT_STRING_SCSU_FONT:
     1251        Offset        = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
     1252        StringTextPtr = BlockHdr + Offset;
     1253        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
     1254        CurrentStringId++;
     1255        break;
     1256
     1257      case EFI_HII_SIBT_STRINGS_SCSU:
     1258        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
     1259        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
     1260        BlockSize    += StringTextPtr - BlockHdr;
     1261
     1262        for (Index = 0; Index < StringCount; Index++) {
     1263          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
     1264          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
     1265          CurrentStringId++;
     1266        }
     1267
     1268        break;
     1269
     1270      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
     1271        CopyMem (
     1272          &StringCount,
     1273          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
     1274          sizeof (UINT16)
     1275          );
     1276        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
     1277        BlockSize    += StringTextPtr - BlockHdr;
     1278
     1279        for (Index = 0; Index < StringCount; Index++) {
     1280          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
     1281          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
     1282          CurrentStringId++;
     1283        }
     1284
     1285        break;
     1286
     1287      case EFI_HII_SIBT_STRING_UCS2:
     1288        Offset        = sizeof (EFI_HII_STRING_BLOCK);
     1289        StringTextPtr = BlockHdr + Offset;
     1290
     1291        // x-UEFI-redfish string is always encoded as UCS and started with '/'.
     1292        if (*StringTextPtr == (UINT16)'/') {
     1293          Status = RedfishXuefiStringInsertDatabase (
     1294                     FormsetPrivate,
     1295                     HiiStringPackageHeader,
     1296                     CurrentStringId,
     1297                     (CHAR16 *)StringTextPtr
     1298                     );
     1299          if (EFI_ERROR (Status)) {
     1300            DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-UEFI-redfish string %s.\n", __func__, StringTextPtr));
     1301            return FALSE;
     1302          }
     1303
     1304          StringsAdded++;
     1305        }
     1306
     1307        BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
     1308        CurrentStringId++;
     1309        break;
     1310
     1311      case EFI_HII_SIBT_STRING_UCS2_FONT:
     1312        Offset        = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
     1313        StringTextPtr = BlockHdr + Offset;
     1314        BlockSize    += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
     1315        CurrentStringId++;
     1316        break;
     1317
     1318      case EFI_HII_SIBT_STRINGS_UCS2:
     1319        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
     1320        StringTextPtr = BlockHdr + Offset;
     1321        BlockSize    += Offset;
     1322        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
     1323        for (Index = 0; Index < StringCount; Index++) {
     1324          BlockSize    += HiiStrSize ((CHAR16 *)StringTextPtr);
     1325          StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
     1326          CurrentStringId++;
     1327        }
     1328
     1329        break;
     1330
     1331      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
     1332        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
     1333        StringTextPtr = BlockHdr + Offset;
     1334        BlockSize    += Offset;
     1335        CopyMem (
     1336          &StringCount,
     1337          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
     1338          sizeof (UINT16)
     1339          );
     1340        for (Index = 0; Index < StringCount; Index++) {
     1341          BlockSize    += HiiStrSize ((CHAR16 *)StringTextPtr);
     1342          StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
     1343          CurrentStringId++;
     1344        }
     1345
     1346        break;
     1347
     1348      case EFI_HII_SIBT_DUPLICATE:
     1349        BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
     1350        CurrentStringId++;
     1351        break;
     1352
     1353      case EFI_HII_SIBT_SKIP1:
     1354        SkipCount       = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
     1355        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
     1356        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
     1357        break;
     1358
     1359      case EFI_HII_SIBT_SKIP2:
     1360        CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
     1361        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
     1362        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
     1363        break;
     1364
     1365      case EFI_HII_SIBT_EXT1:
     1366        CopyMem (
     1367          &Length8,
     1368          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
     1369          sizeof (UINT8)
     1370          );
     1371        BlockSize += Length8;
     1372        break;
     1373
     1374      case EFI_HII_SIBT_EXT2:
     1375        CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
     1376        BlockSize += Ext2.Length;
     1377        break;
     1378
     1379      case EFI_HII_SIBT_EXT4:
     1380        CopyMem (
     1381          &Length32,
     1382          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
     1383          sizeof (UINT32)
     1384          );
     1385
     1386        BlockSize += Length32;
     1387        break;
     1388
     1389      default:
     1390        break;
     1391    }
     1392
     1393    BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
     1394  }
     1395
     1396  *TotalStringAdded = StringsAdded;
     1397  return TRUE;
     1398}
     1399
     1400/**
     1401  Get x-UEFI-redfish string and language by string ID.
     1402
     1403  @param[in]      FormsetPrivate       Pointer to HII form-set private instance.
     1404  @param[in]      StringId             The HII string ID.
     1405  @param[out]     String               Optionally return USC string.
     1406  @param[out]     Language             Optionally return x-UEFI-redfish language.
     1407  @param[out]     XuefiStringDatabase  Optionally return x-UEFI-redfish database.
     1408
     1409  @retval  EFI_SUCCESS            String information is returned.
     1410           EFI_INVALID_PARAMETER  One of the given parameters to this function is
     1411                                  invalid.
     1412           EFI_NOT_FOUND          String is not found.
     1413
     1414**/
     1415EFI_STATUS
     1416GetXuefiStringAndLangByStringId (
     1417  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
     1418  IN   EFI_STRING_ID                             StringId,
     1419  OUT  CHAR16                                    **String OPTIONAL,
     1420  OUT  CHAR8                                     **Language OPTIONAL,
     1421  OUT  REDFISH_X_UEFI_STRING_DATABASE            **XuefiStringDatabase OPTIONAL
     1422  )
     1423{
     1424  REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
     1425  REDFISH_X_UEFI_STRINGS_ARRAY    *StringArray;
     1426  UINT16                          StringIndex;
     1427
     1428  if ((String == NULL) && (Language == NULL) && (XuefiStringDatabase == NULL)) {
     1429    DEBUG ((DEBUG_ERROR, "%a: Invalid parameters for this function.\n", __func__));
     1430    return EFI_INVALID_PARAMETER;
     1431  }
     1432
     1433  if (IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
     1434    return EFI_NOT_FOUND;
     1435  }
     1436
     1437  XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
     1438  while (TRUE) {
     1439    if (Language != NULL) {
     1440      *Language = XuefiRedfishStringDatabase->XuefiRedfishLanguage;
     1441    }
     1442
     1443    StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
     1444
     1445    // Loop to the correct string array.
     1446    StringIndex = StringId;
     1447    while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
     1448      if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray)) {
     1449        goto ErrorExit;
     1450      }
     1451
     1452      StringArray  = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray);
     1453      StringIndex -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
     1454    }
     1455
     1456    //
     1457    // NOTE: The string ID in the formset is a unique number.
     1458    //       If the string in the array is NULL, then the matched string ID
     1459    //       should be in another x-UEFI-redfish database.
     1460    //
     1461    if ((StringArray->ArrayEntryAddress + StringIndex)->UcsString != NULL) {
     1462      //
     1463      // String ID is belong to this x-uef-redfish language database.
     1464      //
     1465      if (String != NULL) {
     1466        *String = (StringArray->ArrayEntryAddress + StringIndex)->UcsString;
     1467      }
     1468
     1469      if (XuefiStringDatabase != NULL) {
     1470        *XuefiStringDatabase = XuefiRedfishStringDatabase;
     1471      }
     1472
     1473      return EFI_SUCCESS;
     1474    }
     1475
     1476    if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
     1477      return EFI_NOT_FOUND;
     1478    }
     1479
     1480    XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (
     1481                                                                     &FormsetPrivate->XuefiRedfishStringDatabase,
     1482                                                                     &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage
     1483                                                                     );
     1484  }
     1485
     1486ErrorExit:;
     1487  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
     1488  return EFI_NOT_FOUND;
     1489}
     1490
     1491/**
     1492  Build a x-UEFI-redfish database for the newly added x-UEFI-redfish language.
     1493
     1494  @param[in]      FormsetPrivate          Pointer to HII form-set private instance.
     1495
     1496**/
     1497VOID
     1498BuildXUefiRedfishStringDatabase (
     1499  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
     1500  )
     1501{
     1502  EFI_STATUS                  Status;
     1503  UINTN                       BufferSize;
     1504  EFI_HII_PACKAGE_HEADER      *PackageHeader;
     1505  UINTN                       EndingPackageAddress;
     1506  EFI_HII_STRING_PACKAGE_HDR  *HiiStringPackageHeader;
     1507  UINTN                       SupportedSchemaLangCount;
     1508  CHAR8                       **SupportedSchemaLang;
     1509  BOOLEAN                     StringIdMapIsBuilt;
     1510  UINTN                       TotalStringsAdded;
     1511  UINTN                       NumberPackageStrings;
     1512
     1513  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Building x-UEFI-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
     1514
     1515  BufferSize = 0;
     1516  Status     = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
     1517                                                             mRedfishPlatformConfigPrivate->HiiDatabase,
     1518                                                             FormsetPrivate->HiiHandle,
     1519                                                             &BufferSize,
     1520                                                             FormsetPrivate->HiiPackageListHeader
     1521                                                             );
     1522  if (Status != EFI_BUFFER_TOO_SMALL) {
     1523    DEBUG ((DEBUG_ERROR, "  Failed to export package list.\n"));
     1524    return;
     1525  }
     1526
     1527  FormsetPrivate->HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)AllocateZeroPool (BufferSize);
     1528  if (FormsetPrivate->HiiPackageListHeader == NULL) {
     1529    DEBUG ((DEBUG_ERROR, "  Failed to allocate memory for the exported package list.\n"));
     1530    return;
     1531  }
     1532
     1533  Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
     1534                                                         mRedfishPlatformConfigPrivate->HiiDatabase,
     1535                                                         FormsetPrivate->HiiHandle,
     1536                                                         &BufferSize,
     1537                                                         FormsetPrivate->HiiPackageListHeader
     1538                                                         );
     1539  if (EFI_ERROR (Status)) {
     1540    FreePool (FormsetPrivate->HiiPackageListHeader);
     1541    FormsetPrivate->HiiPackageListHeader = NULL;
     1542    return;
     1543  }
     1544
     1545  TotalStringsAdded = 0;
     1546  //
     1547  // Finding the string package.
     1548  //
     1549  EndingPackageAddress = (UINTN)FormsetPrivate->HiiPackageListHeader + FormsetPrivate->HiiPackageListHeader->PackageLength;
     1550  PackageHeader        = (EFI_HII_PACKAGE_HEADER *)(FormsetPrivate->HiiPackageListHeader + 1);
     1551  SupportedSchemaLang  = FormsetPrivate->SupportedSchema.SchemaList;
     1552  while ((UINTN)PackageHeader < EndingPackageAddress) {
     1553    switch (PackageHeader->Type) {
     1554      case EFI_HII_PACKAGE_STRINGS:
     1555        StringIdMapIsBuilt     = FALSE;
     1556        HiiStringPackageHeader = (EFI_HII_STRING_PACKAGE_HDR *)PackageHeader;
     1557
     1558        // Check if this is the string package for x-UEFI-redfish
     1559        for (SupportedSchemaLangCount = 0;
     1560             SupportedSchemaLangCount < FormsetPrivate->SupportedSchema.Count;
     1561             SupportedSchemaLangCount++
     1562             )
     1563        {
     1564          if (AsciiStrnCmp (
     1565                *(SupportedSchemaLang + SupportedSchemaLangCount),
     1566                HiiStringPackageHeader->Language,
     1567                AsciiStrLen (HiiStringPackageHeader->Language)
     1568                ) == 0)
     1569          {
     1570            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader, &NumberPackageStrings);
     1571            if (StringIdMapIsBuilt) {
     1572              TotalStringsAdded += NumberPackageStrings;
     1573            }
     1574
     1575            break;
     1576          }
     1577        }
     1578
     1579        if (StringIdMapIsBuilt == FALSE) {
     1580          if (AsciiStrStr (HiiStringPackageHeader->Language, X_UEFI_SCHEMA_PREFIX) == NULL) {
     1581            DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  No need to build x-UEFI-redfish string ID map for HII language %a\n", HiiStringPackageHeader->Language));
     1582          } else {
     1583            DEBUG ((DEBUG_ERROR, "  Failed to build x-UEFI-redfish string ID map of HII language %a\n", HiiStringPackageHeader->Language));
     1584          }
     1585        }
     1586
     1587      default:
     1588        PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader + PackageHeader->Length);
     1589    }
     1590  }
     1591
     1592  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Total %d x-UEFI-redfish config language are added.\n", TotalStringsAdded));
    8501593}
    8511594
     
    8561599  @param[out] FormsetPrivate  The formset private data.
    8571600
    858   @retval EFI_STATUS
     1601  @retval EFI_STATUS          The formset is loaded successfully.
     1602  @retval EFI_UNSUPPORTED     This formset doesn't have any x-UEFI-redfish configuration.
    8591603
    8601604**/
     
    8751619  EFI_GUID                                   ZeroGuid;
    8761620  EXPRESS_RESULT                             ExpressionResult;
     1621  CHAR16                                     *String;
    8771622
    8781623  if ((HiiHandle == NULL) || (FormsetPrivate == NULL)) {
     
    8821627  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
    8831628  if (HiiFormSet == NULL) {
     1629    DEBUG ((DEBUG_ERROR, "%a: No memory resource for HII_FORMSET - %g\n", __func__, FormsetPrivate->Guid));
    8841630    return EFI_OUT_OF_RESOURCES;
    8851631  }
     
    8911637  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
    8921638  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
     1639    DEBUG ((DEBUG_ERROR, "%a: Formset not found by HII handle - %g\n", __func__, FormsetPrivate->Guid));
    8931640    Status = EFI_NOT_FOUND;
    8941641    goto ErrorExit;
     
    9091656  Status                        = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
    9101657  if (EFI_ERROR (Status)) {
    911     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: No schema from HII handle: 0x%x found: %r\n", __func__, FormsetPrivate->HiiHandle, Status));
     1658    if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
     1659      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: No x-UEFI-redfish configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
     1660      //
     1661      // If there is no x-UEFI-redfish language in this form-set, we don't add formset
     1662      // since we don't need to build menu path for attribute registry.
     1663      //
     1664      return EFI_UNSUPPORTED;
     1665    }
     1666  } else {
     1667    // Building x-UEFI-redfish string database
     1668    BuildXUefiRedfishStringDatabase (FormsetPrivate);
    9121669  }
    9131670
     
    9191676    if (HiiFormPrivate == NULL) {
    9201677      Status = EFI_OUT_OF_RESOURCES;
     1678      DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_FORM_PRIVATE.\n", __func__));
    9211679      goto ErrorExit;
    9221680    }
     
    9441702      HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
    9451703      if (HiiStatementPrivate == NULL) {
     1704        DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE.\n", __func__));
    9461705        Status = EFI_OUT_OF_RESOURCES;
    9471706        goto ErrorExit;
     
    9811740      }
    9821741
    983       //
    984       // Attach to statement list.
    985       //
    986       InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
     1742      // Get x-UEFI-redfish string using String ID.
     1743      Status = GetXuefiStringAndLangByStringId (FormsetPrivate, HiiStatementPrivate->Description, &String, NULL, NULL);
     1744      if (!EFI_ERROR (Status)) {
     1745        HiiStatementPrivate->XuefiRedfishStr = String;
     1746        //
     1747        // Attach to statement list.
     1748        //
     1749        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
     1750      } else {
     1751        if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
     1752          //
     1753          // If there is no x-UEFI-redfish language for this statement, we don't add this statement
     1754          // since we don't need to build menu path for attribute registry.
     1755          //
     1756          FreePool (HiiStatementPrivate);
     1757        } else {
     1758          //
     1759          // This is not x-UEFI-redfish string and we don't cache its string for searching Redfish configure language.
     1760          // When caller wants the string, we will read English string by calling HiiGetString().
     1761          //
     1762          HiiStatementPrivate->XuefiRedfishStr = NULL;
     1763          //
     1764          // Attach to statement list.
     1765          //
     1766          InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
     1767        }
     1768      }
     1769
    9871770      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
    9881771    }
     
    10521835  Status = LoadFormset (HiiHandle, FormsetPrivate);
    10531836  if (EFI_ERROR (Status)) {
    1054     DEBUG ((DEBUG_ERROR, "%a: failed to load formset: %r\n", __func__, Status));
     1837    DEBUG ((DEBUG_ERROR, "%a: Formset is not loaded for edk2 redfish: %r\n", __func__, Status));
    10551838    FreePool (FormsetPrivate);
    10561839    return Status;
     
    10631846
    10641847  DEBUG_CODE (
     1848    if (RedfishPlatformConfigDebugProp (REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET)) {
    10651849    DumpFormsetList (FormsetList);
     1850  }
     1851
    10661852    );
    10671853
     
    11831969    TargetPendingList->IsDeleted = FALSE;
    11841970    DEBUG_CODE (
    1185       DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
     1971      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
    11861972      );
    11871973    return EFI_SUCCESS;
     
    11991985
    12001986  DEBUG_CODE (
    1201     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
     1987    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
    12021988    );
    12031989
     
    12362022    TargetPendingList->IsDeleted = TRUE;
    12372023    DEBUG_CODE (
    1238       DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
     2024      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
    12392025      );
    12402026    return EFI_SUCCESS;
     
    12522038
    12532039  DEBUG_CODE (
    1254     DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
     2040    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
    12552041    );
    12562042
     
    13012087      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
    13022088      if (FormsetPrivate != NULL) {
    1303         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, FormsetPrivate->Guid));
     2089        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, FormsetPrivate->Guid));
    13042090        RemoveEntryList (&FormsetPrivate->Link);
    13052091        ReleaseFormset (FormsetPrivate);
    13062092        FreePool (FormsetPrivate);
    13072093      } else {
    1308         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
     2094        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
    13092095      }
    13102096    } else {
     
    13172103        // HII formset already exist, release it and query again.
    13182104        //
    1319         DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
     2105        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
    13202106        RemoveEntryList (&FormsetPrivate->Link);
    13212107        ReleaseFormset (FormsetPrivate);
     
    13252111      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
    13262112      if (EFI_ERROR (Status)) {
    1327         DEBUG ((DEBUG_ERROR, "%a: load formset from HII handle: 0x%x failed: %r\n", __func__, Target->HiiHandle, Status));
     2113        if (Status == EFI_UNSUPPORTED) {
     2114          DEBUG ((DEBUG_ERROR, "  The formset has no x-UEFI-redfish configurations.\n"));
     2115        } else {
     2116          DEBUG ((DEBUG_ERROR, "  load formset from HII handle: 0x%x failed: %r\n", Target->HiiHandle, Status));
     2117        }
    13282118      }
    13292119    }
  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h

    r101291 r105670  
    33
    44  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
    5   Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     5  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
     6  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
    67
    78  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    2930#define IS_EMPTY_STRING(a)  (a == NULL || a[0] == L'\0')
    3031#define ENGLISH_LANGUAGE_CODE  "en-US"
    31 #define X_UEFI_SCHEMA_PREFIX   "x-uefi-redfish-"
     32#define X_UEFI_SCHEMA_PREFIX   "x-UEFI-redfish-"
     33
     34#define MAX_X_UEFI_REDFISH_STRING_SIZE  (128 * 2)// 128 character in UCS.
     35
     36typedef struct _REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
    3237
    3338//
     
    4752} REDFISH_PLATFORM_CONFIG_SCHEMA;
    4853
     54// Defines the number of elements in array
     55#define X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER  1024
     56
     57//
     58// Definition of x-UEFI-redfish string element.
     59//
     60typedef struct {
     61  EFI_STRING_ID    StringId;
     62  CHAR16           *UcsString;
     63} REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT;
     64
     65//
     66// Discrete string array buffer, each has X_UEFI_REDFISH_STRING_ARRAY_NUMBER element.
     67//
     68typedef struct {
     69  LIST_ENTRY                              NextArray;
     70  REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT    *ArrayEntryAddress;
     71} REDFISH_X_UEFI_STRINGS_ARRAY;
     72
     73//
     74// x-UEFI-redfish string database, x-UEFI-redfish language based.
     75//
     76typedef struct {
     77  LIST_ENTRY    NextXuefiRedfishLanguage;                                     // Link to the next suppoted x-UEFI-Redfish language.
     78  CHAR8         *XuefiRedfishLanguage;                                        // x-UEFI-redfish language.
     79  UINTN         StringsArrayBlocks;                                           // Number of the array blocks that accommodate X_UEFI_REDFISH_STRING_ARRAY_NUMBER
     80                                                                              // elements in each.
     81  LIST_ENTRY    XuefiRedfishStringArrays;                                     // Link entry of x-UEFI-redfish string array.
     82} REDFISH_X_UEFI_STRING_DATABASE;
     83
    4984//
    5085// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
     
    5287typedef struct {
    5388  LIST_ENTRY                        Link;
    54   HII_FORMSET                       *HiiFormSet;     // Pointer to HII formset data.
    55   EFI_GUID                          Guid;            // Formset GUID.
    56   EFI_HII_HANDLE                    HiiHandle;       // Hii Handle of this formset.
    57   LIST_ENTRY                        HiiFormList;     // Form list that keep form data under this formset.
    58   CHAR16                            *DevicePathStr;  // Device path of this formset.
    59   REDFISH_PLATFORM_CONFIG_SCHEMA    SupportedSchema; // Schema that is supported in this formset.
     89  HII_FORMSET                       *HiiFormSet;                // Pointer to HII formset data.
     90  EFI_GUID                          Guid;                       // Formset GUID.
     91  EFI_HII_HANDLE                    HiiHandle;                  // Hii Handle of this formset.
     92  EFI_HII_PACKAGE_LIST_HEADER       *HiiPackageListHeader;      // Hii Package list header.
     93  LIST_ENTRY                        HiiFormList;                // Form list that keep form data under this formset.
     94  CHAR16                            *DevicePathStr;             // Device path of this formset.
     95  REDFISH_PLATFORM_CONFIG_SCHEMA    SupportedSchema;            // Schema that is supported in this formset.
     96  LIST_ENTRY                        XuefiRedfishStringDatabase; // x-UEFI-redfish string/Id data base;
    6097} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
    6198
     
    91128// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
    92129//
    93 typedef struct {
     130struct _REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE {
    94131  LIST_ENTRY                                Link;
    95132  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *ParentForm;
    96   HII_STATEMENT                             *HiiStatement;  // Pointer to HII statement data.
    97   EFI_QUESTION_ID                           QuestionId;     // Question ID of this statement.
    98   EFI_STRING_ID                             Description;    // String token of this question.
    99   EFI_STRING_ID                             Help;           // String token of help message.
    100   EFI_STRING                                DesStringCache; // The string cache for search function.
    101   UINT8                                     Flags;          // The statement flag.
    102   REDFISH_PLATFORM_CONFIG_STATEMENT_DATA    StatementData;  // The max/min for statement value.
    103   BOOLEAN                                   Suppressed;     // Statement is suppressed.
    104   BOOLEAN                                   GrayedOut;      // Statement is GrayedOut.
    105 } REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
     133  HII_STATEMENT                             *HiiStatement;     // Pointer to HII statement data.
     134  EFI_QUESTION_ID                           QuestionId;        // Question ID of this statement.
     135  EFI_STRING_ID                             Description;       // String token of this question.
     136  CHAR16                                    *XuefiRedfishStr;  // x-UEFI-redfish string of this question.
     137  EFI_STRING_ID                             Help;              // String token of help message.
     138  UINT8                                     Flags;             // The statement flag.
     139  REDFISH_PLATFORM_CONFIG_STATEMENT_DATA    StatementData;     // The max/min for statement value.
     140  BOOLEAN                                   Suppressed;        // Statement is suppressed.
     141  BOOLEAN                                   GrayedOut;         // Statement is GrayedOut.
     142};
    106143
    107144#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
     
    348385  );
    349386
     387/**
     388  Return the HII string length. We don't check word alignment
     389  of the input string as the same as the checking in StrLen
     390  function. Because the HII string in the database is compact
     391  at the byte alignment.
     392
     393  @param[in]  String  Input UCS format string.
     394
     395  @retval Length of
     396
     397**/
     398UINTN
     399EFIAPI
     400HiiStrLen (
     401  IN  CONST CHAR16  *String
     402  );
     403
     404/**
     405  Return the HII string size. We don't check word alignment
     406  of the input string as the same as the checking in StrLen
     407  function. Because the HII string in the database is compact
     408  at the byte alignment.
     409
     410  @param[in]  String  Input UCS format string.
     411
     412  @retval Size of the string.
     413
     414**/
     415UINTN
     416EFIAPI
     417HiiStrSize (
     418  IN      CONST CHAR16  *String
     419  );
     420
     421/**
     422  Check if the debug property is enabled or not.
     423
     424  @param[in]  DebugType  Debug enablement type
     425
     426  @retval TRUE, the debug property is enabled.
     427          FALSE, the debug property is not enabled.
     428
     429**/
     430BOOLEAN
     431RedfishPlatformConfigDebugProp (
     432  IN UINT64  DebugProp
     433  );
     434
     435/**
     436  Check if the Platform Configure feature is enabled or not.
     437
     438  @param[in]  FeatureType  Redfish platform config feature enablement
     439
     440  @retval TRUE, the feature is enabled.
     441          FALSE, the feature is not enabled.
     442
     443**/
     444BOOLEAN
     445RedfishPlatformConfigFeatureProp (
     446  IN UINT64  FeatureProp
     447  );
     448
    350449#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette