DynamicTablesPkg: Add MetadataHandlerLib library

Built on top of the MetadataObjLib, this library aims to
provide functions for each METADATA_ID to:
- Generate new Metadata on the fly: the caller provides
  minimal information for a METADATA_ID, and the library
  generates the missing information.
- Validate all the Metadata objects for a METADATA_ID.
  For instance, _UID must be unique for a _HID/_CID/EISAID.

This patch also adds support for generation/validation of:
- UIDs:
For each EISAID or NameId, UIDs must be unique. The generation
if UIDs is done by a per-EISAID/NameId incrementing counter.
The validation of the Metadata consists in checking for the
uniqueness of the UID per EISAID/NameId.

- ProximityDomains:
Proximity Domain Ids are generated by a counter, starting
from 0.
The validation of the Metadata consists in checking for
the uniqueness of the proximity domain Ids.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
This commit is contained in:
Pierre Gondois
2025-04-25 11:13:05 +02:00
committed by mergify[bot]
parent 1b7d687dc6
commit d15e48853c
9 changed files with 788 additions and 0 deletions

View File

@@ -23,6 +23,7 @@
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
MetadataObjLib|DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf
MetadataHandlerLib|DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf
[LibraryClasses.AARCH64]
DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf

View File

@@ -46,6 +46,9 @@
## @libraryclass Defines a set of APIs to a handle Metadata around CmObj.
MetadataObjLib|Include/Library/MetadataObjLib.h
## @libraryclass Defines a set of APIs to a handle Metadata generation/validation.
MetadataHandlerLib|Include/Library/MetadataHandlerLib.h
[LibraryClasses.AARCH64]
## @libraryclass Defines a set of APIs to populate CmObj using SCMI.
DynamicTablesScmiInfoLib|Include/Library/DynamicTablesScmiInfoLib.h

View File

@@ -49,6 +49,7 @@
DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf
DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf
[Components.ARM, Components.AARCH64]
DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf

View File

@@ -0,0 +1,57 @@
/** @file
Metadata Handler Library.
Copyright (c) 2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef METADATA_HANDLER_LIB_H_
#define METADATA_HANDLER_LIB_H_
#include <Library/MetadataObjLib.h>
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataHandlerGenerate (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
);
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataHandlerValidate (
IN METADATA_ROOT_HANDLE Root
);
#endif // METADATA_HANDLER_LIB_H_

View File

@@ -0,0 +1,112 @@
/** @file
Metadata Handler Library.
Copyright (c) 2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <ConfigurationManagerObject.h>
#include <Library/MetadataObjLib.h>
#include "MetadataHandler.h"
/* Metadata handlers. */
STATIC METADATA_HANDLERS mMetadataHandlers[MetadataTypeMax] = {
// MetadataTypeUid
{
MetadataGenerateUid,
MetadataValidateUid,
},
// MetadataTypeProximityDomain
{
MetadataGenerateProximityDomain,
MetadataValidateProximityDomain,
},
};
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataHandlerGenerate (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
)
{
EFI_STATUS Status;
if ((Type >= MetadataTypeMax) ||
(Token == CM_NULL_TOKEN) ||
(Metadata == NULL) ||
(MetadataSize == 0))
{
ASSERT (Type < MetadataTypeMax);
ASSERT (Token != CM_NULL_TOKEN);
ASSERT (Metadata != NULL);
ASSERT (MetadataSize != 0);
return EFI_INVALID_PARAMETER;
}
Status = mMetadataHandlers[Type].Generate (
Root,
Type,
Token,
Context,
Metadata,
MetadataSize
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataHandlerValidate (
IN METADATA_ROOT_HANDLE Root
)
{
EFI_STATUS Status;
METADATA_TYPE Type;
for (Type = 0; Type < MetadataTypeMax; Type++) {
Status = mMetadataHandlers[Type].Validate (Root);
ASSERT_EFI_ERROR (Status);
}
return Status;
}

View File

@@ -0,0 +1,144 @@
/** @file
Metadata Handler Library.
Copyright (c) 2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef METADATA_HANDLER_H_
#define METADATA_HANDLER_H_
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
typedef EFI_STATUS (EFIAPI *METADATA_GENERATOR)(
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
);
/** Validate the Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
typedef EFI_STATUS (EFIAPI *METADATA_VALIDATOR)(
IN METADATA_ROOT_HANDLE Root
);
/** Metadata Handlers.
*/
typedef struct MetadataHandlers {
METADATA_GENERATOR Generate;
METADATA_VALIDATOR Validate;
} METADATA_HANDLERS;
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataGenerateUid (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
);
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataValidateUid (
IN METADATA_ROOT_HANDLE Root
);
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataGenerateProximityDomain (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
);
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataValidateProximityDomain (
IN METADATA_ROOT_HANDLE Root
);
#endif // METADATA_HANDLER_H_

View File

@@ -0,0 +1,29 @@
## @file
# Metadata Handler Library
#
# Copyright (c) 2025, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = MetadataHandlerLib
FILE_GUID = 60E0B01A-94E6-48C6-B21B-F772E58352E9
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
LIBRARY_CLASS = MetadataHandlerLib
[Sources]
MetadataHandler.c
MetadataHandler.h
MetadataProximityDomain.c
MetadataUid.c
[Packages]
MdePkg/MdePkg.dec
DynamicTablesPkg/DynamicTablesPkg.dec
[LibraryClasses]
BaseLib
MetadataObjLib

View File

@@ -0,0 +1,154 @@
/** @file
Metadata Proximity Domain handlers.
Copyright (c) 2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <ConfigurationManagerObject.h>
#include <Library/MetadataObjLib.h>
#include "MetadataHandler.h"
typedef struct ProximityDomainData {
/// Current Id used for the Proximity Domain Id generation.
UINT32 CurrentId;
} PROXIMITY_DOMAIN_DATA;
STATIC PROXIMITY_DOMAIN_DATA mProximityDomainData = {
0
};
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataGenerateProximityDomain (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
)
{
EFI_STATUS Status;
METADATA_OBJ_PROXIMITY_DOMAIN *ProximityDomain;
if ((Type != MetadataTypeProximityDomain) ||
(Token == CM_NULL_TOKEN) ||
(Metadata == NULL))
{
ASSERT (Type == MetadataTypeProximityDomain);
ASSERT (Token != CM_NULL_TOKEN);
ASSERT (Metadata != NULL);
return EFI_INVALID_PARAMETER;
}
Status = MetadataGet (Root, Type, Token, Metadata, MetadataSize);
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
ASSERT_EFI_ERROR (Status);
return Status;
} else if (Status == EFI_SUCCESS) {
// Metadata for this (Type/Token) already exists.
return EFI_SUCCESS;
}
// Generate new Metadata (i.e. Status == EFI_NOT_FOUND).
ProximityDomain = (METADATA_OBJ_PROXIMITY_DOMAIN *)Metadata;
ProximityDomain->Id = mProximityDomainData.CurrentId++;
Status = MetadataAdd (Root, Type, Token, Metadata, MetadataSize);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
return EFI_SUCCESS;
}
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataValidateProximityDomain (
IN METADATA_ROOT_HANDLE Root
)
{
METADATA_HANDLE Handle0;
METADATA_HANDLE Handle1;
METADATA_OBJ_PROXIMITY_DOMAIN Metadata0;
METADATA_OBJ_PROXIMITY_DOMAIN Metadata1;
Handle0 = NULL;
while (TRUE) {
Handle0 = MetadataIterate (
Root,
MetadataTypeProximityDomain,
Handle0,
&Metadata0,
sizeof (METADATA_OBJ_PROXIMITY_DOMAIN)
);
if (Handle0 == NULL) {
break;
}
// Loop starting from Handle0
Handle1 = Handle0;
while (TRUE) {
Handle1 = MetadataIterate (
Root,
MetadataTypeProximityDomain,
Handle1,
&Metadata1,
sizeof (METADATA_OBJ_PROXIMITY_DOMAIN)
);
if (Handle1 == NULL) {
break;
}
if (Metadata0.Id == Metadata1.Id) {
DEBUG ((
DEBUG_ERROR,
"Metadata: ProximityDomain: Same Id: %d\n",
Metadata0.Id
));
ASSERT (0);
}
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,287 @@
/** @file
Metadata Proximity Domain handlers.
Copyright (c) 2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <ConfigurationManagerObject.h>
#include <Library/MetadataObjLib.h>
#include "MetadataHandler.h"
/** Uid Entry
One entry is allocated for each HID/CID/EISAID. Each entry
contains a counter used for the generation of UID values.
**/
typedef struct MetadataUidEntry {
LIST_ENTRY List;
/// _HID or _CID of the device (NULL-terminated string).
/// This provides a mean to uniquely identify a device type.
/// If not populated, EisaId must be set.
CHAR8 NameId[9];
/// EisaId of the device.
/// This provides a mean to uniquely identify a device type.
/// If not populated, NameId must be set.
UINT32 EisaId;
/// Current Id used for the generation of a HID/CID/EisaId.
UINT32 CurrId;
} METADATA_UID_ENTRY;
// List of METADATA_UID_ENTRY
STATIC LIST_ENTRY mUidList = INITIALIZE_LIST_HEAD_VARIABLE (mUidList);
/** Allocate a METADATA_UID_ENTRY.
@param [in] Metadata Metadata containing the NameId/EisaId to use.
@param [out] OutEntry Allocated Entry.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
**/
STATIC
EFI_STATUS
EFIAPI
AllocateUidEntry (
IN METADATA_OBJ_UID *Metadata,
OUT METADATA_UID_ENTRY **OutEntry
)
{
METADATA_UID_ENTRY *Entry;
if ((Metadata == NULL) || (OutEntry == NULL)) {
return EFI_INVALID_PARAMETER;
}
Entry = AllocateZeroPool (sizeof (METADATA_UID_ENTRY));
if (Entry == NULL) {
ASSERT (Entry != NULL);
return EFI_OUT_OF_RESOURCES;
}
InitializeListHead (&Entry->List);
Entry->CurrId = 0;
if (Metadata->NameId[0] != 0) {
AsciiStrCpyS (Entry->NameId, sizeof (Metadata->NameId), Metadata->NameId);
} else {
Entry->EisaId = Metadata->EisaId;
}
*OutEntry = Entry;
return EFI_SUCCESS;
}
/** Find a matching METADATA_UID_ENTRY.
If no Entry is found, allocate one.
@param [in] Metadata Metadata containing the NameId/EisaId to search.
@param [out] OutEntry Matching or allocated Entry.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Out of resources.
**/
STATIC
EFI_STATUS
EFIAPI
FindEntry (
IN METADATA_OBJ_UID *Metadata,
OUT METADATA_UID_ENTRY **OutEntry
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
METADATA_UID_ENTRY *Entry;
if ((Metadata == NULL) || (OutEntry == NULL)) {
ASSERT (Metadata != NULL);
ASSERT (OutEntry != NULL);
return EFI_INVALID_PARAMETER;
}
Link = GetNextNode (&mUidList, &mUidList);
while (Link != &mUidList) {
Entry = (METADATA_UID_ENTRY *)Link;
if (Entry->NameId[0] != 0) {
if (AsciiStrnCmp (Entry->NameId, Metadata->NameId, sizeof (Metadata->NameId)) == 0) {
break;
}
} else if (Metadata->EisaId != 0) {
if (Entry->EisaId == Metadata->EisaId) {
break;
}
} else {
DEBUG ((DEBUG_ERROR, "MetadatUid: Empty NameId and EisaId\n"));
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Link = GetNextNode (&mUidList, Link);
} // while
// No matching METADATA_UID_ENTRY found.
if (Link == &mUidList) {
Status = AllocateUidEntry (Metadata, &Entry);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
InsertTailList (&mUidList, &Entry->List);
}
*OutEntry = Entry;
return EFI_SUCCESS;
}
/** Query the MetadataObjLib for metadata matching the input (Type/Token).
If the metadata exists, return it.
Otherwise:
- Generate a new metadata object
- Add it to the MetadataObjLib
- return it
@param[in] Root Root of the Metadata information.
@param[in] Type METADATA_TYPE of the entry to generate.
@param[in] Token Token uniquely identifying an entry among other
objects with the input METADATA_TYPE.
@param[in] Context Optional context to use during the Metadata generation.
@param[in, out] Metadata On input, can contain METADATA_TYPE-specific information.
On output and if success, contains the generated
Metadata object.
@param[in] MetadataSize Size of the input Metadata.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataGenerateUid (
IN METADATA_ROOT_HANDLE Root,
IN METADATA_TYPE Type,
IN CM_OBJECT_TOKEN Token,
IN VOID *Context,
IN OUT VOID *Metadata,
IN UINT32 MetadataSize
)
{
EFI_STATUS Status;
METADATA_OBJ_UID *Uid;
METADATA_UID_ENTRY *Entry;
if ((Type != MetadataTypeUid) ||
(Token == CM_NULL_TOKEN) ||
(Metadata == NULL))
{
ASSERT (Type == MetadataTypeUid);
ASSERT (Token != CM_NULL_TOKEN);
ASSERT (Metadata != NULL);
return EFI_INVALID_PARAMETER;
}
Status = MetadataGet (Root, Type, Token, Metadata, MetadataSize);
if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
ASSERT_EFI_ERROR (Status);
return Status;
} else if (Status == EFI_SUCCESS) {
// Metadata for this (Type/Token) already exists.
return EFI_SUCCESS;
}
// Generate new Metadata (i.e. Status == EFI_NOT_FOUND).
// Get the Current Type for this HID/CID/EISAID
Status = FindEntry (Metadata, &Entry);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
Uid = (METADATA_OBJ_UID *)Metadata;
Uid->Uid = Entry->CurrId++;
Status = MetadataAdd (Root, Type, Token, Metadata, MetadataSize);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
return EFI_SUCCESS;
}
/** Validate the Metadata.
@param[in] Root Root of the Metadata information.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
EFI_STATUS
EFIAPI
MetadataValidateUid (
IN METADATA_ROOT_HANDLE Root
)
{
METADATA_HANDLE Handle0;
METADATA_HANDLE Handle1;
METADATA_OBJ_UID Metadata0;
METADATA_OBJ_UID Metadata1;
Handle0 = NULL;
while (TRUE) {
Handle0 = MetadataIterate (
Root,
MetadataTypeUid,
Handle0,
&Metadata0,
sizeof (METADATA_OBJ_UID)
);
if (Handle0 == NULL) {
break;
}
// Loop starting from Handle0
Handle1 = Handle0;
while (TRUE) {
Handle1 = MetadataIterate (
Root,
MetadataTypeUid,
Handle1,
&Metadata1,
sizeof (METADATA_OBJ_UID)
);
if (Handle1 == NULL) {
break;
}
if (CompareMem (&Metadata0, &Metadata1, sizeof (METADATA_OBJ_UID)) == 0) {
DEBUG ((
DEBUG_ERROR,
"Metadata: Uid: Same Type: EisaId=%d NameId=%a Uid=%d \n",
Metadata0.EisaId,
Metadata0.NameId,
Metadata0.Uid
));
ASSERT (0);
}
}
}
return EFI_SUCCESS;
}