]>
Commit | Line | Data |
---|---|---|
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 | |
44 | EFI_STATUS\r | |
45 | EFIAPI\r | |
46 | GetSmbiosStructureSize (\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 | |
130 | EFI_STATUS\r | |
131 | EFIAPI\r | |
132 | DxeSmbiosDataHobLibConstructor (\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 |