IntelSiliconPkg: Add DxeSmbiosDataHobLib
[mirror_edk2.git] / IntelSiliconPkg / Library / DxeSmbiosDataHobLib / DxeSmbiosDataHobLib.c
CommitLineData
04683038
GM
1/** @file\r
2 Library to add SMBIOS data records from HOB to SMBIOS table.\r
3\r
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials are licensed and made available under\r
7 the terms and conditions of the BSD License which accompanies this distribution.\r
8 The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14 @par Specification Reference:\r
15 System Management BIOS (SMBIOS) Reference Specification v3.0.0\r
16 dated 2015-Feb-12 (DSP0134)\r
17 http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf\r
18\r
19**/\r
20#include <IndustryStandard/SmBios.h>\r
21#include <Library/UefiLib.h>\r
22#include <Library/BaseLib.h>\r
23#include <Library/BaseMemoryLib.h>\r
24#include <Library/MemoryAllocationLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/HobLib.h>\r
27#include <Library/UefiBootServicesTableLib.h>\r
28#include <Protocol/Smbios.h>\r
29\r
30/**\r
31\r
32 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
33 @note: This function is copy from SmbiosDxe in MdeModulePkg.\r
34\r
35 @param[in] This The EFI_SMBIOS_PROTOCOL instance.\r
36 @param[in] Head Pointer to the beginning of SMBIOS structure.\r
37 @param[out] Size The returned size.\r
38 @param[out] NumberOfStrings The returned number of optional strings that follow the formatted structure.\r
39\r
40 @retval EFI_SUCCESS Size returned in Size.\r
41 @retval EFI_INVALID_PARAMETER Input SMBIOS structure mal-formed or Size is NULL.\r
42\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46GetSmbiosStructureSize (\r
47 IN CONST EFI_SMBIOS_PROTOCOL *This,\r
48 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
49 OUT UINTN *Size,\r
50 OUT UINTN *NumberOfStrings\r
51 )\r
52{\r
53 UINTN FullSize;\r
54 UINTN StrLen;\r
55 UINTN MaxLen;\r
56 INT8* CharInStr;\r
57\r
58 if (Size == NULL || NumberOfStrings == NULL) {\r
59 return EFI_INVALID_PARAMETER;\r
60 }\r
61\r
62 FullSize = Head->Length;\r
63 CharInStr = (INT8*)Head + Head->Length;\r
64 *Size = FullSize;\r
65 *NumberOfStrings = 0;\r
66 StrLen = 0;\r
67\r
68 //\r
69 // look for the two consecutive zeros, check the string limit by the way.\r
70 //\r
71 while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
72 if (*CharInStr == 0) {\r
73 *Size += 1;\r
74 CharInStr++;\r
75 }\r
76\r
77 if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {\r
78 MaxLen = SMBIOS_STRING_MAX_LENGTH;\r
79 } else if (This->MajorVersion < 3) {\r
80 //\r
81 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
82 // However, the length of the entire structure table (including all strings) must be reported\r
83 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
84 // which is a WORD field limited to 65,535 bytes.\r
85 //\r
86 MaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
87 } else {\r
88 //\r
89 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
90 // Locate the end of string as long as possible.\r
91 //\r
92 MaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;\r
93 }\r
94\r
95 for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {\r
96 if (*(CharInStr+StrLen) == 0) {\r
97 break;\r
98 }\r
99 }\r
100\r
101 if (StrLen == MaxLen) {\r
102 return EFI_INVALID_PARAMETER;\r
103 }\r
104\r
105 //\r
106 // forward the pointer\r
107 //\r
108 CharInStr += StrLen;\r
109 *Size += StrLen;\r
110 *NumberOfStrings += 1;\r
111 }\r
112\r
113 //\r
114 // count ending two zeros.\r
115 //\r
116 *Size += 2;\r
117 return EFI_SUCCESS;\r
118}\r
119\r
120/**\r
121 Adds SMBIOS records to tables\r
122\r
123 @param[in] ImageHandle Image handle of this driver.\r
124 @param[in] SystemTable Global system service table.\r
125\r
126 @retval EFI_UNSUPPORTED - Could not locate SMBIOS protocol\r
127 @retval EFI_OUT_OF_RESOURCES - Failed to allocate memory for SMBIOS HOB type.\r
128 @retval EFI_SUCCESS - Successfully added SMBIOS records based on HOB.\r
129**/\r
130EFI_STATUS\r
131EFIAPI\r
132DxeSmbiosDataHobLibConstructor (\r
133 IN EFI_HANDLE ImageHandle,\r
134 IN EFI_SYSTEM_TABLE *SystemTable\r
135 )\r
136{\r
137 EFI_PEI_HOB_POINTERS Hob;\r
138 EFI_SMBIOS_HANDLE SmbiosHandle;\r
139 EFI_SMBIOS_PROTOCOL *Smbios;\r
140 EFI_STATUS Status;\r
141 UINTN InstalledPayloadSize;\r
142 UINTN MaxPayloadSize;\r
143 UINT8 *RecordPtr;\r
144 UINT16 RecordCount;\r
145 UINTN StructureSize;\r
146 UINTN NumberOfStrings;\r
147\r
148 RecordCount = 0;\r
149\r
150 DEBUG ((DEBUG_INFO, "Adding SMBIOS records from HOB..\n"));\r
151\r
152 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);\r
153 if (Smbios == NULL) {\r
154 DEBUG ((DEBUG_WARN, " Can't locate SMBIOS protocol\n"));\r
155 return EFI_UNSUPPORTED;\r
156 }\r
157\r
158 ///\r
159 /// Get SMBIOS HOB data\r
160 ///\r
161 for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {\r
162 if ((GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_GUID_EXTENSION) && (CompareGuid (&Hob.Guid->Name, &gIntelSmbiosDataHobGuid))) {\r
163 RecordPtr = (UINT8 *)Hob.Raw + sizeof (EFI_HOB_GUID_TYPE);\r
164 MaxPayloadSize = Hob.Guid->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE);\r
165\r
166 InstalledPayloadSize = 0;\r
167 do {\r
168 StructureSize = 0;\r
169 Status = GetSmbiosStructureSize (Smbios, (EFI_SMBIOS_TABLE_HEADER *)RecordPtr, &StructureSize, &NumberOfStrings);\r
170 if ((Status == EFI_SUCCESS) && (InstalledPayloadSize + StructureSize <= MaxPayloadSize)) {\r
171 InstalledPayloadSize += StructureSize;\r
172\r
173 ///\r
174 /// Add generic SMBIOS HOB to SMBIOS table\r
175 ///\r
176 DEBUG ((DEBUG_VERBOSE, " Add SMBIOS record type: %x\n", ((EFI_SMBIOS_TABLE_HEADER *) RecordPtr)->Type));\r
177 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
178 Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) RecordPtr);\r
179 if (!EFI_ERROR (Status)) {\r
180 RecordPtr += StructureSize;\r
181 RecordCount++;\r
182 }\r
183 } else {\r
184 break;\r
185 }\r
186 } while (TRUE);\r
187 }\r
188 }\r
189 DEBUG ((DEBUG_INFO, " Found %d Records and added to SMBIOS table.\n", RecordCount));\r
190\r
191 return EFI_SUCCESS;\r
192}\r
193\r