mirror of https://github.com/acidanthera/audk.git
2169 lines
75 KiB
C
2169 lines
75 KiB
C
/** @file
|
|
The implementation of EDKII Redfish Platform Config Protocol.
|
|
|
|
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
|
|
Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
#include "RedfishPlatformConfigDxe.h"
|
|
#include "RedfishPlatformConfigImpl.h"
|
|
|
|
extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate;
|
|
|
|
/**
|
|
Debug dump HII string.
|
|
|
|
@param[in] HiiHandle HII handle instance
|
|
@param[in] StringId HII string to dump
|
|
|
|
@retval EFI_SUCCESS Dump HII string successfully
|
|
@retval Others Errors occur
|
|
|
|
**/
|
|
EFI_STATUS
|
|
DumpHiiString (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
EFI_STRING String;
|
|
|
|
if ((HiiHandle == NULL) || (StringId == 0)) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "???"));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
String = HiiGetString (HiiHandle, StringId, NULL);
|
|
if (String == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%s", String));
|
|
FreePool (String);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Debug dump HII form-set data.
|
|
|
|
@param[in] FormsetPrivate HII form-set private instance.
|
|
|
|
@retval EFI_SUCCESS Dump form-set successfully
|
|
@retval Others Errors occur
|
|
|
|
**/
|
|
EFI_STATUS
|
|
DumpFormset (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormLink;
|
|
LIST_ENTRY *HiiNextFormLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
|
|
LIST_ENTRY *HiiStatementLink;
|
|
LIST_ENTRY *HiiNextStatementLink;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
|
|
UINTN Index;
|
|
|
|
if (FormsetPrivate == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Index = 0;
|
|
HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
|
|
while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
|
|
HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
|
|
HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
|
|
DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
|
|
|
|
HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
|
|
while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
|
|
HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
|
|
HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
|
|
DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
|
|
|
|
HiiStatementLink = HiiNextStatementLink;
|
|
}
|
|
|
|
HiiFormLink = HiiNextFormLink;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Debug dump HII form-set list.
|
|
|
|
@param[in] FormsetList Form-set list instance
|
|
|
|
@retval EFI_SUCCESS Dump list successfully
|
|
@retval Others Errors occur
|
|
|
|
**/
|
|
EFI_STATUS
|
|
DumpFormsetList (
|
|
IN LIST_ENTRY *FormsetList
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormsetLink;
|
|
LIST_ENTRY *HiiFormsetNextLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
|
|
UINTN Index;
|
|
|
|
if (FormsetList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsListEmpty (FormsetList)) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Empty formset list\n", __func__));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Index = 0;
|
|
HiiFormsetLink = GetFirstNode (FormsetList);
|
|
while (!IsNull (FormsetList, HiiFormsetLink)) {
|
|
HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
|
|
HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
|
|
DumpFormset (HiiFormsetPrivate);
|
|
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Return the HII string length. We don't check word alignment
|
|
of the input string as same as the checking in StrLen
|
|
function, because the HII string in the database is compact
|
|
at the byte alignment.
|
|
|
|
@param[in] String Input UCS format string.
|
|
|
|
@retval Length of the string.
|
|
|
|
**/
|
|
UINTN
|
|
EFIAPI
|
|
HiiStrLen (
|
|
IN CONST CHAR16 *String
|
|
)
|
|
{
|
|
UINTN Length;
|
|
|
|
ASSERT (String != NULL);
|
|
|
|
for (Length = 0; *String != L'\0'; String++, Length++) {
|
|
}
|
|
|
|
return Length;
|
|
}
|
|
|
|
/**
|
|
Return the HII string size. We don't check word alignment
|
|
of the input string as same as the checking in StrLen
|
|
function, because the HII string in the database is compact
|
|
at the byte alignment.
|
|
|
|
@param[in] String Input UCS format string.
|
|
|
|
@retval Size of the string.
|
|
|
|
**/
|
|
UINTN
|
|
EFIAPI
|
|
HiiStrSize (
|
|
IN CONST CHAR16 *String
|
|
)
|
|
{
|
|
return (HiiStrLen (String) + 1) * sizeof (*String);
|
|
}
|
|
|
|
/**
|
|
Compare two HII strings. We don't check word alignment
|
|
of the input string as same as the checking in StrLen
|
|
function, because the HII string in the database is compact
|
|
at the byte alignment.
|
|
|
|
@param[in] FirstString Input UCS format of string to search.
|
|
@param[in] SecondString Input UCS format of string to look for in
|
|
FirstString;
|
|
|
|
@retval 0 The strings are identical.
|
|
!0 The strings are not identical.
|
|
|
|
**/
|
|
INTN
|
|
EFIAPI
|
|
HiiStrCmp (
|
|
IN CONST CHAR16 *FirstString,
|
|
IN CONST CHAR16 *SecondString
|
|
)
|
|
{
|
|
//
|
|
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength
|
|
//
|
|
ASSERT (HiiStrSize (FirstString) != 0);
|
|
ASSERT (HiiStrSize (SecondString) != 0);
|
|
|
|
while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
|
|
FirstString++;
|
|
SecondString++;
|
|
}
|
|
|
|
return *FirstString - *SecondString;
|
|
}
|
|
|
|
/**
|
|
Delete a string from HII Package List by given HiiHandle.
|
|
|
|
@param[in] StringId Id of the string in HII database.
|
|
@param[in] HiiHandle The HII package list handle.
|
|
|
|
@retval EFI_SUCCESS The string was deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER StringId is zero.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
HiiDeleteString (
|
|
IN EFI_STRING_ID StringId,
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
CHAR16 NullChar;
|
|
|
|
if (StringId == 0x00) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
NullChar = CHAR_NULL;
|
|
HiiSetString (HiiHandle, StringId, &NullChar, NULL);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Retrieves a unicode string from a string package in a given language. The
|
|
returned string is allocated using AllocatePool(). The caller is responsible
|
|
for freeing the allocated buffer using FreePool().
|
|
|
|
If HiiHandle is NULL, then ASSERT().
|
|
If StringId is 0, then ASSET.
|
|
|
|
@param[in] HiiHandle A handle that was previously registered in the HII Database.
|
|
@param[in] Language The specified configure language to get string.
|
|
@param[in] StringId The identifier of the string to retrieved from the string
|
|
package associated with HiiHandle.
|
|
|
|
@retval NULL The string specified by StringId is not present in the string package.
|
|
@retval Other The string was returned.
|
|
|
|
**/
|
|
EFI_STRING
|
|
HiiGetRedfishString (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHAR8 *Language,
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN StringSize;
|
|
CHAR16 TempString;
|
|
EFI_STRING String;
|
|
|
|
if ((mRedfishPlatformConfigPrivate->HiiString == NULL) || (HiiHandle == NULL) || (StringId == 0) || IS_EMPTY_STRING (Language)) {
|
|
ASSERT (FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Retrieve the size of the string in the string package for the BestLanguage
|
|
//
|
|
StringSize = 0;
|
|
Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
|
|
mRedfishPlatformConfigPrivate->HiiString,
|
|
Language,
|
|
HiiHandle,
|
|
StringId,
|
|
&TempString,
|
|
&StringSize,
|
|
NULL
|
|
);
|
|
//
|
|
// If GetString() returns EFI_SUCCESS for a zero size,
|
|
// then there are no supported languages registered for HiiHandle. If GetString()
|
|
// returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
|
|
// in the HII Database
|
|
//
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate a buffer for the return string
|
|
//
|
|
String = AllocateZeroPool (StringSize);
|
|
if (String == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Retrieve the string from the string package
|
|
//
|
|
Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
|
|
mRedfishPlatformConfigPrivate->HiiString,
|
|
Language,
|
|
HiiHandle,
|
|
StringId,
|
|
String,
|
|
&StringSize,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Free the buffer and return NULL if the supported languages can not be retrieved.
|
|
//
|
|
FreePool (String);
|
|
String = NULL;
|
|
}
|
|
|
|
//
|
|
// Return the Null-terminated Unicode string
|
|
//
|
|
return String;
|
|
}
|
|
|
|
/**
|
|
Retrieves a ASCII string from a string package in a given language. The
|
|
returned string is allocated using AllocatePool(). The caller is responsible
|
|
for freeing the allocated buffer using FreePool().
|
|
|
|
If HiiHandle is NULL, then ASSERT().
|
|
If StringId is 0, then ASSET.
|
|
|
|
@param[in] HiiHandle A handle that was previously registered in the HII Database.
|
|
@param[in] Language The specified configure language to get string.
|
|
@param[in] StringId The identifier of the string to retrieved from the string
|
|
package associated with HiiHandle.
|
|
|
|
@retval NULL The string specified by StringId is not present in the string package.
|
|
@retval Other The string was returned.
|
|
|
|
**/
|
|
CHAR8 *
|
|
HiiGetRedfishAsciiString (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN CHAR8 *Language,
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
EFI_STRING HiiString;
|
|
CHAR8 *AsciiString;
|
|
|
|
HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
|
|
if (HiiString == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Can not find string ID: 0x%x with %a\n", __func__, StringId, Language));
|
|
return NULL;
|
|
}
|
|
|
|
AsciiString = StrToAsciiStr (HiiString);
|
|
FreePool (HiiString);
|
|
|
|
return AsciiString;
|
|
}
|
|
|
|
/**
|
|
Get ASCII string from HII database in English language. The returned string is allocated
|
|
using AllocatePool(). The caller is responsible for freeing the allocated buffer using
|
|
FreePool().
|
|
|
|
@param[in] HiiHandle A handle that was previously registered in the HII Database.
|
|
@param[in] StringId The identifier of the string to retrieved from the string
|
|
package associated with HiiHandle.
|
|
|
|
@retval NULL The string specified by StringId is not present in the string package.
|
|
@retval Other The string was returned.
|
|
|
|
**/
|
|
CHAR8 *
|
|
HiiGetEnglishAsciiString (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
EFI_STRING HiiString;
|
|
CHAR8 *AsciiString;
|
|
|
|
HiiString = HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId);
|
|
if (HiiString == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Can not find string ID: 0x%x with %a\n", __func__, StringId, ENGLISH_LANGUAGE_CODE));
|
|
return NULL;
|
|
}
|
|
|
|
AsciiString = StrToAsciiStr (HiiString);
|
|
FreePool (HiiString);
|
|
|
|
return AsciiString;
|
|
}
|
|
|
|
/**
|
|
Check and see if this is supported schema or not.
|
|
|
|
@param[in] SupportedSchema The list of supported schema.
|
|
@param[in] Schema Schema string to be checked.
|
|
|
|
@retval BOOLEAN TRUE if this is supported schema. FALSE otherwise.
|
|
|
|
**/
|
|
BOOLEAN
|
|
CheckSupportedSchema (
|
|
IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
|
|
IN CHAR8 *Schema
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
if ((SupportedSchema == NULL) || IS_EMPTY_STRING (Schema)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (SupportedSchema->Count == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
for (Index = 0; Index < SupportedSchema->Count; Index++) {
|
|
if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Get the list of supported schema from the given HII handle.
|
|
|
|
@param[in] HiiHandle HII handle instance.
|
|
@param[out] SupportedSchema Supported schema on this HII handle.
|
|
|
|
@retval EFI_SUCCESS Schema list is returned.
|
|
@retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NULL.
|
|
@retval EFI_NOT_FOUND No supported schema found.
|
|
@retval EFI_OUT_OF_RESOURCES System is out of memory.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GetSupportedSchema (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
|
|
)
|
|
{
|
|
CHAR8 *SupportedLanguages;
|
|
UINTN Index;
|
|
UINTN LangIndex;
|
|
UINTN Count;
|
|
UINTN StrSize;
|
|
UINTN ListIndex;
|
|
|
|
if ((HiiHandle == NULL) || (SupportedSchema == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
SupportedSchema->Count = 0;
|
|
|
|
SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
|
|
if (SupportedLanguages == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Index = 0;
|
|
LangIndex = 0;
|
|
Count = 0;
|
|
while (TRUE) {
|
|
if ((SupportedLanguages[Index] == ';') || (SupportedLanguages[Index] == '\0')) {
|
|
if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
|
|
++Count;
|
|
}
|
|
|
|
LangIndex = Index + 1;
|
|
}
|
|
|
|
if (SupportedLanguages[Index] == '\0') {
|
|
break;
|
|
}
|
|
|
|
++Index;
|
|
}
|
|
|
|
if (Count == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
SupportedSchema->Count = Count;
|
|
SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
|
|
if (SupportedSchema->SchemaList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Index = 0;
|
|
LangIndex = 0;
|
|
ListIndex = 0;
|
|
while (TRUE) {
|
|
if ((SupportedLanguages[Index] == ';') || (SupportedLanguages[Index] == '\0')) {
|
|
if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
|
|
StrSize = Index - LangIndex;
|
|
SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
|
|
SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
|
|
++ListIndex;
|
|
}
|
|
|
|
LangIndex = Index + 1;
|
|
}
|
|
|
|
if (SupportedLanguages[Index] == '\0') {
|
|
break;
|
|
}
|
|
|
|
++Index;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Search and find statement private instance by given regular expression pattern
|
|
which describes the Configure Language.
|
|
|
|
@param[in] RegularExpressionProtocol Regular express protocol.
|
|
@param[in] FormsetList Form-set list to search.
|
|
@param[in] Schema Schema to be matched.
|
|
@param[in] Pattern Regular expression pattern.
|
|
@param[out] StatementList Statement list that match above pattern.
|
|
|
|
@retval EFI_SUCCESS Statement list is returned.
|
|
@retval EFI_INVALID_PARAMETER Input parameter is NULL.
|
|
@retval EFI_NOT_READY Regular express protocol is NULL.
|
|
@retval EFI_NOT_FOUND No statement is found.
|
|
@retval EFI_OUT_OF_RESOURCES System is out of memory.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GetStatementPrivateByConfigureLangRegex (
|
|
IN EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol,
|
|
IN LIST_ENTRY *FormsetList,
|
|
IN CHAR8 *Schema,
|
|
IN EFI_STRING Pattern,
|
|
OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormsetLink;
|
|
LIST_ENTRY *HiiFormsetNextLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
|
|
LIST_ENTRY *HiiFormLink;
|
|
LIST_ENTRY *HiiNextFormLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
|
|
LIST_ENTRY *HiiStatementLink;
|
|
LIST_ENTRY *HiiNextStatementLink;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
|
|
EFI_STRING TmpString;
|
|
UINTN CaptureCount;
|
|
BOOLEAN IsMatch;
|
|
EFI_STATUS Status;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
|
|
|
|
if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || (StatementList == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (RegularExpressionProtocol == NULL) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
StatementList->Count = 0;
|
|
InitializeListHead (&StatementList->StatementList);
|
|
|
|
if (IsListEmpty (FormsetList)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
HiiFormsetLink = GetFirstNode (FormsetList);
|
|
while (!IsNull (FormsetList, HiiFormsetLink)) {
|
|
HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
|
|
HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
|
|
|
|
//
|
|
// Performance check.
|
|
// If there is no desired Redfish schema found, skip this formset.
|
|
//
|
|
if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
continue;
|
|
}
|
|
|
|
HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
|
|
while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
|
|
HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
|
|
HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
|
|
|
|
HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
|
|
while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
|
|
HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
|
|
HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
|
|
|
|
if ((HiiStatementPrivate->Description != 0) &&
|
|
(RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
|
|
{
|
|
TmpString = HiiStatementPrivate->XuefiRedfishStr;
|
|
if (TmpString != NULL) {
|
|
Status = RegularExpressionProtocol->MatchString (
|
|
RegularExpressionProtocol,
|
|
TmpString,
|
|
Pattern,
|
|
&gEfiRegexSyntaxTypePerlGuid,
|
|
&IsMatch,
|
|
NULL,
|
|
&CaptureCount
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: MatchString \"%s\" failed: %r\n", __func__, Pattern, Status));
|
|
ASSERT (FALSE);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Found
|
|
//
|
|
if (IsMatch) {
|
|
StatementRef = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
|
|
if (StatementRef == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
StatementRef->Statement = HiiStatementPrivate;
|
|
InsertTailList (&StatementList->StatementList, &StatementRef->Link);
|
|
++StatementList->Count;
|
|
}
|
|
} else {
|
|
if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
|
|
ASSERT (FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
HiiStatementLink = HiiNextStatementLink;
|
|
}
|
|
|
|
HiiFormLink = HiiNextFormLink;
|
|
}
|
|
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get statement private instance by the given configure language.
|
|
|
|
@param[in] FormsetList Form-set list to search.
|
|
@param[in] Schema Schema to be matched.
|
|
@param[in] ConfigureLang Configure language.
|
|
|
|
@retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to statement private instance.
|
|
|
|
**/
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
|
|
GetStatementPrivateByConfigureLang (
|
|
IN LIST_ENTRY *FormsetList,
|
|
IN CHAR8 *Schema,
|
|
IN EFI_STRING ConfigureLang
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormsetLink;
|
|
LIST_ENTRY *HiiFormsetNextLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
|
|
LIST_ENTRY *HiiFormLink;
|
|
LIST_ENTRY *HiiNextFormLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
|
|
LIST_ENTRY *HiiStatementLink;
|
|
LIST_ENTRY *HiiNextStatementLink;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
|
|
EFI_STRING TmpString;
|
|
UINTN Index;
|
|
|
|
if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (IsListEmpty (FormsetList)) {
|
|
return NULL;
|
|
}
|
|
|
|
Index = 0;
|
|
HiiFormsetLink = GetFirstNode (FormsetList);
|
|
while (!IsNull (FormsetList, HiiFormsetLink)) {
|
|
HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
|
|
HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
|
|
|
|
//
|
|
// Performance check.
|
|
// If there is no desired Redfish schema found, skip this formset.
|
|
//
|
|
if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
continue;
|
|
}
|
|
|
|
HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
|
|
while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
|
|
HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
|
|
HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
|
|
|
|
HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
|
|
while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
|
|
HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
|
|
HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
|
|
|
|
if ((HiiStatementPrivate->Description != 0) &&
|
|
(RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
|
|
{
|
|
TmpString = HiiStatementPrivate->XuefiRedfishStr;
|
|
if (TmpString != NULL) {
|
|
Index++;
|
|
DEBUG_REDFISH_THIS_MODULE (
|
|
REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH,
|
|
"%a: [%d] check %s in QID: 0x%x form: 0x%x formset: %g\n",
|
|
__func__,
|
|
Index,
|
|
ConfigureLang,
|
|
HiiStatementPrivate->QuestionId,
|
|
HiiFormPrivate->Id,
|
|
&HiiFormsetPrivate->Guid
|
|
);
|
|
if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
|
|
return HiiStatementPrivate;
|
|
}
|
|
} else {
|
|
if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-UEFI-string has something wrong.\n", __func__));
|
|
ASSERT (FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
HiiStatementLink = HiiNextStatementLink;
|
|
}
|
|
|
|
HiiFormLink = HiiNextFormLink;
|
|
}
|
|
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
Get form-set private instance by the given HII handle.
|
|
|
|
@param[in] HiiHandle HII handle instance.
|
|
@param[in] FormsetList Form-set list to search.
|
|
|
|
@retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to form-set private instance.
|
|
|
|
**/
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
|
|
GetFormsetPrivateByHiiHandle (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN LIST_ENTRY *FormsetList
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormsetLink;
|
|
LIST_ENTRY *HiiFormsetNextLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
|
|
|
|
if ((HiiHandle == NULL) || (FormsetList == NULL)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (IsListEmpty (FormsetList)) {
|
|
return NULL;
|
|
}
|
|
|
|
HiiFormsetLink = GetFirstNode (FormsetList);
|
|
while (!IsNull (FormsetList, HiiFormsetLink)) {
|
|
HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
|
|
HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
|
|
|
|
if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
|
|
return HiiFormsetPrivate;
|
|
}
|
|
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
Release x-UEFI-string related information.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
|
|
@retval EFI_STATUS
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ReleaseXuefiStringDatabase (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
|
|
)
|
|
{
|
|
REDFISH_X_UEFI_STRING_DATABASE *ThisDatabase;
|
|
REDFISH_X_UEFI_STRING_DATABASE *PreDatabase;
|
|
REDFISH_X_UEFI_STRINGS_ARRAY *ThisStringArray;
|
|
REDFISH_X_UEFI_STRINGS_ARRAY *PreStringArray;
|
|
BOOLEAN EndDatabase;
|
|
BOOLEAN EndArray;
|
|
|
|
if (FormsetPrivate->HiiPackageListHeader != NULL) {
|
|
FreePool (FormsetPrivate->HiiPackageListHeader);
|
|
}
|
|
|
|
// Walk through x-UEFI-redfish string database.
|
|
if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
|
|
EndDatabase = FALSE;
|
|
ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
|
|
while (!EndDatabase) {
|
|
// Walk through string arrays.
|
|
if (!IsListEmpty (&ThisDatabase->XuefiRedfishStringArrays)) {
|
|
EndArray = FALSE;
|
|
ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&ThisDatabase->XuefiRedfishStringArrays);
|
|
while (!EndArray) {
|
|
// Remove this array
|
|
FreePool (ThisStringArray->ArrayEntryAddress);
|
|
EndArray = IsNodeAtEnd (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
|
|
PreStringArray = ThisStringArray;
|
|
if (!EndArray) {
|
|
ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
|
|
}
|
|
|
|
RemoveEntryList (&PreStringArray->NextArray);
|
|
FreePool (PreStringArray);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remove this database
|
|
//
|
|
EndDatabase = IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
|
|
PreDatabase = ThisDatabase;
|
|
if (!EndDatabase) {
|
|
ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
|
|
}
|
|
|
|
RemoveEntryList (&PreDatabase->NextXuefiRedfishLanguage);
|
|
FreePool (PreDatabase);
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Release formset and all the forms and statements that belong to this formset.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
|
|
@retval EFI_STATUS
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ReleaseFormset (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormLink;
|
|
LIST_ENTRY *HiiNextFormLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
|
|
LIST_ENTRY *HiiStatementLink;
|
|
LIST_ENTRY *HiiNextStatementLink;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
|
|
UINTN Index;
|
|
|
|
if (FormsetPrivate == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
|
|
while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
|
|
HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
|
|
HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
|
|
|
|
HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
|
|
while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
|
|
HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
|
|
HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
|
|
|
|
//
|
|
// HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
|
|
//
|
|
RemoveEntryList (&HiiStatementPrivate->Link);
|
|
FreePool (HiiStatementPrivate);
|
|
HiiStatementLink = HiiNextStatementLink;
|
|
}
|
|
|
|
//
|
|
// HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
|
|
//
|
|
|
|
RemoveEntryList (&HiiFormPrivate->Link);
|
|
FreePool (HiiFormPrivate);
|
|
HiiFormLink = HiiNextFormLink;
|
|
}
|
|
|
|
if (FormsetPrivate->HiiFormSet != NULL) {
|
|
DestroyFormSet (FormsetPrivate->HiiFormSet);
|
|
FormsetPrivate->HiiFormSet = NULL;
|
|
}
|
|
|
|
if (FormsetPrivate->DevicePathStr != NULL) {
|
|
FreePool (FormsetPrivate->DevicePathStr);
|
|
}
|
|
|
|
//
|
|
// Release schema list
|
|
//
|
|
if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
|
|
for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
|
|
FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
|
|
}
|
|
|
|
FreePool (FormsetPrivate->SupportedSchema.SchemaList);
|
|
FormsetPrivate->SupportedSchema.SchemaList = NULL;
|
|
FormsetPrivate->SupportedSchema.Count = 0;
|
|
}
|
|
|
|
ReleaseXuefiStringDatabase (FormsetPrivate);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Create new form-set instance.
|
|
|
|
@retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to newly created form-set private instance.
|
|
|
|
**/
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
|
|
NewFormsetPrivate (
|
|
VOID
|
|
)
|
|
{
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
|
|
|
|
NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
|
|
if (NewFormsetPrivate == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initial newly created formset private data.
|
|
//
|
|
InitializeListHead (&NewFormsetPrivate->HiiFormList);
|
|
InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
|
|
|
|
return NewFormsetPrivate;
|
|
}
|
|
|
|
/**
|
|
Create new x-UEFI-redfish string array.
|
|
|
|
@param[in] XuefiRedfishStringDatabase The x-UEFI-redfish string database.
|
|
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory for creating a new array.
|
|
EFI_SUCCESS New array is created successfully.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
NewRedfishXuefiStringArray (
|
|
IN REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase
|
|
)
|
|
{
|
|
REDFISH_X_UEFI_STRINGS_ARRAY *ArrayAddress;
|
|
|
|
// Initial first REDFISH_X_UEFI_STRINGS_ARRAY memory.
|
|
ArrayAddress = (REDFISH_X_UEFI_STRINGS_ARRAY *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY));
|
|
if (ArrayAddress == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to allocate REDFISH_X_UEFI_STRINGS_ARRAY.\n", __func__));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
InitializeListHead (&ArrayAddress->NextArray);
|
|
|
|
// Allocate memory buffer for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT elements.
|
|
ArrayAddress->ArrayEntryAddress = \
|
|
(REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT) * X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER);
|
|
if (ArrayAddress->ArrayEntryAddress == NULL) {
|
|
FreePool (ArrayAddress);
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to allocate array for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENTs.\n", __func__));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
XuefiRedfishStringDatabase->StringsArrayBlocks++;
|
|
InsertTailList (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ArrayAddress->NextArray);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get the pointer of x-UEFI-redfish database or create a new database.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
@param[in] HiiStringPackageHeader HII string package header.
|
|
|
|
@retval Pointer to REDFISH_X_UEFI_STRING_DATABASE.
|
|
If NULL, it fails to obtain x-UEFI-redfish database.
|
|
|
|
**/
|
|
REDFISH_X_UEFI_STRING_DATABASE *
|
|
GetExistOrCreateXuefiStringDatabase (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
|
|
IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN CreateNewOne;
|
|
REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
|
|
|
|
CreateNewOne = TRUE;
|
|
XuefiRedfishStringDatabase = NULL;
|
|
if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
|
|
XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
|
|
|
|
while (TRUE) {
|
|
if (AsciiStriCmp (XuefiRedfishStringDatabase->XuefiRedfishLanguage, HiiStringPackageHeader->Language) == 0) {
|
|
CreateNewOne = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
|
|
break;
|
|
}
|
|
|
|
XuefiRedfishStringDatabase = \
|
|
(REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
|
|
}
|
|
}
|
|
|
|
if (CreateNewOne) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " Creating x-UEFI-redfish (%a) string database...\n", HiiStringPackageHeader->Language));
|
|
XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRING_DATABASE));
|
|
if (XuefiRedfishStringDatabase == NULL) {
|
|
DEBUG ((DEBUG_ERROR, " Failed to allocate REDFISH_X_UEFI_STRING_DATABASE.\n"));
|
|
return NULL;
|
|
}
|
|
|
|
InitializeListHead (&XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
|
|
InitializeListHead (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
|
|
XuefiRedfishStringDatabase->StringsArrayBlocks = 0;
|
|
XuefiRedfishStringDatabase->XuefiRedfishLanguage = HiiStringPackageHeader->Language;
|
|
|
|
Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (XuefiRedfishStringDatabase);
|
|
return NULL;
|
|
}
|
|
|
|
DEBUG ((
|
|
DEBUG_REDFISH_PLATFORM_CONFIG,
|
|
" x-UEFI-redfish (%a):\n String array is added to XuefiRedfishStringDatabase, total %d arrays now.\n",
|
|
XuefiRedfishStringDatabase->XuefiRedfishLanguage,
|
|
XuefiRedfishStringDatabase->StringsArrayBlocks
|
|
));
|
|
|
|
// Link string database to FormsetPrivate.
|
|
InsertTailList (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
|
|
}
|
|
|
|
return XuefiRedfishStringDatabase;
|
|
}
|
|
|
|
/**
|
|
Check and allocate a new x-UEFI-redfish array if it is insufficient for the
|
|
newly added x-UEFI-redfish string.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
@param[in] XuefiRedfishStringDatabase Pointer to the x-UEFI-redfish database.
|
|
@param[in] StringId String ID added to database.
|
|
|
|
@retval EFI_SUCCESS The size of x-UEFI-string array is adjusted or
|
|
is not required to be adjusted.
|
|
Otherwise, refer to the error code returned from NewRedfishXuefiStringArray().
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RedfishXuefiStringAdjustArrays (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
|
|
IN REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase,
|
|
IN EFI_STRING_ID StringId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
while (((StringId + X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) / X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) > (UINT16)XuefiRedfishStringDatabase->StringsArrayBlocks) {
|
|
Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-string array", __func__));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Insert a x-UEFI-redfish string to database.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
@param[in] HiiStringPackageHeader Pointer to HII string package.
|
|
@param[in] StringId The HII string ID
|
|
@param[in] StringTextPtr Pointer to HII string text.
|
|
|
|
@retval EFI_SUCCESS The HII string is added to database.
|
|
EFI_LOAD_ERROR Something wrong when insert an HII string
|
|
to database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RedfishXuefiStringInsertDatabase (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
|
|
IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader,
|
|
IN EFI_STRING_ID StringId,
|
|
IN CHAR16 *StringTextPtr
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN StringIdOffset;
|
|
REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
|
|
REDFISH_X_UEFI_STRINGS_ARRAY *ThisArray;
|
|
|
|
XuefiRedfishStringDatabase = GetExistOrCreateXuefiStringDatabase (FormsetPrivate, HiiStringPackageHeader);
|
|
if (XuefiRedfishStringDatabase == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to get REDFISH_X_UEFI_STRING_DATABASE of x-UEFI-redfish language %a.\n", __func__, HiiStringPackageHeader->Language));
|
|
ReleaseXuefiStringDatabase (FormsetPrivate);
|
|
return EFI_LOAD_ERROR;
|
|
}
|
|
|
|
Status = RedfishXuefiStringAdjustArrays (FormsetPrivate, XuefiRedfishStringDatabase, StringId);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-UEFI-redfish string array.\n", __func__));
|
|
ReleaseXuefiStringDatabase (FormsetPrivate);
|
|
return EFI_LOAD_ERROR;
|
|
}
|
|
|
|
// Insert string to x-UEFI-redfish string array.
|
|
StringIdOffset = (UINTN)StringId;
|
|
ThisArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
|
|
while (StringIdOffset >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
|
|
ThisArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ThisArray->NextArray);
|
|
StringIdOffset -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
|
|
}
|
|
|
|
// Insert string
|
|
(ThisArray->ArrayEntryAddress + StringIdOffset)->StringId = StringId;
|
|
(ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;
|
|
|
|
DEBUG_REDFISH_THIS_MODULE (
|
|
REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE,
|
|
" Insert string ID: (%d) to database\n x-UEFI-string: \"%s\"\n Language: %a.\n",
|
|
StringId,
|
|
StringTextPtr,
|
|
HiiStringPackageHeader->Language
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get x-UEFI-redfish string and language by string ID.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
@param[in] HiiStringPackageHeader HII string package header.
|
|
@param[out] TotalStringAdded Return the total strings added to database.
|
|
|
|
@retval TRUE x-UEFI-redfish string and ID map is inserted to database.
|
|
FALSE Something is wrong when insert x-UEFI-redfish string and ID map.
|
|
|
|
**/
|
|
BOOLEAN
|
|
CreateXuefiLanguageStringIdMap (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
|
|
IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader,
|
|
OUT UINTN *TotalStringAdded
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *BlockHdr;
|
|
EFI_STRING_ID CurrentStringId;
|
|
UINTN BlockSize;
|
|
UINTN Index;
|
|
UINT8 *StringTextPtr;
|
|
UINTN Offset;
|
|
UINT16 StringCount;
|
|
UINT16 SkipCount;
|
|
UINT8 Length8;
|
|
EFI_HII_SIBT_EXT2_BLOCK Ext2;
|
|
UINT32 Length32;
|
|
UINT8 *StringBlockInfo;
|
|
UINTN StringsAdded;
|
|
|
|
StringsAdded = 0;
|
|
|
|
//
|
|
// Parse the string blocks to get the string text and font.
|
|
//
|
|
StringBlockInfo = (UINT8 *)((UINTN)HiiStringPackageHeader + HiiStringPackageHeader->StringInfoOffset);
|
|
BlockHdr = StringBlockInfo;
|
|
BlockSize = 0;
|
|
Offset = 0;
|
|
CurrentStringId = 1;
|
|
while (*BlockHdr != EFI_HII_SIBT_END) {
|
|
switch (*BlockHdr) {
|
|
case EFI_HII_SIBT_STRING_SCSU:
|
|
Offset = sizeof (EFI_HII_STRING_BLOCK);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRING_SCSU_FONT:
|
|
Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRINGS_SCSU:
|
|
CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
|
|
StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
|
|
BlockSize += StringTextPtr - BlockHdr;
|
|
|
|
for (Index = 0; Index < StringCount; Index++) {
|
|
BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRINGS_SCSU_FONT:
|
|
CopyMem (
|
|
&StringCount,
|
|
(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
|
|
sizeof (UINT16)
|
|
);
|
|
StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
|
|
BlockSize += StringTextPtr - BlockHdr;
|
|
|
|
for (Index = 0; Index < StringCount; Index++) {
|
|
BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRING_UCS2:
|
|
Offset = sizeof (EFI_HII_STRING_BLOCK);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
|
|
// x-UEFI-redfish string is always encoded as UCS and started with '/'.
|
|
if (*StringTextPtr == (UINT16)'/') {
|
|
Status = RedfishXuefiStringInsertDatabase (
|
|
FormsetPrivate,
|
|
HiiStringPackageHeader,
|
|
CurrentStringId,
|
|
(CHAR16 *)StringTextPtr
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-UEFI-redfish string %s.\n", __func__, StringTextPtr));
|
|
return FALSE;
|
|
}
|
|
|
|
StringsAdded++;
|
|
}
|
|
|
|
BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
|
|
CurrentStringId++;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRING_UCS2_FONT:
|
|
Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
|
|
CurrentStringId++;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRINGS_UCS2:
|
|
Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
BlockSize += Offset;
|
|
CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
|
|
for (Index = 0; Index < StringCount; Index++) {
|
|
BlockSize += HiiStrSize ((CHAR16 *)StringTextPtr);
|
|
StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_HII_SIBT_STRINGS_UCS2_FONT:
|
|
Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
|
|
StringTextPtr = BlockHdr + Offset;
|
|
BlockSize += Offset;
|
|
CopyMem (
|
|
&StringCount,
|
|
(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
|
|
sizeof (UINT16)
|
|
);
|
|
for (Index = 0; Index < StringCount; Index++) {
|
|
BlockSize += HiiStrSize ((CHAR16 *)StringTextPtr);
|
|
StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
|
|
CurrentStringId++;
|
|
}
|
|
|
|
break;
|
|
|
|
case EFI_HII_SIBT_DUPLICATE:
|
|
BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
|
|
CurrentStringId++;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_SKIP1:
|
|
SkipCount = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
|
|
CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
|
|
BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
|
|
break;
|
|
|
|
case EFI_HII_SIBT_SKIP2:
|
|
CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
|
|
CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
|
|
BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
|
|
break;
|
|
|
|
case EFI_HII_SIBT_EXT1:
|
|
CopyMem (
|
|
&Length8,
|
|
(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
|
|
sizeof (UINT8)
|
|
);
|
|
BlockSize += Length8;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_EXT2:
|
|
CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
|
|
BlockSize += Ext2.Length;
|
|
break;
|
|
|
|
case EFI_HII_SIBT_EXT4:
|
|
CopyMem (
|
|
&Length32,
|
|
(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
|
|
sizeof (UINT32)
|
|
);
|
|
|
|
BlockSize += Length32;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
|
|
}
|
|
|
|
*TotalStringAdded = StringsAdded;
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Get x-UEFI-redfish string and language by string ID.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
@param[in] StringId The HII string ID.
|
|
@param[out] String Optionally return USC string.
|
|
@param[out] Language Optionally return x-UEFI-redfish language.
|
|
@param[out] XuefiStringDatabase Optionally return x-UEFI-redfish database.
|
|
|
|
@retval EFI_SUCCESS String information is returned.
|
|
EFI_INVALID_PARAMETER One of the given parameters to this function is
|
|
invalid.
|
|
EFI_NOT_FOUND String is not found.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GetXuefiStringAndLangByStringId (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
|
|
IN EFI_STRING_ID StringId,
|
|
OUT CHAR16 **String OPTIONAL,
|
|
OUT CHAR8 **Language OPTIONAL,
|
|
OUT REDFISH_X_UEFI_STRING_DATABASE **XuefiStringDatabase OPTIONAL
|
|
)
|
|
{
|
|
REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
|
|
REDFISH_X_UEFI_STRINGS_ARRAY *StringArray;
|
|
UINT16 StringIndex;
|
|
|
|
if ((String == NULL) && (Language == NULL) && (XuefiStringDatabase == NULL)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Invalid parameters for this function.\n", __func__));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
|
|
while (TRUE) {
|
|
if (Language != NULL) {
|
|
*Language = XuefiRedfishStringDatabase->XuefiRedfishLanguage;
|
|
}
|
|
|
|
StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
|
|
|
|
// Loop to the correct string array.
|
|
StringIndex = StringId;
|
|
while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
|
|
if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray)) {
|
|
goto ErrorExit;
|
|
}
|
|
|
|
StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray);
|
|
StringIndex -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
|
|
}
|
|
|
|
//
|
|
// NOTE: The string ID in the formset is a unique number.
|
|
// If the string in the array is NULL, then the matched string ID
|
|
// should be in another x-UEFI-redfish database.
|
|
//
|
|
if ((StringArray->ArrayEntryAddress + StringIndex)->UcsString != NULL) {
|
|
//
|
|
// String ID is belong to this x-uef-redfish language database.
|
|
//
|
|
if (String != NULL) {
|
|
*String = (StringArray->ArrayEntryAddress + StringIndex)->UcsString;
|
|
}
|
|
|
|
if (XuefiStringDatabase != NULL) {
|
|
*XuefiStringDatabase = XuefiRedfishStringDatabase;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (
|
|
&FormsetPrivate->XuefiRedfishStringDatabase,
|
|
&XuefiRedfishStringDatabase->NextXuefiRedfishLanguage
|
|
);
|
|
}
|
|
|
|
ErrorExit:;
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
/**
|
|
Build a x-UEFI-redfish database for the newly added x-UEFI-redfish language.
|
|
|
|
@param[in] FormsetPrivate Pointer to HII form-set private instance.
|
|
|
|
**/
|
|
VOID
|
|
BuildXUefiRedfishStringDatabase (
|
|
IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_HII_PACKAGE_HEADER *PackageHeader;
|
|
UINTN EndingPackageAddress;
|
|
EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader;
|
|
UINTN SupportedSchemaLangCount;
|
|
CHAR8 **SupportedSchemaLang;
|
|
BOOLEAN StringIdMapIsBuilt;
|
|
UINTN TotalStringsAdded;
|
|
UINTN NumberPackageStrings;
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Building x-UEFI-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
|
|
|
|
BufferSize = 0;
|
|
Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
|
|
mRedfishPlatformConfigPrivate->HiiDatabase,
|
|
FormsetPrivate->HiiHandle,
|
|
&BufferSize,
|
|
FormsetPrivate->HiiPackageListHeader
|
|
);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
DEBUG ((DEBUG_ERROR, " Failed to export package list.\n"));
|
|
return;
|
|
}
|
|
|
|
FormsetPrivate->HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)AllocateZeroPool (BufferSize);
|
|
if (FormsetPrivate->HiiPackageListHeader == NULL) {
|
|
DEBUG ((DEBUG_ERROR, " Failed to allocate memory for the exported package list.\n"));
|
|
return;
|
|
}
|
|
|
|
Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
|
|
mRedfishPlatformConfigPrivate->HiiDatabase,
|
|
FormsetPrivate->HiiHandle,
|
|
&BufferSize,
|
|
FormsetPrivate->HiiPackageListHeader
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (FormsetPrivate->HiiPackageListHeader);
|
|
FormsetPrivate->HiiPackageListHeader = NULL;
|
|
return;
|
|
}
|
|
|
|
TotalStringsAdded = 0;
|
|
//
|
|
// Finding the string package.
|
|
//
|
|
EndingPackageAddress = (UINTN)FormsetPrivate->HiiPackageListHeader + FormsetPrivate->HiiPackageListHeader->PackageLength;
|
|
PackageHeader = (EFI_HII_PACKAGE_HEADER *)(FormsetPrivate->HiiPackageListHeader + 1);
|
|
SupportedSchemaLang = FormsetPrivate->SupportedSchema.SchemaList;
|
|
while ((UINTN)PackageHeader < EndingPackageAddress) {
|
|
switch (PackageHeader->Type) {
|
|
case EFI_HII_PACKAGE_STRINGS:
|
|
StringIdMapIsBuilt = FALSE;
|
|
HiiStringPackageHeader = (EFI_HII_STRING_PACKAGE_HDR *)PackageHeader;
|
|
|
|
// Check if this is the string package for x-UEFI-redfish
|
|
for (SupportedSchemaLangCount = 0;
|
|
SupportedSchemaLangCount < FormsetPrivate->SupportedSchema.Count;
|
|
SupportedSchemaLangCount++
|
|
)
|
|
{
|
|
if (AsciiStrnCmp (
|
|
*(SupportedSchemaLang + SupportedSchemaLangCount),
|
|
HiiStringPackageHeader->Language,
|
|
AsciiStrLen (HiiStringPackageHeader->Language)
|
|
) == 0)
|
|
{
|
|
StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader, &NumberPackageStrings);
|
|
if (StringIdMapIsBuilt) {
|
|
TotalStringsAdded += NumberPackageStrings;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (StringIdMapIsBuilt == FALSE) {
|
|
if (AsciiStrStr (HiiStringPackageHeader->Language, X_UEFI_SCHEMA_PREFIX) == NULL) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " No need to build x-UEFI-redfish string ID map for HII language %a\n", HiiStringPackageHeader->Language));
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, " Failed to build x-UEFI-redfish string ID map of HII language %a\n", HiiStringPackageHeader->Language));
|
|
}
|
|
}
|
|
|
|
default:
|
|
PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader + PackageHeader->Length);
|
|
}
|
|
}
|
|
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " Total %d x-UEFI-redfish config language are added.\n", TotalStringsAdded));
|
|
}
|
|
|
|
/**
|
|
Load the HII formset from the given HII handle.
|
|
|
|
@param[in] HiiHandle Target HII handle to load.
|
|
@param[out] FormsetPrivate The formset private data.
|
|
|
|
@retval EFI_STATUS The formset is loaded successfully.
|
|
@retval EFI_UNSUPPORTED This formset doesn't have any x-UEFI-redfish configuration.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
LoadFormset (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HII_FORMSET *HiiFormSet;
|
|
HII_FORM *HiiForm;
|
|
LIST_ENTRY *HiiFormLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
|
|
HII_STATEMENT *HiiStatement;
|
|
LIST_ENTRY *HiiStatementLink;
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
|
|
EFI_GUID ZeroGuid;
|
|
EXPRESS_RESULT ExpressionResult;
|
|
CHAR16 *String;
|
|
|
|
if ((HiiHandle == NULL) || (FormsetPrivate == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
|
|
if (HiiFormSet == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: No memory resource for HII_FORMSET - %g\n", __func__, FormsetPrivate->Guid));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Find HII formset by the given HII handle.
|
|
//
|
|
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
|
|
Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
|
|
if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Formset not found by HII handle - %g\n", __func__, FormsetPrivate->Guid));
|
|
Status = EFI_NOT_FOUND;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Initialize formset
|
|
//
|
|
InitializeFormSet (HiiFormSet);
|
|
|
|
//
|
|
// Initialize formset private data.
|
|
//
|
|
FormsetPrivate->HiiFormSet = HiiFormSet;
|
|
FormsetPrivate->HiiHandle = HiiHandle;
|
|
CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
|
|
FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
|
|
Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
|
|
if (EFI_ERROR (Status)) {
|
|
if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: No x-UEFI-redfish configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
|
|
//
|
|
// If there is no x-UEFI-redfish language in this form-set, we don't add formset
|
|
// since we don't need to build menu path for attribute registry.
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
} else {
|
|
// Building x-UEFI-redfish string database
|
|
BuildXUefiRedfishStringDatabase (FormsetPrivate);
|
|
}
|
|
|
|
HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
|
|
while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
|
|
HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
|
|
|
|
HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
|
|
if (HiiFormPrivate == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_FORM_PRIVATE.\n", __func__));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Initialize form private data.
|
|
//
|
|
HiiFormPrivate->HiiForm = HiiForm;
|
|
HiiFormPrivate->Id = HiiForm->FormId;
|
|
HiiFormPrivate->Title = HiiForm->FormTitle;
|
|
HiiFormPrivate->ParentFormset = FormsetPrivate;
|
|
HiiFormPrivate->Suppressed = FALSE;
|
|
InitializeListHead (&HiiFormPrivate->StatementList);
|
|
|
|
if ((HiiForm->SuppressExpression != NULL) &&
|
|
(EvaluateExpressionList (HiiForm->SuppressExpression, TRUE, HiiFormSet, HiiForm) == ExpressSuppress))
|
|
{
|
|
HiiFormPrivate->Suppressed = TRUE;
|
|
}
|
|
|
|
HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
|
|
while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
|
|
HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
|
|
|
|
HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
|
|
if (HiiStatementPrivate == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE.\n", __func__));
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Initialize statement private data.
|
|
//
|
|
HiiStatementPrivate->HiiStatement = HiiStatement;
|
|
HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
|
|
HiiStatementPrivate->Description = HiiStatement->Prompt;
|
|
HiiStatementPrivate->Help = HiiStatement->Help;
|
|
HiiStatementPrivate->ParentForm = HiiFormPrivate;
|
|
HiiStatementPrivate->Flags = HiiStatement->QuestionFlags;
|
|
HiiStatementPrivate->StatementData.NumMaximum = HiiStatement->ExtraData.NumData.Maximum;
|
|
HiiStatementPrivate->StatementData.NumMinimum = HiiStatement->ExtraData.NumData.Minimum;
|
|
HiiStatementPrivate->StatementData.NumStep = HiiStatement->ExtraData.NumData.Step;
|
|
HiiStatementPrivate->StatementData.StrMaxSize = HiiStatement->ExtraData.StrData.MaxSize;
|
|
HiiStatementPrivate->StatementData.StrMinSize = HiiStatement->ExtraData.StrData.MinSize;
|
|
HiiStatementPrivate->Suppressed = FALSE;
|
|
HiiStatementPrivate->GrayedOut = FALSE;
|
|
|
|
//
|
|
// Expression
|
|
//
|
|
if (HiiFormPrivate->Suppressed) {
|
|
HiiStatementPrivate->Suppressed = TRUE;
|
|
} else {
|
|
if (HiiStatement->ExpressionList != NULL) {
|
|
ExpressionResult = EvaluateExpressionList (HiiStatement->ExpressionList, TRUE, HiiFormSet, HiiForm);
|
|
if (ExpressionResult == ExpressGrayOut) {
|
|
HiiStatementPrivate->GrayedOut = TRUE;
|
|
} else if (ExpressionResult == ExpressSuppress) {
|
|
HiiStatementPrivate->Suppressed = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get x-UEFI-redfish string using String ID.
|
|
Status = GetXuefiStringAndLangByStringId (FormsetPrivate, HiiStatementPrivate->Description, &String, NULL, NULL);
|
|
if (!EFI_ERROR (Status)) {
|
|
HiiStatementPrivate->XuefiRedfishStr = String;
|
|
//
|
|
// Attach to statement list.
|
|
//
|
|
InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
|
|
} else {
|
|
if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
|
|
//
|
|
// If there is no x-UEFI-redfish language for this statement, we don't add this statement
|
|
// since we don't need to build menu path for attribute registry.
|
|
//
|
|
FreePool (HiiStatementPrivate);
|
|
} else {
|
|
//
|
|
// This is not x-UEFI-redfish string and we don't cache its string for searching Redfish configure language.
|
|
// When caller wants the string, we will read English string by calling HiiGetString().
|
|
//
|
|
HiiStatementPrivate->XuefiRedfishStr = NULL;
|
|
//
|
|
// Attach to statement list.
|
|
//
|
|
InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
|
|
}
|
|
}
|
|
|
|
HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
|
|
}
|
|
|
|
//
|
|
// Attach to form list.
|
|
//
|
|
InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
|
|
HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
ErrorExit:
|
|
|
|
//
|
|
// Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
|
|
//
|
|
if ((HiiFormSet != NULL) && (FormsetPrivate->HiiFormSet != HiiFormSet)) {
|
|
DestroyFormSet (HiiFormSet);
|
|
}
|
|
|
|
//
|
|
// Release resource when error happens.
|
|
//
|
|
ReleaseFormset (FormsetPrivate);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Load formset list on given HII handle.
|
|
|
|
@param[in] HiiHandle HII handle to load formset list.
|
|
@param[out] FormsetList Pointer to formset list returned on given handle.
|
|
|
|
@retval EFI_STATUS
|
|
|
|
**/
|
|
EFI_STATUS
|
|
LoadFormsetList (
|
|
IN EFI_HII_HANDLE *HiiHandle,
|
|
OUT LIST_ENTRY *FormsetList
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
|
|
|
|
if ((HiiHandle == NULL) || (FormsetList == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
|
|
if (FormsetPrivate != NULL) {
|
|
return EFI_ALREADY_STARTED;
|
|
}
|
|
|
|
FormsetPrivate = NewFormsetPrivate ();
|
|
if (FormsetPrivate == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Load formset on the given HII handle.
|
|
//
|
|
Status = LoadFormset (HiiHandle, FormsetPrivate);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Formset is not loaded for edk2 redfish: %r\n", __func__, Status));
|
|
FreePool (FormsetPrivate);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Attach to cache list.
|
|
//
|
|
InsertTailList (FormsetList, &FormsetPrivate->Link);
|
|
|
|
DEBUG_CODE (
|
|
if (RedfishPlatformConfigDebugProp (REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET)) {
|
|
DumpFormsetList (FormsetList);
|
|
}
|
|
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Release formset list and all the forms that belong to this formset.
|
|
|
|
@param[in] FormsetList Pointer to formset list that needs to be
|
|
released.
|
|
|
|
@retval EFI_STATUS
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ReleaseFormsetList (
|
|
IN LIST_ENTRY *FormsetList
|
|
)
|
|
{
|
|
LIST_ENTRY *HiiFormsetLink;
|
|
LIST_ENTRY *HiiFormsetNextLink;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
|
|
|
|
if (FormsetList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsListEmpty (FormsetList)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
HiiFormsetLink = GetFirstNode (FormsetList);
|
|
while (!IsNull (FormsetList, HiiFormsetLink)) {
|
|
HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
|
|
HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
|
|
|
|
//
|
|
// Detach from list.
|
|
//
|
|
RemoveEntryList (&HiiFormsetPrivate->Link);
|
|
ReleaseFormset (HiiFormsetPrivate);
|
|
FreePool (HiiFormsetPrivate);
|
|
HiiFormsetLink = HiiFormsetNextLink;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Get all pending list.
|
|
|
|
@param[in] HiiHandle HII handle instance.
|
|
@param[in] PendingList Pending list to keep pending data.
|
|
|
|
@retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to pending list data.
|
|
|
|
**/
|
|
REDFISH_PLATFORM_CONFIG_PENDING_LIST *
|
|
GetPendingList (
|
|
IN EFI_HII_HANDLE *HiiHandle,
|
|
IN LIST_ENTRY *PendingList
|
|
)
|
|
{
|
|
LIST_ENTRY *PendingListLink;
|
|
REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
|
|
|
|
if ((HiiHandle == NULL) || (PendingList == NULL)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (IsListEmpty (PendingList)) {
|
|
return NULL;
|
|
}
|
|
|
|
PendingListLink = GetFirstNode (PendingList);
|
|
while (!IsNull (PendingList, PendingListLink)) {
|
|
Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
|
|
|
|
if (Target->HiiHandle == HiiHandle) {
|
|
return Target;
|
|
}
|
|
|
|
PendingListLink = GetNextNode (PendingList, PendingListLink);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
When HII database is updated. Keep updated HII handle into pending list so
|
|
we can process them later.
|
|
|
|
@param[in] HiiHandle HII handle instance.
|
|
@param[in] PendingList Pending list to keep HII handle which is recently updated.
|
|
|
|
@retval EFI_SUCCESS HII handle is saved in pending list.
|
|
@retval EFI_INVALID_PARAMETER HiiHandle is NULL or PendingList is NULL.
|
|
@retval EFI_OUT_OF_RESOURCES System is out of memory.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
NotifyFormsetUpdate (
|
|
IN EFI_HII_HANDLE *HiiHandle,
|
|
IN LIST_ENTRY *PendingList
|
|
)
|
|
{
|
|
REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
|
|
|
|
if ((HiiHandle == NULL) || (PendingList == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Check and see if this HII handle is processed already.
|
|
//
|
|
TargetPendingList = GetPendingList (HiiHandle, PendingList);
|
|
if (TargetPendingList != NULL) {
|
|
TargetPendingList->IsDeleted = FALSE;
|
|
DEBUG_CODE (
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
TargetPendingList = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
|
|
if (TargetPendingList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
TargetPendingList->HiiHandle = HiiHandle;
|
|
TargetPendingList->IsDeleted = FALSE;
|
|
|
|
InsertTailList (PendingList, &TargetPendingList->Link);
|
|
|
|
DEBUG_CODE (
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
|
|
we can process them later.
|
|
|
|
@param[in] HiiHandle HII handle instance.
|
|
@param[in] PendingList Pending list to keep HII handle which is recently updated.
|
|
|
|
@retval EFI_SUCCESS HII handle is saved in pending list.
|
|
@retval EFI_INVALID_PARAMETER HiiHandle is NULL or PendingList is NULL.
|
|
@retval EFI_OUT_OF_RESOURCES System is out of memory.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
NotifyFormsetDeleted (
|
|
IN EFI_HII_HANDLE *HiiHandle,
|
|
IN LIST_ENTRY *PendingList
|
|
)
|
|
{
|
|
REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
|
|
|
|
if ((HiiHandle == NULL) || (PendingList == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Check and see if this HII handle is processed already.
|
|
//
|
|
TargetPendingList = GetPendingList (HiiHandle, PendingList);
|
|
if (TargetPendingList != NULL) {
|
|
TargetPendingList->IsDeleted = TRUE;
|
|
DEBUG_CODE (
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
TargetPendingList = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
|
|
if (TargetPendingList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
TargetPendingList->HiiHandle = HiiHandle;
|
|
TargetPendingList->IsDeleted = TRUE;
|
|
|
|
InsertTailList (PendingList, &TargetPendingList->Link);
|
|
|
|
DEBUG_CODE (
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
There are HII database update and we need to process them accordingly so that we
|
|
won't use stale data. This function will parse updated HII handle again in order
|
|
to get updated data-set.
|
|
|
|
@param[in] FormsetList List to keep HII form-set.
|
|
@param[in] PendingList List to keep HII handle that is updated.
|
|
|
|
@retval EFI_SUCCESS HII handle is saved in pending list.
|
|
@retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ProcessPendingList (
|
|
IN LIST_ENTRY *FormsetList,
|
|
IN LIST_ENTRY *PendingList
|
|
)
|
|
{
|
|
LIST_ENTRY *PendingListLink;
|
|
LIST_ENTRY *PendingListNextLink;
|
|
REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
|
|
REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
|
|
EFI_STATUS Status;
|
|
|
|
if ((FormsetList == NULL) || (PendingList == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsListEmpty (PendingList)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
PendingListLink = GetFirstNode (PendingList);
|
|
while (!IsNull (PendingList, PendingListLink)) {
|
|
PendingListNextLink = GetNextNode (PendingList, PendingListLink);
|
|
Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
|
|
|
|
if (Target->IsDeleted) {
|
|
//
|
|
// The HII resource on this HII handle is removed. Release the formset.
|
|
//
|
|
FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
|
|
if (FormsetPrivate != NULL) {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, FormsetPrivate->Guid));
|
|
RemoveEntryList (&FormsetPrivate->Link);
|
|
ReleaseFormset (FormsetPrivate);
|
|
FreePool (FormsetPrivate);
|
|
} else {
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
|
|
}
|
|
} else {
|
|
//
|
|
// The HII resource on this HII handle is updated/removed.
|
|
//
|
|
FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
|
|
if (FormsetPrivate != NULL) {
|
|
//
|
|
// HII formset already exist, release it and query again.
|
|
//
|
|
DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
|
|
RemoveEntryList (&FormsetPrivate->Link);
|
|
ReleaseFormset (FormsetPrivate);
|
|
FreePool (FormsetPrivate);
|
|
}
|
|
|
|
Status = LoadFormsetList (Target->HiiHandle, FormsetList);
|
|
if (EFI_ERROR (Status)) {
|
|
if (Status == EFI_UNSUPPORTED) {
|
|
DEBUG ((DEBUG_ERROR, " The formset has no x-UEFI-redfish configurations.\n"));
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, " load formset from HII handle: 0x%x failed: %r\n", Target->HiiHandle, Status));
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detach it from list first.
|
|
//
|
|
RemoveEntryList (&Target->Link);
|
|
FreePool (Target);
|
|
|
|
PendingListLink = PendingListNextLink;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Release all resource in statement list.
|
|
|
|
@param[in] StatementList Statement list to be released.
|
|
|
|
@retval EFI_SUCCESS All resource are released.
|
|
@retval EFI_INVALID_PARAMETER StatementList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ReleaseStatementList (
|
|
IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList
|
|
)
|
|
{
|
|
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
|
|
LIST_ENTRY *NextLink;
|
|
|
|
if (StatementList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsListEmpty (&StatementList->StatementList)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
NextLink = GetFirstNode (&StatementList->StatementList);
|
|
while (!IsNull (&StatementList->StatementList, NextLink)) {
|
|
StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
|
|
NextLink = GetNextNode (&StatementList->StatementList, NextLink);
|
|
|
|
RemoveEntryList (&StatementRef->Link);
|
|
FreePool (StatementRef);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|