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