+/** @file\r
+ This driver installs SMBIOS information for OVMF\r
+\r
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\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
+**/\r
+\r
+#include "SmbiosPlatformDxe.h"\r
+\r
+\r
+/**\r
+ Validates the SMBIOS entry point structure\r
+\r
+ @param EntryPointStructure SMBIOS entry point structure\r
+\r
+ @retval TRUE The entry point structure is valid\r
+ @retval FALSE The entry point structure is not valid\r
+\r
+**/\r
+BOOLEAN\r
+IsEntryPointStructureValid (\r
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINT8 Length;\r
+ UINT8 Checksum;\r
+ UINT8 *BytePtr;\r
+\r
+ BytePtr = (UINT8*) EntryPointStructure;\r
+ Length = EntryPointStructure->EntryPointLength;\r
+ Checksum = 0;\r
+\r
+ for (Index = 0; Index < Length; Index++) {\r
+ Checksum += BytePtr[Index];\r
+ }\r
+\r
+ if (Checksum != 0) {\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Get SMBIOS record length.\r
+\r
+ @param SmbiosTable SMBIOS pointer.\r
+\r
+**/\r
+UINTN\r
+SmbiosTableLength (\r
+ IN SMBIOS_STRUCTURE_POINTER SmbiosTable\r
+ )\r
+{\r
+ CHAR8 *AChar;\r
+ UINTN Length;\r
+\r
+ AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);\r
+\r
+ //\r
+ // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)\r
+ //\r
+ while ((*AChar != 0) || (*(AChar + 1) != 0)) {\r
+ AChar ++;\r
+ }\r
+ Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);\r
+\r
+ return Length;\r
+}\r
+\r
+\r
+/**\r
+ Install all structures from the given SMBIOS structures block\r
+\r
+ @param Smbios SMBIOS protocol\r
+ @param EntryPointStructure SMBIOS entry point structures block\r
+\r
+**/\r
+EFI_STATUS\r
+InstallAllStructures (\r
+ IN EFI_SMBIOS_PROTOCOL *Smbios,\r
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SMBIOS_STRUCTURE_POINTER SmbiosTable;\r
+ EFI_SMBIOS_HANDLE SmbiosHandle;\r
+\r
+ SmbiosTable.Raw = (UINT8*)(UINTN) EntryPointStructure->TableAddress;\r
+ if (SmbiosTable.Raw == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ while (SmbiosTable.Hdr->Type != 127) {\r
+ //\r
+ // Log the SMBIOS data for this structure\r
+ //\r
+ SmbiosHandle = 0;\r
+ Status = Smbios->Add (\r
+ Smbios,\r
+ NULL,\r
+ &SmbiosHandle,\r
+ (EFI_SMBIOS_TABLE_HEADER*) SmbiosTable.Raw\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Get the next structure address\r
+ //\r
+ SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Installs SMBIOS information for OVMF\r
+\r
+ @param ImageHandle Module's image handle\r
+ @param SystemTable Pointer of EFI_SYSTEM_TABLE\r
+\r
+ @retval EFI_SUCCESS Smbios data successfully installed\r
+ @retval Other Smbios data was not installed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosTablePublishEntry (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SMBIOS_PROTOCOL *Smbios;\r
+ SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;\r
+\r
+ //\r
+ // Find the SMBIOS protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiSmbiosProtocolGuid,\r
+ NULL,\r
+ (VOID**)&Smbios\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Add Xen SMBIOS data if found\r
+ //\r
+ EntryPointStructure = GetXenSmbiosTables ();\r
+ if (EntryPointStructure != NULL) {\r
+ Status = InstallAllStructures (Smbios, EntryPointStructure);\r
+ }\r
+\r
+ return Status;\r
+}\r