* [PATCH v2 0/5] Add DynamicPlatRepoLib
@ 2021-11-23 11:10 PierreGondois
2021-11-23 11:10 ` [PATCH v2 1/5] DynamicTablesPkg: Definition for DynamicPlatRepoLib interface PierreGondois
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
v2:
- Various small fixes (change status returned, reset values when
freeing memory, ...). [Sami]
Ref:https://bugzilla.tianocore.org/show_bug.cgi?id=3743
The DynamicPlatRepoLib is library allowing to receive and then
give Configuration Manager (CM) objects.
After being initialized, a dynamic platform repository can receive
CMObjects. The library generates a token to uniquely identify the
CMObject in the repository. The dynamic platform repository must
then be 'finalized' before receiving CMObject queries.
This library is complementary to the 'static' definition of
CMObjects (i.e. as C structs). It is particularly useful when
using a HwInfoParserLib that dynamically creates CMObjects
(from a device tree for instance).
The changes can be seen at: https://github.com/PierreARM/edk2/tree/1788_Add_Dynamic_Plarform_Repository_Lib_v2
Pierre Gondois (5):
DynamicTablesPkg: Definition for DynamicPlatRepoLib interface
DynamicTablesPkg: DynamicPlatRepo: Add TokenGenerator
DynamicTablesPkg: DynamicPlatRepo: Add TokenFixer
DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper
DynamicTablesPkg: Add DynamicPlatRepo library
DynamicTablesPkg/DynamicTablesPkg.dec | 3 +
DynamicTablesPkg/DynamicTablesPkg.dsc | 1 +
.../Include/Library/DynamicPlatRepoLib.h | 114 ++++
.../DynamicPlatRepoLib/CmObjectTokenFixer.c | 164 ++++++
.../DynamicPlatRepoLib/CmObjectTokenFixer.h | 52 ++
.../DynamicPlatRepoLib/DynamicPlatRepo.c | 515 ++++++++++++++++++
.../DynamicPlatRepoInternal.h | 78 +++
.../DynamicPlatRepoLib/DynamicPlatRepoLib.inf | 33 ++
.../DynamicPlatRepoLib/TokenGenerator.c | 28 +
.../DynamicPlatRepoLib/TokenGenerator.h | 26 +
.../Common/DynamicPlatRepoLib/TokenMapper.c | 218 ++++++++
.../Common/DynamicPlatRepoLib/TokenMapper.h | 123 +++++
12 files changed, 1355 insertions(+)
create mode 100644 DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.h
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.h
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/5] DynamicTablesPkg: Definition for DynamicPlatRepoLib interface
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
@ 2021-11-23 11:10 ` PierreGondois
2021-11-23 11:10 ` [PATCH v2 2/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenGenerator PierreGondois
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
The DynamicPlatRepoLib library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.
A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to
retrieve dynamic CmObjs among all CmObj (static CmObj for instance).
This patch defines the library interface of the DynamicPlatRepo.
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.dec | 3 +
.../Include/Library/DynamicPlatRepoLib.h | 114 ++++++++++++++++++
2 files changed, 117 insertions(+)
create mode 100644 DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index 80a61dd2dbac..9b74c5a67178 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -24,6 +24,9 @@ [LibraryClasses]
## @libraryclass Defines a set of APIs for Dynamic AML generation.
AmlLib|Include/Library/AmlLib/AmlLib.h
+ ## @libraryclass Defines a set of APIs to handle dynamically created CmObj.
+ DynamicPlatRepoLib|Include/Library/DynamicPlatRepoLib.h
+
## @libraryclass Defines a set of APIs to a hardware information parser.
HwInfoParserLib|Include/Library/HwInfoParserLib.h
diff --git a/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h b/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
new file mode 100644
index 000000000000..4a76b30399b4
--- /dev/null
+++ b/DynamicTablesPkg/Include/Library/DynamicPlatRepoLib.h
@@ -0,0 +1,114 @@
+/** @file
+ Dynamic Platform Info Repository
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef DYNAMIC_PLAT_REPO_H_
+#define DYNAMIC_PLAT_REPO_H_
+
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** A structure describing the platform configuration
+ manager repository information
+*/
+typedef VOID* DYNAMIC_PLATFORM_REPOSITORY_INFO;
+
+/** Add an object to the dynamic platform repository.
+
+ @param [in] This This dynamic platform repository.
+ @param [in] CmObjDesc CmObj to add. The data is copied.
+ @param [out] Token If not NULL, token allocated to this CmObj.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynPlatRepoAddObject (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This,
+ IN CONST CM_OBJ_DESCRIPTOR * CmObjDesc,
+ OUT CM_OBJECT_TOKEN * Token OPTIONAL
+ );
+
+/** Finalise the dynamic repository.
+
+ Finalising means:
+ - Preventing any further objects from being added.
+ - Allowing to get objects from the dynamic repository
+ (not possible before a call to this function).
+
+ @param [in] This This dynamic platform repository.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoFinalise (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This
+ );
+
+/** Get a CmObj from the dynamic repository.
+
+ @param [in] This Pointer to the Dynamic Platform Repository.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObjDesc Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoGetObject (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This,
+ IN CM_OBJECT_ID CmObjectId,
+ IN CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CmObjDesc
+ );
+
+/** Initialize the dynamic platform repository.
+
+ @param [out] DynPlatRepo If success, contains the initialised dynamic
+ platform repository.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoInit (
+ OUT DYNAMIC_PLATFORM_REPOSITORY_INFO ** DynPlatRepo
+ );
+
+/** Shutdown the dynamic platform repository.
+
+ Free all the memory allocated for the dynamic platform repository.
+
+ @param [in] DynPlatRepo The dynamic platform repository.
+
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoShutdown (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * DynPlatRepo
+ );
+
+#endif // DYNAMIC_PLAT_REPO_H_
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenGenerator
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
2021-11-23 11:10 ` [PATCH v2 1/5] DynamicTablesPkg: Definition for DynamicPlatRepoLib interface PierreGondois
@ 2021-11-23 11:10 ` PierreGondois
2021-11-23 11:10 ` [PATCH v2 3/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenFixer PierreGondois
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.
A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).
This patch add the TokenGenerator files.
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
.../DynamicPlatRepoLib/TokenGenerator.c | 28 +++++++++++++++++++
.../DynamicPlatRepoLib/TokenGenerator.h | 26 +++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.h
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.c
new file mode 100644
index 000000000000..637e784bd284
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.c
@@ -0,0 +1,28 @@
+/** @file
+ Token Generator
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** Generate a token.
+
+ @return A token.
+**/
+CM_OBJECT_TOKEN
+EFIAPI
+GenerateToken (
+ VOID
+ )
+{
+ // Start Tokens at 1 to avoid collisions with CM_NULL_TOKEN.
+ STATIC UINTN CurrentToken = 1;
+ return (CM_OBJECT_TOKEN)(CurrentToken++);
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.h
new file mode 100644
index 000000000000..44d32e5b41a1
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenGenerator.h
@@ -0,0 +1,26 @@
+/** @file
+ Token Generator
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef TOKEN_GENERATOR_H_
+#define TOKEN_GENERATOR_H_
+
+/** Generate a token.
+
+ @return A token.
+**/
+CM_OBJECT_TOKEN
+EFIAPI
+GenerateToken (
+ VOID
+ );
+
+#endif // TOKEN_GENERATOR_H_
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenFixer
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
2021-11-23 11:10 ` [PATCH v2 1/5] DynamicTablesPkg: Definition for DynamicPlatRepoLib interface PierreGondois
2021-11-23 11:10 ` [PATCH v2 2/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenGenerator PierreGondois
@ 2021-11-23 11:10 ` PierreGondois
2021-11-23 11:10 ` [PATCH v2 4/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper PierreGondois
2021-11-23 11:10 ` [PATCH v2 5/5] DynamicTablesPkg: Add DynamicPlatRepo library PierreGondois
4 siblings, 0 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.
A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).
This patch add the TokenFixer files, allowing to update the
self-token some CmObj have.
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
.../DynamicPlatRepoLib/CmObjectTokenFixer.c | 164 ++++++++++++++++++
.../DynamicPlatRepoLib/CmObjectTokenFixer.h | 52 ++++++
2 files changed, 216 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.h
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
new file mode 100644
index 000000000000..74eeefccf4ce
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
@@ -0,0 +1,164 @@
+/** @file
+ Configuration Manager object token fixer
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/DebugLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include "CmObjectTokenFixer.h"
+
+/** Token fixer not implemented.
+
+ Most of the objects are not generated by this parser. Add the missing
+ functions when needed.
+
+ CmObjectToken fixer function that updates the Tokens in the CmObjects.
+
+ @param [in] CmObject Pointer to the Configuration Manager Object.
+ @param [in] Token Token to be updated in the CmObject.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+TokenFixerNotImplemented (
+ IN CM_OBJ_DESCRIPTOR * CmObject,
+ IN CM_OBJECT_TOKEN Token
+ )
+{
+ ASSERT (0);
+ return EFI_UNSUPPORTED;
+}
+
+/** EArmObjItsGroup token fixer.
+
+ CmObjectToken fixer function that updates the Tokens in the CmObjects.
+
+ @param [in] CmObject Pointer to the Configuration Manager Object.
+ @param [in] Token Token to be updated in the CmObject.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+TokenFixerItsGroup (
+ IN CM_OBJ_DESCRIPTOR * CmObject,
+ IN CM_OBJECT_TOKEN Token
+ )
+{
+ ASSERT (CmObject != NULL);
+ ((CM_ARM_ITS_GROUP_NODE*)CmObject)->Token = Token;
+ return EFI_SUCCESS;
+}
+
+/** TokenFixer functions table.
+
+ A CmObj having a CM_OBJECT_TOKEN field might need to have its
+ Token fixed. Each CmObj can have its Token in a specific way.
+*/
+CONST
+CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = {
+ NULL, ///< 0 - Reserved
+ NULL, ///< 1 - Boot Architecture Info
+ NULL, ///< 2 - CPU Info
+ NULL, ///< 3 - Power Management Profile Info
+ NULL, ///< 4 - GIC CPU Interface Info
+ NULL, ///< 5 - GIC Distributor Info
+ NULL, ///< 6 - GIC MSI Frame Info
+ NULL, ///< 7 - GIC Redistributor Info
+ NULL, ///< 8 - GIC ITS Info
+ NULL, ///< 9 - Serial Console Port Info
+ NULL, ///< 10 - Serial Debug Port Info
+ NULL, ///< 11 - Generic Timer Info
+ NULL, ///< 12 - Platform GT Block Info
+ NULL, ///< 13 - Generic Timer Block Frame Info
+ NULL, ///< 14 - Platform Generic Watchdog
+ NULL, ///< 15 - PCI Configuration Space Info
+ NULL, ///< 16 - Hypervisor Vendor Id
+ NULL, ///< 17 - Fixed feature flags for FADT
+ TokenFixerItsGroup, ///< 18 - ITS Group
+ TokenFixerNotImplemented, ///< 19 - Named Component
+ TokenFixerNotImplemented, ///< 20 - Root Complex
+ TokenFixerNotImplemented, ///< 21 - SMMUv1 or SMMUv2
+ TokenFixerNotImplemented, ///< 22 - SMMUv3
+ TokenFixerNotImplemented, ///< 23 - PMCG
+ NULL, ///< 24 - GIC ITS Identifier Array
+ NULL, ///< 25 - ID Mapping Array
+ NULL, ///< 26 - SMMU Interrupt Array
+ TokenFixerNotImplemented, ///< 27 - Processor Hierarchy Info
+ TokenFixerNotImplemented, ///< 28 - Cache Info
+ TokenFixerNotImplemented, ///< 29 - Processor Node ID Info
+ NULL, ///< 30 - CM Object Reference
+ NULL, ///< 31 - Memory Affinity Info
+ NULL, ///< 32 - Device Handle Acpi
+ NULL, ///< 33 - Device Handle Pci
+ NULL, ///< 34 - Generic Initiator Affinity
+ NULL, ///< 35 - Generic Serial Port Info
+ NULL, ///< 36 - CMN-600 Info
+ NULL, ///< 37 - Lpi Info
+ NULL, ///< 38 - Pci Address Map Info
+ NULL, ///< 39 - Pci Interrupt Map Info
+};
+
+/** CmObj token fixer.
+
+ Some CmObj structures have a self-token, i.e. they are storing their own
+ token value in the CmObj. Dynamically created CmObj need to have their
+ self-token assigned at some point.
+
+ @param [in] CmObjDesc Pointer to the Configuration Manager Object.
+ @param [in] Token Token to update the CmObjDesc with.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+EFI_STATUS
+EFIAPI
+FixupCmObjectSelfToken (
+ IN CM_OBJ_DESCRIPTOR * CmObjDesc,
+ IN CM_OBJECT_TOKEN Token
+ )
+{
+ EFI_STATUS Status;
+ CM_OBJECT_TOKEN_FIXER TokenFixerFunc;
+ CM_OBJECT_ID ArmNamespaceObjId;
+
+ // Only support Arm objects for now.
+ if ((CmObjDesc == NULL) ||
+ (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
+ if (ArmNamespaceObjId >= EArmObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Fixup self-token if necessary.
+ TokenFixerFunc = TokenFixer[ArmNamespaceObjId];
+ if (TokenFixerFunc != NULL) {
+ Status = TokenFixerFunc (CmObjDesc, Token);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.h
new file mode 100644
index 000000000000..d8cc7094697f
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.h
@@ -0,0 +1,52 @@
+/** @file
+ Configuration Manager object token fixer
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef CM_OBJECT_TOKEN_FIXER_H_
+#define CM_OBJECT_TOKEN_FIXER_H_
+
+/** CmObjectToken fixer function that updates the Tokens in the CmObjects.
+
+ @param [in] CmObject Pointer to the Configuration Manager Object.
+ @param [in] Token Token to be updated in the CmObject.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * CM_OBJECT_TOKEN_FIXER) (
+ IN CM_OBJ_DESCRIPTOR * CmObject,
+ IN CM_OBJECT_TOKEN Token
+ );
+
+/** CmObj token fixer.
+
+ Some CmObj structures have a self-token, i.e. they are storing their own
+ token value in the CmObj. Dynamically created CmObj need to have their
+ self-token assigned at some point.
+
+ @param [in] CmObjDesc Pointer to the Configuration Manager Object.
+ @param [in] Token Token to update the CmObjDesc with.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+EFI_STATUS
+EFIAPI
+FixupCmObjectSelfToken (
+ IN CM_OBJ_DESCRIPTOR * CmObjDesc,
+ IN CM_OBJECT_TOKEN Token
+ );
+
+#endif // CM_OBJECT_TOKEN_FIXER_H_
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 4/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
` (2 preceding siblings ...)
2021-11-23 11:10 ` [PATCH v2 3/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenFixer PierreGondois
@ 2021-11-23 11:10 ` PierreGondois
2021-11-23 11:10 ` [PATCH v2 5/5] DynamicTablesPkg: Add DynamicPlatRepo library PierreGondois
4 siblings, 0 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.
A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).
This patch add the TokenMapper files, allowing to retrieve a CmObj
from a token/CmObjId couple.
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
.../Common/DynamicPlatRepoLib/TokenMapper.c | 218 ++++++++++++++++++
.../Common/DynamicPlatRepoLib/TokenMapper.h | 123 ++++++++++
2 files changed, 341 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
new file mode 100644
index 000000000000..a871320715a3
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
@@ -0,0 +1,218 @@
+/** @file
+ Token Mapper
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "TokenMapper.h"
+
+/** Add a CmObjDesc to the TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token CmObj token.
+ @param [in] ObjectId CmObj ObjectId.
+ @param [in] Size CmObj Size.
+ @param [in] Data CmObj Data.
+ This memory is referenced, not copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperAddObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ IN UINT32 Size,
+ IN VOID *Data
+ )
+{
+ TOKEN_MAP_DESCRIPTOR *TokenMapDesc;
+ CM_OBJ_DESCRIPTOR *CmObjDesc;
+
+ if ((TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL) ||
+ (Size == 0) ||
+ (Data == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TokenMapper->ItemCount >= TokenMapper->MaxTokenDescCount) {
+ ASSERT (0);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ TokenMapDesc = &TokenMapper->TokenDescArray[TokenMapper->ItemCount++];
+ TokenMapDesc->Token = Token;
+ CmObjDesc = &TokenMapDesc->CmObjDesc;
+ CmObjDesc->ObjectId = ObjectId;
+ CmObjDesc->Size = Size;
+
+ // Point inside the finalized array.
+ CmObjDesc->Data = Data;
+
+ // Only EArmObjCmRef CmObj can be added as arrays (more than 1 elements).
+ if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) &&
+ (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef)) {
+ CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF);
+ } else {
+ CmObjDesc->Count = 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Get a CmObjDesc from a ObjectId/Token couple.
+
+ The Token parameter is not optional. An existing token must be provided.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token Token of the CmObj to search.
+ @param [in] ObjectId Object Id of the CmObj to search.
+ @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperGetObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ OUT CM_OBJ_DESCRIPTOR *CmObjDesc
+ )
+{
+ UINTN Index;
+ UINTN MaxCount;
+ TOKEN_MAP_DESCRIPTOR *TokenMapDesc;
+
+ // Nothing to do.
+ if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
+ goto exit_handler;
+ }
+
+ if ((Token == CM_NULL_TOKEN) ||
+ (CmObjDesc == NULL) ||
+ (TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TokenMapDesc = TokenMapper->TokenDescArray;
+ MaxCount = TokenMapper->MaxTokenDescCount;
+ for (Index = 0; Index < MaxCount; Index++) {
+ if ((TokenMapDesc->CmObjDesc.ObjectId == ObjectId) &&
+ (TokenMapDesc->Token == Token)) {
+ CopyMem (
+ CmObjDesc,
+ &TokenMapDesc->CmObjDesc,
+ sizeof (CM_OBJ_DESCRIPTOR)
+ );
+ return EFI_SUCCESS;
+ }
+ TokenMapDesc++;
+ } // for
+
+exit_handler:
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Requested CmObj of type 0x%x with token 0x%x"
+ " not found in the dynamic repository\n.",
+ ObjectId,
+ Token
+ ));
+ return EFI_NOT_FOUND;
+}
+
+/** Initialise a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to initialise.
+ @param [in] DescriptorCount Number of entries to allocate.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperInitialise (
+ IN TOKEN_MAPPER * TokenMapper,
+ IN UINTN DescriptorCount
+ )
+{
+ if (TokenMapper == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Nothing to do.
+ if (DescriptorCount == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (TokenMapper->TokenDescArray != NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Token mapper already initialised\n."));
+ ASSERT (0);
+ return EFI_ALREADY_STARTED;
+ }
+
+ TokenMapper->TokenDescArray =
+ AllocateZeroPool (sizeof (TOKEN_MAP_DESCRIPTOR) * DescriptorCount);
+ if (TokenMapper->TokenDescArray == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TokenMapper->MaxTokenDescCount = DescriptorCount;
+ TokenMapper->ItemCount = 0;
+
+ return EFI_SUCCESS;
+}
+
+/** Shutdown a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to shutdown.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperShutdown (
+ IN TOKEN_MAPPER * TokenMapper
+ )
+{
+ // Nothing to do.
+ if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((TokenMapper == NULL) ||
+ (TokenMapper->TokenDescArray == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (TokenMapper->TokenDescArray);
+ TokenMapper->TokenDescArray = NULL;
+ TokenMapper->MaxTokenDescCount = 0;
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
new file mode 100644
index 000000000000..377fc03dcd01
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h
@@ -0,0 +1,123 @@
+/** @file
+ Token Mapper
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef TOKEN_MAPPER_H_
+#define TOKEN_MAPPER_H_
+
+#pragma pack(1)
+
+/** Token mapping descriptor.
+
+ Bind a token and a CmObj together.
+*/
+typedef struct TokenMapDescriptor {
+ /// Object Token.
+ CM_OBJECT_TOKEN Token;
+
+ /// CmObjectDescriptor CM_OBJ_DESCRIPTOR.Data is a reference copy
+ /// and not allocated. It points to the individual objects in the
+ /// Dynamic Plat Repo ArmNameSpaceObjectArray.
+ CM_OBJ_DESCRIPTOR CmObjDesc;
+} TOKEN_MAP_DESCRIPTOR;
+
+/** Token mapper.
+
+ Contain all the Token/CmObj couple mapping.
+**/
+typedef struct TokenMapper {
+ /// Maximum number of TOKEN_MAP_DESCRIPTOR entries in TokenDescArray.
+ UINTN MaxTokenDescCount;
+
+ /// Next TOKEN_MAP_DESCRIPTOR entry to use in TokenDescArray.
+ UINTN ItemCount;
+
+ /// Array of TOKEN_MAP_DESCRIPTOR.
+ TOKEN_MAP_DESCRIPTOR * TokenDescArray;
+} TOKEN_MAPPER;
+
+#pragma pack()
+
+/** Add a CmObjDesc to the TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token CmObj token.
+ @param [in] ObjectId CmObj ObjectId.
+ @param [in] Size CmObj Size.
+ @param [in] Data CmObj Data.
+ This memory is referenced, not copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperAddObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ IN UINT32 Size,
+ IN VOID *Data
+ );
+
+/** Get a CmObjDesc from a ObjectId/Token couple.
+
+ The Token parameter is not optional. An existing token must be provided.
+
+ @param [in] TokenMapper The TokenMapper instance.
+ @param [in] Token Token of the CmObj to search.
+ @param [in] ObjectId Object Id of the CmObj to search.
+ @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperGetObject (
+ IN TOKEN_MAPPER *TokenMapper,
+ IN CM_OBJECT_TOKEN Token,
+ IN CM_OBJECT_ID ObjectId,
+ OUT CM_OBJ_DESCRIPTOR *CmObjDesc
+ );
+
+/** Initialise a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to initialise.
+ @param [in] DescriptorCount Number of entries to allocate.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperInitialise (
+ IN TOKEN_MAPPER * TokenMapper,
+ IN UINTN DescriptorCount
+ );
+
+/** Shutdown a TokenMapper.
+
+ @param [in] TokenMapper The TokenMapper to shutdown.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+TokenMapperShutdown (
+ IN TOKEN_MAPPER * TokenMapper
+ );
+
+#endif // TOKEN_MAPPER_H_
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 5/5] DynamicTablesPkg: Add DynamicPlatRepo library
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
` (3 preceding siblings ...)
2021-11-23 11:10 ` [PATCH v2 4/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper PierreGondois
@ 2021-11-23 11:10 ` PierreGondois
4 siblings, 0 replies; 6+ messages in thread
From: PierreGondois @ 2021-11-23 11:10 UTC (permalink / raw)
To: pierre.gondois, devel; +Cc: Sami Mujawar, Alexei Fedorov
From: Pierre Gondois <Pierre.Gondois@arm.com>
The DynamicPlatRepo library allows to handle dynamically created
CmObj. The dynamic platform repository can be in the following states:
1 - Non-initialised
2 - Transient:
Possibility to add CmObj to the platform, but not to query them.
3 - Finalised:
Possibility to query CmObj, but not to add new.
A token is allocated to each CmObj added to the dynamic platform
repository (except for reference tokens CmObj). This allows to retrieve
dynamic CmObjs among all CmObj (static CmObj for instance).
This patch add the inf file of the module and the main module
functionnalities and update the dsc file of the package.
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.dsc | 1 +
.../DynamicPlatRepoLib/DynamicPlatRepo.c | 515 ++++++++++++++++++
.../DynamicPlatRepoInternal.h | 78 +++
.../DynamicPlatRepoLib/DynamicPlatRepoLib.inf | 33 ++
4 files changed, 627 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
create mode 100644 DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc
index a2a1b8d004d2..068f0bc63080 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dsc
+++ b/DynamicTablesPkg/DynamicTablesPkg.dsc
@@ -44,6 +44,7 @@ [Components.common]
DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
+ DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
new file mode 100644
index 000000000000..faa431455761
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
@@ -0,0 +1,515 @@
+/** @file
+ Dynamic Platform Info Repository
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "CmObjectTokenFixer.h"
+#include "DynamicPlatRepoInternal.h"
+#include "TokenGenerator.h"
+
+/** Allocate a CM_OBJ_NODE.
+
+ @param [in] CmObjDesc CmObj to wrap in a node.
+ All the fields of the CmObj (Data field included),
+ are copied.
+ @param [in] Token Token to assign to this CmObj/node.
+ @param [out] ObjNode Allocated ObjNode.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AllocCmObjNode (
+ IN CONST CM_OBJ_DESCRIPTOR * CmObjDesc,
+ IN CM_OBJECT_TOKEN Token,
+ OUT CM_OBJ_NODE ** ObjNode
+ )
+{
+ CM_OBJ_NODE *Node;
+ CM_OBJ_DESCRIPTOR *Desc;
+
+ if ((CmObjDesc == NULL) || (ObjNode == NULL)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Node = AllocateZeroPool (sizeof (CM_OBJ_NODE));
+ if (Node == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Initialise the list head.
+ InitializeListHead (&Node->Link);
+ Node->Token = Token;
+ Desc = &Node->CmObjDesc;
+ Desc->ObjectId = CmObjDesc->ObjectId;
+ Desc->Size = CmObjDesc->Size;
+ Desc->Count = CmObjDesc->Count;
+
+ // Allocate and copy the CmObject Data.
+ Desc->Data = AllocateCopyPool (CmObjDesc->Size, CmObjDesc->Data);
+ if (Desc->Data == NULL) {
+ FreePool (Node);
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *ObjNode = Node;
+ return EFI_SUCCESS;
+}
+
+/** Free a CM_OBJ_NODE.
+
+ @param [in] ObjNode ObjNode to free.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FreeCmObjNode (
+ IN CM_OBJ_NODE * ObjNode
+ )
+{
+ CM_OBJ_DESCRIPTOR *Desc;
+
+ if (ObjNode == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Unlink Node
+ RemoveEntryList (&ObjNode->Link);
+
+ Desc = &ObjNode->CmObjDesc;
+ if (Desc->Data != NULL) {
+ FreePool (Desc->Data);
+ }
+
+ FreePool (ObjNode);
+ return EFI_SUCCESS;
+}
+
+/** Add an object to the dynamic platform repository.
+
+ @param [in] This This dynamic platform repository.
+ @param [in] CmObjDesc CmObj to add. The data is copied.
+ @param [out] Token If not NULL, token allocated to this CmObj.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynPlatRepoAddObject (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This,
+ IN CONST CM_OBJ_DESCRIPTOR * CmObjDesc,
+ OUT CM_OBJECT_TOKEN * Token OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CM_OBJ_NODE *ObjNode;
+ CM_OBJECT_ID ArmNamespaceObjId;
+ CM_OBJECT_TOKEN NewToken;
+
+ // The dynamic repository must be able to receive objects.
+ if ((This == NULL) ||
+ (CmObjDesc == NULL) ||
+ (This->RepoState != DynRepoTransient)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check the CmObjDesc:
+ // - only Arm objects are supported for now.
+ // - only EArmObjCmRef objects can be added as arrays.
+ ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
+ if ((CmObjDesc->Size == 0) ||
+ (CmObjDesc->Count == 0) ||
+ (ArmNamespaceObjId >= EArmObjMax) ||
+ ((CmObjDesc->Count > 1) && (ArmNamespaceObjId != EArmObjCmRef)) ||
+ (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Generate a token.
+ NewToken = GenerateToken ();
+
+ // Create an ObjNode.
+ Status = AllocCmObjNode (CmObjDesc, NewToken, &ObjNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Fixup self-token if necessary.
+ Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
+ if (EFI_ERROR (Status)) {
+ FreeCmObjNode (ObjNode);
+ ASSERT (0);
+ return Status;
+ }
+
+ // Add to link list.
+ InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
+ This->ObjectCount += 1;
+
+ if (Token != NULL) {
+ *Token = NewToken;
+ }
+ return EFI_SUCCESS;
+}
+
+/** Group lists of CmObjNode from the ArmNameSpace to one array.
+
+ @param [in] This This dynamic platform repository.
+ @param [in] ArmObjIndex Index in EARM_OBJECT_ID
+ (must be < EArmObjMax).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GroupCmObjNodes (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This,
+ IN UINT32 ArmObjIndex
+ )
+{
+ EFI_STATUS Status;
+ UINTN Count;
+ UINTN Size;
+ UINT32 CmObjId;
+ UINT8 *GroupedData;
+ UINT8 *Data;
+ CM_OBJ_DESCRIPTOR *CmObjDesc;
+ LIST_ENTRY *ListHead;
+ LIST_ENTRY *Link;
+
+ if ((This == NULL) ||
+ (ArmObjIndex >= EArmObjMax)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Count = 0;
+ Size = 0;
+ CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
+ ListHead = &This->ArmCmObjList[ArmObjIndex];
+ Link = GetFirstNode (ListHead);
+
+ // Compute the total count and size of the CmObj in the list.
+ while (Link != ListHead) {
+ CmObjDesc = &((CM_OBJ_NODE*)Link)->CmObjDesc;
+
+ if (CmObjDesc->ObjectId != CmObjId) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)){
+ // We expect each descriptor to contain an individual object.
+ // EArmObjCmRef objects are counted as groups, so +1 as well.
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Count++;
+ Size += CmObjDesc->Size;
+
+ // Next Link
+ Link = GetNextNode (ListHead, Link);
+ } // while
+
+ if (Count == 0) {
+ // No objects found.
+ return EFI_SUCCESS;
+ }
+
+ GroupedData = AllocateZeroPool (Size);
+ if (GroupedData == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Copy the Object Data and add to the TokenMapper.
+ Data = GroupedData;
+ Link = GetFirstNode (ListHead);
+ while (Link != ListHead) {
+ CmObjDesc = &((CM_OBJ_NODE*)Link)->CmObjDesc;
+ CopyMem (Data, CmObjDesc->Data, CmObjDesc->Size);
+
+ // Add the object to the Token Mapper.
+ // Note: The CmObject Data field of objects in the Token Mapper point
+ // to the memory in the GroupedData array.
+ Status = TokenMapperAddObject (
+ &This->TokenMapper,
+ ((CM_OBJ_NODE*)Link)->Token,
+ CmObjDesc->ObjectId,
+ CmObjDesc->Size,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (GroupedData);
+ return Status;
+ }
+
+ Data += CmObjDesc->Size;
+ Link = GetNextNode (ListHead, Link);
+ } // while
+
+ CmObjDesc = &This->ArmCmObjArray[ArmObjIndex];
+ CmObjDesc->ObjectId = CmObjId;
+ CmObjDesc->Size = Size;
+ CmObjDesc->Count = Count;
+ CmObjDesc->Data = GroupedData;
+
+ return Status;
+}
+
+/** Finalise the dynamic repository.
+
+ Finalising means:
+ - Preventing any further objects from being added.
+ - Allowing to get objects from the dynamic repository
+ (not possible before a call to this function).
+
+ @param [in] This This dynamic platform repository.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_ALREADY_STARTED Instance already initialised.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoFinalise (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This
+ )
+{
+ EFI_STATUS Status;
+ UINTN ArmObjIndex;
+
+ if ((This == NULL) ||
+ (This->RepoState != DynRepoTransient)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Prevent any further objects from being added.
+ This->RepoState = DynRepoFinalized;
+
+ // Initialise the token mapper.
+ Status = TokenMapperInitialise (&This->TokenMapper, This->ObjectCount);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // For each CM_OBJECT_ID:
+ // - Convert the list of nodes to an array
+ // (the array is wrapped in a CmObjDesc).
+ // - Add the Token/CmObj binding to the token mapper.
+ for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
+ Status = GroupCmObjNodes (This, ArmObjIndex);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ // Free the TokenMapper.
+ // Ignore the returned Status since we already failed.
+ TokenMapperShutdown (&This->TokenMapper);
+ return Status;
+ }
+ } // for
+
+ return EFI_SUCCESS;
+}
+
+/** Get a CmObj from the dynamic repository.
+
+ @param [in] This Pointer to the Dynamic Platform Repository.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObjDesc Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoGetObject (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * This,
+ IN CM_OBJECT_ID CmObjectId,
+ IN CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CmObjDesc
+ )
+{
+ EFI_STATUS Status;
+ CM_OBJ_DESCRIPTOR *Desc;
+ CM_OBJECT_ID ArmNamespaceObjId;
+
+ if ((This == NULL) ||
+ (CmObjDesc == NULL) ||
+ (This->RepoState != DynRepoFinalized)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
+ if (ArmNamespaceObjId >= EArmObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Token != CM_NULL_TOKEN) {
+ // Search in the Token Mapper and return the object.
+ Status = TokenMapperGetObject (
+ &This->TokenMapper,
+ Token,
+ CmObjectId,
+ CmObjDesc
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if (ArmNamespaceObjId == EArmObjCmRef) {
+ // EArmObjCmRef object must be requested using a valid token.
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Desc = &This->ArmCmObjArray[ArmNamespaceObjId];
+
+ // Nothing here.
+ if (Desc->Count == 0) {
+ return EFI_NOT_FOUND;
+ } else {
+ // Return the full array.
+ CmObjDesc->ObjectId = Desc->ObjectId;
+ CmObjDesc->Size = Desc->Size;
+ CmObjDesc->Data = Desc->Data;
+ CmObjDesc->Count = Desc->Count;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Initialize the dynamic platform repository.
+
+ @param [out] DynPlatRepo If success, contains the initialised dynamic
+ platform repository.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES An allocation has failed.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoInit (
+ OUT DYNAMIC_PLATFORM_REPOSITORY_INFO ** DynPlatRepo
+ )
+{
+ UINTN Index;
+ DYNAMIC_PLATFORM_REPOSITORY_INFO * Repo;
+
+ if (DynPlatRepo == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Repo = AllocateZeroPool (sizeof (DYNAMIC_PLATFORM_REPOSITORY_INFO));
+ if (Repo == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Initialise the CmObject List.
+ for (Index = 0; Index < EArmObjMax; Index++) {
+ InitializeListHead (&Repo->ArmCmObjList[Index]);
+ }
+
+ Repo->ObjectCount = 0;
+ Repo->RepoState = DynRepoTransient;
+
+ *DynPlatRepo = Repo;
+
+ return EFI_SUCCESS;
+}
+
+/** Shutdown the dynamic platform repository.
+
+ Free all the memory allocated for the dynamic platform repository.
+
+ @param [in] DynPlatRepo The dynamic platform repository.
+
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoShutdown (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO * DynPlatRepo
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ LIST_ENTRY * ListHead;
+ CM_OBJ_DESCRIPTOR * CmObjDesc;
+ VOID * Data;
+
+ if (DynPlatRepo == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Free the list of objects.
+ for (Index = 0; Index < EArmObjMax; Index++) {
+ // Free all the nodes with this object Id.
+ ListHead = &DynPlatRepo->ArmCmObjList[Index];
+ while (!IsListEmpty (ListHead)) {
+ FreeCmObjNode ((CM_OBJ_NODE*)GetFirstNode (ListHead));
+ } // while
+ } // for
+
+ // Free the arrays.
+ CmObjDesc = DynPlatRepo->ArmCmObjArray;
+ for (Index = 0; Index < EArmObjMax; Index++) {
+ Data = CmObjDesc[Index].Data;
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+ } // for
+
+ // Free the TokenMapper
+ Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);
+ ASSERT_EFI_ERROR (Status);
+ FreePool (DynPlatRepo);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
new file mode 100644
index 000000000000..d03fa2b7dcec
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
@@ -0,0 +1,78 @@
+/** @file
+ Dynamic Platform Info Repository Internal
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef DYNAMIC_PLAT_REPO_INTERNAL_H_
+#define DYNAMIC_PLAT_REPO_INTERNAL_H_
+
+#include "TokenMapper.h"
+
+#pragma pack(1)
+
+/** CmObj node.
+
+ This is a node wrapper around the CM_OBJ_DESCRIPTOR structure.
+ It also allows to bind a token to the CM_OBJ_DESCRIPTOR.
+*/
+typedef struct CmObjectNode {
+ /// This must be the first field in this structure.
+ LIST_ENTRY Link;
+
+ /// Token associated with the CmObjDesc.
+ CM_OBJECT_TOKEN Token;
+
+ /// CmObjDesc wrapped.
+ /// Note: the CM_OBJ_DESCRIPTOR.Data field is allocated and copied.
+ CM_OBJ_DESCRIPTOR CmObjDesc;
+} CM_OBJ_NODE;
+
+/** Dynamic repository states.
+
+ The states must progress as:
+ UnInitialised -> Transient -> Finalized
+*/
+typedef enum DynRepoState {
+ DynRepoUnInitialised, ///< Un-Initialised state
+ DynRepoTransient, ///< Transient state - CmObjects can be added.
+ DynRepoFinalized, ///< Repo Locked - No further CmObjects can be added.
+ ///< Getting objects is now possible.
+ DynRepoMax ///< Max value.
+} EDYNAMIC_REPO_STATE;
+
+/** A structure describing the platform configuration
+ manager repository information
+*/
+typedef struct DynamicPlatformRepositoryInfo {
+ /// Repo state machine.
+ EDYNAMIC_REPO_STATE RepoState;
+
+ /// Count of all the objects added to the Dynamic Platform Repo
+ /// during the Transient state.
+ UINTN ObjectCount;
+
+ /// Link lists of CmObj from the ArmNameSpace
+ /// that are added in the Transient state.
+ LIST_ENTRY ArmCmObjList[EArmObjMax];
+
+ /// Structure Members used in Finalized state.
+ /// An array of CmObj Descriptors from the ArmNameSpace
+ /// This array is populated when the Repo is finalized.
+ CM_OBJ_DESCRIPTOR ArmCmObjArray[EArmObjMax];
+
+ /// A token mapper for the objects in the ArmNamespaceObjectArray
+ /// The Token mapper is populated when the Repo is finalized in
+ /// a call to DynamicPlatRepoFinalise ().
+ TOKEN_MAPPER TokenMapper;
+} DYNAMIC_PLATFORM_REPOSITORY_INFO;
+
+#pragma pack()
+
+#endif // DYNAMIC_PLAT_REPO_INTERNAL_H_
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
new file mode 100644
index 000000000000..9a3cc87fd91d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Dynamic Platform Repository
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = DynamicPlatRepoLib
+ FILE_GUID = 836D253D-3144-4A89-9BEE-BC55AFDC814E
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = DynamicPlatRepoLib
+
+[Sources]
+ CmObjectTokenFixer.c
+ CmObjectTokenFixer.h
+ DynamicPlatRepo.c
+ DynamicPlatRepoInternal.h
+ TokenGenerator.c
+ TokenGenerator.h
+ TokenMapper.c
+ TokenMapper.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ AcpiHelperLib
+ BaseLib
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-11-23 11:10 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-11-23 11:10 [PATCH v2 0/5] Add DynamicPlatRepoLib PierreGondois
2021-11-23 11:10 ` [PATCH v2 1/5] DynamicTablesPkg: Definition for DynamicPlatRepoLib interface PierreGondois
2021-11-23 11:10 ` [PATCH v2 2/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenGenerator PierreGondois
2021-11-23 11:10 ` [PATCH v2 3/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenFixer PierreGondois
2021-11-23 11:10 ` [PATCH v2 4/5] DynamicTablesPkg: DynamicPlatRepo: Add TokenMapper PierreGondois
2021-11-23 11:10 ` [PATCH v2 5/5] DynamicTablesPkg: Add DynamicPlatRepo library PierreGondois
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox