SmbiosPlatformDxe.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /** @file
  2. This driver installs SMBIOS information for OVMF
  3. Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>
  4. Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
  5. Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include "SmbiosPlatformDxe.h"
  9. #define TYPE0_STRINGS \
  10. "EFI Development Kit II / OVMF\0" /* Vendor */ \
  11. "0.0.0\0" /* BiosVersion */ \
  12. "02/06/2015\0" /* BiosReleaseDate */
  13. //
  14. // Type definition and contents of the default Type 0 SMBIOS table.
  15. //
  16. #pragma pack(1)
  17. typedef struct {
  18. SMBIOS_TABLE_TYPE0 Base;
  19. UINT8 Strings[sizeof (TYPE0_STRINGS)];
  20. } OVMF_TYPE0;
  21. #pragma pack()
  22. STATIC CONST OVMF_TYPE0 mOvmfDefaultType0 = {
  23. {
  24. // SMBIOS_STRUCTURE Hdr
  25. {
  26. EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
  27. sizeof (SMBIOS_TABLE_TYPE0), // UINT8 Length
  28. },
  29. 1, // SMBIOS_TABLE_STRING Vendor
  30. 2, // SMBIOS_TABLE_STRING BiosVersion
  31. 0xE800, // UINT16 BiosSegment
  32. 3, // SMBIOS_TABLE_STRING BiosReleaseDate
  33. 0, // UINT8 BiosSize
  34. { // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
  35. 0, // Reserved :2
  36. 0, // Unknown :1
  37. 1, // BiosCharacteristicsNotSupported :1
  38. // Remaining BiosCharacteristics bits left unset :60
  39. },
  40. { // BIOSCharacteristicsExtensionBytes[2]
  41. 0, // BiosReserved
  42. 0x1C // SystemReserved = VirtualMachineSupported |
  43. // UefiSpecificationSupported |
  44. // TargetContentDistributionEnabled
  45. },
  46. 0, // UINT8 SystemBiosMajorRelease
  47. 0, // UINT8 SystemBiosMinorRelease
  48. 0xFF, // UINT8 EmbeddedControllerFirmwareMajorRelease
  49. 0xFF // UINT8 EmbeddedControllerFirmwareMinorRelease
  50. },
  51. // Text strings (unformatted area)
  52. TYPE0_STRINGS
  53. };
  54. /**
  55. Validates the SMBIOS entry point structure
  56. @param EntryPointStructure SMBIOS entry point structure
  57. @retval TRUE The entry point structure is valid
  58. @retval FALSE The entry point structure is not valid
  59. **/
  60. BOOLEAN
  61. IsEntryPointStructureValid (
  62. IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
  63. )
  64. {
  65. UINTN Index;
  66. UINT8 Length;
  67. UINT8 Checksum;
  68. UINT8 *BytePtr;
  69. BytePtr = (UINT8 *)EntryPointStructure;
  70. Length = EntryPointStructure->EntryPointLength;
  71. Checksum = 0;
  72. for (Index = 0; Index < Length; Index++) {
  73. Checksum = Checksum + (UINT8)BytePtr[Index];
  74. }
  75. if (Checksum != 0) {
  76. return FALSE;
  77. } else {
  78. return TRUE;
  79. }
  80. }
  81. /**
  82. Get SMBIOS record length.
  83. @param SmbiosTable SMBIOS pointer.
  84. **/
  85. UINTN
  86. SmbiosTableLength (
  87. IN SMBIOS_STRUCTURE_POINTER SmbiosTable
  88. )
  89. {
  90. CHAR8 *AChar;
  91. UINTN Length;
  92. AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
  93. //
  94. // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)
  95. //
  96. while ((*AChar != 0) || (*(AChar + 1) != 0)) {
  97. AChar++;
  98. }
  99. Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
  100. return Length;
  101. }
  102. /**
  103. Install all structures from the given SMBIOS structures block
  104. @param Smbios SMBIOS protocol
  105. @param TableAddress SMBIOS tables starting address
  106. **/
  107. EFI_STATUS
  108. InstallAllStructures (
  109. IN EFI_SMBIOS_PROTOCOL *Smbios,
  110. IN UINT8 *TableAddress
  111. )
  112. {
  113. EFI_STATUS Status;
  114. SMBIOS_STRUCTURE_POINTER SmbiosTable;
  115. EFI_SMBIOS_HANDLE SmbiosHandle;
  116. BOOLEAN NeedSmbiosType0;
  117. SmbiosTable.Raw = TableAddress;
  118. if (SmbiosTable.Raw == NULL) {
  119. return EFI_INVALID_PARAMETER;
  120. }
  121. NeedSmbiosType0 = TRUE;
  122. while (SmbiosTable.Hdr->Type != 127) {
  123. //
  124. // Log the SMBIOS data for this structure
  125. //
  126. SmbiosHandle = SmbiosTable.Hdr->Handle;
  127. Status = Smbios->Add (
  128. Smbios,
  129. NULL,
  130. &SmbiosHandle,
  131. (EFI_SMBIOS_TABLE_HEADER *)SmbiosTable.Raw
  132. );
  133. ASSERT_EFI_ERROR (Status);
  134. if (SmbiosTable.Hdr->Type == 0) {
  135. NeedSmbiosType0 = FALSE;
  136. }
  137. //
  138. // Get the next structure address
  139. //
  140. SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
  141. }
  142. if (NeedSmbiosType0) {
  143. //
  144. // Add OVMF default Type 0 (BIOS Information) table
  145. //
  146. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  147. Status = Smbios->Add (
  148. Smbios,
  149. NULL,
  150. &SmbiosHandle,
  151. (EFI_SMBIOS_TABLE_HEADER *)&mOvmfDefaultType0
  152. );
  153. ASSERT_EFI_ERROR (Status);
  154. }
  155. return EFI_SUCCESS;
  156. }
  157. /**
  158. Installs SMBIOS information for OVMF
  159. @param ImageHandle Module's image handle
  160. @param SystemTable Pointer of EFI_SYSTEM_TABLE
  161. @retval EFI_SUCCESS Smbios data successfully installed
  162. @retval Other Smbios data was not installed
  163. **/
  164. EFI_STATUS
  165. EFIAPI
  166. SmbiosTablePublishEntry (
  167. IN EFI_HANDLE ImageHandle,
  168. IN EFI_SYSTEM_TABLE *SystemTable
  169. )
  170. {
  171. EFI_STATUS Status;
  172. EFI_SMBIOS_PROTOCOL *Smbios;
  173. SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;
  174. UINT8 *SmbiosTables = NULL;
  175. //
  176. // Find the SMBIOS protocol
  177. //
  178. Status = gBS->LocateProtocol (
  179. &gEfiSmbiosProtocolGuid,
  180. NULL,
  181. (VOID **)&Smbios
  182. );
  183. if (EFI_ERROR (Status)) {
  184. return Status;
  185. }
  186. //
  187. // Add bhyve SMBIOS data
  188. //
  189. EntryPointStructure = GetBhyveSmbiosTables ();
  190. if (EntryPointStructure != NULL) {
  191. SmbiosTables = (UINT8 *)(UINTN)EntryPointStructure->TableAddress;
  192. }
  193. if (SmbiosTables != NULL) {
  194. Status = InstallAllStructures (Smbios, SmbiosTables);
  195. //
  196. // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):
  197. //
  198. if (EntryPointStructure == NULL) {
  199. FreePool (SmbiosTables);
  200. }
  201. }
  202. return Status;
  203. }