Date   

[edk2-staging][PATCH v3 06/15] edk2-staging/RedfishClientPkg: Introduce RedfishConfigLangMap driver

Nickle Wang
 

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.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../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/EdkIIRedfishConfigLangMapProtocol.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/RedfishMemoryCollectionDxe.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.inf b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf
new file mode 100644
index 0000000000..9f19533815
--- /dev/null
+++ b/RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf
@@ -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


[edk2-staging][PATCH v3 05/15] edk2-staging/RedfishClientPkg: Introduce resource identify library

Nickle Wang
 

Introduce resource identify library which works with resource config
protocol to identify Redfish resource. This library provides the
flexibility for platform to implement its own policy and identify
resource. Two library implementation are provided as demonstration
code. NULL version of library accepts all Redfish resource and another
implementation to computer system resource uses UUID to identify
Redfish resource.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Library/RedfishResourceIdentifyLib.h | 29 ++++
.../RedfishResourceIdentifyLibComuterSystem.c | 164 ++++++++++++++++++
...edfishResourceIdentifyLibComuterSystem.inf | 39 +++++
.../RedfishResourceIdentifyLibNull.c | 37 ++++
.../RedfishResourceIdentifyLibNull.inf | 32 ++++
RedfishClientPkg/RedfishClientLibs.dsc.inc | 2 +-
RedfishClientPkg/RedfishClientPkg.dec | 1 +
7 files changed, 303 insertions(+), 1 deletion(-)
create mode 100644 RedfishClientPkg/Include/Library/RedfishResourceIdentifyLib.h
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.c
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.inf
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.c
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf

diff --git a/RedfishClientPkg/Include/Library/RedfishResourceIdentifyLib.h b/RedfishClientPkg/Include/Library/RedfishResourceIdentifyLib.h
new file mode 100644
index 0000000000..91d01b7d68
--- /dev/null
+++ b/RedfishClientPkg/Include/Library/RedfishResourceIdentifyLib.h
@@ -0,0 +1,29 @@
+/** @file
+ This file defines the Redfish resource identify Library interface.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_RESOURCE_IDENTIFY_LIB_H_
+#define REDFISH_RESOURCE_IDENTIFY_LIB_H_
+
+/**
+ Identify resource from given URI and context in JSON format
+
+ @param[in] Uri URI of given Redfish resource
+ @param[in] Json Context in JSON format of give Redfish resource
+
+ @retval TRUE This is the Redfish resource that we have to handle.
+ @retval FALSE We don't handle this Redfish resource.
+
+**/
+BOOLEAN
+RedfishIdentifyResource (
+ IN EFI_STRING Uri,
+ IN CHAR8 *Json
+ );
+
+#endif
diff --git a/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.c b/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.c
new file mode 100644
index 0000000000..e5699f194c
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.c
@@ -0,0 +1,164 @@
+/** @file
+ Redfish resource identify library implementation for computer system version 1.5.0
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <RedfishBase.h>
+
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/NetLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RedfishResourceIdentifyLib.h>
+
+#include <Protocol/RestJsonStructure.h>
+
+#include <RedfishJsonStructure/ComputerSystem/v1_5_0/EfiComputerSystemV1_5_0.h>
+
+EFI_REST_JSON_STRUCTURE_PROTOCOL *mJsonStructProtocol = NULL;
+
+/**
+ Identify resource from given URI and context in JSON format
+
+ @param[in] Uri URI of given Redfish resource
+ @param[in] Json Context in JSON format of give Redfish resource
+
+ @retval TRUE This is the Redfish resource that we have to handle.
+ @retval FALSE We don't handle this Redfish resource.
+
+**/
+BOOLEAN
+RedfishIdentifyResource (
+ IN EFI_STRING Uri,
+ IN CHAR8 *Json
+ )
+{
+ EFI_STATUS Status;
+ EFI_REDFISH_COMPUTERSYSTEM_V1_5_0 *ComputerSystem;
+ EFI_REDFISH_COMPUTERSYSTEM_V1_5_0_CS *ComputerSystemCs;
+ EFI_GUID SystemUuid;
+ EFI_GUID ResourceUuid;
+
+ if (IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Json)) {
+ return FALSE;
+ }
+
+ if (mJsonStructProtocol == NULL) {
+ return FALSE;
+ }
+
+ ComputerSystem = NULL;
+ ComputerSystemCs = NULL;
+
+ Status = mJsonStructProtocol->ToStructure (
+ mJsonStructProtocol,
+ NULL,
+ Json,
+ (EFI_REST_JSON_STRUCTURE_HEADER **)&ComputerSystem
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ToStructure() failed: %r\n", __FUNCTION__, Status));
+ return FALSE;
+ }
+
+ ComputerSystemCs = ComputerSystem->ComputerSystem;
+
+ if (IS_EMPTY_STRING (ComputerSystemCs->UUID)) {
+ return FALSE;
+ }
+
+ Status = AsciiStrToGuid (ComputerSystemCs->UUID, &ResourceUuid);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, fail to get resource UUID: %r\n", __FUNCTION__, Status));
+ return FALSE;
+ }
+
+ Status = NetLibGetSystemGuid (&SystemUuid);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, fail to get system UUID from SMBIOS: %r\n", __FUNCTION__, Status));
+ return FALSE;
+ }
+
+ DEBUG ((REDFISH_DEBUG_TRACE, "%a, Identify: System: %g Resource: %g\n", __FUNCTION__, &SystemUuid, &ResourceUuid));
+ if (CompareGuid (&ResourceUuid, &SystemUuid)) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ mJsonStructProtocol->DestoryStructure (
+ mJsonStructProtocol,
+ (EFI_REST_JSON_STRUCTURE_HEADER *)ComputerSystem
+ );
+
+ return (Status == EFI_SUCCESS ? TRUE : FALSE);
+}
+
+/**
+ Callback function when gEfiRestJsonStructureProtocolGuid is installed.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+RestJasonStructureProtocolIsReady
+ (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ if (mJsonStructProtocol != NULL) {
+ return;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiRestJsonStructureProtocolGuid,
+ NULL,
+ (VOID **)&mJsonStructProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to locate gEfiRestJsonStructureProtocolGuid: %r\n", __FUNCTION__, Status));
+ }
+
+ gBS->CloseEvent (Event);
+}
+
+/**
+
+ Install JSON protocol notification
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCEESS Install Boot manager menu success.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceIdentifyComuterSystemConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VOID *Registration;
+
+ EfiCreateProtocolNotifyEvent (
+ &gEfiRestJsonStructureProtocolGuid,
+ TPL_CALLBACK,
+ RestJasonStructureProtocolIsReady,
+ NULL,
+ &Registration
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.inf b/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.inf
new file mode 100644
index 0000000000..ae269b5849
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.inf
@@ -0,0 +1,39 @@
+## @file
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = RedfishResourceIdentifyLibComuterSystem
+ FILE_GUID = 2AEE2C80-126A-44A6-877E-642F20510D13
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishResourceIdentifyLib| DXE_DRIVER
+ CONSTRUCTOR = RedfishResourceIdentifyComuterSystemConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ RedfishResourceIdentifyLibComuterSystem.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+ UefiLib
+
+[Protocols]
+ gEfiRestJsonStructureProtocolGuid ## CONSUMES
diff --git a/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.c b/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.c
new file mode 100644
index 0000000000..98eb8fde47
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.c
@@ -0,0 +1,37 @@
+/** @file
+ Redfish resource identify NULL library implementation
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <RedfishBase.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RedfishResourceIdentifyLib.h>
+
+/**
+ Identify resource from given URI and context in JSON format
+
+ @param[in] Uri URI of given Redfish resource
+ @param[in] Json Context in JSON format of give Redfish resource
+
+ @retval TRUE This is the Redfish resource that we have to handle.
+ @retval FALSE We don't handle this Redfish resource.
+
+**/
+BOOLEAN
+RedfishIdentifyResource (
+ IN EFI_STRING Uri,
+ IN CHAR8 *Json
+ )
+{
+ if (!IS_EMPTY_STRING (Uri)) {
+ DEBUG ((DEBUG_VERBOSE, "%a, accept resource: %s\n", __FUNCTION__, Uri));
+ }
+
+ return TRUE;
+}
diff --git a/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf b/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf
new file mode 100644
index 0000000000..9164b229ba
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf
@@ -0,0 +1,32 @@
+## @file
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = RedfishResourceIdentifyLibNull
+ FILE_GUID = 6FFD4E25-48F8-4CB6-B194-CFAB407316E1
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishResourceIdentifyLib| DXE_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ RedfishResourceIdentifyLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/RedfishClientLibs.dsc.inc
index 8acb479170..413b83a732 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -27,7 +27,7 @@
RedfishPlatformConfigLib|RedfishPkg/Library/RedfishPlatformConfigLib/RedfishPlatformConfigLib.inf
RedfishContentCodingLib|RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf
ConverterCommonLib|RedfishClientPkg/ConverterLib/edk2library/ConverterCommonLib/ConverterCommonLib.inf
-
+ RedfishResourceIdentifyLib|RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf
EdkIIRedfishResourceConfigLib|RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
RedfishEventLib|RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
RedfishVersionLib|RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index 9d18c42c24..c61c581213 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -21,6 +21,7 @@

[LibraryClasses]
RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h
+ RedfishResourceIdentifyLib|Include/Library/RedfishResourceIdentifyLib.h
EdkIIRedfishResourceConfigLib|Include/Library/EdkIIRedfishResourceConfigLib.h
RedfishEventLib|Include/Library/RedfishEventLib.h
RedfishVersionLib|Include/Library/RedfishVersionLib.h
--
2.32.0.windows.2


[edk2-staging][PATCH v3 04/15] edk2-staging/RedfishClientPkg: Introduce Redfish resource config library

Nickle Wang
 

Add EdkIIRedfishResourceConfigLib in order to work with Redfish Config
Protocol and do the communication between each feature drivers. Also
introduce Redfish interchange data protocol to exchange data
efficiently.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Library/EdkIIRedfishResourceConfigLib.h | 163 +++++
.../Protocol/EdkIIRedfishInterchangeData.h | 52 ++
.../EdkIIRedfishResourceConfigLib.c | 593 ++++++++++++++++++
.../EdkIIRedfishResourceConfigLib.inf | 49 ++
.../RedfishFeatureUtilityInternal.h | 3 +-
RedfishClientPkg/RedfishClientLibs.dsc.inc | 1 +
RedfishClientPkg/RedfishClientPkg.dec | 5 +-
7 files changed, 864 insertions(+), 2 deletions(-)
create mode 100644 RedfishClientPkg/Include/Library/EdkIIRedfishResourceConfigLib.h
create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishInterchangeData.h
create mode 100644 RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
create mode 100644 RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf

diff --git a/RedfishClientPkg/Include/Library/EdkIIRedfishResourceConfigLib.h b/RedfishClientPkg/Include/Library/EdkIIRedfishResourceConfigLib.h
new file mode 100644
index 0000000000..1e843ec551
--- /dev/null
+++ b/RedfishClientPkg/Include/Library/EdkIIRedfishResourceConfigLib.h
@@ -0,0 +1,163 @@
+/** @file
+ This file defines the EDKII resource config Library interface.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_RESOURCE_CONFIG_LIB_H_
+#define EDKII_REDFISH_RESOURCE_CONFIG_LIB_H_
+
+#include <Uefi.h>
+#include <Library/PcdLib.h>
+#include <Library/RedfishLib.h>
+#include <Protocol/RestJsonStructure.h>
+#include <Protocol/EdkIIRedfishResourceConfigProtocol.h>
+#include <Protocol/EdkIIRedfishInterchangeData.h>
+/**
+ Provising redfish resource by given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri Target URI to create resource.
+ @param[in] InformationExchange Pointer to RESOURCE_INFORMATION_EXCHANGE.
+ @param[in] HttpPostMode TRUE if resource does not exist, HTTP POST method is used.
+ FALSE if the resource exist but some of properties are missing,
+ HTTP PUT method is used.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigProvisionging (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri,
+ IN RESOURCE_INFORMATION_EXCHANGE *InformationExchange,
+ IN BOOLEAN HttpPostMode
+ );
+
+/**
+ Consume resource from given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigConsume (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ );
+
+
+/**
+ Update resource to given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigUpdate (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ );
+
+
+/**
+ Check resource on given URI.
+
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigCheck (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ );
+
+/**
+ Identify resource on given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+ @param[in] InformationExchange Pointer to RESOURCE_INFORMATION_EXCHANGE.
+
+ @retval EFI_SUCCESS This is target resource which we want to handle.
+ @retval EFI_UNSUPPORTED This is not the target resource.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigIdentify (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri,
+ IN RESOURCE_INFORMATION_EXCHANGE *InformationExchangeUri
+ );
+
+/**
+ Set Configure language of this resource in the
+ RESOURCE_INFORMATION_EXCHANGE structure.
+
+ @param[in] ConfigLangList Pointer to REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
+
+ @retval EFI_SUCCESS Configure language is set.
+ @retval EFI_UNSUPPORTED EdkIIRedfishFeatureInterchangeDataProtocol is not found.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceSetConfigureLang (
+ REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST *ConfigLangList
+ );
+
+/**
+
+ Get schema information by given protocol and service instance.
+
+ @param[in] RedfishService Pointer to Redfish service instance.
+ @param[in] JsonStructProtocol Json Structure protocol instance.
+ @param[in] Uri Target URI.
+ @param[out] SchemaInfo Returned schema information.
+
+ @retval EFI_SUCCESS Schema information is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+GetRedfishSchemaInfo (
+ IN REDFISH_SERVICE *RedfishService,
+ IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol,
+ IN EFI_STRING Uri,
+ OUT REDFISH_SCHEMA_INFO *SchemaInfo
+ );
+
+/**
+
+ Get supported schema list by given specify schema name.
+
+ @param[in] Schema Schema type name.
+ @param[out] SchemaInfo Returned schema information.
+
+ @retval EFI_SUCCESS Schema information is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+GetSupportedSchemaVersion (
+ IN CHAR8 *Schema,
+ OUT REDFISH_SCHEMA_INFO *SchemaInfo
+ );
+
+#endif
diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishInterchangeData.h b/RedfishClientPkg/Include/Protocol/EdkIIRedfishInterchangeData.h
new file mode 100644
index 0000000000..e8d0462fb7
--- /dev/null
+++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishInterchangeData.h
@@ -0,0 +1,52 @@
+/** @file
+ This file defines the EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL interface.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_H_
+#define EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_H_
+
+#include <Library/RedfishFeatureUtilityLib.h>
+
+typedef struct _EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL;
+
+#define EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL_GUID \
+ { \
+ 0x4B8FF71C, 0x4A7B, 0x9478, { 0xB7, 0x81, 0x35, 0x9B, 0x0A, 0xF2, 0x00, 0x91 } \
+ }
+
+typedef enum {
+ InformationTypeNone = 0, ///< Invalid information.
+ InformationTypeCollectionMemberUri, ///< URI to the new created collection member.
+ InformationTypeCollectionMemberConfigLanguage, ///< URI to the new created collection member.
+ InformationTypeMax
+} RESOURCE_INFORMATION_EXCHANGE_TYPE;
+
+typedef struct {
+ RESOURCE_INFORMATION_EXCHANGE_TYPE Type;
+ EFI_STRING ParentUri; ///< The parent URI (in configure language) of the resource to process.
+ EFI_STRING PropertyName; ///< The property name of the resource to process.
+ EFI_STRING FullUri; ///< The full URI (in configure language) of the resource to process.
+} RESOURCE_INFORMATION_SEND;
+
+typedef struct {
+ RESOURCE_INFORMATION_EXCHANGE_TYPE Type;
+ REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST ConfigureLanguageList;
+} RESOURCE_INFORMATION_RETURNED;
+
+typedef struct {
+ RESOURCE_INFORMATION_SEND SendInformation;
+ RESOURCE_INFORMATION_RETURNED ReturnedInformation;
+} RESOURCE_INFORMATION_EXCHANGE;
+
+struct _EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL {
+ RESOURCE_INFORMATION_EXCHANGE *ResourceInformationExchage;
+};
+
+extern EFI_GUID gEdkIIRedfishFeatureInterchangeDataProtocolGuid;
+
+#endif
diff --git a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
new file mode 100644
index 0000000000..d09da6bd67
--- /dev/null
+++ b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
@@ -0,0 +1,593 @@
+/** @file
+ Redfish resource config library implementation
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <RedfishBase.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/EdkIIRedfishResourceConfigLib.h>
+#include <Library/RedfishFeatureUtilityLib.h>
+#include <Library/RedfishPlatformConfigLib.h>
+
+EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *mRedfishResourceConfigProtocol = NULL;
+EFI_HANDLE medfishResourceConfigProtocolHandle;
+EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL mRedfishFeatureInterchangeData;
+REDFISH_SCHEMA_INFO mSchemaInfoCache;
+
+#define SCHEMA_NAME_PREFIX_OFFSET 15 // x-uefi-redfish-
+
+/**
+
+ Get schema information by given protocol and service instance.
+
+ @param[in] RedfishService Pointer to Redfish service instance.
+ @param[in] JsonStructProtocol Json Structure protocol instance.
+ @param[in] Uri Target URI.
+ @param[out] SchemaInfo Returned schema information.
+
+ @retval EFI_SUCCESS Schema information is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+GetRedfishSchemaInfo (
+ IN REDFISH_SERVICE *RedfishService,
+ IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol,
+ IN EFI_STRING Uri,
+ OUT REDFISH_SCHEMA_INFO *SchemaInfo
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_RESPONSE Response;
+ REDFISH_PAYLOAD Payload;
+ CHAR8 *JsonText;
+ EFI_REST_JSON_STRUCTURE_HEADER *Header;
+
+ if (RedfishService == NULL || JsonStructProtocol == NULL || IS_EMPTY_STRING (Uri) || SchemaInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetResourceByUri (RedfishService, Uri, &Response);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to get resource from %s: %r", __FUNCTION__, Uri, Status));
+ return Status;
+ }
+
+ Payload = Response.Payload;
+ ASSERT (Payload != NULL);
+
+ JsonText = JsonDumpString (RedfishJsonInPayload (Payload), EDKII_JSON_COMPACT);
+ ASSERT (JsonText != NULL);
+
+ //
+ // Convert JSON text to C structure.
+ //
+ Status = JsonStructProtocol->ToStructure (
+ JsonStructProtocol,
+ NULL,
+ JsonText,
+ &Header
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ToStructure() failed: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE, Header->JsonRsrcIdentifier.NameSpace.ResourceTypeName);
+ AsciiStrCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE, Header->JsonRsrcIdentifier.NameSpace.MajorVersion);
+ AsciiStrCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE, Header->JsonRsrcIdentifier.NameSpace.MinorVersion);
+ AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE, Header->JsonRsrcIdentifier.NameSpace.ErrataVersion);
+
+ //
+ // Release resource.
+ //
+ JsonStructProtocol->DestoryStructure (JsonStructProtocol, Header);
+ FreePool (JsonText);
+ RedfishFreeResponse (Response.StatusCode, Response.HeaderCount, Response.Headers, Response.Payload);
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Get supported schema list by given specify schema name.
+
+ @param[in] Schema Schema type name.
+ @param[out] SchemaInfo Returned schema information.
+
+ @retval EFI_SUCCESS Schema information is returned successfully.
+ @retval Others Errors occur.
+
+**/
+EFI_STATUS
+GetSupportedSchemaVersion (
+ IN CHAR8 *Schema,
+ OUT REDFISH_SCHEMA_INFO *SchemaInfo
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *SupportSchema;
+ CHAR8 *SchemaName;
+ UINTN Index;
+ UINTN Index2;
+ BOOLEAN Found;
+
+ if (IS_EMPTY_STRING (Schema) || SchemaInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = RedfishPlatformConfigGetSupportedSchema (NULL, &SupportSchema);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, "Supported schema: %a\n", SupportSchema));
+
+ Index = 0;
+ Found = FALSE;
+ SchemaName = SupportSchema;
+ while (TRUE) {
+
+ if (SupportSchema[Index] == ';' || SupportSchema[Index] == '\0') {
+ if (AsciiStrnCmp (&SchemaName[SCHEMA_NAME_PREFIX_OFFSET], Schema, AsciiStrLen (Schema)) == 0) {
+ Found = TRUE;
+ SupportSchema[Index] = '\0';
+ break;
+ }
+
+ SchemaName = &SupportSchema[Index + 1];
+ }
+
+ if (SupportSchema[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ if (Found) {
+
+ AsciiStrCpyS (SchemaInfo->Schema, REDFISH_SCHEMA_STRING_SIZE, Schema);
+
+ //
+ // forward to '.'
+ //
+ Index = 0;
+ while (SchemaName[Index] != '\0' && SchemaName[Index] != '.') {
+ ++Index;
+ }
+ ASSERT (SchemaName[Index] != '\0');
+
+ //
+ // Skip '.' and 'v'
+ //
+ Index += 2;
+
+ //
+ // forward to '_'
+ //
+ Index2 = Index;
+ while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
+ ++Index2;
+ }
+ ASSERT (SchemaName[Index2] != '\0');
+
+ AsciiStrnCpyS (SchemaInfo->Major, REDFISH_SCHEMA_VERSION_SIZE, &SchemaName[Index], (Index2 - Index));
+ Index = Index2;
+
+ //
+ // Skip '_'
+ //
+ ++Index;
+
+ //
+ // forward to '_'
+ //
+ Index2 = Index;
+ while (SchemaName[Index2] != '\0' && SchemaName[Index2] != '_') {
+ ++Index2;
+ }
+ ASSERT (SchemaName[Index2] != '\0');
+
+ AsciiStrnCpyS (SchemaInfo->Minor, REDFISH_SCHEMA_VERSION_SIZE, &SchemaName[Index], (Index2 - Index));
+ Index = Index2;
+
+ //
+ // Skip '_'
+ //
+ ++Index;
+
+ AsciiStrCpyS (SchemaInfo->Errata, REDFISH_SCHEMA_VERSION_SIZE, &SchemaName[Index]);
+ }
+
+ FreePool (SupportSchema);
+
+ return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
+
+/**
+
+ Find Redfish Resource Config Protocol that supports given schema and version.
+
+ @param[in] Schema Schema name.
+ @param[out] Handle Pointer to receive the handle that has EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL
+ installed on it.
+
+ @retval EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL * Pointer to protocol
+ @retval NULL No protocol found.
+
+**/
+EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *
+GetRedfishResourceConfigProtocol (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ OUT EFI_HANDLE *Handle OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *Protocol;
+ REDFISH_SCHEMA_INFO SchemaInfo;
+ BOOLEAN Found;
+
+ if (IS_EMPTY_STRING (Schema->Schema) ||
+ IS_EMPTY_STRING (Schema->Major) ||
+ IS_EMPTY_STRING (Schema->Minor) ||
+ IS_EMPTY_STRING (Schema->Errata)
+ ) {
+ return NULL;
+ }
+
+ if (mRedfishResourceConfigProtocol != NULL) {
+ if (AsciiStrCmp (Schema->Schema, mSchemaInfoCache.Schema) == 0 &&
+ AsciiStrCmp (Schema->Major, mSchemaInfoCache.Major) == 0 &&
+ AsciiStrCmp (Schema->Minor, mSchemaInfoCache.Minor) == 0 &&
+ AsciiStrCmp (Schema->Errata, mSchemaInfoCache.Errata) == 0) {
+ if (Handle != NULL) {
+ *Handle = medfishResourceConfigProtocolHandle;
+ }
+ return mRedfishResourceConfigProtocol;
+ }
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEdkIIRedfishResourceConfigProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Found = FALSE;
+
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEdkIIRedfishResourceConfigProtocolGuid,
+ (VOID **) &Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = Protocol->GetInfo (Protocol, &SchemaInfo);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (AsciiStrCmp (Schema->Schema, SchemaInfo.Schema) == 0 &&
+ AsciiStrCmp (Schema->Major, SchemaInfo.Major) == 0 &&
+ AsciiStrCmp (Schema->Minor, SchemaInfo.Minor) == 0 &&
+ AsciiStrCmp (Schema->Errata, SchemaInfo.Errata) == 0) {
+ Found = TRUE;
+ break;
+ }
+ }
+
+ if (Found) {
+ medfishResourceConfigProtocolHandle = HandleBuffer[Index];
+ mRedfishResourceConfigProtocol = Protocol;
+ CopyMem (&mSchemaInfoCache, Schema, sizeof (REDFISH_SCHEMA_INFO));
+ if (Handle != NULL) {
+ *Handle = HandleBuffer[Index];
+ }
+ }
+ FreePool(HandleBuffer);
+
+ return (Found ? Protocol : NULL);
+}
+
+/**
+ Install EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL
+ on child feature driver handle.
+
+ @param[in] Handle Handle to install EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL.
+ @param[in] InformationExchange Pointer to RESOURCE_INFORMATION_EXCHANGE.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+InstallInterchangeDataProtocol (
+ IN EFI_HANDLE Handle,
+ IN RESOURCE_INFORMATION_EXCHANGE *InformationExchange
+ )
+{
+ EFI_STATUS Status;
+ EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL *Interface;
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEdkIIRedfishFeatureInterchangeDataProtocolGuid,
+ (VOID **)&Interface
+ );
+ if (!EFI_ERROR (Status)) {
+ Interface->ResourceInformationExchage = InformationExchange;
+ return EFI_SUCCESS;
+ }
+ if (Status == EFI_UNSUPPORTED) {
+ mRedfishFeatureInterchangeData.ResourceInformationExchage = InformationExchange;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEdkIIRedfishFeatureInterchangeDataProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *)&mRedfishFeatureInterchangeData
+ );
+ }
+ return Status;
+}
+
+/**
+ Set Configure language of this resource in the
+ RESOURCE_INFORMATION_EXCHANGE structure.
+
+ @param[in] ConfigLangList Pointer to REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST.
+
+ @retval EFI_SUCCESS Configure language is set.
+ @retval EFI_UNSUPPORTED EdkIIRedfishFeatureInterchangeDataProtocol is not found.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceSetConfigureLang (
+ REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST *ConfigLangList
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL *Interface;
+
+ Status = gBS->HandleProtocol (
+ medfishResourceConfigProtocolHandle,
+ &gEdkIIRedfishFeatureInterchangeDataProtocolGuid,
+ (VOID **)&Interface
+ );
+ if (EFI_ERROR (Status)){
+ DEBUG ((DEBUG_ERROR, "%a, EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL is not installed %r", __FUNCTION__, Status));
+ return Status;
+ }
+ Interface->ResourceInformationExchage->ReturnedInformation.Type = InformationTypeCollectionMemberConfigLanguage;
+ Interface->ResourceInformationExchage->ReturnedInformation.ConfigureLanguageList.Count = ConfigLangList->Count;
+ Interface->ResourceInformationExchage->ReturnedInformation.ConfigureLanguageList.List =
+ AllocateZeroPool(sizeof (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG) * ConfigLangList->Count);
+ if (Interface->ResourceInformationExchage->ReturnedInformation.ConfigureLanguageList.List == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, Fail to allocate memory for REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG.\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ for (Index = 0; Index < ConfigLangList->Count; Index++) {
+ Interface->ResourceInformationExchage->ReturnedInformation.ConfigureLanguageList.List [Index].Index = ConfigLangList->List[Index].Index;
+ Interface->ResourceInformationExchage->ReturnedInformation.ConfigureLanguageList.List [Index].ConfigureLang =
+ (EFI_STRING)AllocateCopyPool(StrSize(ConfigLangList->List[Index].ConfigureLang), (VOID *)ConfigLangList->List[Index].ConfigureLang);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Provising redfish resource by given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri Target URI to create resource.
+ @param[in] InformationExchange Pointer to RESOURCE_INFORMATION_EXCHANGE.
+ @param[in] HttpPostMode TRUE if resource does not exist, HTTP POST method is used.
+ FALSE if the resource exist but some of properties are missing,
+ HTTP PUT method is used.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigProvisionging (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri,
+ IN RESOURCE_INFORMATION_EXCHANGE *InformationExchange,
+ IN BOOLEAN HttpPostMode
+ )
+{
+ EFI_HANDLE Handle;
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *protocol;
+
+ protocol = GetRedfishResourceConfigProtocol (Schema, &Handle);
+ if (protocol == NULL || Handle == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Install EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL on the child
+ // feature driver handle.
+ //
+ InstallInterchangeDataProtocol (Handle, InformationExchange);
+ return protocol->Provisioning(protocol, Uri, HttpPostMode);
+}
+
+/**
+ Consume resource from given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigConsume (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ )
+{
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *protocol;
+
+ protocol = GetRedfishResourceConfigProtocol (Schema, NULL);
+ if (protocol == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return protocol->Consume (protocol, Uri);
+}
+
+
+/**
+ Update resource to given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigUpdate (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ )
+{
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *protocol;
+
+ protocol = GetRedfishResourceConfigProtocol (Schema, NULL);
+ if (protocol == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return protocol->Update (protocol, Uri);
+}
+
+/**
+ Check resource on given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigCheck (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri
+ )
+{
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *protocol;
+
+ protocol = GetRedfishResourceConfigProtocol (Schema, NULL);
+ if (protocol == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return protocol->Check (protocol, Uri);
+}
+
+/**
+ Identify resource on given URI.
+
+ @param[in] Schema Redfish schema information.
+ @param[in] Uri The target URI to consume.
+ @param[in] InformationExchange Pointer to RESOURCE_INFORMATION_EXCHANGE.
+
+ @retval EFI_SUCCESS This is target resource which we want to handle.
+ @retval EFI_UNSUPPORTED This is not the target resource.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EdkIIRedfishResourceConfigIdentify (
+ IN REDFISH_SCHEMA_INFO *Schema,
+ IN EFI_STRING Uri,
+ IN RESOURCE_INFORMATION_EXCHANGE *InformationExchange
+ )
+{
+ EFI_HANDLE Handle;
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *protocol;
+
+ protocol = GetRedfishResourceConfigProtocol (Schema, &Handle);
+ if (protocol == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Install EDKII_REDFISH_FEATURE_INTERCHANGE_DATA_PROTOCOL on the child
+ // feature driver handle.
+ //
+ InstallInterchangeDataProtocol (Handle, InformationExchange);
+ return protocol->Identify (protocol, Uri);
+}
+
+/**
+
+ Initial resource config library instace.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCEESS Install Boot manager menu success.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceConfigConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mRedfishResourceConfigProtocol = NULL;
+ ZeroMem (&mSchemaInfoCache, sizeof (REDFISH_SCHEMA_INFO));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release allocated resource.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceConfigDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mRedfishResourceConfigProtocol = NULL;
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
new file mode 100644
index 0000000000..0da3423d26
--- /dev/null
+++ b/RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
@@ -0,0 +1,49 @@
+## @file
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = EdkIIRedfishResourceConfigLib
+ FILE_GUID = B41884F6-693B-4ADE-9558-5C220A24A025
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EdkIIRedfishResourceConfigLib| DXE_DRIVER
+ CONSTRUCTOR = RedfishResourceConfigConstructor
+ DESTRUCTOR = RedfishResourceConfigDestructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ EdkIIRedfishResourceConfigLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ PcdLib
+ MemoryAllocationLib
+ RedfishFeatureUtilityLib
+ RedfishPlatformConfigLib
+
+[Protocols]
+ gEdkIIRedfishResourceConfigProtocolGuid ## CONSUMES ##
+ gEdkIIRedfishFeatureInterchangeDataProtocolGuid ## CONSUMES ##
+
+[Pcd]
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize
+
diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInternal.h b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInternal.h
index b8f4df7bcd..7d38d327ef 100644
--- a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInternal.h
+++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityInternal.h
@@ -34,7 +34,8 @@
#define INDEX_STRING_SIZE 16
#define IS_EMPTY_STRING(a) (a == NULL || a[0] == '\0')
#define INDEX_STRING L"{%d}"
-#define SCHEMA_NAME_PREFIX_OFFSET 15 // x-uefi-redfish-
+#define SCHEMA_NAME_PREFIX "x-uefi-redfish-"
+#define SCHEMA_NAME_PREFIX_OFFSET (AsciiStrLen (SCHEMA_NAME_PREFIX))
#define REDFISH_SYSTEM_ROOT_PATH "/v1/Systems[UUID~%g]"
#define MAX_CONF_LANG_LEN 128

diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/RedfishClientLibs.dsc.inc
index 1cf0406912..8acb479170 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -28,5 +28,6 @@
RedfishContentCodingLib|RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf
ConverterCommonLib|RedfishClientPkg/ConverterLib/edk2library/ConverterCommonLib/ConverterCommonLib.inf

+ EdkIIRedfishResourceConfigLib|RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
RedfishEventLib|RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
RedfishVersionLib|RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index 2ce51d14af..9d18c42c24 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -1,7 +1,7 @@
## @file
# Redfish Client Package
#
-# (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
##
@@ -21,6 +21,7 @@

[LibraryClasses]
RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h
+ EdkIIRedfishResourceConfigLib|Include/Library/EdkIIRedfishResourceConfigLib.h
RedfishEventLib|Include/Library/RedfishEventLib.h
RedfishVersionLib|Include/Library/RedfishVersionLib.h

@@ -36,6 +37,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/EdkIIRedfishInterchangeData.h
+ gEdkIIRedfishFeatureInterchangeDataProtocolGuid = { 0x4B8FF71C, 0x4A7B, 0x9478, { 0xB7, 0x81, 0x35, 0x9B, 0x0A, 0xF2, 0x00, 0x91 } }

[Guids]
## Include/Guid/RedfishClientPkgTokenSpace.h
--
2.32.0.windows.2


[edk2-staging][PATCH v3 03/15] edk2-staging/RedfishClientPkg: Update Redfish Resource Config Protocol

Nickle Wang
 

Update Redfish resource config protocol to support Identify action in
order to identify remote resource and see if this is resource belongs
to current owner or not. Use unicode string instead of ASCII string for
all interfaces to align with HTTP interface.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../EdkIIRedfishResourceConfigProtocol.h | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishResourceConfigProtocol.h b/RedfishClientPkg/Include/Protocol/EdkIIRedfishResourceConfigProtocol.h
index d6c41dda52..574c82c442 100644
--- a/RedfishClientPkg/Include/Protocol/EdkIIRedfishResourceConfigProtocol.h
+++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishResourceConfigProtocol.h
@@ -1,7 +1,7 @@
/** @file
This file defines the EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL interface.

- (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

@@ -29,7 +29,7 @@ typedef
EFI_STATUS
(EFIAPI *EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_PROVISIONING) (
IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This,
- IN CHAR8 *Uri,
+ IN EFI_STRING Uri,
IN BOOLEAN HttpPostMode
);

@@ -47,7 +47,7 @@ typedef
EFI_STATUS
(EFIAPI *EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_CONSUME) (
IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This,
- IN CHAR8 *Uri
+ IN EFI_STRING Uri
);


@@ -65,7 +65,7 @@ typedef
EFI_STATUS
(EFIAPI *EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_UPDATE) (
IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This,
- IN CHAR8 *Uri
+ IN EFI_STRING Uri
);


@@ -83,7 +83,25 @@ typedef
EFI_STATUS
(EFIAPI *EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_CHECK) (
IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This,
- IN CHAR8 *Uri
+ IN EFI_STRING Uri
+ );
+
+/**
+ Identify resource on given URI.
+
+ @param[in] This Pointer to EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL instance.
+ @param[in] Uri The target URI to consume.
+
+ @retval EFI_SUCCESS This is target resource which we want to handle.
+ @retval EFI_UNSUPPORTED This is not the target resource.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_IDENTIFY) (
+ IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This,
+ IN EFI_STRING Uri
);

//
@@ -121,6 +139,7 @@ struct _EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL {
EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_CONSUME Consume;
EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_UPDATE Update;
EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_CHECK Check;
+ EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_IDENTIFY Identify;
EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL_GET_INFO GetInfo;
};

--
2.32.0.windows.2


[edk2-staging][PATCH v3 02/15] edk2-staging/RedfishClientPkg: Introduce Redfish version library

Nickle Wang
 

Add RedfishVersionLib in order to get Redfish version hosted at BMC.
When there is trouble to get Redfish support version, the default
version is retrieved from pre-defined PCD value.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Include/Library/RedfishVersionLib.h | 30 +++
RedfishClientPkg/Include/RedfishBase.h | 21 ++
.../RedfishVersionLib/RedfishVersionLib.c | 203 ++++++++++++++++++
.../RedfishVersionLib/RedfishVersionLib.inf | 50 +++++
RedfishClientPkg/RedfishClientLibs.dsc.inc | 1 +
RedfishClientPkg/RedfishClientPkg.dec | 4 +-
6 files changed, 308 insertions(+), 1 deletion(-)
create mode 100644 RedfishClientPkg/Include/Library/RedfishVersionLib.h
create mode 100644 RedfishClientPkg/Include/RedfishBase.h
create mode 100644 RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
create mode 100644 RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf

diff --git a/RedfishClientPkg/Include/Library/RedfishVersionLib.h b/RedfishClientPkg/Include/Library/RedfishVersionLib.h
new file mode 100644
index 0000000000..319f22bd37
--- /dev/null
+++ b/RedfishClientPkg/Include/Library/RedfishVersionLib.h
@@ -0,0 +1,30 @@
+/** @file
+ This file defines the Redfish version Library interface.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_VERSION_LIB_H_
+#define REDFISH_VERSION_LIB_H_
+
+/**
+ Query HTTP request to BMC with given redfish service and return redfish
+ version information. If there is troulbe to get Redfish version on BMC,
+ The value of PcdDefaultRedfishVersion is returned.
+
+ It's call responsibility to release returned buffer.
+
+ @param[in] Service Redfish service instance
+
+ @retval EFI_STRING Redfish version string. NULL while error occurs.
+
+**/
+EFI_STRING
+RedfishGetVersion (
+ IN REDFISH_SERVICE *Service
+ );
+
+#endif
diff --git a/RedfishClientPkg/Include/RedfishBase.h b/RedfishClientPkg/Include/RedfishBase.h
new file mode 100644
index 0000000000..cf320bb0eb
--- /dev/null
+++ b/RedfishClientPkg/Include/RedfishBase.h
@@ -0,0 +1,21 @@
+/** @file
+ Redfish base header file.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EFI_REDFISH_BASE_H_
+#define EFI_REDFISH_BASE_H_
+
+#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
+#define REDFISH_DEBUG_TRACE DEBUG_INFO
+
+///
+/// This GUID is used for an EFI Variable that stores the Redfish data.
+///
+EFI_GUID mRedfishVariableGuid = {0x91c46a3d, 0xed1a, 0x477b, {0xa5, 0x33, 0x87, 0x2d, 0xcd, 0xb0, 0xfc, 0xc1}};
+
+#endif
diff --git a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
new file mode 100644
index 0000000000..0a2ace7726
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
@@ -0,0 +1,203 @@
+/** @file
+ Redfish version library implementation
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <RedfishBase.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/RedfishLib.h>
+#include <Library/JsonLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/RedfishVersionLib.h>
+
+#define REDFISH_VERSION_DEFAULT_STRING L"v1"
+#define REDFISH_ROOT_URI "/redfish"
+
+REDFISH_SERVICE *mCacheService;
+EFI_STRING mVersionCache;
+UINTN mVersionStringSize;
+
+/**
+ Cache the redfish service version for later use so we don't have to query
+ HTTP request everytime.
+
+ @param[in] Service Redfish service instance
+ @param[in] Version Version string to cache
+
+ @retval EFI_SUCCESS Version is saved in cache successfully.
+ @retval Others
+
+**/
+EFI_STATUS
+CacheVersion (
+ IN REDFISH_SERVICE *Service,
+ IN EFI_STRING Version
+ )
+{
+ if (Service == NULL || IS_EMPTY_STRING (Version)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mCacheService == Service) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ mCacheService = Service;
+ if (mVersionCache != NULL) {
+ FreePool (mVersionCache);
+ }
+
+ mVersionStringSize = StrSize (Version);
+ mVersionCache = AllocateCopyPool (mVersionStringSize, Version);
+ if (mVersionCache == NULL) {
+ mCacheService = NULL;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Query HTTP request to BMC with given redfish service and return redfish
+ version information. If there is troulbe to get Redfish version on BMC,
+ The value of PcdDefaultRedfishVersion is returned.
+
+ It's call responsibility to release returned buffer.
+
+ @param[in] Service Redfish service instance
+
+ @retval EFI_STRING Redfish version string. NULL while error occurs.
+
+**/
+EFI_STRING
+RedfishGetVersion (
+ IN REDFISH_SERVICE *Service
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING VersionString;
+ REDFISH_RESPONSE Response;
+ EDKII_JSON_VALUE JsonValue;
+ EDKII_JSON_VALUE N;
+ CHAR8 *Key;
+ EDKII_JSON_VALUE Value;
+
+ VersionString = NULL;
+
+ if (Service == NULL) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Use cache to prevent HTTP connection.
+ //
+ if (Service == mCacheService) {
+ return AllocateCopyPool (mVersionStringSize, mVersionCache);
+ }
+
+ //
+ // Get resource from redfish service.
+ //
+ Status = RedfishGetByUri (
+ Service,
+ REDFISH_ROOT_URI,
+ &Response
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RedfishGetByService to %a failed: %r\n", __FUNCTION__, REDFISH_ROOT_URI, Status));
+ if (Response.Payload != NULL) {
+ RedfishDumpPayload (Response.Payload);
+ RedfishFreeResponse (
+ NULL,
+ 0,
+ NULL,
+ Response.Payload
+ );
+ Response.Payload = NULL;
+ }
+
+ goto ON_ERROR;
+ }
+
+ JsonValue = RedfishJsonInPayload (Response.Payload);
+ if (JsonValue == NULL || !JsonValueIsObject (JsonValue)) {
+ goto ON_ERROR;
+ }
+
+ EDKII_JSON_OBJECT_FOREACH_SAFE (JsonValue, N, Key, Value) {
+ if (Key[0] == 'v' && JsonValueIsString (Value)) {
+ VersionString = JsonValueGetUnicodeString (Value);
+ break;
+ }
+ }
+
+ if (VersionString != NULL) {
+ CacheVersion (Service, VersionString);
+ return VersionString;
+ }
+
+ON_ERROR:
+
+ VersionString = (CHAR16 *)PcdGetPtr (PcdDefaultRedfishVersion);
+ if (VersionString == NULL) {
+ VersionString = REDFISH_VERSION_DEFAULT_STRING;
+ }
+
+ return AllocateCopyPool (StrSize (VersionString), VersionString);
+}
+
+/**
+
+ Initial redfish version library instace.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCEESS Install Boot manager menu success.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishVersionLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mCacheService = NULL;
+ mVersionCache = NULL;
+ mVersionStringSize = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Release allocated resource.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishVersionLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (mVersionCache != NULL) {
+ FreePool (mVersionCache);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
new file mode 100644
index 0000000000..34d13d64f1
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
@@ -0,0 +1,50 @@
+## @file
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = RedfishVersionLib
+ FILE_GUID = 396A7508-B611-49F7-9C81-DAD96B526B61
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishVersionLib| DXE_DRIVER
+ CONSTRUCTOR = RedfishVersionLibConstructor
+ DESTRUCTOR = RedfishVersionLibDestructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ RedfishVersionLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MemoryAllocationLib
+ PcdLib
+ RedfishLib
+ JsonLib
+
+[Protocols]
+
+[Pcd]
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdDefaultRedfishVersion
+
+[BuildOptions]
+ #
+ # NOTE: /wd4706 disables the following Visual Studio compiler warning in Jansson:
+ # "C4706: assignment within conditional expression"
+ #
+ MSFT:*_*_*_CC_FLAGS = /wd4706
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/RedfishClientLibs.dsc.inc
index ce1c27d884..1cf0406912 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -29,3 +29,4 @@
ConverterCommonLib|RedfishClientPkg/ConverterLib/edk2library/ConverterCommonLib/ConverterCommonLib.inf

RedfishEventLib|RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
+ RedfishVersionLib|RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index 39b2f5baf8..2ce51d14af 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -22,6 +22,7 @@
[LibraryClasses]
RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h
RedfishEventLib|Include/Library/RedfishEventLib.h
+ RedfishVersionLib|Include/Library/RedfishVersionLib.h

[LibraryClasses.Common.Private]
## @libraryclass Redfish Helper Library
@@ -52,4 +53,5 @@
# { 0x7CE88FB3, 0x4BD7, 0x4679, { 0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B }}
#
gEfiRedfishClientPkgTokenSpaceGuid.PcdEdkIIRedfishFeatureDriverStartupEventGuid|{0xB3, 0x8F, 0xE8, 0x7C, 0xD7, 0x4B, 0x79, 0x46, 0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B}|VOID*|0x10000003
-
+ ## Default Redfish version string
+ gEfiRedfishClientPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x10000004
--
2.32.0.windows.2


[edk2-staging][PATCH v3 01/15] edk2-staging/RedfishClientPkg: Introduce Redfish event library

Nickle Wang
 

Add RedfishEventLib to handle Redfish event. There are two events
defined in this library. One is the event before feature driver
provisioning and the other one is the event after all provisioning
is finished.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Include/Guid/RedfishClientEventGroup.h | 27 ++++
.../Include/Library/RedfishEventLib.h | 77 ++++++++++
.../Library/RedfishEventLib/RedfishEventLib.c | 139 ++++++++++++++++++
.../RedfishEventLib/RedfishEventLib.inf | 42 ++++++
RedfishClientPkg/RedfishClientLibs.dsc.inc | 1 +
RedfishClientPkg/RedfishClientPkg.dec | 5 +
6 files changed, 291 insertions(+)
create mode 100644 RedfishClientPkg/Include/Guid/RedfishClientEventGroup.h
create mode 100644 RedfishClientPkg/Include/Library/RedfishEventLib.h
create mode 100644 RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.c
create mode 100644 RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf

diff --git a/RedfishClientPkg/Include/Guid/RedfishClientEventGroup.h b/RedfishClientPkg/Include/Guid/RedfishClientEventGroup.h
new file mode 100644
index 0000000000..0d88dd4726
--- /dev/null
+++ b/RedfishClientPkg/Include/Guid/RedfishClientEventGroup.h
@@ -0,0 +1,27 @@
+/** @file
+ GUID for Redfish Client Event Group GUID
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_CLIENT_EVENT_GROUP_GUID_H_
+#define REDFISH_CLIENT_EVENT_GROUP_GUID_H_
+
+#define REDFISH_CLIENT_FEATURE_READY_TO_PROVISIONING_GUID \
+ { \
+ 0x77E4FC1C, 0x2428, 0x47EE, { 0x9E, 0xEC, 0x8B, 0x77, 0xEF, 0x9D, 0x4E, 0xF0 } \
+ }
+
+extern EFI_GUID gEfiRedfishClientFeatureReadyToProvisioningGuid;
+
+#define REDFISH_CLIENT_FEATURE_AFTER_PROVISIONING_GUID \
+ { \
+ 0xE547CB6F, 0x306F, 0x4226, { 0xAB, 0x70, 0xA0, 0x6E, 0x26, 0xF1, 0x2E, 0xD0 } \
+ }
+
+extern EFI_GUID gEfiRedfishClientFeatureAfterProvisioningGuid;
+
+#endif
diff --git a/RedfishClientPkg/Include/Library/RedfishEventLib.h b/RedfishClientPkg/Include/Library/RedfishEventLib.h
new file mode 100644
index 0000000000..1f3d0acf19
--- /dev/null
+++ b/RedfishClientPkg/Include/Library/RedfishEventLib.h
@@ -0,0 +1,77 @@
+/** @file
+ This file defines the Redfish event library interface.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_EVENT_LIB_H_
+#define REDFISH_EVENT_LIB_H_
+
+#include <Uefi.h>
+
+/**
+ Create an EFI event before Redfish provisioning start.
+
+ @param NotifyFunction The notification function to call when the event is signaled.
+ @param NotifyContext The content to pass to NotifyFunction when the event is signaled.
+ @param ReadyToProvisioningEvent Returns the EFI event returned from gBS->CreateEvent(Ex).
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateReadyToProvisioningEvent (
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *ReadyToProvisioningEvent
+ );
+
+/**
+ Create an EFI event after Redfish provisioning finished.
+
+ @param NotifyFunction The notification function to call when the event is signaled.
+ @param NotifyContext The content to pass to NotifyFunction when the event is signaled.
+ @param ReadyToProvisioningEvent Returns the EFI event returned from gBS->CreateEvent(Ex).
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateAfterProvisioningEvent (
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *ReadyToProvisioningEvent
+ );
+
+/**
+ Signal ready to provisioning event.
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+SignalReadyToProvisioningEvent (
+ IN VOID
+ );
+
+/**
+ Signal after provisioning event.
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+SignalAfterProvisioningEvent (
+ IN VOID
+ );
+
+#endif
diff --git a/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.c b/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.c
new file mode 100644
index 0000000000..0a8483c371
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.c
@@ -0,0 +1,139 @@
+/** @file
+ Redfish event library to deliver Redfish specific event.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/RedfishClientEventGroup.h>
+
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RedfishEventLib.h>
+
+/**
+ Create an EFI event before Redfish provisioning start.
+
+ @param NotifyFunction The notification function to call when the event is signaled.
+ @param NotifyContext The content to pass to NotifyFunction when the event is signaled.
+ @param ReadyToProvisioningEvent Returns the EFI event returned from gBS->CreateEvent(Ex).
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateReadyToProvisioningEvent (
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *ReadyToProvisioningEvent
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ (NotifyFunction == NULL ? EfiEventEmptyFunction : NotifyFunction),
+ NotifyContext,
+ &gEfiRedfishClientFeatureReadyToProvisioningGuid,
+ ReadyToProvisioningEvent
+ );
+
+ return Status;
+}
+
+/**
+ Create an EFI event after Redfish provisioning finished.
+
+ @param NotifyFunction The notification function to call when the event is signaled.
+ @param NotifyContext The content to pass to NotifyFunction when the event is signaled.
+ @param ReadyToProvisioningEvent Returns the EFI event returned from gBS->CreateEvent(Ex).
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateAfterProvisioningEvent (
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *ReadyToProvisioningEvent
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ (NotifyFunction == NULL ? EfiEventEmptyFunction : NotifyFunction),
+ NotifyContext,
+ &gEfiRedfishClientFeatureAfterProvisioningGuid,
+ ReadyToProvisioningEvent
+ );
+
+ return Status;
+}
+
+/**
+ Signal ready to provisioning event.
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+SignalReadyToProvisioningEvent (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ Status = CreateReadyToProvisioningEvent (NULL, NULL, &Event);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create after provisioning event\n", __FUNCTION__));
+ return Status;
+ }
+
+ gBS->SignalEvent (Event);
+ gBS->CloseEvent (Event);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Signal after provisioning event.
+
+ @retval EFI_SUCCESS Event was created.
+ @retval Other Event was not created.
+
+**/
+EFI_STATUS
+SignalAfterProvisioningEvent (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ Status = CreateAfterProvisioningEvent (NULL, NULL, &Event);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create after provisioning event\n", __FUNCTION__));
+ return Status;
+ }
+
+ gBS->SignalEvent (Event);
+ gBS->CloseEvent (Event);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf b/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
new file mode 100644
index 0000000000..a9d475c27c
--- /dev/null
+++ b/RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = RedfishEventLib
+ FILE_GUID = C4F7E27D-2338-43EA-9D1F-D10960E36521
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishEventLib| DXE_DRIVER UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ RedfishEventLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+ UefiLib
+
+[Protocols]
+
+[Pcd]
+
+[Guids]
+ gEfiRedfishClientFeatureReadyToProvisioningGuid
+ gEfiRedfishClientFeatureAfterProvisioningGuid
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/RedfishClientLibs.dsc.inc
index 5467acedd0..ce1c27d884 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -28,3 +28,4 @@
RedfishContentCodingLib|RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf
ConverterCommonLib|RedfishClientPkg/ConverterLib/edk2library/ConverterCommonLib/ConverterCommonLib.inf

+ RedfishEventLib|RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index 09df062dd3..39b2f5baf8 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -21,6 +21,7 @@

[LibraryClasses]
RedfishFeatureUtilityLib|Include/Library/RedfishFeatureUtilityLib.h
+ RedfishEventLib|Include/Library/RedfishEventLib.h

[LibraryClasses.Common.Private]
## @libraryclass Redfish Helper Library
@@ -39,6 +40,10 @@
## Include/Guid/RedfishClientPkgTokenSpace.h
gEfiRedfishClientPkgTokenSpaceGuid = { 0x8c444dae, 0x728b, 0x48ee, { 0x9e, 0x19, 0x8f, 0x0a, 0x3d, 0x4e, 0x9c, 0xc8 } }

+ ## Include/Guid/RedfishClientEventGroup.h
+ gEfiRedfishClientFeatureReadyToProvisioningGuid = { 0x77E4FC1C, 0x2428, 0x47EE, { 0x9E, 0xEC, 0x8B, 0x77, 0xEF, 0x9D, 0x4E, 0xF0 } }
+ gEfiRedfishClientFeatureAfterProvisioningGuid = { 0xE547CB6F, 0x306F, 0x4226, { 0xAB, 0x70, 0xA0, 0x6E, 0x26, 0xF1, 0x2E, 0xD0 } }
+
[PcdsFixedAtBuild]
gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize|32|UINT32|0x10000001
gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize|8|UINT32|0x10000002
--
2.32.0.windows.2


[edk2-staging][PATCH v3 00/15] Update RedfishClientpkg

Nickle Wang
 

In this series of patch files, additional three feature drivers are
enabled. Corresponding libraries and protocols are introduced to help
performing Redfish operation like provisioning, consuming and updating
Redfish resource between UEFI HII driver and Redfish service hosted at
BMC side.

Nickle Wang (15):
edk2-staging/RedfishClientPkg: Introduce Redfish event library
edk2-staging/RedfishClientPkg: Introduce Redfish version library
edk2-staging/RedfishClientPkg: Update Redfish Resource Config Protocol
edk2-staging/RedfishClientPkg: Introduce Redfish resource config
library
edk2-staging/RedfishClientPkg: Introduce resource identify library
edk2-staging/RedfishClientPkg: Introduce RedfishConfigLangMap driver
edk2-staging/RedfishClientPkg: Update ETag driver
edk2-staging/RedfishClientPkg: Update Redfish feature core driver
edk2-staging/RedfishClientPkg: Update RedfishLib
edk2-staging/RedfishClientPkg: Update Redfish feature utility library
edk2-staging/RedfishClientPkg: Rename RedfishMemoryCollection driver
edk2-staging/RedfishClientPkg: Rename Memory feature driver
edk2-staging/RedfishClientPkg: Introduce Computer System collection
driver
edk2-staging/RedfishClientPkg: Introduce Computer System feature
driver
edk2-staging/RedfishClientPkg: Introduce Bios feature driver

.../Features/Bios/v1_0_9/Common/BiosCommon.c | 741 ++++
.../Features/Bios/v1_0_9/Common/BiosCommon.h | 30 +
.../Features/Bios/v1_0_9/Dxe/BiosDxe.c | 789 ++++
.../Features/Bios/v1_0_9/Dxe/BiosDxe.inf | 52 +
.../v1_5_0/Common/ComputerSystemCommon.c | 1614 ++++++++
.../v1_5_0/Common/ComputerSystemCommon.h | 27 +
.../v1_5_0/Dxe/ComputerSystemDxe.c | 645 +++
.../v1_5_0/Dxe/ComputerSystemDxe.inf | 51 +
.../ComputerSystemCollectionDxe.c | 667 +++
.../ComputerSystemCollectionDxe.h | 21 +
.../ComputerSystemCollectionDxe.inf | 56 +
.../{RedfishMemoryCommon.c => MemoryCommon.c} | 1194 +++---
.../{RedfishMemoryCommon.h => MemoryCommon.h} | 2 +-
.../Dxe/{RedfishMemoryDxe.c => MemoryDxe.c} | 138 +-
.../{RedfishMemoryDxe.inf => MemoryDxe.inf} | 21 +-
.../MemoryCollectionDxe.c} | 259 +-
.../MemoryCollectionDxe.h} | 7 +-
.../MemoryCollectionDxe.inf} | 19 +-
.../Include/Guid/RedfishClientEventGroup.h | 27 +
.../Library/EdkIIRedfishResourceConfigLib.h | 163 +
.../Include/Library/RedfishEventLib.h | 77 +
.../Library/RedfishFeatureUtilityLib.h | 756 +++-
.../Library/RedfishResourceIdentifyLib.h | 29 +
.../Include/Library/RedfishVersionLib.h | 30 +
.../EdkIIRedfishConfigLangMapProtocol.h | 88 +
.../Include/Protocol/EdkIIRedfishFeature.h | 20 +-
.../Protocol/EdkIIRedfishInterchangeData.h | 52 +
.../EdkIIRedfishResourceConfigProtocol.h | 29 +-
RedfishClientPkg/Include/RedfishBase.h | 21 +
.../Include/RedfishCollectionCommon.h | 14 +-
.../RedfishJsonStructure/RedfishCsCommon.h | 14 +
.../Include/RedfishResourceCommon.h | 38 +-
.../EdkIIRedfishResourceConfigLib.c | 593 +++
.../EdkIIRedfishResourceConfigLib.inf | 49 +
.../Library/RedfishEventLib/RedfishEventLib.c | 139 +
.../RedfishEventLib/RedfishEventLib.inf | 42 +
.../RedfishFeatureUtilityInternal.h | 19 +-
.../RedfishFeatureUtilityLib.c | 3662 +++++++++++++----
.../RedfishFeatureUtilityLib.inf | 20 +-
.../RedfishResourceIdentifyLibComuterSystem.c | 164 +
...edfishResourceIdentifyLibComuterSystem.inf | 39 +
.../RedfishResourceIdentifyLibNull.c | 37 +
.../RedfishResourceIdentifyLibNull.inf | 32 +
.../RedfishVersionLib/RedfishVersionLib.c | 203 +
.../RedfishVersionLib/RedfishVersionLib.inf | 50 +
.../PrivateLibrary/RedfishLib/RedfishLib.c | 12 +-
.../edk2libredfish/include/redfishPayload.h | 5 +-
.../edk2libredfish/include/redfishService.h | 5 +-
.../RedfishLib/edk2libredfish/src/payload.c | 90 +-
.../RedfishLib/edk2libredfish/src/service.c | 554 ++-
RedfishClientPkg/RedfishClient.fdf.inc | 13 +-
.../RedfishClientComponents.dsc.inc | 16 +-
RedfishClientPkg/RedfishClientLibs.dsc.inc | 13 +-
RedfishClientPkg/RedfishClientPkg.dec | 19 +-
.../RedfishConfigLangMapDxe.c | 810 ++++
.../RedfishConfigLangMapDxe.h | 71 +
.../RedfishConfigLangMapDxe.inf | 46 +
.../RedfishETagDxe/RedfishETagDxe.c | 10 +-
.../RedfishETagDxe/RedfishETagDxe.h | 4 +-
.../RedfishFeatureCoreDxe.c | 290 +-
.../RedfishFeatureCoreDxe.h | 20 +-
.../RedfishFeatureCoreDxe.inf | 5 +-
62 files changed, 12942 insertions(+), 1781 deletions(-)
create mode 100644 RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c
create mode 100644 RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.h
create mode 100644 RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c
create mode 100644 RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
create mode 100644 RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.c
create mode 100644 RedfishClientPkg/Features/ComputerSystem/v1_5_0/Common/ComputerSystemCommon.h
create mode 100644 RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c
create mode 100644 RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.inf
create mode 100644 RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.c
create mode 100644 RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.h
create mode 100644 RedfishClientPkg/Features/ComputerSystemCollectionDxe/ComputerSystemCollectionDxe.inf
rename RedfishClientPkg/Features/Memory/V1_7_1/Common/{RedfishMemoryCommon.c => MemoryCommon.c} (64%)
rename RedfishClientPkg/Features/Memory/V1_7_1/Common/{RedfishMemoryCommon.h => MemoryCommon.h} (89%)
rename RedfishClientPkg/Features/Memory/V1_7_1/Dxe/{RedfishMemoryDxe.c => MemoryDxe.c} (75%)
rename RedfishClientPkg/Features/Memory/V1_7_1/Dxe/{RedfishMemoryDxe.inf => MemoryDxe.inf} (57%)
rename RedfishClientPkg/Features/{RedfishMemoryCollectionDxe/RedfishMemoryCollectionDxe.c => MemoryCollectionDxe/MemoryCollectionDxe.c} (66%)
rename RedfishClientPkg/Features/{RedfishMemoryCollectionDxe/RedfishMemoryCollectionDxe.h => MemoryCollectionDxe/MemoryCollectionDxe.h} (64%)
rename RedfishClientPkg/Features/{RedfishMemoryCollectionDxe/RedfishMemoryCollectionDxe.inf => MemoryCollectionDxe/MemoryCollectionDxe.inf} (71%)
create mode 100644 RedfishClientPkg/Include/Guid/RedfishClientEventGroup.h
create mode 100644 RedfishClientPkg/Include/Library/EdkIIRedfishResourceConfigLib.h
create mode 100644 RedfishClientPkg/Include/Library/RedfishEventLib.h
create mode 100644 RedfishClientPkg/Include/Library/RedfishResourceIdentifyLib.h
create mode 100644 RedfishClientPkg/Include/Library/RedfishVersionLib.h
create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishConfigLangMapProtocol.h
create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishInterchangeData.h
create mode 100644 RedfishClientPkg/Include/RedfishBase.h
create mode 100644 RedfishClientPkg/Include/RedfishJsonStructure/RedfishCsCommon.h
create mode 100644 RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.c
create mode 100644 RedfishClientPkg/Library/EdkIIRedfishResourceConfigLib/EdkIIRedfishResourceConfigLib.inf
create mode 100644 RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.c
create mode 100644 RedfishClientPkg/Library/RedfishEventLib/RedfishEventLib.inf
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.c
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibComuterSystem/v1_5_0/RedfishResourceIdentifyLibComuterSystem.inf
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.c
create mode 100644 RedfishClientPkg/Library/RedfishResourceIdentifyLibNull/RedfishResourceIdentifyLibNull.inf
create mode 100644 RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.c
create mode 100644 RedfishClientPkg/Library/RedfishVersionLib/RedfishVersionLib.inf
create mode 100644 RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.c
create mode 100644 RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.h
create mode 100644 RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf

--
2.32.0.windows.2


Re: [Patch 0/2] Remove MptScsi and PvScsi reviewers

Yao, Jiewen
 

Reviewed-by: Jiewen Yao <Jiewen.yao@...>

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, July 27, 2022 3:47 AM
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@...>; Leif Lindholm
<quic_llindhol@...>; Ard Biesheuvel <ardb+tianocore@...>;
Yao, Jiewen <jiewen.yao@...>; Justen, Jordan L
<jordan.l.justen@...>; Gerd Hoffmann <kraxel@...>
Subject: [Patch 0/2] Remove MptScsi and PvScsi reviewers

The email addresses for the reviewers of the MptScsi and
PvScsi in the OvmfPkg are no longer valid. Remove the
reviewers for the MptScsi and PvScsi drivers until new
maintainers/reviewers can be identified.

Cc: Andrew Fish <afish@...>
Cc: Leif Lindholm <quic_llindhol@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>

Michael D Kinney (2):
OvmfPkg: Change default to disable MptScsi and PvScsi
Maintainers.txt: Remove MptScsi and PvScsi reviewers

Maintainers.txt | 6 ------
OvmfPkg/AmdSev/AmdSevX64.dsc | 4 ++--
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++--
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 ++--
OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++--
OvmfPkg/OvmfPkgX64.dsc | 4 ++--
8 files changed, 14 insertions(+), 20 deletions(-)

--
2.32.0.windows.1


回复: [edk2-devel] Event: TianoCore Bug Triage - APAC / NAMO - 07/26/2022 #cal-reminder

gaoliming
 

Few issues are reported this week. Let’s cancel the meeting.

 

Thanks

Liming

发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Group Notification
发送时间: 2022726 9:30
收件人: devel@edk2.groups.io
主题: [edk2-devel] Event: TianoCore Bug Triage - APAC / NAMO - 07/26/2022 #cal-reminder

 

Reminder: TianoCore Bug Triage - APAC / NAMO

When:
07/26/2022
6:30pm to 7:30pm
(UTC-07:00) America/Los Angeles

Where:
https://teams.microsoft.com/l/meetup-join/19%3ameeting_OTk1YzJhN2UtOGQwNi00NjY4LWEwMTktY2JiODRlYTY1NmY0%40thread.v2/0?context=%7b%22Tid%22%3a%2246c98d88-e344-4ed4-8496-4ed7712e255d%22%2c%22Oid%22%3a%226e4ce4c4-1242-431b-9a51-92cd01a5df3c%22%7d

Organizer: Liming Gao gaoliming@...

View Event

Description:

TianoCore Bug Triage - APAC / NAMO

Hosted by Liming Gao

 

________________________________________________________________________________

Microsoft Teams meeting

Join on your computer or mobile app

Click here to join the meeting

Join with a video conferencing device

teams@...

Video Conference ID: 116 062 094 0

Alternate VTC dialing instructions

Or call in (audio only)

+1 916-245-6934,,77463821#   United States, Sacramento

Phone Conference ID: 774 638 21#

Find a local number | Reset PIN

Learn More | Meeting options


Recent change in edk2 causing problems with USB, SD and MMC devices

Sean Rhodes
 

Hi All

For a large number of boards running coreboot (reported on CML, TGL, ADL, SKL and APL), a change in the last few months has caused an indefinite hang.

For the last three years, coreboot has used a default value of 1000 for gEfiMdeModulePkgTokenSpaceGuid.PcdSdMmcGenericTimeoutValue, but to workaround the hang, this value had to be changed to 10000.

The new value will get the device booting, but on a smaller selection of boards, USB devices are not visible to edk2 (either in the EFI Shell, Debug output or Boot Manager). They function normally in the OS, and the debug output is below.

I don't suppose anyone would have a hunch as to the cause of this problem?

Many thanks

Sean


XhcGetCapability: 16 ports, 64 bit 1
UsbRootHubInit: root hub E9E3F18 - max speed 3, 16 ports
XhcClearRootHubPortFeature: status Success
UsbEnumeratePort: port 4 state - 801, change - 01 on E9E3F18
UsbEnumeratePort: Device Connect/Disconnect Normally
UsbEnumeratePort: new device connected at port 4
XhcUsbPortReset!
XhcSetRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
Enable Slot Successfully, The Slot ID = 0x1
    Address 1 assigned successfully
UsbEnumerateNewDev: hub port 4 is reset
UsbEnumerateNewDev: device is of 3 speed
UsbEnumerateNewDev: device uses translator (0, 0)
UsbEnumerateNewDev: device is now ADDRESSED at 1
UsbEnumerateNewDev: max packet size for EP 0 is 64
UsbBuildDescTable: failed to get device descriptor - Invalid Parameter
UsbEnumerateNewDev: failed to build descriptor table - Invalid Parameter
XhcClearRootHubPortFeature: status Success
UsbEnumeratePort: port 5 state - 801, change - 01 on E9E3F18
UsbEnumeratePort: Device Connect/Disconnect Normally
UsbEnumeratePort: new device connected at port 5
XhcUsbPortReset!
XhcSetRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
Enable Slot Successfully, The Slot ID = 0x2
    Address 2 assigned successfully
UsbEnumerateNewDev: hub port 5 is reset
UsbEnumerateNewDev: device is of 3 speed
UsbEnumerateNewDev: device uses translator (0, 0)
UsbEnumerateNewDev: device is now ADDRESSED at 2
UsbEnumerateNewDev: max packet size for EP 0 is 64
UsbBuildDescTable: failed to get device descriptor - Invalid Parameter
UsbEnumerateNewDev: failed to build descriptor table - Invalid Parameter
XhcClearRootHubPortFeature: status Success
UsbEnumeratePort: port 6 state - 801, change - 01 on E9E3F18
UsbEnumeratePort: Device Connect/Disconnect Normally
UsbEnumeratePort: new device connected at port 6
XhcUsbPortReset!
XhcSetRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
Enable Slot Successfully, The Slot ID = 0x3
    Address 3 assigned successfully
UsbEnumerateNewDev: hub port 6 is reset
UsbEnumerateNewDev: device is of 3 speed
UsbEnumerateNewDev: device uses translator (0, 0)
UsbEnumerateNewDev: device is now ADDRESSED at 3
UsbEnumerateNewDev: max packet size for EP 0 is 64
UsbBuildDescTable: failed to get device descriptor - Invalid Parameter
UsbEnumerateNewDev: failed to build descriptor table - Invalid Parameter
XhcClearRootHubPortFeature: status Success
UsbEnumeratePort: port 8 state - 801, change - 01 on E9E3F18
UsbEnumeratePort: Device Connect/Disconnect Normally
UsbEnumeratePort: new device connected at port 8
XhcUsbPortReset!
XhcSetRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
XhcClearRootHubPortFeature: status Success
Enable Slot Successfully, The Slot ID = 0x4
    Address 4 assigned successfully
UsbEnumerateNewDev: hub port 8 is reset
UsbEnumerateNewDev: device is of 3 speed
UsbEnumerateNewDev: device uses translator (0, 0)
UsbEnumerateNewDev: device is now ADDRESSED at 4
UsbEnumerateNewDev: max packet size for EP 0 is 64
UsbBuildDescTable: failed to get device descriptor - Invalid Parameter
UsbEnumerateNewDev: failed to build descriptor table - Invalid Parameter
UsbBusStart: usb bus started on EAEB818, root hub E9E3F18


Re: Casting i128 into f64 in UEFI Rust pagefaults

Andrew Fish
 

Ayush,


Well bugs in the runtime are a classic case when have good debugging infrastructure pays off and that class of issue is what started this email thread. 

It is not hard to try out gdb to see what happens if you are using QEMU. 
From the root of the edk2 repo:
OvmfPkg/build.sh qemu -gdb tcp::9000

Then from another terminal
$ cd BaseTools/Scripts
$  gdb -ex "target remote localhost:9000" -ex "source efi_gdb.py"

That should get you a symbolicated stack frame. 

The QEMU -gdb works like a JTAG debugger. You can put dead loops in your code, let it run, and then attach. 

Thanks,

Andrew Fish

On Jul 26, 2022, at 12:15 PM, Ayush Singh <ayushdevel1325@...> wrote:

Hi Andrew. I do agree with having better debugging support for Rust-UEFI. However, I am not much experienced with even the C side of UEFI debugging, so it has been difficult for me to do much on the Rust side either. It isn't like Rust UEFI debugging is not possible. There are some examples ([1]), but as you might guess, they are quite few. Additionally, most of them seem to be concentrated around Windows. Finally, there is actually quite good debugging support in uefi-rs [2], but well, that's licensed under MPL-2.0, so I have stayed clear of it.


Another reason I have gone so long without using any actual debugger is because, well, Rust makes it quite explicit where wired errors can occur. Most functions, even inside the std, don't use pointers but rather use `NonNull`, `MaybeUninint` or some other safe abstraction. Even on the worst failure, the program will abort instead of crash. On aborting, Rust also gives a nice message on stderr stating exactly where the error occurred along with all the details of the error. Basically, it was always so clear what caused the error and where it occurred that I simply didn't feel the need to attach a debugger, till now.


There is some work going on to actually document using Rust for UEFI in the rustc docs, sponsored by Red Hat [3], so the situation should improve soon. What I do know is that the `.pdb` files generated by Rust (which are always generated) should contain all the symbols for debugging. I can work on debugging once I finish up with solving all other errors which are due to my implementation of std rather than the ones that have been caused by the rust intrinsic.


Ayush Singh


[1]: https://xitan.me/posts/rust-uefi-runtime-driver/

[2]: https://github.com/rust-osdev/uefi-rs

[3]: https://github.com/rust-lang/rust/pull/99760


On 7/26/22 23:20, Andrew Fish wrote:
On Jul 25, 2022, at 10:43 PM, Ayush Singh <ayushdevel1325@...> wrote:

Hi Andrew. Thanks for all your work. The more I look at this, the more it feels like it might be a problem on the LLVM side instead of Rust. I also found some more tests (all related to numbers btw) which can cause different types of exceptions, so I think I will try filing bugs upstream.


Ayush,

In general If we want to move to Rust we are going to need a way to debug issues like this down to the root cause. I think figuring out how to debug will make it easier to move forward with the Rust port in general. It will time well spent. 

The best way to get LLVM fixed, if it is even broken, is to provide a simple test case that reproduces the behavior. I don’t think at this point we know what is going on. It is very unlikely that some random LLVM developer is going to invest the time in trying to setup some UEFI environment to try and root cause this bug. I general find I have to create a simple at desk example and then I get stuff fixed quickly. Basically a test case the LLVM developer can compile at their desk and see the error in assembler, or at least run it at desk and have bogus output. 

I’m not 100% sure what toolchain you are using. Can you `objdump -d hello_world_std.efi`and get some symbols with the disassembly? For VC++ I think it would be `DUMPBIN /DISASM`.

What are you planning on using for source level debugging Rust? I wrote some gdb[1] and lldb[2] debugging commands in Python. I’m guessing loading Rust symbols from PE/COFF images should be similar, as long as the debugger knows about rust. 

I’m happy to help you figure out stuff related to debugging Rust. 


Thanks,

Andrew Fish

Yours Sincerely,

Ayush Singh


On 7/26/22 00:24, Andrew Fish wrote:
I guess I could at least dump to the end (req)…. Going backwards is a bit painful in x86. 

(lldb) dis -s 0x0000000140001B60 -b -c 30
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi
hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                 callq  0x1400070e0
hello_world_std.efi[0x140001b84]: 48 09 f0                       orq    %rsi, %rax
hello_world_std.efi[0x140001b87]: 48 83 c4 20                    addq   $0x20, %rsp
hello_world_std.efi[0x140001b8b]: 5e                             popq   %rsi
hello_world_std.efi[0x140001b8c]: c3                             retq   
hello_world_std.efi[0x140001b8d]: cc                             int3   
hello_world_std.efi[0x140001b8e]: cc                             int3   
hello_world_std.efi[0x140001b8f]: cc                             int3   
hello_world_std.efi[0x140001b90]: e9 db 55 00 00                 jmp    0x140007170
hello_world_std.efi[0x140001b95]: cc                             int3   

Then we can guess based on how functions get aligned to find the start….

hello_world_std.efi[0x140001b50]: 56                                   pushq  %rsi
hello_world_std.efi[0x140001b51]: 48 83 ec 20                          subq   $0x20, %rsp
hello_world_std.efi[0x140001b55]: 4c 8b 41 08                          movq   0x8(%rcx), %r8
hello_world_std.efi[0x140001b59]: 4c 89 c0                             movq   %r8, %rax
hello_world_std.efi[0x140001b5c]: 48 c1 f8 3f                          sarq   $0x3f, %rax
hello_world_std.efi[0x140001b60]: 48 8b 09                             movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                             addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                             movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                             adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                             xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                             xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80        movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                             andq   %r8, %rsi
hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                       callq  0x1400070e0
hello_world_std.efi[0x140001b84]: 48 09 f0                             orq    %rsi, %rax
hello_world_std.efi[0x140001b87]: 48 83 c4 20                          addq   $0x20, %rsp
hello_world_std.efi[0x140001b8b]: 5e                                   popq   %rsi
hello_world_std.efi[0x140001b8c]: c3                                   retq   

So the faulting function is getting passed a bad pointer as its 1st arg. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 11:45 AM, Andrew Fish <afish@...> wrote:

Ops… Looks like your PE/COFF is linked at 0x0000000140000000, so 0x140001b60 is the interesting bit.

(lldb) dis -s 0x0000000140001B60 -b
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

 RCX - FFFFFFFFFFFFFFFF

So yea that looks like the fault. 

I don’t see that pattern in your .s file…. 

Can you figure out what function is @ 0x140001b60 in the PE/COFF image. Do you have a map file from the linker?

Thanks,

Andrew Fish

PS Again sorry I don’t have anything installed to crack PDB files. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:51 AM, Andrew Fish via groups.io <afish@...> wrote:

Ayush,

CR2 is the fault address so 0xFFFFFFFFFFFFFFFF. Given for EFI Virt == Physical the fault address looks like a bad pointer. 

Sorry I’ve not used VC++ in a long time so I don’t know how to debug with VC++, but If I was using clang/lldb I’d look at the source and assembly for the fault address. 

The image base is: 0x000000000603C000
The fault PC/RIP is: 000000000603DB60

So the faulting code is at 0x1B60 in the image. Given the images are linked at zero you should be able to load the build product into the debugger and look at what code is at offset 0x1B60. The same should work for any tools that dump the binary. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:33 AM, Ayush Singh <ayushdevel1325@...> wrote:

Hello everyone.While running Rust tests in UEFI environment, I have come across a numeric test that causes a pagefault. A simple reproducible example for this is given below:

```rust

fn main() {
    use std::hint::black_box as b;

    let z: i128 = b(1);
    assert!((-z as f64) < 0.0);
}

```


The exception output is as follows:

```

!!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000  I:0 R:0 U:0 W:0 P:0 PK:0 SS:0 SGX:0
RIP  - 000000000603DB60, CS  - 0000000000000038, RFLAGS - 0000000000000246
RAX  - 0000000000000000, RCX - FFFFFFFFFFFFFFFF, RDX - FFFFFFFFFFFFFFFF
RBX  - 0000000000000000, RSP - 0000000007EDF1D0, RBP - 0000000007EDF4C0
RSI  - 0000000007EDF360, RDI - 0000000007EDF3C0
R8   - 0000000000000000, R9  - 0000000000000038, R10 - 0000000000000000
R11  - 0000000000000000, R12 - 00000000060C6018, R13 - 0000000007EDF520
R14  - 0000000007EDF6A8, R15 - 0000000005FA9490
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - FFFFFFFFFFFFFFFF, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007418018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007EDEE30
!!!! Find image based on IP(0x603DB60) /var/home/ayush/Documents/Programming/Rust/uefi/hello_world_std/target/x86_64-unknown-uefi/debug/deps/hello_world_std-338028f9369e2d42.pdb (ImageBase=000000000603C000, EntryPoint=000000000603D8C0) !!!!

```


From my testing, the exception only occurs when a few conditions are met.

1. The binary is compiled in Debug mode. No error in Release mode.

2. `i128` is in a black_box [1]. Does not occur if `black_box` is not present.

3. It has to be `i128`. `i64` or something else work fine.

4. The cast has to be done on `-z`. Doing the same with `+z` is fine.


I have also been discussing this in the Rust zulipchat [2], so feel free to chime in there.


Additionally, here are links for more information about this program:

1. Assembly: https://rust-lang.zulipchat.com/user_uploads/4715/od51Y9Dkfjahcg9HHcOud8Fm/hello_world_std-338028f9369e2d42.s

2. EFI Binary: https://rust-lang.zulipchat.com/user_uploads/4715/CknqtXLR8SaJZmyOnXctQkpL/hello_world_std.efi

3. PDB file: https://rust-lang.zulipchat.com/user_uploads/4715/zV4i6DsjgQXotp_gS1naEsU0/hello_world_std-338028f9369e2d42.pdb


Yours Sincerely,

Ayush Singh


[1]: https://doc.rust-lang.org/std/hint/fn.black_box.html

[2]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Casting.20i128.20to.20f64.20in.20black_box.20causes.20exception.20in.20UEFI









Re: [Patch 0/2] Remove MptScsi and PvScsi reviewers

Ard Biesheuvel
 

On Tue, 26 Jul 2022 at 12:46, Michael D Kinney
<michael.d.kinney@...> wrote:

The email addresses for the reviewers of the MptScsi and
PvScsi in the OvmfPkg are no longer valid. Remove the
reviewers for the MptScsi and PvScsi drivers until new
maintainers/reviewers can be identified.

Cc: Andrew Fish <afish@...>
Cc: Leif Lindholm <quic_llindhol@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>

Michael D Kinney (2):
OvmfPkg: Change default to disable MptScsi and PvScsi
Maintainers.txt: Remove MptScsi and PvScsi reviewers
Acked-by: Ard Biesheuvel <ardb@...>

Maintainers.txt | 6 ------
OvmfPkg/AmdSev/AmdSevX64.dsc | 4 ++--
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++--
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 ++--
OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++--
OvmfPkg/OvmfPkgX64.dsc | 4 ++--
8 files changed, 14 insertions(+), 20 deletions(-)

--
2.32.0.windows.1


Re: [PATCH 1/1] OvmfPkg/XenHypercallLib: Fix naming of AArch64

Ard Biesheuvel
 

On Tue, 26 Jul 2022 at 12:30, Kinney, Michael D
<michael.d.kinney@...> wrote:

Reviewed-by: Michael D Kinney <michael.d.kinney@...>
Acked-by: Ard Biesheuvel <ardb@...>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Anthony PERARD via groups.io
Sent: Wednesday, July 20, 2022 6:17 AM
To: devel@edk2.groups.io
Cc: Anthony PERARD <anthony.perard@...>; Ard Biesheuvel <ardb+tianocore@...>; Yao, Jiewen
<jiewen.yao@...>; Justen, Jordan L <jordan.l.justen@...>; Gerd Hoffmann <kraxel@...>; Julien Grall
<julien@...>
Subject: [edk2-devel] [PATCH 1/1] OvmfPkg/XenHypercallLib: Fix naming of AArch64

From: Anthony PERARD <anthony.perard@...>

Fix path to follow naming convention of "AArch64", and allow the path
in "Maintainers.txt" to work as expected.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3982
Signed-off-by: Anthony PERARD <anthony.perard@...>
---
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Julien Grall <julien@...>
---
OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf | 2 +-
.../Library/XenHypercallLib/{Aarch64 => AArch64}/Hypercall.S | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename OvmfPkg/Library/XenHypercallLib/{Aarch64 => AArch64}/Hypercall.S (100%)

diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
index 32ae73f7aac5..edb77872391c 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -42,7 +42,7 @@ [Sources.ARM]
Arm/Hypercall.S

[Sources.AARCH64]
- Aarch64/Hypercall.S
+ AArch64/Hypercall.S

[Sources]
XenHypercall.c
diff --git a/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/AArch64/Hypercall.S
similarity index 100%
rename from OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
rename to OvmfPkg/Library/XenHypercallLib/AArch64/Hypercall.S
--
Anthony PERARD





[Patch 1/2] OvmfPkg: Change default to disable MptScsi and PvScsi

Michael D Kinney
 

The email addresses for the reviewers of the MptScsi and
PvScsi are no longer valid. Disable the MptScsi and PvScsi
drivers in all DSC files until new maintainers/reviewers can
be identified.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Sebastien Boeuf <sebastien.boeuf@...>
Cc: Brijesh Singh <brijesh.singh@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Min Xu <min.m.xu@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>
---
OvmfPkg/AmdSev/AmdSevX64.dsc | 4 ++--
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++--
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 ++--
OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++--
OvmfPkg/OvmfPkgX64.dsc | 4 ++--
7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 726521c94381..90e8a213ef77 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -43,8 +43,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 0bfe542f8a88..f0d700f14477 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -49,8 +49,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 144d50aa9dba..71b1cf8e7090 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -34,8 +34,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 61db9b6e4c83..52498bbe90a8 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -47,8 +47,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index e708411076ca..725a01ae9a20 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -50,8 +50,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 0b036d8bb53f..adc813ba2e1e 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -49,8 +49,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 8ad04b50f74f..6e68f60dc90f 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -49,8 +49,8 @@ [Defines]
#
# Device drivers
#
- DEFINE PVSCSI_ENABLE = TRUE
- DEFINE MPT_SCSI_ENABLE = TRUE
+ DEFINE PVSCSI_ENABLE = FALSE
+ DEFINE MPT_SCSI_ENABLE = FALSE
DEFINE LSI_SCSI_ENABLE = FALSE

#
--
2.32.0.windows.1


[Patch 2/2] Maintainers.txt: Remove MptScsi and PvScsi reviewers

Michael D Kinney
 

The email addresses for the reviewers of the MptScsi and
PvScsi in the OvmfPkg are no longer valid. Remove the
reviewers for the MptScsi and PvScsi drivers until new
maintainers/reviewers can be identified.

Cc: Andrew Fish <afish@...>
Cc: Leif Lindholm <quic_llindhol@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>
---
Maintainers.txt | 6 ------
1 file changed, 6 deletions(-)

diff --git a/Maintainers.txt b/Maintainers.txt
index 0ea6b4041654..071644c35612 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -489,12 +489,6 @@ OvmfPkg: LsiScsi driver
F: OvmfPkg/LsiScsiDxe/
R: Gary Lin <gary.lin@...> [lcp]

-OvmfPkg: MptScsi and PVSCSI driver
-F: OvmfPkg/MptScsiDxe/
-F: OvmfPkg/PvScsiDxe/
-R: Liran Alon <liran.alon@...>
-R: Nikita Leshenko <nikita.leshchenko@...>
-
OvmfPkg: TCG- and TPM2-related modules
F: OvmfPkg/Include/IndustryStandard/QemuTpm.h
F: OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
--
2.32.0.windows.1


[Patch 0/2] Remove MptScsi and PvScsi reviewers

Michael D Kinney
 

The email addresses for the reviewers of the MptScsi and
PvScsi in the OvmfPkg are no longer valid. Remove the
reviewers for the MptScsi and PvScsi drivers until new
maintainers/reviewers can be identified.

Cc: Andrew Fish <afish@...>
Cc: Leif Lindholm <quic_llindhol@...>
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Signed-off-by: Michael D Kinney <michael.d.kinney@...>

Michael D Kinney (2):
OvmfPkg: Change default to disable MptScsi and PvScsi
Maintainers.txt: Remove MptScsi and PvScsi reviewers

Maintainers.txt | 6 ------
OvmfPkg/AmdSev/AmdSevX64.dsc | 4 ++--
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++--
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 4 ++--
OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32.dsc | 4 ++--
OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++--
OvmfPkg/OvmfPkgX64.dsc | 4 ++--
8 files changed, 14 insertions(+), 20 deletions(-)

--
2.32.0.windows.1


Re: [PATCH 1/1] OvmfPkg/XenHypercallLib: Fix naming of AArch64

Michael D Kinney
 

Reviewed-by: Michael D Kinney <michael.d.kinney@...>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Anthony PERARD via groups.io
Sent: Wednesday, July 20, 2022 6:17 AM
To: devel@edk2.groups.io
Cc: Anthony PERARD <anthony.perard@...>; Ard Biesheuvel <ardb+tianocore@...>; Yao, Jiewen
<jiewen.yao@...>; Justen, Jordan L <jordan.l.justen@...>; Gerd Hoffmann <kraxel@...>; Julien Grall
<julien@...>
Subject: [edk2-devel] [PATCH 1/1] OvmfPkg/XenHypercallLib: Fix naming of AArch64

From: Anthony PERARD <anthony.perard@...>

Fix path to follow naming convention of "AArch64", and allow the path
in "Maintainers.txt" to work as expected.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3982
Signed-off-by: Anthony PERARD <anthony.perard@...>
---
Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Julien Grall <julien@...>
---
OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf | 2 +-
.../Library/XenHypercallLib/{Aarch64 => AArch64}/Hypercall.S | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename OvmfPkg/Library/XenHypercallLib/{Aarch64 => AArch64}/Hypercall.S (100%)

diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
index 32ae73f7aac5..edb77872391c 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -42,7 +42,7 @@ [Sources.ARM]
Arm/Hypercall.S

[Sources.AARCH64]
- Aarch64/Hypercall.S
+ AArch64/Hypercall.S

[Sources]
XenHypercall.c
diff --git a/OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S b/OvmfPkg/Library/XenHypercallLib/AArch64/Hypercall.S
similarity index 100%
rename from OvmfPkg/Library/XenHypercallLib/Aarch64/Hypercall.S
rename to OvmfPkg/Library/XenHypercallLib/AArch64/Hypercall.S
--
Anthony PERARD





Re: Casting i128 into f64 in UEFI Rust pagefaults

 

When I mentioned upstream, I was talking about Rust repository, since as you said, I am not sure if this is LLVM problem yet. There is already a similar bug filed in rust repo about u128 division causing exception [1], and there is a possible fix [2] (which does not work for the page fault). I have also found 1 more edge case in numbers to cause `General Exception`, which just like the other two seems to be related to rust intrinsic or LLVM, but since I am not sure, and simply haven't done any testing on, I cannot really say.


Anyway, filing them in Rust repository is helpful since the bug might affect other `msvc-like` tier-2 and tier-3 targets. There is also renewed interest in making UEFI targets Tier-2 from Tier-3 (sponsored by Red Hat), so it's possible that someone else might pick it up before I am done with the std errors I am trying to fix.


Ayush Singh


[1]: https://github.com/rust-lang/rust/issues/86494

[2]: https://github.com/rust-lang/compiler-builtins/pull/475


On 7/27/22 00:42, Pedro Falcato wrote:

Fyi, please don't file bugs upstream just now. You're not sure if they're LLVM problems (and they're likely not, else they would affect everyone else, not just UEFI code). Try to get a simpler, reliable repro (and do share with us!) before saying it's an LLVM bug.
In my experience, most "what the hell" "compiler bugs" ended up being things I accidentally set up wrong, or didn't set up at all, and broke things in a subtle way.

On Tue, Jul 26, 2022 at 6:43 AM Ayush Singh <ayushdevel1325@...> wrote:

Hi Andrew. Thanks for all your work. The more I look at this, the more it feels like it might be a problem on the LLVM side instead of Rust. I also found some more tests (all related to numbers btw) which can cause different types of exceptions, so I think I will try filing bugs upstream.

Yours Sincerely,

Ayush Singh


On 7/26/22 00:24, Andrew Fish wrote:
I guess I could at least dump to the end (req)…. Going backwards is a bit painful in x86. 

(lldb) dis -s 0x0000000140001B60 -b -c 30

hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx

hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx

hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx

hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx

hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx

hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx

hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 

hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                 callq  0x1400070e0

hello_world_std.efi[0x140001b84]: 48 09 f0                       orq    %rsi, %rax

hello_world_std.efi[0x140001b87]: 48 83 c4 20                    addq   $0x20, %rsp

hello_world_std.efi[0x140001b8b]: 5e                             popq   %rsi

hello_world_std.efi[0x140001b8c]: c3                             retq   

hello_world_std.efi[0x140001b8d]: cc                             int3   

hello_world_std.efi[0x140001b8e]: cc                             int3   

hello_world_std.efi[0x140001b8f]: cc                             int3   

hello_world_std.efi[0x140001b90]: e9 db 55 00 00                 jmp    0x140007170

hello_world_std.efi[0x140001b95]: cc                             int3   


Then we can guess based on how functions get aligned to find the start….

hello_world_std.efi[0x140001b50]: 56                                   pushq  %rsi

hello_world_std.efi[0x140001b51]: 48 83 ec 20                          subq   $0x20, %rsp

hello_world_std.efi[0x140001b55]: 4c 8b 41 08                          movq   0x8(%rcx), %r8

hello_world_std.efi[0x140001b59]: 4c 89 c0                             movq   %r8, %rax

hello_world_std.efi[0x140001b5c]: 48 c1 f8 3f                          sarq   $0x3f, %rax

hello_world_std.efi[0x140001b60]: 48 8b 09                             movq   (%rcx), %rcx

hello_world_std.efi[0x140001b63]: 48 01 c1                             addq   %rax, %rcx

hello_world_std.efi[0x140001b66]: 4c 89 c2                             movq   %r8, %rdx

hello_world_std.efi[0x140001b69]: 48 11 c2                             adcq   %rax, %rdx

hello_world_std.efi[0x140001b6c]: 48 31 c1                             xorq   %rax, %rcx

hello_world_std.efi[0x140001b6f]: 48 31 c2                             xorq   %rax, %rdx

hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80        movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 

hello_world_std.efi[0x140001b7c]: 4c 21 c6                             andq   %r8, %rsi

hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                       callq  0x1400070e0

hello_world_std.efi[0x140001b84]: 48 09 f0                             orq    %rsi, %rax

hello_world_std.efi[0x140001b87]: 48 83 c4 20                          addq   $0x20, %rsp

hello_world_std.efi[0x140001b8b]: 5e                                   popq   %rsi

hello_world_std.efi[0x140001b8c]: c3                                   retq   


So the faulting function is getting passed a bad pointer as its 1st arg. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 11:45 AM, Andrew Fish <afish@...> wrote:

Ops… Looks like your PE/COFF is linked at 0x0000000140000000, so 0x140001b60 is the interesting bit.

(lldb) dis -s 0x0000000140001B60 -b
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

 RCX - FFFFFFFFFFFFFFFF

So yea that looks like the fault. 

I don’t see that pattern in your .s file…. 

Can you figure out what function is @ 0x140001b60 in the PE/COFF image. Do you have a map file from the linker?

Thanks,

Andrew Fish

PS Again sorry I don’t have anything installed to crack PDB files. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:51 AM, Andrew Fish via groups.io <afish@...> wrote:

Ayush,

CR2 is the fault address so 0xFFFFFFFFFFFFFFFF. Given for EFI Virt == Physical the fault address looks like a bad pointer. 

Sorry I’ve not used VC++ in a long time so I don’t know how to debug with VC++, but If I was using clang/lldb I’d look at the source and assembly for the fault address. 

The image base is: 0x000000000603C000
The fault PC/RIP is: 000000000603DB60

So the faulting code is at 0x1B60 in the image. Given the images are linked at zero you should be able to load the build product into the debugger and look at what code is at offset 0x1B60. The same should work for any tools that dump the binary. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:33 AM, Ayush Singh <ayushdevel1325@...> wrote:

Hello everyone.While running Rust tests in UEFI environment, I have come across a numeric test that causes a pagefault. A simple reproducible example for this is given below:

```rust

fn main() {
    use std::hint::black_box as b;

    let z: i128 = b(1);
    assert!((-z as f64) < 0.0);
}

```


The exception output is as follows:

```

!!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000  I:0 R:0 U:0 W:0 P:0 PK:0 SS:0 SGX:0
RIP  - 000000000603DB60, CS  - 0000000000000038, RFLAGS - 0000000000000246
RAX  - 0000000000000000, RCX - FFFFFFFFFFFFFFFF, RDX - FFFFFFFFFFFFFFFF
RBX  - 0000000000000000, RSP - 0000000007EDF1D0, RBP - 0000000007EDF4C0
RSI  - 0000000007EDF360, RDI - 0000000007EDF3C0
R8   - 0000000000000000, R9  - 0000000000000038, R10 - 0000000000000000
R11  - 0000000000000000, R12 - 00000000060C6018, R13 - 0000000007EDF520
R14  - 0000000007EDF6A8, R15 - 0000000005FA9490
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - FFFFFFFFFFFFFFFF, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007418018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007EDEE30
!!!! Find image based on IP(0x603DB60) /var/home/ayush/Documents/Programming/Rust/uefi/hello_world_std/target/x86_64-unknown-uefi/debug/deps/hello_world_std-338028f9369e2d42.pdb (ImageBase=000000000603C000, EntryPoint=000000000603D8C0) !!!!

```


From my testing, the exception only occurs when a few conditions are met.

1. The binary is compiled in Debug mode. No error in Release mode.

2. `i128` is in a black_box [1]. Does not occur if `black_box` is not present.

3. It has to be `i128`. `i64` or something else work fine.

4. The cast has to be done on `-z`. Doing the same with `+z` is fine.


I have also been discussing this in the Rust zulipchat [2], so feel free to chime in there.


Additionally, here are links for more information about this program:

1. Assembly: https://rust-lang.zulipchat.com/user_uploads/4715/od51Y9Dkfjahcg9HHcOud8Fm/hello_world_std-338028f9369e2d42.s

2. EFI Binary: https://rust-lang.zulipchat.com/user_uploads/4715/CknqtXLR8SaJZmyOnXctQkpL/hello_world_std.efi

3. PDB file: https://rust-lang.zulipchat.com/user_uploads/4715/zV4i6DsjgQXotp_gS1naEsU0/hello_world_std-338028f9369e2d42.pdb


Yours Sincerely,

Ayush Singh


[1]: https://doc.rust-lang.org/std/hint/fn.black_box.html

[2]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Casting.20i128.20to.20f64.20in.20black_box.20causes.20exception.20in.20UEFI








--
Pedro Falcato


Re: Casting i128 into f64 in UEFI Rust pagefaults

 

Hi Andrew. I do agree with having better debugging support for Rust-UEFI. However, I am not much experienced with even the C side of UEFI debugging, so it has been difficult for me to do much on the Rust side either. It isn't like Rust UEFI debugging is not possible. There are some examples ([1]), but as you might guess, they are quite few. Additionally, most of them seem to be concentrated around Windows. Finally, there is actually quite good debugging support in uefi-rs [2], but well, that's licensed under MPL-2.0, so I have stayed clear of it.


Another reason I have gone so long without using any actual debugger is because, well, Rust makes it quite explicit where wired errors can occur. Most functions, even inside the std, don't use pointers but rather use `NonNull`, `MaybeUninint` or some other safe abstraction. Even on the worst failure, the program will abort instead of crash. On aborting, Rust also gives a nice message on stderr stating exactly where the error occurred along with all the details of the error. Basically, it was always so clear what caused the error and where it occurred that I simply didn't feel the need to attach a debugger, till now.


There is some work going on to actually document using Rust for UEFI in the rustc docs, sponsored by Red Hat [3], so the situation should improve soon. What I do know is that the `.pdb` files generated by Rust (which are always generated) should contain all the symbols for debugging. I can work on debugging once I finish up with solving all other errors which are due to my implementation of std rather than the ones that have been caused by the rust intrinsic.


Ayush Singh


[1]: https://xitan.me/posts/rust-uefi-runtime-driver/

[2]: https://github.com/rust-osdev/uefi-rs

[3]: https://github.com/rust-lang/rust/pull/99760


On 7/26/22 23:20, Andrew Fish wrote:

On Jul 25, 2022, at 10:43 PM, Ayush Singh <ayushdevel1325@...> wrote:

Hi Andrew. Thanks for all your work. The more I look at this, the more it feels like it might be a problem on the LLVM side instead of Rust. I also found some more tests (all related to numbers btw) which can cause different types of exceptions, so I think I will try filing bugs upstream.


Ayush,

In general If we want to move to Rust we are going to need a way to debug issues like this down to the root cause. I think figuring out how to debug will make it easier to move forward with the Rust port in general. It will time well spent. 

The best way to get LLVM fixed, if it is even broken, is to provide a simple test case that reproduces the behavior. I don’t think at this point we know what is going on. It is very unlikely that some random LLVM developer is going to invest the time in trying to setup some UEFI environment to try and root cause this bug. I general find I have to create a simple at desk example and then I get stuff fixed quickly. Basically a test case the LLVM developer can compile at their desk and see the error in assembler, or at least run it at desk and have bogus output. 

I’m not 100% sure what toolchain you are using. Can you `objdump -d hello_world_std.efi`and get some symbols with the disassembly? For VC++ I think it would be `DUMPBIN /DISASM`.

What are you planning on using for source level debugging Rust? I wrote some gdb[1] and lldb[2] debugging commands in Python. I’m guessing loading Rust symbols from PE/COFF images should be similar, as long as the debugger knows about rust. 

I’m happy to help you figure out stuff related to debugging Rust. 


Thanks,

Andrew Fish

Yours Sincerely,

Ayush Singh


On 7/26/22 00:24, Andrew Fish wrote:
I guess I could at least dump to the end (req)…. Going backwards is a bit painful in x86. 

(lldb) dis -s 0x0000000140001B60 -b -c 30
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi
hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                 callq  0x1400070e0
hello_world_std.efi[0x140001b84]: 48 09 f0                       orq    %rsi, %rax
hello_world_std.efi[0x140001b87]: 48 83 c4 20                    addq   $0x20, %rsp
hello_world_std.efi[0x140001b8b]: 5e                             popq   %rsi
hello_world_std.efi[0x140001b8c]: c3                             retq   
hello_world_std.efi[0x140001b8d]: cc                             int3   
hello_world_std.efi[0x140001b8e]: cc                             int3   
hello_world_std.efi[0x140001b8f]: cc                             int3   
hello_world_std.efi[0x140001b90]: e9 db 55 00 00                 jmp    0x140007170
hello_world_std.efi[0x140001b95]: cc                             int3   

Then we can guess based on how functions get aligned to find the start….

hello_world_std.efi[0x140001b50]: 56                                   pushq  %rsi
hello_world_std.efi[0x140001b51]: 48 83 ec 20                          subq   $0x20, %rsp
hello_world_std.efi[0x140001b55]: 4c 8b 41 08                          movq   0x8(%rcx), %r8
hello_world_std.efi[0x140001b59]: 4c 89 c0                             movq   %r8, %rax
hello_world_std.efi[0x140001b5c]: 48 c1 f8 3f                          sarq   $0x3f, %rax
hello_world_std.efi[0x140001b60]: 48 8b 09                             movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                             addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                             movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                             adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                             xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                             xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80        movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                             andq   %r8, %rsi
hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                       callq  0x1400070e0
hello_world_std.efi[0x140001b84]: 48 09 f0                             orq    %rsi, %rax
hello_world_std.efi[0x140001b87]: 48 83 c4 20                          addq   $0x20, %rsp
hello_world_std.efi[0x140001b8b]: 5e                                   popq   %rsi
hello_world_std.efi[0x140001b8c]: c3                                   retq   

So the faulting function is getting passed a bad pointer as its 1st arg. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 11:45 AM, Andrew Fish <afish@...> wrote:

Ops… Looks like your PE/COFF is linked at 0x0000000140000000, so 0x140001b60 is the interesting bit.

(lldb) dis -s 0x0000000140001B60 -b
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

 RCX - FFFFFFFFFFFFFFFF

So yea that looks like the fault. 

I don’t see that pattern in your .s file…. 

Can you figure out what function is @ 0x140001b60 in the PE/COFF image. Do you have a map file from the linker?

Thanks,

Andrew Fish

PS Again sorry I don’t have anything installed to crack PDB files. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:51 AM, Andrew Fish via groups.io <afish@...> wrote:

Ayush,

CR2 is the fault address so 0xFFFFFFFFFFFFFFFF. Given for EFI Virt == Physical the fault address looks like a bad pointer. 

Sorry I’ve not used VC++ in a long time so I don’t know how to debug with VC++, but If I was using clang/lldb I’d look at the source and assembly for the fault address. 

The image base is: 0x000000000603C000
The fault PC/RIP is: 000000000603DB60

So the faulting code is at 0x1B60 in the image. Given the images are linked at zero you should be able to load the build product into the debugger and look at what code is at offset 0x1B60. The same should work for any tools that dump the binary. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:33 AM, Ayush Singh <ayushdevel1325@...> wrote:

Hello everyone.While running Rust tests in UEFI environment, I have come across a numeric test that causes a pagefault. A simple reproducible example for this is given below:

```rust

fn main() {
    use std::hint::black_box as b;

    let z: i128 = b(1);
    assert!((-z as f64) < 0.0);
}

```


The exception output is as follows:

```

!!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000  I:0 R:0 U:0 W:0 P:0 PK:0 SS:0 SGX:0
RIP  - 000000000603DB60, CS  - 0000000000000038, RFLAGS - 0000000000000246
RAX  - 0000000000000000, RCX - FFFFFFFFFFFFFFFF, RDX - FFFFFFFFFFFFFFFF
RBX  - 0000000000000000, RSP - 0000000007EDF1D0, RBP - 0000000007EDF4C0
RSI  - 0000000007EDF360, RDI - 0000000007EDF3C0
R8   - 0000000000000000, R9  - 0000000000000038, R10 - 0000000000000000
R11  - 0000000000000000, R12 - 00000000060C6018, R13 - 0000000007EDF520
R14  - 0000000007EDF6A8, R15 - 0000000005FA9490
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - FFFFFFFFFFFFFFFF, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007418018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007EDEE30
!!!! Find image based on IP(0x603DB60) /var/home/ayush/Documents/Programming/Rust/uefi/hello_world_std/target/x86_64-unknown-uefi/debug/deps/hello_world_std-338028f9369e2d42.pdb (ImageBase=000000000603C000, EntryPoint=000000000603D8C0) !!!!

```


From my testing, the exception only occurs when a few conditions are met.

1. The binary is compiled in Debug mode. No error in Release mode.

2. `i128` is in a black_box [1]. Does not occur if `black_box` is not present.

3. It has to be `i128`. `i64` or something else work fine.

4. The cast has to be done on `-z`. Doing the same with `+z` is fine.


I have also been discussing this in the Rust zulipchat [2], so feel free to chime in there.


Additionally, here are links for more information about this program:

1. Assembly: https://rust-lang.zulipchat.com/user_uploads/4715/od51Y9Dkfjahcg9HHcOud8Fm/hello_world_std-338028f9369e2d42.s

2. EFI Binary: https://rust-lang.zulipchat.com/user_uploads/4715/CknqtXLR8SaJZmyOnXctQkpL/hello_world_std.efi

3. PDB file: https://rust-lang.zulipchat.com/user_uploads/4715/zV4i6DsjgQXotp_gS1naEsU0/hello_world_std-338028f9369e2d42.pdb


Yours Sincerely,

Ayush Singh


[1]: https://doc.rust-lang.org/std/hint/fn.black_box.html

[2]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Casting.20i128.20to.20f64.20in.20black_box.20causes.20exception.20in.20UEFI








Re: Casting i128 into f64 in UEFI Rust pagefaults

Pedro Falcato
 

Fyi, please don't file bugs upstream just now. You're not sure if they're LLVM problems (and they're likely not, else they would affect everyone else, not just UEFI code). Try to get a simpler, reliable repro (and do share with us!) before saying it's an LLVM bug.
In my experience, most "what the hell" "compiler bugs" ended up being things I accidentally set up wrong, or didn't set up at all, and broke things in a subtle way.


On Tue, Jul 26, 2022 at 6:43 AM Ayush Singh <ayushdevel1325@...> wrote:

Hi Andrew. Thanks for all your work. The more I look at this, the more it feels like it might be a problem on the LLVM side instead of Rust. I also found some more tests (all related to numbers btw) which can cause different types of exceptions, so I think I will try filing bugs upstream.

Yours Sincerely,

Ayush Singh


On 7/26/22 00:24, Andrew Fish wrote:
I guess I could at least dump to the end (req)…. Going backwards is a bit painful in x86. 

(lldb) dis -s 0x0000000140001B60 -b -c 30

hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx

hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx

hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx

hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx

hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx

hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx

hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 

hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                 callq  0x1400070e0

hello_world_std.efi[0x140001b84]: 48 09 f0                       orq    %rsi, %rax

hello_world_std.efi[0x140001b87]: 48 83 c4 20                    addq   $0x20, %rsp

hello_world_std.efi[0x140001b8b]: 5e                             popq   %rsi

hello_world_std.efi[0x140001b8c]: c3                             retq   

hello_world_std.efi[0x140001b8d]: cc                             int3   

hello_world_std.efi[0x140001b8e]: cc                             int3   

hello_world_std.efi[0x140001b8f]: cc                             int3   

hello_world_std.efi[0x140001b90]: e9 db 55 00 00                 jmp    0x140007170

hello_world_std.efi[0x140001b95]: cc                             int3   


Then we can guess based on how functions get aligned to find the start….

hello_world_std.efi[0x140001b50]: 56                                   pushq  %rsi

hello_world_std.efi[0x140001b51]: 48 83 ec 20                          subq   $0x20, %rsp

hello_world_std.efi[0x140001b55]: 4c 8b 41 08                          movq   0x8(%rcx), %r8

hello_world_std.efi[0x140001b59]: 4c 89 c0                             movq   %r8, %rax

hello_world_std.efi[0x140001b5c]: 48 c1 f8 3f                          sarq   $0x3f, %rax

hello_world_std.efi[0x140001b60]: 48 8b 09                             movq   (%rcx), %rcx

hello_world_std.efi[0x140001b63]: 48 01 c1                             addq   %rax, %rcx

hello_world_std.efi[0x140001b66]: 4c 89 c2                             movq   %r8, %rdx

hello_world_std.efi[0x140001b69]: 48 11 c2                             adcq   %rax, %rdx

hello_world_std.efi[0x140001b6c]: 48 31 c1                             xorq   %rax, %rcx

hello_world_std.efi[0x140001b6f]: 48 31 c2                             xorq   %rax, %rdx

hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80        movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 

hello_world_std.efi[0x140001b7c]: 4c 21 c6                             andq   %r8, %rsi

hello_world_std.efi[0x140001b7f]: e8 5c 55 00 00                       callq  0x1400070e0

hello_world_std.efi[0x140001b84]: 48 09 f0                             orq    %rsi, %rax

hello_world_std.efi[0x140001b87]: 48 83 c4 20                          addq   $0x20, %rsp

hello_world_std.efi[0x140001b8b]: 5e                                   popq   %rsi

hello_world_std.efi[0x140001b8c]: c3                                   retq   


So the faulting function is getting passed a bad pointer as its 1st arg. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 11:45 AM, Andrew Fish <afish@...> wrote:

Ops… Looks like your PE/COFF is linked at 0x0000000140000000, so 0x140001b60 is the interesting bit.

(lldb) dis -s 0x0000000140001B60 -b
hello_world_std.efi[0x140001b60]: 48 8b 09                       movq   (%rcx), %rcx
hello_world_std.efi[0x140001b63]: 48 01 c1                       addq   %rax, %rcx
hello_world_std.efi[0x140001b66]: 4c 89 c2                       movq   %r8, %rdx
hello_world_std.efi[0x140001b69]: 48 11 c2                       adcq   %rax, %rdx
hello_world_std.efi[0x140001b6c]: 48 31 c1                       xorq   %rax, %rcx
hello_world_std.efi[0x140001b6f]: 48 31 c2                       xorq   %rax, %rdx
hello_world_std.efi[0x140001b72]: 48 be 00 00 00 00 00 00 00 80  movabsq $-0x8000000000000000, %rsi ; imm = 0x8000000000000000 
hello_world_std.efi[0x140001b7c]: 4c 21 c6                       andq   %r8, %rsi

 RCX - FFFFFFFFFFFFFFFF

So yea that looks like the fault. 

I don’t see that pattern in your .s file…. 

Can you figure out what function is @ 0x140001b60 in the PE/COFF image. Do you have a map file from the linker?

Thanks,

Andrew Fish

PS Again sorry I don’t have anything installed to crack PDB files. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:51 AM, Andrew Fish via groups.io <afish@...> wrote:

Ayush,

CR2 is the fault address so 0xFFFFFFFFFFFFFFFF. Given for EFI Virt == Physical the fault address looks like a bad pointer. 

Sorry I’ve not used VC++ in a long time so I don’t know how to debug with VC++, but If I was using clang/lldb I’d look at the source and assembly for the fault address. 

The image base is: 0x000000000603C000
The fault PC/RIP is: 000000000603DB60

So the faulting code is at 0x1B60 in the image. Given the images are linked at zero you should be able to load the build product into the debugger and look at what code is at offset 0x1B60. The same should work for any tools that dump the binary. 

Thanks,

Andrew Fish

On Jul 25, 2022, at 10:33 AM, Ayush Singh <ayushdevel1325@...> wrote:

Hello everyone.While running Rust tests in UEFI environment, I have come across a numeric test that causes a pagefault. A simple reproducible example for this is given below:

```rust

fn main() {
    use std::hint::black_box as b;

    let z: i128 = b(1);
    assert!((-z as f64) < 0.0);
}

```


The exception output is as follows:

```

!!!! X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000  I:0 R:0 U:0 W:0 P:0 PK:0 SS:0 SGX:0
RIP  - 000000000603DB60, CS  - 0000000000000038, RFLAGS - 0000000000000246
RAX  - 0000000000000000, RCX - FFFFFFFFFFFFFFFF, RDX - FFFFFFFFFFFFFFFF
RBX  - 0000000000000000, RSP - 0000000007EDF1D0, RBP - 0000000007EDF4C0
RSI  - 0000000007EDF360, RDI - 0000000007EDF3C0
R8   - 0000000000000000, R9  - 0000000000000038, R10 - 0000000000000000
R11  - 0000000000000000, R12 - 00000000060C6018, R13 - 0000000007EDF520
R14  - 0000000007EDF6A8, R15 - 0000000005FA9490
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - FFFFFFFFFFFFFFFF, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007418018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007EDEE30
!!!! Find image based on IP(0x603DB60) /var/home/ayush/Documents/Programming/Rust/uefi/hello_world_std/target/x86_64-unknown-uefi/debug/deps/hello_world_std-338028f9369e2d42.pdb (ImageBase=000000000603C000, EntryPoint=000000000603D8C0) !!!!

```


From my testing, the exception only occurs when a few conditions are met.

1. The binary is compiled in Debug mode. No error in Release mode.

2. `i128` is in a black_box [1]. Does not occur if `black_box` is not present.

3. It has to be `i128`. `i64` or something else work fine.

4. The cast has to be done on `-z`. Doing the same with `+z` is fine.


I have also been discussing this in the Rust zulipchat [2], so feel free to chime in there.


Additionally, here are links for more information about this program:

1. Assembly: https://rust-lang.zulipchat.com/user_uploads/4715/od51Y9Dkfjahcg9HHcOud8Fm/hello_world_std-338028f9369e2d42.s

2. EFI Binary: https://rust-lang.zulipchat.com/user_uploads/4715/CknqtXLR8SaJZmyOnXctQkpL/hello_world_std.efi

3. PDB file: https://rust-lang.zulipchat.com/user_uploads/4715/zV4i6DsjgQXotp_gS1naEsU0/hello_world_std-338028f9369e2d42.pdb


Yours Sincerely,

Ayush Singh


[1]: https://doc.rust-lang.org/std/hint/fn.black_box.html

[2]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Casting.20i128.20to.20f64.20in.20black_box.20causes.20exception.20in.20UEFI








--
Pedro Falcato

4861 - 4880 of 96644