[AMD Official Use Only - General] Reviewed-by: Abner Chang <abner.ch...@amd.com>
> -----Original Message----- > From: Nickle Wang <nickle.w...@hpe.com> > Sent: Wednesday, July 27, 2022 9:38 AM > To: devel@edk2.groups.io > Cc: Chang, Abner <abner.ch...@amd.com>; Yang, Atom > <atom.y...@amd.com>; Nick Ramirez <nrami...@nvidia.com> > Subject: [edk2-staging][PATCH v3 06/15] edk2-staging/RedfishClientPkg: > Introduce RedfishConfigLangMap driver > > [CAUTION: External Email] > > Introduce Redfish configure language map driver. This driver keeps the > mapping between configure language and Redfish URI for internal use. > This saves the communication time between feature drivers and Redfish > service. It also provides the history records so that feature drivers can do > provisioning, consuming and updating efficiently. > > Signed-off-by: Nickle Wang <nickle.w...@hpe.com> > Cc: Abner Chang <abner.ch...@amd.com> > Cc: Yang Atom <atom.y...@amd.com> > Cc: Nick Ramirez <nrami...@nvidia.com> > --- > .../EdkIIRedfishConfigLangMapProtocol.h | 88 ++ > RedfishClientPkg/RedfishClient.fdf.inc | 3 +- > .../RedfishClientComponents.dsc.inc | 1 + > RedfishClientPkg/RedfishClientPkg.dec | 2 + > .../RedfishConfigLangMapDxe.c | 810 ++++++++++++++++++ > .../RedfishConfigLangMapDxe.h | 71 ++ > .../RedfishConfigLangMapDxe.inf | 46 + > 7 files changed, 1020 insertions(+), 1 deletion(-) create mode 100644 > RedfishClientPkg/Include/Protocol/EdkIIRedfishConfigLangMapProtocol.h > create mode 100644 > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.c > create mode 100644 > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.h > create mode 100644 > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf > > diff --git > a/RedfishClientPkg/Include/Protocol/EdkIIRedfishConfigLangMapProtocol.h > b/RedfishClientPkg/Include/Protocol/EdkIIRedfishConfigLangMapProtocol.h > new file mode 100644 > index 0000000000..03d18aa297 > --- /dev/null > +++ > b/RedfishClientPkg/Include/Protocol/EdkIIRedfishConfigLangMapProtoco > +++ l.h > @@ -0,0 +1,88 @@ > +/** @file > + This file defines the EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL > interface. > + > + (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_H_ > +#define EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_H_ > + > +typedef struct _EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL > +EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL; > + > +/** > + Definition of REDFISH_CONFIG_LANG_MAP_GET_TYPE **/ typedef enum > { > + RedfishGetTypeUri = 0, > + RedfishGetTypeConfigLang, > + RedfishGetTypeMax > +} REDFISH_CONFIG_LANG_MAP_GET_TYPE; > + > +/** > + Get string in database by given query string. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + @param[in] QueryStringType The type of given QueryString. > + @param[in] QueryString Query string. > + @param[out] ResultString Returned string mapping to give query > string. > + > + @retval EFI_SUCCESS The result is found successfully. > + @retval EFI_INVALID_PARAMETER Invalid parameter is given. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_GET) ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This, > + IN REDFISH_CONFIG_LANG_MAP_GET_TYPE QueryStringType, > + IN EFI_STRING QueryString, > + OUT EFI_STRING *ResultString > + ); > + > +/** > + Save URI string which maps to given ConfigLang. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + @param[in] ConfigLang Config language to set > + @param[in] Uri Uri which is mapping to give ConfigLang. > If Uri is > NULL, > + the record will be removed. > + > + @retval EFI_SUCCESS Uri is saved successfully. > + @retval Others Some error happened. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_SET) ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This, > + IN EFI_STRING ConfigLang, > + IN EFI_STRING Uri OPTIONAL > + ); > + > +/** > + Refresh the resource map database and save database to variable. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + > + @retval EFI_SUCCESS database is saved successfully. > + @retval Others Some error happened. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_FLUSH) ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This > + ); > + > +struct _EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL { > + EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_GET Get; > + EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_SET Set; > + EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL_FLUSH Flush; }; > + > +extern EFI_GUID gEdkIIRedfishConfigLangMapProtocolGuid; > + > +#endif > diff --git a/RedfishClientPkg/RedfishClient.fdf.inc > b/RedfishClientPkg/RedfishClient.fdf.inc > index d5d04e4c6c..6292de4e81 100644 > --- a/RedfishClientPkg/RedfishClient.fdf.inc > +++ b/RedfishClientPkg/RedfishClient.fdf.inc > @@ -5,7 +5,7 @@ > # by using "!include RedfishClientPkg/RedfisClientLibs.fdf.inc" to specify > the > module instances # to be built in the firmware volume. > # > -# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> > +# (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR> > # > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > @@ -13,6 +13,7 @@ > !if $(REDFISH_CLIENT) == TRUE > INF RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf > INF RedfishClientPkg/RedfishETagDxe/RedfishETagDxe.inf > + INF > + > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf > INF > RedfishClientPkg/Features/Memory/V1_7_1/Dxe/RedfishMemoryDxe.inf > INF > RedfishClientPkg/Features/RedfishMemoryCollectionDxe/RedfishMemoryC > ollectionDxe.inf > > diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc > b/RedfishClientPkg/RedfishClientComponents.dsc.inc > index b89df12c6f..ee4602fe79 100644 > --- a/RedfishClientPkg/RedfishClientComponents.dsc.inc > +++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc > @@ -15,6 +15,7 @@ > !if $(REDFISH_CLIENT) == TRUE > RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf > RedfishClientPkg/RedfishETagDxe/RedfishETagDxe.inf > + > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf > # > # Below two modules should be pulled in by build tool. > # > diff --git a/RedfishClientPkg/RedfishClientPkg.dec > b/RedfishClientPkg/RedfishClientPkg.dec > index c61c581213..7bdab5be0c 100644 > --- a/RedfishClientPkg/RedfishClientPkg.dec > +++ b/RedfishClientPkg/RedfishClientPkg.dec > @@ -38,6 +38,8 @@ > gEdkIIRedfishResourceConfigProtocolGuid = { 0x6f164c68, 0xfb09, 0x4646, > { 0xa8, 0xd3, 0x24, 0x11, 0x5d, 0xab, 0x3e, 0xe7 } } > ## Include/Protocol/EdkiiRedfishETagProtocol.h > gEdkIIRedfishETagProtocolGuid = { 0x5706d368, 0xaf66, 0x48f5, { > 0x89, > 0xfc, 0xa6, 0x61, 0xce, 0xb5, 0xa6, 0xa9 } } > + ## Include/Protocol/EdkIIRedfishConfigLangMapProtocol.h > + gEdkIIRedfishConfigLangMapProtocolGuid = { 0x1d9ba9fe, 0x5d5a, > 0x4b66, {0x83, 0x5b, 0xe2, 0x5d, 0x13, 0x93, 0x4a, 0x9c } } > ## Include/Protocol/EdkIIRedfishInterchangeData.h > gEdkIIRedfishFeatureInterchangeDataProtocolGuid = { 0x4B8FF71C, 0x4A7B, > 0x9478, { 0xB7, 0x81, 0x35, 0x9B, 0x0A, 0xF2, 0x00, 0x91 } } > > diff --git > a/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.c > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.c > new file mode 100644 > index 0000000000..2762bbefab > --- /dev/null > +++ > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.c > @@ -0,0 +1,810 @@ > +/** @file > + > + (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "RedfishConfigLangMapDxe.h" > + > +REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA > *mRedfishConfigLangMapPrivate = > +NULL; > + > +/** > + Release REDFISH_CONFIG_LANG_MAP_RECORD resource > + > + @param[in] Record Pointer to REDFISH_CONFIG_LANG_MAP_RECORD > instance > + > + @retval EFI_SUCCESS REDFISH_CONFIG_LANG_MAP_RECORD is > released successfully. > + @retval EFI_INVALID_PARAMETER Record is NULL > + > +**/ > +EFI_STATUS > +ReleaseConfigLangMapRecord ( > + IN REDFISH_CONFIG_LANG_MAP_RECORD *Record > + ) > +{ > + if (Record == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Record->Uri != NULL) { > + FreePool (Record->Uri); > + } > + > + if (Record->ConfigLang != NULL) { > + FreePool (Record->ConfigLang); > + } > + > + FreePool (Record); > + > + return EFI_SUCCESS; > +} > + > +/** > + Create new resource map resource. > + > + @param[in] Uri The URI string matching to this ConfigLang. > + @param[in] ConfigLang ConfigLang string. > + > + @retval REDFISH_CONFIG_LANG_MAP_RECORD * Pointer to newly > created config language map. > + @retval NULL No memory available. > + > +**/ > +REDFISH_CONFIG_LANG_MAP_RECORD * > +NewConfigLangMapRecord ( > + IN EFI_STRING Uri, > + IN EFI_STRING ConfigLang > + ) > +{ > + REDFISH_CONFIG_LANG_MAP_RECORD *NewRecord; > + UINTN Size; > + > + if (IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (ConfigLang)) { > + return NULL; > + } > + > + NewRecord = AllocateZeroPool (sizeof > + (REDFISH_CONFIG_LANG_MAP_RECORD)); > + if (NewRecord == NULL) { > + return NULL; > + } > + > + Size = StrSize (Uri); > + NewRecord->Uri = AllocateCopyPool (Size, Uri); if (NewRecord->Uri == > + NULL) { > + goto ON_ERROR; > + } > + > + NewRecord->Size = Size; > + Size = StrSize (ConfigLang); > + NewRecord->ConfigLang = AllocateCopyPool (Size, ConfigLang); if > + (NewRecord->ConfigLang == NULL) { > + goto ON_ERROR; > + } > + > + NewRecord->Size += Size; > + return NewRecord; > + > +ON_ERROR: > + > + if (NewRecord != NULL) { > + ReleaseConfigLangMapRecord (NewRecord); } > + > + return NULL; > +} > + > +/** > + Add new config language map by given URI and ConfigLang string to > specify List. > + > + @param[in] List Target config language map list to add. > + @param[in] Uri The URI string matching to this ConfigLang. > + @param[in] ConfigLang ConfigLang string. > + > + @retval EFI_SUCCESS config language map recourd is added. > + @retval Others Fail to add config language map. > + > +**/ > +EFI_STATUS > +AddConfigLangMapRecord ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *List, > + IN EFI_STRING Uri, > + IN EFI_STRING ConfigLang > + ) > +{ > + REDFISH_CONFIG_LANG_MAP_RECORD *NewRecord; > + > + if (List == NULL || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING > (ConfigLang)) { > + return EFI_INVALID_PARAMETER; > + } > + > + NewRecord = NewConfigLangMapRecord (Uri, ConfigLang); if > + (NewConfigLangMapRecord == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + InsertTailList (&List->Listheader, &NewRecord->List); ++List->Count; > + List->TotalSize += NewRecord->Size; > + > + return EFI_SUCCESS; > +} > + > +/** > + Delete an config language map by given config language map instance. > + > + @param[in] List Target config language map list to be removed. > + @param[in] Record Pointer to the instance to be deleted. > + > + @retval EFI_SUCCESS config language map recourd is removed. > + @retval Others Fail to add config language map. > + > +**/ > +EFI_STATUS > +DeleteConfigLangMapRecord ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *List, > + IN REDFISH_CONFIG_LANG_MAP_RECORD *Record > + ) > +{ > + if (List == NULL || Record == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + RemoveEntryList (&Record->List); > + --List->Count; > + List->TotalSize -= Record->Size; > + > + return ReleaseConfigLangMapRecord (Record); } > + > +/** > + Search on given ListHeader for given ConfigLang string. > + > + @param[in] ListHeader Target list to search. > + @param[in] Query Target string to search. > + @param[in] QueryIsUri Query string is URI string or not > + > + @retval REDFISH_CONFIG_LANG_MAP_RECORD Target in map is found. > + @retval NULL No target in map with given query > is found. > + > +**/ > +REDFISH_CONFIG_LANG_MAP_RECORD * > +FindConfigLangMapRecord ( > + IN LIST_ENTRY *ListHeader, > + IN EFI_STRING Query, > + IN BOOLEAN QueryIsUri > + ) > +{ > + LIST_ENTRY *List; > + REDFISH_CONFIG_LANG_MAP_RECORD *Record; > + > + if (IsListEmpty (ListHeader)) { > + return NULL; > + } > + > + if (IS_EMPTY_STRING (Query)) { > + return NULL; > + } > + > + Record = NULL; > + List = GetFirstNode (ListHeader); > + while (!IsNull (ListHeader, List)) { > + Record = REDFISH_CONFIG_LANG_MAP_RECORD_FROM_LIST (List); > + > + if (QueryIsUri) { > + if (StrCmp (Record->Uri, Query) == 0) { > + return Record; > + } > + } else { > + if (StrCmp (Record->ConfigLang, Query) == 0) { > + return Record; > + } > + } > + > + List = GetNextNode (ListHeader, List); } > + > + return NULL; > +} > + > +#if CONFIG_LANG_MAP_DEBUG_ENABLED > +/** > + Debug output the config language map list. > + > + @param[in] ConfigLangMapList Target list to dump > + @param[in] Msg Debug message string. > + > + @retval EFI_SUCCESS Debug dump finished. > + @retval EFI_INVALID_PARAMETER ConfigLangMapList is NULL. > + > +**/ > +EFI_STATUS > +DumpConfigLangMapList ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *ConfigLangMapList, > + IN EFI_STRING Msg > + ) > +{ > + LIST_ENTRY *List; > + REDFISH_CONFIG_LANG_MAP_RECORD *Record; > + > + if (ConfigLangMapList == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_EMPTY_STRING (Msg)) { > + DEBUG ((DEBUG_ERROR, "%s\n", Msg)); } > + > + if (IsListEmpty (&ConfigLangMapList->Listheader)) { > + DEBUG ((DEBUG_INFO, "ConfigLangMap list is empty\n")); > + return EFI_NOT_FOUND; > + } > + > + DEBUG ((DEBUG_INFO, "Count: %d Total Size: %d\n", > + ConfigLangMapList->Count, ConfigLangMapList->TotalSize)); Record = > + NULL; List = GetFirstNode (&ConfigLangMapList->Listheader); while > + (!IsNull (&ConfigLangMapList->Listheader, List)) { > + Record = REDFISH_CONFIG_LANG_MAP_RECORD_FROM_LIST (List); > + > + DEBUG ((DEBUG_INFO, "ConfigLang: %s Uri: %s Size: %d\n", > + Record->ConfigLang, Record->Uri, Record->Size)); > + > + List = GetNextNode (&ConfigLangMapList->Listheader, List); } > + > + return EFI_SUCCESS; > +} > + > +/** > + Debug output raw data buffer. > + > + @param[in] Buffer Debug output data buffer. > + @param[in] BufferSize The size of Buffer in byte. > + > + @retval EFI_SUCCESS Debug dump finished. > + @retval EFI_INVALID_PARAMETER Buffer is NULL. > + > +**/ > +EFI_STATUS > +DumpRawBuffer ( > + IN UINT8 *Buffer, > + IN UINTN BufferSize > + ) > +{ > + UINTN Index; > + CHAR16 *Seeker; > + > + if (Buffer == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Index = 0; > + Seeker = (CHAR16 *)Buffer; > + DEBUG ((DEBUG_ERROR, "Buffer size: %d\n", BufferSize)); while > + (Seeker[Index] != '\0') { > + DEBUG ((DEBUG_ERROR, "(%d) %c ", (Index + 1), Seeker[Index])); > + > + ++Index; > + } > + DEBUG ((DEBUG_ERROR, "\n")); > + > + return EFI_SUCCESS; > +} > +#endif > + > +/** > + Release all ConfigLangMap from list. > + > + @param[in] ConfigLangMapList The list to be released. > + > + @retval EFI_SUCCESS All config lang is released. > + @retval EFI_INVALID_PARAMETER ConfigLangMapList is NULL. > + > +**/ > +EFI_STATUS > +ReleaseConfigLangMapList ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *ConfigLangMapList > + ) > +{ > + LIST_ENTRY *List; > + LIST_ENTRY *Next; > + REDFISH_CONFIG_LANG_MAP_RECORD *Record; > + > + if (ConfigLangMapList == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (IsListEmpty (&ConfigLangMapList->Listheader)) { > + return EFI_SUCCESS; > + } > + > + Record = NULL; > + Next = NULL; > + List = GetFirstNode (&ConfigLangMapList->Listheader); while (!IsNull > + (&ConfigLangMapList->Listheader, List)) { > + Record = REDFISH_CONFIG_LANG_MAP_RECORD_FROM_LIST (List); > + Next = GetNextNode (&ConfigLangMapList->Listheader, List); > + > + DeleteConfigLangMapRecord (ConfigLangMapList, Record); > + > + List = Next; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Save config lang in list to UEFI variable. > + > + @param[in] ConfigLangMapList The list to be saved. > + @param[in] VariableName The UEFI variable name. > + > + @retval EFI_SUCCESS All config lang is saved. > + @retval EFI_INVALID_PARAMETER VariableName or ConfigLangMapList is > NULL. > + > +**/ > +EFI_STATUS > +SaveConfigLangMapList ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *ConfigLangMapList, > + IN EFI_STRING VariableName > + ) > +{ > + LIST_ENTRY *List; > + REDFISH_CONFIG_LANG_MAP_RECORD *Record; > + UINT8 *VarData; > + VOID *Data; > + EFI_STRING Seeker; > + UINTN VarSize; > + UINTN StringSize; > + EFI_STATUS Status; > + > + if (ConfigLangMapList == NULL || IS_EMPTY_STRING (VariableName)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (IsListEmpty (&ConfigLangMapList->Listheader)) { > + return EFI_SUCCESS; > + } > + > + // > + // Caculate the total size we need to keep ConfigLangMap list. > + // > + VarSize = ConfigLangMapList->TotalSize + sizeof (CHAR16); // > + terminator character VarData = AllocateZeroPool (VarSize); if > + (VarData == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + Seeker = (EFI_STRING)VarData; > + Record = NULL; > + List = GetFirstNode (&ConfigLangMapList->Listheader); while (!IsNull > + (&ConfigLangMapList->Listheader, List)) { > + Record = REDFISH_CONFIG_LANG_MAP_RECORD_FROM_LIST (List); > + > + StringSize = StrSize (Record->Uri); > + CopyMem (Seeker, Record->Uri, StringSize); > + > + Seeker += (StringSize / sizeof (CHAR16) - 1); > + *Seeker = '|'; > + ++Seeker; > + > + StringSize = StrSize (Record->ConfigLang); > + CopyMem (Seeker, Record->ConfigLang, StringSize); > + > + Seeker += (StringSize / sizeof (CHAR16) - 1); > + *Seeker = '\n'; > + > + ++Seeker; > + > + List = GetNextNode (&ConfigLangMapList->Listheader, List);; } > + > + *Seeker = '\0'; > + > +#if CONFIG_LANG_MAP_DEBUG_ENABLED > + DumpRawBuffer (VarData, VarSize); > +#endif > + > + ASSERT (((UINTN)Seeker - (UINTN)VarData + sizeof (CHAR16)) == > + VarSize); > + > + // > + // Check if variable exists already. If yes, remove it first. > + // > + Status = GetVariable2 ( > + VariableName, > + &mRedfishVariableGuid, > + (VOID *)&Data, > + NULL > + ); > + if (!EFI_ERROR (Status)) { > + FreePool (Data); > + gRT->SetVariable (VariableName, &mRedfishVariableGuid, > + VARIABLE_ATTRIBUTE_NV_BS, 0, NULL); } > + > + > + return gRT->SetVariable (VariableName, &mRedfishVariableGuid, > +VARIABLE_ATTRIBUTE_NV_BS, VarSize, (VOID *)VarData); } > + > +/** > + Read config lang map from UEFI variable if it exists. > + > + @param[in] ConfigLangMapList The list to be loaded. > + @param[in] VariableName The UEFI variable name. > + > + @retval EFI_SUCCESS All config lang is read successfully. > + @retval EFI_INVALID_PARAMETER VariableName or ConfigLangMapList is > NULL. > + @retval EFI_NOT_FOUND No config lang is found on UEFI variable. > + > +**/ > +EFI_STATUS > +InitialConfigLangMapList ( > + IN REDFISH_CONFIG_LANG_MAP_LIST *ConfigLangMapList, > + IN EFI_STRING VariableName > + ) > +{ > + UINT8 *VarData; > + EFI_STRING UriPointer; > + EFI_STRING ConfigLangPointer; > + EFI_STRING Seeker; > + UINTN VariableSize; > + EFI_STATUS Status; > + > + if (ConfigLangMapList == NULL || IS_EMPTY_STRING (VariableName)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check if variable exists already. > + // > + Status = GetVariable2 ( > + VariableName, > + &mRedfishVariableGuid, > + (VOID *)&VarData, > + &VariableSize > + ); > + if (EFI_ERROR (Status)) { > + return EFI_NOT_FOUND; > + } > + > + Seeker = (EFI_STRING)VarData; > + UriPointer = (EFI_STRING)VarData; > + ConfigLangPointer = (EFI_STRING)VarData; while (*Seeker != '\0') { > + > + // > + // Find URI > + // > + Seeker = StrStr (UriPointer, L"|"); > + if (Seeker == NULL) { > + DEBUG ((DEBUG_ERROR, "%a, data corrupted\n", __FUNCTION__)); > + Status = EFI_DEVICE_ERROR; > + goto ON_ERROR; > + } > + > + *Seeker = '\0'; > + ConfigLangPointer = ++Seeker; > + > + // > + // Find config language map > + // > + Seeker = StrStr (ConfigLangPointer, L"\n"); > + if (Seeker == NULL) { > + DEBUG ((DEBUG_ERROR, "%a, data corrupted\n", __FUNCTION__)); > + Status = EFI_DEVICE_ERROR; > + goto ON_ERROR; > + } > + > + *Seeker = '\0'; > + > + AddConfigLangMapRecord (ConfigLangMapList, UriPointer, > + ConfigLangPointer); > + > + UriPointer = ++Seeker; > + } > + > +#if CONFIG_LANG_MAP_DEBUG_ENABLED > + DumpConfigLangMapList (ConfigLangMapList, L"Initial ConfigLangMap > +List from Variable"); #endif > + > + Status = EFI_SUCCESS; > + > +ON_ERROR: > + > + FreePool (VarData); > + > + return Status; > +} > + > +/** > + Get string in database by given query string. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + @param[in] QueryStringType The type of given QueryString. > + @param[in] QueryString Query string. > + @param[out] ResultString Returned string mapping to give query > string. > + > + @retval EFI_SUCCESS The result is found successfully. > + @retval EFI_INVALID_PARAMETER Invalid parameter is given. > + > +**/ > +EFI_STATUS > +RedfishConfigLangMapGet ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This, > + IN REDFISH_CONFIG_LANG_MAP_GET_TYPE QueryStringType, > + IN EFI_STRING QueryString, > + OUT EFI_STRING *ResultString > + ) > +{ > + REDFISH_CONFIG_LANG_MAP_RECORD *Target; > + REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA *Private; > + EFI_STRING Result; > + > + if (This == NULL || IS_EMPTY_STRING (QueryString) || ResultString == > NULL || QueryStringType >= RedfishGetTypeMax) { > + return EFI_INVALID_PARAMETER; > + } > + > + Private = REDFISH_CONFIG_LANG_MAP_PRIVATE_FROM_THIS (This); > + > + *ResultString = NULL; > + > + Target = FindConfigLangMapRecord > +(&Private->ConfigLangList.Listheader, QueryString, (QueryStringType == > +RedfishGetTypeUri)); > + if (Target == NULL) { > +#if CONFIG_LANG_MAP_DEBUG_ENABLED > + DumpConfigLangMapList (&Private->ConfigLangList, L"EFI_NOT_FOUND"); > +#endif > + return EFI_NOT_FOUND; > + } > + > + Result = (QueryStringType == RedfishGetTypeUri ? Target->ConfigLang : > + Target->Uri); *ResultString = AllocateCopyPool (StrSize (Result), > + Result); if (*ResultString == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Save URI string which maps to given ConfigLang. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + @param[in] ConfigLang Config language to set > + @param[in] Uri Uri which is mapping to give ConfigLang. > If Uri is > NULL, > + the record will be removed. > + > + @retval EFI_SUCCESS Uri is saved successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishConfigLangMapSet ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This, > + IN EFI_STRING ConfigLang, > + IN EFI_STRING Uri OPTIONAL > + ) > +{ > + REDFISH_CONFIG_LANG_MAP_RECORD *Target; > + REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA *Private; > + EFI_STATUS Status; > + > + if (This == NULL || IS_EMPTY_STRING (ConfigLang)) { > + return EFI_INVALID_PARAMETER; > + } > + > + Private = REDFISH_CONFIG_LANG_MAP_PRIVATE_FROM_THIS (This); > + > + Status = EFI_NOT_FOUND; > + Target = FindConfigLangMapRecord > + (&Private->ConfigLangList.Listheader, ConfigLang, FALSE); if (Target != > NULL) { > + // > + // Remove old one and create new one. > + // > + Status = DeleteConfigLangMapRecord (&Private->ConfigLangList, > + Target); } > + > + // > + // When Uri is NULL, it means that we want to remov this record. > + // > + if (Uri == NULL) { > + return Status; > + } > + > + return AddConfigLangMapRecord (&Private->ConfigLangList, Uri, > +ConfigLang); } > + > +/** > + Refresh the resource map database and save database to variable. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL instance. > + > + @retval EFI_SUCCESS This handler has been stoped successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +RedfishConfigLangMapFlush ( > + IN EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL *This > + ) > +{ > + REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA *Private; > + EFI_STATUS Status; > + > + if (This == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Private = REDFISH_CONFIG_LANG_MAP_PRIVATE_FROM_THIS (This); > + > + Status = SaveConfigLangMapList (&Private->ConfigLangList, > + Private->VariableName); if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a, save ConfigLangMap list to variable: %s > + failed: %r\n", __FUNCTION__, Private->VariableName, Status)); } > + > + return Status; > +} > + > +/** > + Callback function executed when the ExitBootService event group is > signaled. > + > + @param[in] Event Event whose notification function is being invoked. > + @param[out] Context Pointer to the Context buffer > + > +**/ > +VOID > +EFIAPI > +RedfishConfigLangMapOnExitBootService ( > + IN EFI_EVENT Event, > + OUT VOID *Context > + ) > +{ > + // > + // Memory is about to be released. Keep list into variable. > + // > + RedfishConfigLangMapFlush (&mRedfishConfigLangMapPrivate->Protocol); > +} > + > +/** > + Unloads an image. > + > + @param[in] ImageHandle Handle that identifies the image to be > unloaded. > + > + @retval EFI_SUCCESS The image has been unloaded. > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image > handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishConfigLangMapDriverUnload ( > + IN EFI_HANDLE ImageHandle > + ) > +{ > + EFI_STATUS Status; > + > + if (mRedfishConfigLangMapPrivate != NULL) { > + > + Status = gBS->UninstallProtocolInterface ( > + mRedfishConfigLangMapPrivate->ImageHandle, > + &gEdkIIRedfishConfigLangMapProtocolGuid, > + (VOID*)&mRedfishConfigLangMapPrivate->Protocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a, can not uninstall > gEdkIIRedfishConfigLangMapProtocolGuid: %r\n", __FUNCTION__, Status)); > + ASSERT (FALSE); > + } > + > + ReleaseConfigLangMapList > + (&mRedfishConfigLangMapPrivate->ConfigLangList); > + > + if (mRedfishConfigLangMapPrivate->VariableName != NULL) { > + FreePool (mRedfishConfigLangMapPrivate->VariableName); > + } > + > + if (mRedfishConfigLangMapPrivate->ExitBootEvent != NULL) { > + gBS->CloseEvent (mRedfishConfigLangMapPrivate->ExitBootEvent); > + } > + > + if (mRedfishConfigLangMapPrivate->ProvisionEvent != NULL) { > + gBS->CloseEvent (mRedfishConfigLangMapPrivate->ProvisionEvent); > + } > + > + FreePool (mRedfishConfigLangMapPrivate); > + mRedfishConfigLangMapPrivate = NULL; } > + > + return EFI_SUCCESS; > +} > + > +// > +// EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL. > +// > +EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL > mRedfishConfigLangMapProtocol = > +{ > + RedfishConfigLangMapGet, > + RedfishConfigLangMapSet, > + RedfishConfigLangMapFlush > +}; > + > +/** > + This is the declaration of an EFI image entry point. This entry point > +is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers > +including > + both device drivers and bus drivers. > + > + @param[in] ImageHandle The firmware allocated handle for the UEFI > image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishConfigLangMapDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + mRedfishConfigLangMapPrivate = AllocateZeroPool (sizeof > + (REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA)); > + if (mRedfishConfigLangMapPrivate == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + InitializeListHead > + (&mRedfishConfigLangMapPrivate->ConfigLangList.Listheader); > + mRedfishConfigLangMapPrivate->VariableName = AllocateCopyPool > + (StrSize (CONFIG_LANG_MAP_VARIABLE_NAME), > CONFIG_LANG_MAP_VARIABLE_NAME); if > (mRedfishConfigLangMapPrivate->VariableName == NULL) { > + goto ON_ERROR; > + } > + > + mRedfishConfigLangMapPrivate->ImageHandle = ImageHandle; > CopyMem > + (&mRedfishConfigLangMapPrivate->Protocol, > + &mRedfishConfigLangMapProtocol, sizeof > + (EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL)); > + > + Status = gBS->InstallProtocolInterface ( > + &ImageHandle, > + &gEdkIIRedfishConfigLangMapProtocolGuid, > + EFI_NATIVE_INTERFACE, > + (VOID*)&mRedfishConfigLangMapPrivate->Protocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a, can not install > gEdkIIRedfishConfigLangMapProtocolGuid: %r\n", __FUNCTION__, Status)); > + ASSERT (FALSE); > + goto ON_ERROR; > + } > + > + // > + // Create Exit Boot Service event. > + // > + Status = gBS->CreateEventEx ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + RedfishConfigLangMapOnExitBootService, > + NULL, > + &gEfiEventExitBootServicesGuid, > + &mRedfishConfigLangMapPrivate->ExitBootEvent > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Fail to register Exit Boot Service event.", > __FUNCTION__)); > + goto ON_ERROR; > + } > + > + // > + // Read existing record from variable. > + // > + Status = InitialConfigLangMapList > + (&mRedfishConfigLangMapPrivate->ConfigLangList, > + mRedfishConfigLangMapPrivate->VariableName); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, "%a, Initial ConfigLangMap List: %r\n", > + __FUNCTION__, Status)); } > + > + // > + // Register after provisioning event > + // > + Status = CreateAfterProvisioningEvent ( > + RedfishConfigLangMapOnExitBootService, > + NULL, > + &mRedfishConfigLangMapPrivate->ProvisionEvent > + ); > + > + return EFI_SUCCESS; > + > +ON_ERROR: > + > + RedfishConfigLangMapDriverUnload (ImageHandle); > + > + return Status; > +} > diff --git > a/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.h > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe. > h > new file mode 100644 > index 0000000000..d053921068 > --- /dev/null > +++ > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe. > h > @@ -0,0 +1,71 @@ > +/** @file > + Common header file for RedfishConfigLangMapDxe driver. > + > + (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef REDFISH_CONFIG_LANG_MAP_DXE_H_ > +#define REDFISH_CONFIG_LANG_MAP_DXE_H_ > + > +#include <Uefi.h> > +#include <RedfishBase.h> > + > +// > +// Libraries > +// > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > + > +#include <Library/MemoryAllocationLib.h> #include > +<Library/UefiBootServicesTableLib.h> > +#include <Library/UefiDriverEntryPoint.h> #include <Library/UefiLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > +#include <Library/RedfishEventLib.h> > +#include <Protocol/EdkIIRedfishConfigLangMapProtocol.h> > + > +#include <Guid/VariableFormat.h> > + > +#define CONFIG_LANG_MAP_VARIABLE_NAME > L"RedfishConfigLangMap" > +#define CONFIG_LANG_MAP_DEBUG_ENABLED 0x00 > + > +// > +// Definition of REDFISH_CONFIG_LANG_MAP_RECORD // typedef struct { > + LIST_ENTRY List; > + EFI_STRING Uri; > + EFI_STRING ConfigLang; > + UINTN Size; > +} REDFISH_CONFIG_LANG_MAP_RECORD; > + > +#define REDFISH_CONFIG_LANG_MAP_RECORD_FROM_LIST(a) BASE_CR > (a, > +REDFISH_CONFIG_LANG_MAP_RECORD, List) > + > +// > +// Definition of REDFISH_CONFIG_LANG_MAP_LIST // typedef struct { > + LIST_ENTRY Listheader; > + UINTN TotalSize; > + UINTN Count; > +} REDFISH_CONFIG_LANG_MAP_LIST; > + > +// > +// Definition of REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA > +// > +typedef struct { > + EFI_HANDLE ImageHandle; > + REDFISH_CONFIG_LANG_MAP_LIST ConfigLangList; > + EDKII_REDFISH_CONFIG_LANG_MAP_PROTOCOL Protocol; > + EFI_STRING VariableName; > + EFI_EVENT ExitBootEvent; > + EFI_EVENT ProvisionEvent; > +} REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA; > + > +#define REDFISH_CONFIG_LANG_MAP_PRIVATE_FROM_THIS(a) BASE_CR > (a, > +REDFISH_CONFIG_LANG_MAP_PRIVATE_DATA, Protocol) > + > +#endif > diff --git > a/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.i > nf > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.i > nf > new file mode 100644 > index 0000000000..9f19533815 > --- /dev/null > +++ > b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.i > +++ nf > @@ -0,0 +1,46 @@ > +## @file > +# > +# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> # # > +SPDX-License-Identifier: BSD-2-Clause-Patent # ## > + > +[Defines] > + INF_VERSION = 0x0001000b > + BASE_NAME = RedfishConfigLangMapDxe > + FILE_GUID = F4121E32-454D-4E51-AB4B-DAA577833E95 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = RedfishConfigLangMapDriverEntryPoint > + UNLOAD_IMAGE = RedfishConfigLangMapDriverUnload > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + RedfishPkg/RedfishPkg.dec > + RedfishClientPkg/RedfishClientPkg.dec > + > +[Sources] > + RedfishConfigLangMapDxe.h > + RedfishConfigLangMapDxe.c > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + MemoryAllocationLib > + UefiLib > + UefiBootServicesTableLib > + UefiRuntimeServicesTableLib > + UefiDriverEntryPoint > + RedfishEventLib > + > +[Protocols] > + gEdkIIRedfishConfigLangMapProtocolGuid ## PRODUCED ## > + > +[Guids] > + gEfiEventExitBootServicesGuid ## CONSUMED ## > + > +[Depex] > + TRUE > -- > 2.32.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#91913): https://edk2.groups.io/g/devel/message/91913 Mute This Topic: https://groups.io/mt/92641648/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-