1 /** @file
2
3 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 SmbiosGen.c
15
16 Abstract:
17
18 **/
19
20 #include "SmbiosGen.h"
21 extern UINT8 SmbiosGenDxeStrings[];
22 EFI_SMBIOS_PROTOCOL *gSmbios;
23 EFI_HII_HANDLE gStringHandle;
24
25 VOID *
GetSmbiosTablesFromHob(VOID)26 GetSmbiosTablesFromHob (
27 VOID
28 )
29 {
30 EFI_PHYSICAL_ADDRESS *Table;
31 EFI_PEI_HOB_POINTERS GuidHob;
32
33 GuidHob.Raw = GetFirstGuidHob (&gEfiSmbiosTableGuid);
34 if (GuidHob.Raw != NULL) {
35 Table = GET_GUID_HOB_DATA (GuidHob.Guid);
36 if (Table != NULL) {
37 return (VOID *)(UINTN)*Table;
38 }
39 }
40
41 return NULL;
42 }
43
44
45 VOID
InstallProcessorSmbios(IN VOID * Smbios)46 InstallProcessorSmbios (
47 IN VOID *Smbios
48 )
49 {
50 SMBIOS_STRUCTURE_POINTER SmbiosTable;
51 CHAR8 *AString;
52 CHAR16 *UString;
53 STRING_REF Token;
54
55 //
56 // Processor info (TYPE 4)
57 //
58 SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 4, 0);
59 if (SmbiosTable.Raw == NULL) {
60 DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 4 (Processor Info) not found!\n"));
61 return ;
62 }
63
64 //
65 // Log Smbios Record Type4
66 //
67 LogSmbiosData(gSmbios,(UINT8*)SmbiosTable.Type4);
68
69 //
70 // Set ProcessorVersion string
71 //
72 AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type4->ProcessorVersion);
73 UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16));
74 ASSERT (UString != NULL);
75 AsciiStrToUnicodeStr (AString, UString);
76
77 Token = HiiSetString (gStringHandle, 0, UString, NULL);
78 if (Token == 0) {
79 gBS->FreePool (UString);
80 return ;
81 }
82 gBS->FreePool (UString);
83 return ;
84 }
85
86 VOID
InstallCacheSmbios(IN VOID * Smbios)87 InstallCacheSmbios (
88 IN VOID *Smbios
89 )
90 {
91 return ;
92 }
93
94 VOID
InstallMemorySmbios(IN VOID * Smbios)95 InstallMemorySmbios (
96 IN VOID *Smbios
97 )
98 {
99 SMBIOS_STRUCTURE_POINTER SmbiosTable;
100
101 //
102 // Generate Memory Array Mapped Address info (TYPE 19)
103 //
104 SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 19, 0);
105 if (SmbiosTable.Raw == NULL) {
106 DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 19 (Memory Array Mapped Address Info) not found!\n"));
107 return ;
108 }
109
110 //
111 // Record Smbios Type 19
112 //
113 LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type19);
114 return ;
115 }
116
117 VOID
InstallMiscSmbios(IN VOID * Smbios)118 InstallMiscSmbios (
119 IN VOID *Smbios
120 )
121 {
122 SMBIOS_STRUCTURE_POINTER SmbiosTable;
123 CHAR8 *AString;
124 CHAR16 *UString;
125 STRING_REF Token;
126
127 //
128 // BIOS information (TYPE 0)
129 //
130 SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 0, 0);
131 if (SmbiosTable.Raw == NULL) {
132 DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 0 (BIOS Information) not found!\n"));
133 return ;
134 }
135
136 //
137 // Record Type 2
138 //
139 AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type0->BiosVersion);
140 UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_BIOS_VERSIONE));
141 ASSERT (UString != NULL);
142 CopyMem (UString, FIRMWARE_BIOS_VERSIONE, sizeof(FIRMWARE_BIOS_VERSIONE));
143 AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_BIOS_VERSIONE) / sizeof(CHAR16) - 1);
144
145 Token = HiiSetString (gStringHandle, 0, UString, NULL);
146 if (Token == 0) {
147 gBS->FreePool (UString);
148 return ;
149 }
150 gBS->FreePool (UString);
151
152 //
153 // Log Smios Type 0
154 //
155 LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type0);
156
157 //
158 // System information (TYPE 1)
159 //
160 SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 1, 0);
161 if (SmbiosTable.Raw == NULL) {
162 DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 1 (System Information) not found!\n"));
163 return ;
164 }
165
166 //
167 // Record Type 3
168 //
169 AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type1->ProductName);
170 UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_PRODUCT_NAME));
171 ASSERT (UString != NULL);
172 CopyMem (UString, FIRMWARE_PRODUCT_NAME, sizeof(FIRMWARE_PRODUCT_NAME));
173 AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_PRODUCT_NAME) / sizeof(CHAR16) - 1);
174
175 Token = HiiSetString (gStringHandle, 0, UString, NULL);
176 if (Token == 0) {
177 gBS->FreePool (UString);
178 return ;
179 }
180 gBS->FreePool (UString);
181
182 //
183 // Log Smbios Type 1
184 //
185 LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type1);
186
187 return ;
188 }
189
190 EFI_STATUS
191 EFIAPI
SmbiosGenEntrypoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)192 SmbiosGenEntrypoint (
193 IN EFI_HANDLE ImageHandle,
194 IN EFI_SYSTEM_TABLE *SystemTable
195 )
196 {
197 EFI_STATUS Status;
198 VOID *Smbios;
199
200 Smbios = GetSmbiosTablesFromHob ();
201 if (Smbios == NULL) {
202 return EFI_NOT_FOUND;
203 }
204
205 Status = gBS->LocateProtocol (
206 &gEfiSmbiosProtocolGuid,
207 NULL,
208 (VOID**)&gSmbios
209 );
210 if (EFI_ERROR (Status)) {
211 return Status;
212 }
213
214 gStringHandle = HiiAddPackages (
215 &gEfiCallerIdGuid,
216 NULL,
217 SmbiosGenDxeStrings,
218 NULL
219 );
220 ASSERT (gStringHandle != NULL);
221
222 InstallProcessorSmbios (Smbios);
223 InstallCacheSmbios (Smbios);
224 InstallMemorySmbios (Smbios);
225 InstallMiscSmbios (Smbios);
226
227 return EFI_SUCCESS;
228 }
229
230 //
231 // Internal function
232 //
233
234 UINTN
SmbiosTableLength(IN SMBIOS_STRUCTURE_POINTER SmbiosTable)235 SmbiosTableLength (
236 IN SMBIOS_STRUCTURE_POINTER SmbiosTable
237 )
238 {
239 CHAR8 *AChar;
240 UINTN Length;
241
242 AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
243 while ((*AChar != 0) || (*(AChar + 1) != 0)) {
244 AChar ++;
245 }
246 Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
247
248 return Length;
249 }
250
251 SMBIOS_STRUCTURE_POINTER
GetSmbiosTableFromType(IN SMBIOS_TABLE_ENTRY_POINT * Smbios,IN UINT8 Type,IN UINTN Index)252 GetSmbiosTableFromType (
253 IN SMBIOS_TABLE_ENTRY_POINT *Smbios,
254 IN UINT8 Type,
255 IN UINTN Index
256 )
257 {
258 SMBIOS_STRUCTURE_POINTER SmbiosTable;
259 UINTN SmbiosTypeIndex;
260
261 SmbiosTypeIndex = 0;
262 SmbiosTable.Raw = (UINT8 *)(UINTN)Smbios->TableAddress;
263 if (SmbiosTable.Raw == NULL) {
264 return SmbiosTable;
265 }
266 while ((SmbiosTypeIndex != Index) || (SmbiosTable.Hdr->Type != Type)) {
267 if (SmbiosTable.Hdr->Type == 127) {
268 SmbiosTable.Raw = NULL;
269 return SmbiosTable;
270 }
271 if (SmbiosTable.Hdr->Type == Type) {
272 SmbiosTypeIndex ++;
273 }
274 SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
275 }
276
277 return SmbiosTable;
278 }
279
280 CHAR8 *
GetSmbiosString(IN SMBIOS_STRUCTURE_POINTER SmbiosTable,IN SMBIOS_TABLE_STRING String)281 GetSmbiosString (
282 IN SMBIOS_STRUCTURE_POINTER SmbiosTable,
283 IN SMBIOS_TABLE_STRING String
284 )
285 {
286 CHAR8 *AString;
287 UINT8 Index;
288
289 Index = 1;
290 AString = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
291 while (Index != String) {
292 while (*AString != 0) {
293 AString ++;
294 }
295 AString ++;
296 if (*AString == 0) {
297 return AString;
298 }
299 Index ++;
300 }
301
302 return AString;
303 }
304
305
306 /**
307 Logs SMBIOS record.
308
309 @param Smbios Pointer to SMBIOS protocol instance.
310 @param Buffer Pointer to the data buffer.
311
312 **/
313 VOID
LogSmbiosData(IN EFI_SMBIOS_PROTOCOL * Smbios,IN UINT8 * Buffer)314 LogSmbiosData (
315 IN EFI_SMBIOS_PROTOCOL *Smbios,
316 IN UINT8 *Buffer
317 )
318 {
319 EFI_STATUS Status;
320 EFI_SMBIOS_HANDLE SmbiosHandle;
321
322 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
323 Status = Smbios->Add (
324 Smbios,
325 NULL,
326 &SmbiosHandle,
327 (EFI_SMBIOS_TABLE_HEADER*)Buffer
328 );
329 ASSERT_EFI_ERROR (Status);
330 }
331