+/** @file\r
+ SMBIOS Table Factory\r
+\r
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Glossary:\r
+ - Std - Standard\r
+**/\r
+\r
+#include <IndustryStandard/SmBios.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+// Module specific include files.\r
+#include <SmbiosTableGenerator.h>\r
+#include <ConfigurationManagerObject.h>\r
+#include <Protocol/ConfigurationManagerProtocol.h>\r
+#include <Protocol/DynamicTableFactoryProtocol.h>\r
+\r
+#include "DynamicTableFactory.h"\r
+\r
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;\r
+\r
+/** Return a pointer to the SMBIOS table generator.\r
+\r
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.\r
+ @param [in] GeneratorId The SMBIOS table generator ID for the\r
+ requested generator.\r
+ @param [out] Generator Pointer to the requested SMBIOS table\r
+ generator.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+ @retval EFI_NOT_FOUND The requested generator is not found\r
+ in the list of registered generators.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetSmbiosTableGenerator (\r
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,\r
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,\r
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator\r
+ )\r
+{\r
+ UINT16 TableId;\r
+ EDKII_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo;\r
+\r
+ ASSERT (This != NULL);\r
+\r
+ FactoryInfo = This->TableFactoryInfo;\r
+\r
+ if (Generator == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!IS_GENERATOR_TYPE_SMBIOS (GeneratorId)) {\r
+ DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not SMBIOS\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Generator = NULL;\r
+ TableId = GET_TABLE_ID (GeneratorId);\r
+ if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) {\r
+ if (TableId >= EStdSmbiosTableIdMax) {\r
+ ASSERT (TableId < EStdSmbiosTableIdMax);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (FactoryInfo->StdSmbiosTableGeneratorList[TableId] != NULL) {\r
+ *Generator = FactoryInfo->StdSmbiosTableGeneratorList[TableId];\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {\r
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (FactoryInfo->CustomSmbiosTableGeneratorList[TableId] != NULL) {\r
+ *Generator = FactoryInfo->CustomSmbiosTableGeneratorList[TableId];\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Register SMBIOS table factory generator.\r
+\r
+ The SMBIOS table factory maintains a list of the Standard and OEM SMBIOS\r
+ table generators.\r
+\r
+ @param [in] Generator Pointer to the SMBIOS table generator.\r
+\r
+ @retval EFI_SUCCESS The Generator was registered\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or\r
+ the Generator pointer is NULL.\r
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is\r
+ already registered.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterSmbiosTableGenerator (\r
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator\r
+ )\r
+{\r
+ UINT16 TableId;\r
+\r
+ if (Generator == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS register - Invalid Generator\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: SMBIOS register - Generator" \\r
+ " Type is not SMBIOS\n"\r
+ ));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description));\r
+\r
+ TableId = GET_TABLE_ID (Generator->GeneratorID);\r
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {\r
+ if (TableId >= EStdSmbiosTableIdMax) {\r
+ ASSERT (TableId < EStdSmbiosTableIdMax);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] == NULL) {\r
+ TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = Generator;\r
+ } else {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ } else {\r
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {\r
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] == NULL) {\r
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = Generator;\r
+ } else {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Deregister SMBIOS generator.\r
+\r
+ This function is called by the SMBIOS table generator to deregister itself\r
+ from the SMBIOS table factory.\r
+\r
+ @param [in] Generator Pointer to the SMBIOS table generator.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER The generator is invalid.\r
+ @retval EFI_NOT_FOUND The requested generator is not found\r
+ in the list of registered generators.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DeregisterSmbiosTableGenerator (\r
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator\r
+ )\r
+{\r
+ UINT16 TableId;\r
+\r
+ if (Generator == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS deregister - Invalid Generator\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: SMBIOS deregister - Generator" \\r
+ " Type is not SMBIOS\n"\r
+ ));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ TableId = GET_TABLE_ID (Generator->GeneratorID);\r
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {\r
+ if (TableId >= EStdSmbiosTableIdMax) {\r
+ ASSERT (TableId < EStdSmbiosTableIdMax);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] != NULL) {\r
+ if (Generator != TableFactoryInfo.StdSmbiosTableGeneratorList[TableId]) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = NULL;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {\r
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] != NULL) {\r
+ if (Generator !=\r
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId]) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = NULL;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description));\r
+ return EFI_SUCCESS;\r
+}\r