From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by mx.groups.io with SMTP id smtpd.web10.441.1596212376194265621 for ; Fri, 31 Jul 2020 09:19:36 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=mA/haqwh; spf=pass (domain: nuviainc.com, ip: 209.85.221.42, mailfrom: tomas@nuviainc.com) Received: by mail-wr1-f42.google.com with SMTP id r4so25547803wrx.9 for ; Fri, 31 Jul 2020 09:19:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SVKSk9DKibIhk7E//2kcKU7jdGDLYkhXzDpmCtgo1rA=; b=mA/haqwhbE9f8wp5wXgrPSmeDTnRP9SZ81r1FTlXNw57fr0bIl/L1jU2vPb1JqDn9/ pIMp+I9EvjaaKwnYwT2AWzWv9Dyli4QXXca5eGg2m5YifrT+Oe9Dm4MyX5mK4AiAekzq Sdn3Qs2aAvfhbuP8bqbMVIyEZZ2nhEVPGWp3iVXa/qqsw9MpxKUIQz4jbmqx7ye1JbnK SGP85UdMW0jiDGPZZtKsFKvDQa2um1eKXiCC2AdHxCshYKVP1kNL1PonxWY8qa10aCSe slDh+LNNqRpnMzpGSjo6nIVnfXTirL23PwUrnQn5dKj9mRGm0vskoNzUrMjkSQ3pXbOR bnJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SVKSk9DKibIhk7E//2kcKU7jdGDLYkhXzDpmCtgo1rA=; b=EwYc9K2oG8AQrGYOd5UjRNuh3sNACcRdvOvaXbPxK8zhx+j5vG1uljMXDi2R4YJnWC 90F5NUo6sO2n0Rtk+nBY/n+MsrQ/EveBDji1xvCBwEXe2nAVIui8VbvfEMcLf8rTiKsa FEz7Sztvl+aFqaE5smGrORJb1/p7+h0lAlWXzxFjfAyXGyQoGWDkNVy+BRYihEjRWc4g makMBnbFznzQUVLWBtC7Qk5QJMNPpX9XC/spMsu3FGW4ZDgRyPb97LAJjmjMOvp7U72y cGzvA/sgXdqxTRMjtHR6aMNuNBITTToJHK9I1hQJUaCMzSqGB9xOhPy6yQtPOm2CDkXz lQjw== X-Gm-Message-State: AOAM532tUEQiemBqe2RAIsjtGWW4PH+KAeXVQ8IvknC+hzLeJbo+L9hM Ut6/G3NK9U6ZL6RcDecKmj17r+NMz2dTv7AFf6A+CmQ2slXxf5JfrXFa1f3aizRlylOlb9OyT4x eZn+2IEdHRxMepj/yDyYhFBpMP5YDaBNc6+OaRUwpXh/Zx7dZqhXEAc2ZulVEl6VfBrk= X-Google-Smtp-Source: ABdhPJwkLMdbb6d/DaiRTRx86ZRvNo0sRmljgLlDnQ9UCxQOxArueHSvjCYSpb1vNM6hDXS5jEZGgg== X-Received: by 2002:a5d:4a03:: with SMTP id m3mr3985160wrq.186.1596212373727; Fri, 31 Jul 2020 09:19:33 -0700 (PDT) Return-Path: Received: from localhost.localdomain (cpc159317-cmbg20-2-0-cust162.5-4.cable.virginm.net. [81.111.29.163]) by smtp.gmail.com with ESMTPSA id v11sm14149739wrr.10.2020.07.31.09.19.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2020 09:19:32 -0700 (PDT) From: "Tomas Pilar (tpilar)" To: devel@edk2.groups.io Cc: Sami Mujawar , Alexei Fedorov Subject: [PATCH 5/8] DynamicTablesPkg: Add CfgMgrProtocol helper functions Date: Fri, 31 Jul 2020 17:19:23 +0100 Message-Id: <20200731161926.341330-6-tomas@nuviainc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200731161926.341330-1-tomas@nuviainc.com> References: <20200731161926.341330-1-tomas@nuviainc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add functions abstracting adding and removing of objects using the ConfigurationManagerProtocol to TableHelperLib. Also add helpers for writing component library constructors for component libraries populating a ConfigurationManager. Cc: Sami Mujawar Cc: Alexei Fedorov Signed-off-by: Tomas Pilar --- .../Include/Library/TableHelperLib.h | 170 ++++++++ .../Common/TableHelperLib/TableHelper.c | 379 +++++++++++++++++- .../Common/TableHelperLib/TableHelperLib.inf | 6 + 3 files changed, 554 insertions(+), 1 deletion(-) diff --git a/DynamicTablesPkg/Include/Library/TableHelperLib.h b/DynamicTablesPkg/Include/Library/TableHelperLib.h index e4a8dfa046..0d3d1bbd60 100644 --- a/DynamicTablesPkg/Include/Library/TableHelperLib.h +++ b/DynamicTablesPkg/Include/Library/TableHelperLib.h @@ -12,6 +12,176 @@ #ifndef TABLE_HELPER_LIB_H_ #define TABLE_HELPER_LIB_H_ +#include + +/** + Get a unique token that can be used for configuration object + cross referencing. + + @retval Unique arbitrary cross reference token. +**/ +UINTN +EFIAPI +GetNewToken(); + +/** + Return the count of objects of a given ObjectId. + + @param[in] CmObjectId The id of the desired configuration objects. + @param[out] ItemCount Number of objects with given ObjectId. +**/ +EFI_STATUS +EFIAPI +CfgMgrCountObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + OUT UINT32 *ItemCount + ); + +/** + Get a single object form the configuration manager with the + matching ObjectId regardless of any cross reference tokens. + + @param[in] CmObjectId The id of the desired configuration object + @param[out] Buffer Buffer containing the payload of the CmObject. + + @retval EFI_SUCCESS Payload was successfully returned + @retval EFI_NOT_FOUND There was no such object + @retval EFI_UNSUPPORTED ConfigurationManangerProtocol is not installed +**/ +EFI_STATUS +EFIAPI +CfgMgrGetSimpleObject( + IN CONST CM_OBJECT_ID CmObjectId, + OUT VOID ** Buffer + ); + +/** + Prototype for an initialiser function to be used by component + libraries that are linked as NULL libraries to a Configuration + Manager binary and used to populate said Configuration Manager + with objects. + + @param[in] CfgMgrProtocol The newly installed ConfigurationManagerProtocol + that can be used by the library to populate the + Configuration Manager with objects. +**/ +typedef EFI_STATUS (EFIAPI *CFG_MGR_COMPONENT_LIB_INIT) ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol + ); + +/** + Register a callback inintialiser to be called when a configuration + manager is installed. The initialiser function is expected to + populate the newly installed configuration manager with objects when + called. + + This helper should be used by component libraries that want to + provide configuration objects and are to be linked in as NULL + libraries into the configuration manager binary. + + @param[in] InitFunction An initialiser function that will be called when + a configuration manager becomes available. + @retval EFI_OUT_OF_RESOURCES Failed to allocate necessary memory. + @retval EFI_SUCCESS Registration was successful. +**/ +EFI_STATUS +EFIAPI +RegisterForCfgManager ( + IN CONST CFG_MGR_COMPONENT_LIB_INIT InitFunction + ); + +/** + Remove a configuration object from the configuration manager. If a + cross reference token is supplied, only objects referenced by that + token will be removed. If a token is not supplied, all objects of the + given type will be removed. + + @param[in] CmObjectId The id of the object that is to be removed. + @param[in] Token Unique cross-reference token of the object to be removed. + + @retval EFI_UNSUPPORTED There is no configuration manager installed. + @retval EFI_NOT_FOUND The combination of id and token was not found in the + configuration manager. + @retval EFI_SUCCESS Object was successfully deleted. +**/ +EFI_STATUS +EFIAPI +CfgMgrRemoveObject ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL + ); + +/** + Add an instance of object to the configuration manager. If an object with + the specified object id and token already exists in the manager, append the + provided object to the existing list. Otherwise, create a new list with this + object being the only member. + + @param[in] CmObjectId The id of the object that is to be added. + @param[in] Token The unique cross-reference token for this object. + @param[in] Buffer The instance of the object being added. + @param[in] BufferSize Size of Buffer in bytes. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate required memory when appending data + @retval EFI_UNSUPPORTED There is no Configuration Manager installed + @retval EFI_SUCCESS Object was successfully added to the Configuration Manager +**/ +EFI_STATUS +EFIAPI +CfgMgrAddObject ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN VOID * Buffer, + IN UINTN BufferSize + ); + +/** + Add multiple objects of the same type/token to the configuration manager. + If an object with the specified object id and token already exists in the + manager, append the provided objects to the existing list. Otherwise, create + a new list. + + @param[in] CmObjectId The id of the object that is to be added. + @param[in] Token The unique cross-reference token for this object. + @param[in] Buffer The instance of the objects being added. + @param[in] BufferSize Size of Buffer in bytes. + @param[in] ItemCount Number of instances of object in the Buffer. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate required memory when appending data. + @retval EFI_UNSUPPORTED There is no Configuration Manager installed. + @retval EFI_SUCCESS Object was successfully added to the Configuration Manager. +**/ +EFI_STATUS +EFIAPI +CfgMgrAddObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN VOID * Buffer, + IN UINTN BufferSize, + IN UINT32 ItemCount + ); + +/** + Retrieve an object with a given id from the installed configuration + manager. If a token is not specified, returns all objects of given + id, regardless of token. The methods unwraps the CmObject abstraction + and only returns the payloads. + + @param[in] CmObjectId The id of the desired configuration objects. + @param[in] Token Optional cross reference token. If not supplied, all. + objects of the given id are returned. + @param[out] Buffer Buffer containing a number of payloads of CmObjects. + @param[out] ItemCount The count of payloads in Buffer. +**/ +EFI_STATUS +EFIAPI +CfgMgrGetObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + OUT VOID ** Buffer OPTIONAL, + OUT UINT32 * ItemCount OPTIONAL + ); + /** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO object from the Configuration Manager. diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c index fc6cf3b088..18c0e95e0d 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c @@ -6,9 +6,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include + #include -#include #include +#include +#include +#include +#include // Module specific include files. #include @@ -16,6 +20,378 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +/** + Get a unique token that can be used for configuration object + cross referencing. + + @retval Unique arbitrary cross reference token +**/ +UINTN +EFIAPI +GetNewToken() +{ + UINTN Token; + EFI_STATUS Status = gBS->GetNextMonotonicCount(&Token); + if (EFI_ERROR(Status)) { + return CM_NULL_TOKEN; + } + + return Token; +} + +/** + Event callback for executing the registered component library + inintialiser with the newly installed ConfigurationManagerProtocol + as the only parameter. +**/ +STATIC +VOID +EFIAPI +ComponentInitEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + ASSERT (Context != NULL); + + CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; + CFG_MGR_COMPONENT_LIB_INIT InitFunction = Context; + + EFI_STATUS Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, + NULL, + (VOID **) &CfgMgrProtocol); + + + if (EFI_ERROR(Status)) { // Should never happen + gBS->CloseEvent(Event); + RegisterForCfgManager(InitFunction); + return; + } + + InitFunction(CfgMgrProtocol); +} + +/** + Register a callback inintialiser to be called when a configuration + manager is installed. The initialiser function is expected to + populate the newly installed configuration manager with objects when + called. + + This helper should be used by component libraries that want to + provide configuration objects and are to be linked in as NULL + libraries into the configuration manager binary. + + @param[in] InitFunction An initialiser function that will be called when + a configuration manager becomes available. + @retval EFI_OUT_OF_RESOURCES Failed to allocate necessary memory + @retval EFI_SUCCESS Registration was successful +**/ +EFI_STATUS +EFIAPI +RegisterForCfgManager ( + CONST CFG_MGR_COMPONENT_LIB_INIT InitFunction + ) +{ + EFI_STATUS Status = EFI_NOT_STARTED; + EFI_EVENT InitEvent; + VOID *Registration; + + ASSERT(InitFunction != NULL); + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + ComponentInitEvent, + InitFunction, + &InitEvent); + + if (EFI_ERROR(Status)) { + return Status; + } + + Status = gBS->RegisterProtocolNotify ( + &gEdkiiConfigurationManagerProtocolGuid, + InitEvent, + &Registration); + + if (EFI_ERROR(Status)) { + gBS->CloseEvent(InitEvent); + } + + return Status; +} + +/** + Return the count of objects of a given ObjectId. + If there are no objects, ItemCount is set to zero. + + @param[in] CmObjectId The id of the desired configuration objects. + @param[out] ItemCount Number of objects with given ObjectId. +**/ +EFI_STATUS +EFIAPI +CfgMgrCountObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + OUT UINT32 *ItemCount + ) +{ + EFI_STATUS Status = EFI_NOT_STARTED; + + Status = CfgMgrGetObjects (CmObjectId, CM_NULL_TOKEN, NULL, ItemCount); + if (Status == EFI_NOT_FOUND) { + *ItemCount = 0; + } + + return Status; +} + +/** + Retrieve an object with a given id from the installed configuration + manager. If a token is not specified, returns all objects of given + id, regardless of token. The methods unwraps the CmObject abstraction + and only returns the payloads. + + If Buffer is not NULL, the data will be returned in allocated memory. The + caller must free this memory when they are done with the data. + + If ItemCount is not NULL, the count of items matching the criteria + is returned. + + @param[in] CmObjectId The id of the desired configuration objects + @param[in] Token Optional cross reference token. If not supplied, all + objects of the given id are returned. + @param[out] Buffer Buffer containing a number of payloads of CmObjects. + @param[out] ItemCount The count of payloads in Buffer +**/ +EFI_STATUS +EFIAPI +CfgMgrGetObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + OUT VOID ** Buffer OPTIONAL, + OUT UINT32 * ItemCount OPTIONAL + ) +{ + EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgr; + EFI_STATUS Status; + + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, NULL, (VOID **) &CfgMgr); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "ERROR: No Configuration Manager Protocol Found!\n")); + return EFI_UNSUPPORTED; + } + + CM_OBJ_DESCRIPTOR Object; + + Status = CfgMgr->GetObject(CfgMgr, CmObjectId, Token, &Object); + if (EFI_ERROR(Status)) { + if (Status != EFI_NOT_FOUND) { + DEBUG ( + (DEBUG_ERROR, + "ERROR: FADT: Failed to get <%s> [%r]\n", + CmObjectIdName (CmObjectId), + Status)); + } + + return Status; + } + + if (Buffer) { + *Buffer = AllocateCopyPool (Object.Size, Object.Data); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if (ItemCount) { + *ItemCount = Object.Count; + } + + if (CfgMgr->Revision >= CREATE_REVISION(1, 1)) { + CfgMgr->FreeObject(CfgMgr, &Object); + } + + return EFI_SUCCESS; +} + +/** + Get a single object form the configuration manager with the + matching ObjectId regardless of any cross reference tokens. + + @param[in] CmObjectId The id of the desired configuration object + @param[out] Buffer Buffer containing the payload of the CmObject. + + @retval EFI_SUCCESS Payload was successfully returned + @retval EFI_NOT_FOUND There was no such object + @retval EFI_UNSUPPORTED ConfigurationManangerProtocol is not installed +**/ +EFI_STATUS +EFIAPI +CfgMgrGetSimpleObject( + IN CONST CM_OBJECT_ID CmObjectId, + OUT VOID ** Buffer + ) +{ + EFI_STATUS Status; + + Status = CfgMgrGetObjects(CmObjectId, CM_NULL_TOKEN, Buffer, NULL); + if (Status == EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, + "ERROR: Failed to get <%s> [%r]\n", + CmObjectIdName (CmObjectId), + Status)); + } + return Status; +} + +/** + Add an instance of object to the configuration manager. If an object with + the specified object id and token already exists in the manager, append the + provided object to the existing list. Otherwise, create a new list with this + object being the only member. + + @param[in] CmObjectId The id of the object that is to be added + @param[in] Token The unique cross-reference token for this object + @param[in] Buffer The instance of the object being added + @param[in] BufferSize Size of Buffer in bytes + + @retval EFI_OUT_OF_RESOURCES Failed to allocate required memory when appending data + @retval EFI_UNSUPPORTED There is no Configuration Manager installed + @retval EFI_SUCCESS Object was successfully added to the Configuration Manager +**/ +EFI_STATUS +EFIAPI +CfgMgrAddObject ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN VOID * Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; + CM_OBJ_DESCRIPTOR CurrentObject = { 0 }; + CM_OBJ_DESCRIPTOR NewObject; + + ASSERT(Buffer != NULL); + ASSERT(BufferSize != 0); + + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, NULL, (VOID **) &CfgMgrProtocol); + + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + Status = CfgMgrProtocol->GetObject ( + CfgMgrProtocol, CmObjectId, Token, &CurrentObject); + + NewObject.ObjectId = CmObjectId; + NewObject.Count = 1 + CurrentObject.Count; + NewObject.Size = BufferSize +CurrentObject.Size; + + NewObject.Data = AllocateZeroPool(NewObject.Size); + if (NewObject.Data == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem(NewObject.Data, CurrentObject.Data, CurrentObject.Size); // NOP if CurrentObject does not exist + CopyMem((UINT8 *) NewObject.Data + CurrentObject.Size, Buffer, BufferSize); + + Status = + CfgMgrProtocol->SetObject (CfgMgrProtocol, CmObjectId, Token, &NewObject); + + FreePool (NewObject.Data); + return Status; +} + +/** + Add multiple objects of the same type/token to the configuration manager. + If an object with the specified object id and token already exists in the + manager, append the provided objects to the existing list. Otherwise, create + a new list. + + @param[in] CmObjectId The id of the object that is to be added. + @param[in] Token The unique cross-reference token for this object. + @param[in] Buffer The instance of the objects being added. + @param[in] BufferSize Size of Buffer in bytes. + @param[in] ItemCount Number of instances of object in the Buffer. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate required memory when appending data. + @retval EFI_UNSUPPORTED There is no Configuration Manager installed. + @retval EFI_SUCCESS Object was successfully added to the Configuration Manager. +**/ +EFI_STATUS +EFIAPI +CfgMgrAddObjects ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN VOID * Buffer, + IN UINTN BufferSize, + IN UINT32 ItemCount + ) +{ + UINTN Index; + UINT8 *Cursor = Buffer; + UINTN ItemSize = BufferSize / ItemCount; + EFI_STATUS Status = EFI_NOT_STARTED; + + for (Index = 0; Index < ItemCount; Index++) { + Status = CfgMgrAddObject(CmObjectId, Token, Cursor, ItemSize); + if (EFI_ERROR(Status)) { + return Status; + } + Cursor += ItemSize; + } + + return EFI_SUCCESS; +} + +/** + Remove a configuration object from the configuration manager. If a + cross reference token is supplied, only objects referenced by that + token will be removed. If a token is not supplied, all objects of the + given type will be removed. + + @param[in] CmObjectId The id of object that is to be removed + @param[in] Token Unique cross-reference token of the object to be removed + + @retval EFI_UNSUPPORTED There is no configuration manager installed + @retval EFI_NOT_FOUND The combination of id and token was not found in the + configuration manager + @retval EFI_SUCCESS Object was successfully deleted +**/ +EFI_STATUS +EFIAPI +CfgMgrRemoveObject ( + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL + ) +{ + EFI_STATUS Status = EFI_NOT_STARTED; + EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; + CM_OBJ_DESCRIPTOR CurrentObject; + + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, NULL, (VOID **) &CfgMgrProtocol); + + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + Status = CfgMgrProtocol->GetObject ( + CfgMgrProtocol, CmObjectId, Token, &CurrentObject); + + if (EFI_ERROR(Status)) { + return Status; + } + + return CfgMgrProtocol->SetObject (CfgMgrProtocol, CmObjectId, Token, NULL); +} + + /** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO object from the Configuration Manager. @@ -44,6 +420,7 @@ GetCgfMgrInfo ( ASSERT (CfgMfrInfo != NULL); *CfgMfrInfo = NULL; + Status = CfgMgrProtocol->GetObject ( CfgMgrProtocol, CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo), diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf index 26d82e6850..e12380073e 100644 --- a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf @@ -23,8 +23,14 @@ [LibraryClasses] BaseLib + BaseMemoryLib + DebugLib + PrintLib + MemoryAllocationLib + UefiBootServicesTableLib [Protocols] + gEfiSerialIoProtocolGuid [Guids] -- 2.25.1