MiscBiosVendorFunction.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /** @file
  2. Copyright (c) 2022, Ampere Computing LLC. All rights reserved.<BR>
  3. Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
  4. Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
  5. Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
  6. Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
  7. SPDX-License-Identifier: BSD-2-Clause-Patent
  8. **/
  9. #include <Library/BaseLib.h>
  10. #include <Library/BaseMemoryLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/HiiLib.h>
  13. #include <Library/MemoryAllocationLib.h>
  14. #include <Library/OemMiscLib.h>
  15. #include <Library/PrintLib.h>
  16. #include <Library/UefiBootServicesTableLib.h>
  17. #include "SmbiosMisc.h"
  18. typedef struct {
  19. CONST CHAR8 *MonthStr;
  20. UINT32 MonthInt;
  21. } MONTH_DESCRIPTION;
  22. STATIC CONST
  23. MONTH_DESCRIPTION mMonthDescription[] = {
  24. { "Jan", 1 },
  25. { "Feb", 2 },
  26. { "Mar", 3 },
  27. { "Apr", 4 },
  28. { "May", 5 },
  29. { "Jun", 6 },
  30. { "Jul", 7 },
  31. { "Aug", 8 },
  32. { "Sep", 9 },
  33. { "Oct", 10 },
  34. { "Nov", 11 },
  35. { "Dec", 12 },
  36. { "???", 1 }, // Use 1 as default month
  37. };
  38. /**
  39. Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
  40. as the unit.
  41. @param Value Pointer to Base2_Data
  42. @retval
  43. **/
  44. UINT8
  45. Base2ToByteWith64KUnit (
  46. IN UINTN Value
  47. )
  48. {
  49. UINT8 Size;
  50. Size = ((Value + (SIZE_64KB - 1)) >> 16);
  51. return Size;
  52. }
  53. /**
  54. Returns the date and time this file (and firmware) was built.
  55. @param[out] *Time Pointer to the EFI_TIME structure to fill in.
  56. **/
  57. VOID
  58. GetReleaseTime (
  59. OUT EFI_TIME *Time
  60. )
  61. {
  62. CONST CHAR8 *ReleaseDate = __DATE__;
  63. CONST CHAR8 *ReleaseTime = __TIME__;
  64. UINTN i;
  65. for (i = 0; i < 12; i++) {
  66. if (AsciiStrnCmp (ReleaseDate, mMonthDescription[i].MonthStr, 3) == 0) {
  67. break;
  68. }
  69. }
  70. Time->Month = mMonthDescription[i].MonthInt;
  71. Time->Day = AsciiStrDecimalToUintn (ReleaseDate + 4);
  72. Time->Year = AsciiStrDecimalToUintn (ReleaseDate + 7);
  73. Time->Hour = AsciiStrDecimalToUintn (ReleaseTime);
  74. Time->Minute = AsciiStrDecimalToUintn (ReleaseTime + 3);
  75. Time->Second = AsciiStrDecimalToUintn (ReleaseTime + 6);
  76. }
  77. /**
  78. Fetches the firmware ('BIOS') release date from the
  79. FirmwareVersionInfo HOB.
  80. @return The release date as a UTF-16 string
  81. **/
  82. CHAR16 *
  83. GetBiosReleaseDate (
  84. VOID
  85. )
  86. {
  87. CHAR16 *ReleaseDate;
  88. EFI_TIME BuildTime;
  89. ReleaseDate = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
  90. if (ReleaseDate == NULL) {
  91. return NULL;
  92. }
  93. GetReleaseTime (&BuildTime);
  94. (VOID)UnicodeSPrintAsciiFormat (
  95. ReleaseDate,
  96. (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH,
  97. "%02d/%02d/%4d",
  98. BuildTime.Month,
  99. BuildTime.Day,
  100. BuildTime.Year
  101. );
  102. return ReleaseDate;
  103. }
  104. /**
  105. Fetches the firmware ('BIOS') version from the
  106. FirmwareVersionInfo HOB.
  107. @return The version as a UTF-16 string
  108. **/
  109. CHAR16 *
  110. GetBiosVersion (
  111. VOID
  112. )
  113. {
  114. CHAR16 *ReleaseString;
  115. ReleaseString = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVersionString);
  116. return ReleaseString;
  117. }
  118. /**
  119. This function makes boot time changes to the contents of the
  120. MiscBiosVendor (Type 0) record.
  121. @param RecordData Pointer to SMBIOS table with default values.
  122. @param Smbios SMBIOS protocol.
  123. @retval EFI_SUCCESS The SMBIOS table was successfully added.
  124. @retval EFI_INVALID_PARAMETER Invalid parameter was found.
  125. @retval EFI_OUT_OF_RESOURCES Failed to allocate required memory.
  126. **/
  127. SMBIOS_MISC_TABLE_FUNCTION (MiscBiosVendor) {
  128. CHAR8 *OptionalStrStart;
  129. CHAR8 *StrStart;
  130. UINTN VendorStrLen;
  131. UINTN VerStrLen;
  132. UINTN DateStrLen;
  133. UINTN BiosPhysicalSize;
  134. CHAR16 *Vendor;
  135. CHAR16 *Version;
  136. CHAR16 *ReleaseDate;
  137. CHAR16 *Char16String;
  138. EFI_STATUS Status;
  139. EFI_STRING_ID TokenToUpdate;
  140. EFI_STRING_ID TokenToGet;
  141. SMBIOS_TABLE_TYPE0 *SmbiosRecord;
  142. SMBIOS_TABLE_TYPE0 *InputData;
  143. //
  144. // First check for invalid parameters.
  145. //
  146. if (RecordData == NULL) {
  147. return EFI_INVALID_PARAMETER;
  148. }
  149. InputData = (SMBIOS_TABLE_TYPE0 *)RecordData;
  150. Vendor = (CHAR16 *)PcdGetPtr (PcdFirmwareVendor);
  151. if (StrLen (Vendor) > 0) {
  152. TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
  153. HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Vendor, NULL);
  154. }
  155. Version = GetBiosVersion ();
  156. if (StrLen (Version) > 0) {
  157. TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION);
  158. HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Version, NULL);
  159. } else {
  160. OemUpdateSmbiosInfo (
  161. mSmbiosMiscHiiHandle,
  162. STRING_TOKEN (STR_MISC_BIOS_VERSION),
  163. BiosVersionType00
  164. );
  165. }
  166. Char16String = GetBiosReleaseDate ();
  167. if (StrLen (Char16String) > 0) {
  168. TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
  169. HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Char16String, NULL);
  170. }
  171. TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR);
  172. Vendor = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
  173. VendorStrLen = StrLen (Vendor);
  174. TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
  175. Version = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
  176. VerStrLen = StrLen (Version);
  177. TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE);
  178. ReleaseDate = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
  179. DateStrLen = StrLen (ReleaseDate);
  180. //
  181. // Now update the BiosPhysicalSize
  182. //
  183. BiosPhysicalSize = FixedPcdGet32 (PcdFdSize);
  184. //
  185. // Two zeros following the last string.
  186. //
  187. SmbiosRecord = AllocateZeroPool (
  188. sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 +
  189. VerStrLen + 1 +
  190. DateStrLen + 1 + 1
  191. );
  192. if (SmbiosRecord == NULL) {
  193. Status = EFI_OUT_OF_RESOURCES;
  194. goto Exit;
  195. }
  196. (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0));
  197. SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
  198. SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB);
  199. if (BiosPhysicalSize < SIZE_16MB) {
  200. SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSize) - 1;
  201. } else {
  202. SmbiosRecord->BiosSize = 0xFF;
  203. if (BiosPhysicalSize < SIZE_16GB) {
  204. SmbiosRecord->ExtendedBiosSize.Size = BiosPhysicalSize / SIZE_1MB;
  205. SmbiosRecord->ExtendedBiosSize.Unit = 0; // Size is in MB
  206. } else {
  207. SmbiosRecord->ExtendedBiosSize.Size = BiosPhysicalSize / SIZE_1GB;
  208. SmbiosRecord->ExtendedBiosSize.Unit = 1; // Size is in GB
  209. }
  210. }
  211. SmbiosRecord->SystemBiosMajorRelease = (UINT8)(OemGetBiosRelease () >> 8);
  212. SmbiosRecord->SystemBiosMinorRelease = (UINT8)(OemGetBiosRelease () & 0xFF);
  213. SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = (UINT16)(OemGetEmbeddedControllerFirmwareRelease () >> 8);
  214. SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = (UINT16)(OemGetEmbeddedControllerFirmwareRelease () & 0xFF);
  215. OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
  216. UnicodeStrToAsciiStrS (Vendor, OptionalStrStart, VendorStrLen + 1);
  217. StrStart = OptionalStrStart + VendorStrLen + 1;
  218. UnicodeStrToAsciiStrS (Version, StrStart, VerStrLen + 1);
  219. StrStart += VerStrLen + 1;
  220. UnicodeStrToAsciiStrS (ReleaseDate, StrStart, DateStrLen + 1);
  221. //
  222. // Now we have got the full smbios record, call smbios protocol to add this record.
  223. //
  224. Status = SmbiosMiscAddRecord ((UINT8 *)SmbiosRecord, NULL);
  225. if (EFI_ERROR (Status)) {
  226. DEBUG ((
  227. DEBUG_ERROR,
  228. "[%a]:[%dL] Smbios Type00 Table Log Failed! %r \n",
  229. __FUNCTION__,
  230. DEBUG_LINE_NUMBER,
  231. Status
  232. ));
  233. }
  234. FreePool (SmbiosRecord);
  235. Exit:
  236. if (Vendor != NULL) {
  237. FreePool (Vendor);
  238. }
  239. if (Version != NULL) {
  240. FreePool (Version);
  241. }
  242. if (ReleaseDate != NULL) {
  243. FreePool (ReleaseDate);
  244. }
  245. if (Char16String != NULL) {
  246. FreePool (Char16String);
  247. }
  248. return Status;
  249. }