1 /** @file
2   This driver parses the mMiscSubclassDataTable structure and reports
3   any generated data to smbios.
4 
5   Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
6 
7   Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
8   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
9   Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
10   Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
11   SPDX-License-Identifier: BSD-2-Clause-Patent
12 
13 **/
14 
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/HiiLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/OemMiscLib.h>
21 #include <Library/PrintLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 
24 #include "SmbiosMisc.h"
25 
26 /**
27   This function makes boot time changes to the contents of the
28   MiscSystemManufacturer (Type 1) record.
29 
30   @param  RecordData                 Pointer to SMBIOS table with default values.
31   @param  Smbios                     SMBIOS protocol.
32 
33   @retval EFI_SUCCESS                The SMBIOS table was successfully added.
34   @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
35   @retval EFI_OUT_OF_RESOURCES       Failed to allocate required memory.
36 
37 **/
SMBIOS_MISC_TABLE_FUNCTION(MiscSystemManufacturer)38 SMBIOS_MISC_TABLE_FUNCTION(MiscSystemManufacturer)
39 {
40   CHAR8                           *OptionalStrStart;
41   CHAR8                           *StrStart;
42   UINTN                           ManuStrLen;
43   UINTN                           VerStrLen;
44   UINTN                           PdNameStrLen;
45   UINTN                           SerialNumStrLen;
46   UINTN                           SKUNumStrLen;
47   UINTN                           FamilyStrLen;
48   UINTN                           RecordLength;
49   EFI_STRING                      Manufacturer;
50   EFI_STRING                      ProductName;
51   EFI_STRING                      Version;
52   EFI_STRING                      SerialNumber;
53   EFI_STRING                      SKUNumber;
54   EFI_STRING                      Family;
55   EFI_STRING_ID                   TokenToGet;
56   SMBIOS_TABLE_TYPE1              *SmbiosRecord;
57   SMBIOS_TABLE_TYPE1              *InputData;
58   EFI_STATUS                      Status;
59   EFI_STRING_ID                   TokenToUpdate;
60   CHAR16                          *Product;
61   CHAR16                          *pVersion;
62 
63   Status = EFI_SUCCESS;
64 
65   //
66   // First check for invalid parameters.
67   //
68   if (RecordData == NULL) {
69     return EFI_INVALID_PARAMETER;
70   }
71 
72   InputData = (SMBIOS_TABLE_TYPE1 *)RecordData;
73 
74   Product = (CHAR16 *) PcdGetPtr (PcdSystemProductName);
75   if (StrLen (Product) > 0) {
76     TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
77     HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, Product, NULL);
78   }
79 
80   pVersion = (CHAR16 *) PcdGetPtr (PcdSystemVersion);
81   if (StrLen (pVersion) > 0) {
82     TokenToUpdate = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
83     HiiSetString (mSmbiosMiscHiiHandle, TokenToUpdate, pVersion, NULL);
84   }
85 
86   OemUpdateSmbiosInfo (mSmbiosMiscHiiHandle,
87                        STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER),
88                        SerialNumType01);
89   OemUpdateSmbiosInfo (mSmbiosMiscHiiHandle,
90                        STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER),
91                        SystemManufacturerType01);
92   OemUpdateSmbiosInfo (mSmbiosMiscHiiHandle,
93                        STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER),
94                        SkuNumberType01);
95   OemUpdateSmbiosInfo (mSmbiosMiscHiiHandle,
96                        STRING_TOKEN (STR_MISC_SYSTEM_FAMILY),
97                        FamilyType01);
98 
99   TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
100   Manufacturer = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
101   ManuStrLen   = StrLen (Manufacturer);
102 
103   TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
104   ProductName  = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
105   PdNameStrLen = StrLen (ProductName);
106 
107   TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
108   Version    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
109   VerStrLen  = StrLen (Version);
110 
111   TokenToGet      = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER);
112   SerialNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
113   SerialNumStrLen = StrLen (SerialNumber);
114 
115   TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
116   SKUNumber    = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
117   SKUNumStrLen = StrLen (SKUNumber);
118 
119   TokenToGet   = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY);
120   Family       = HiiGetPackageString (&gEfiCallerIdGuid, TokenToGet, NULL);
121   FamilyStrLen = StrLen (Family);
122 
123   //
124   // Two zeros following the last string.
125   //
126   RecordLength = sizeof (SMBIOS_TABLE_TYPE1) +
127                  ManuStrLen      + 1 +
128                  PdNameStrLen    + 1 +
129                  VerStrLen       + 1 +
130                  SerialNumStrLen + 1 +
131                  SKUNumStrLen    + 1 +
132                  FamilyStrLen    + 1 + 1;
133   SmbiosRecord = AllocateZeroPool (RecordLength);
134 
135   if (SmbiosRecord == NULL) {
136     Status = EFI_OUT_OF_RESOURCES;
137     goto Exit;
138   }
139 
140   (VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE1));
141 
142   SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);
143 
144   CopyGuid(&SmbiosRecord->Uuid, &InputData->Uuid);
145 
146   OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
147   UnicodeStrToAsciiStrS (Manufacturer, OptionalStrStart, ManuStrLen + 1);
148   StrStart = OptionalStrStart + ManuStrLen + 1;
149   UnicodeStrToAsciiStrS (ProductName,  StrStart, PdNameStrLen + 1);
150   StrStart += PdNameStrLen + 1;
151   UnicodeStrToAsciiStrS (Version, StrStart, VerStrLen + 1);
152   StrStart += VerStrLen + 1;
153   UnicodeStrToAsciiStrS (SerialNumber, StrStart, SerialNumStrLen + 1);
154   StrStart += SerialNumStrLen + 1;
155   UnicodeStrToAsciiStrS (SKUNumber, StrStart, SKUNumStrLen + 1);
156   StrStart += SKUNumStrLen + 1;
157   UnicodeStrToAsciiStrS (Family, StrStart, FamilyStrLen + 1);
158 
159   //
160   // Now we have got the full smbios record, call smbios protocol to add this record.
161   //
162   Status = SmbiosMiscAddRecord ((UINT8*)SmbiosRecord, NULL);
163   if (EFI_ERROR (Status)) {
164     DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type01 Table Log Failed! %r \n",
165             __FUNCTION__, __LINE__, Status));
166   }
167 
168   FreePool (SmbiosRecord);
169 
170 Exit:
171   if (Manufacturer != NULL) {
172     FreePool (Manufacturer);
173   }
174 
175   if (ProductName != NULL) {
176     FreePool (ProductName);
177   }
178 
179   if (Version != NULL) {
180     FreePool (Version);
181   }
182 
183   if (SerialNumber != NULL) {
184     FreePool (SerialNumber);
185   }
186 
187   if (SKUNumber != NULL) {
188     FreePool (SKUNumber);
189   }
190 
191   if (Family != NULL) {
192     FreePool (Family);
193   }
194 
195   return Status;
196 }
197