]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvLib.c
Free the buffer allocated by GetSectionFromAnyFv() when exit, and add Error Status...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / PiSmbiosRecordOnDataHubSmbiosRecordThunk / ConvLib.c
CommitLineData
bd1a4d18 1/** @file\r
024b1029 2 Common filling functions used in translating Datahub's record\r
3 to PI SMBIOS's record.\r
4 \r
2788ff51 5Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
584d5652 6This program and the accompanying materials\r
024b1029 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Thunk.h"\r
17\r
18/**\r
19 Field Filling Function for Cache SubClass record type 5&6 -- Cache SRAM type.\r
20 Offset is mandatory\r
21 \r
22 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
23 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
24 @param RecordData RecordData buffer will be filled.\r
25 @param RecordDataSize The size of RecordData buffer.\r
26 \r
27 @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.\r
28**/\r
29EFI_STATUS\r
30SmbiosFldCacheType5 (\r
31 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
32 IN UINT32 Offset,\r
33 IN VOID *RecordData,\r
34 IN UINT32 RecordDataSize\r
35 )\r
36{\r
37 EFI_CACHE_SRAM_TYPE_DATA SramData;\r
38 UINT32 Temp;\r
39\r
40 SramData = *(EFI_CACHE_SRAM_TYPE_DATA*)RecordData;\r
41\r
42 //\r
43 // Swap two fields because of inconsistency between smbios and datahub specs\r
44 //\r
45 Temp = SramData.Asynchronous;\r
46 SramData.Asynchronous = SramData.Synchronous;\r
47 SramData.Synchronous = Temp;\r
48 \r
49 //\r
50 // Truncate the data to word\r
51 //\r
52 CopyMem (\r
53 (UINT8 *) (StructureNode->Structure) + Offset,\r
54 (EFI_CACHE_SRAM_TYPE_DATA *) &SramData,\r
55 2\r
56 );\r
57\r
58 return EFI_SUCCESS;\r
59}\r
60\r
61/**\r
62 Field Filling Function for Cache SubClass record type 10 -- Cache Config.\r
63 Offset is mandatory\r
64\r
65 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
66 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
67 @param RecordData RecordData buffer will be filled.\r
68 @param RecordDataSize The size of RecordData buffer.\r
69 \r
70 @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.\r
71**/\r
72EFI_STATUS\r
73SmbiosFldCacheType10 (\r
74 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
75 IN UINT32 Offset,\r
76 IN VOID *RecordData,\r
77 IN UINT32 RecordDataSize\r
78 )\r
79{\r
80\r
81 UINT16 CacheConfig;\r
82\r
83 CopyMem (&CacheConfig, RecordData, 2);\r
84\r
85 if ((CacheConfig & 0x07) == 0) {\r
86 return EFI_INVALID_PARAMETER;\r
87 }\r
88 //\r
89 // Truncate the data to 2 bytes and make cache level zero-based.\r
90 //\r
91 CacheConfig--;\r
92 CopyMem (\r
93 (UINT8 *) (StructureNode->Structure) + Offset,\r
94 &CacheConfig,\r
95 2\r
96 );\r
97\r
98 return EFI_SUCCESS;\r
99}\r
100\r
101/**\r
102 Enlarge the structure buffer of a structure node in SMBIOS database.\r
103 The function maybe lead the structure pointer for SMBIOS record changed.\r
104 \r
105 @param StructureNode The structure node whose structure buffer is to be enlarged.\r
106 @param NewLength The new length of SMBIOS record which does not include unformat area.\r
107 @param OldBufferSize The old size of SMBIOS record buffer.\r
bd1a4d18 108 @param NewBufferSize The new size is targeted for enlarged.\r
024b1029 109 \r
110 @retval EFI_OUT_OF_RESOURCES No more memory to allocate new record\r
111 @retval EFI_SUCCESS Success to enlarge the record buffer size.\r
112**/\r
113EFI_STATUS\r
114SmbiosEnlargeStructureBuffer (\r
115 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
116 UINT8 NewLength,\r
117 UINTN OldBufferSize,\r
118 UINTN NewBufferSize\r
119 )\r
120{\r
121 EFI_SMBIOS_TABLE_HEADER *NewRecord;\r
122 EFI_SMBIOS_PROTOCOL *Smbios;\r
123 EFI_STATUS Status;\r
124 UINT8 CountOfString;\r
125 \r
126 NewRecord = NULL;\r
127 Smbios = GetSmbiosProtocol();\r
128 ASSERT (Smbios != NULL);\r
129 \r
130 NewRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (NewBufferSize);\r
131 if (NewRecord == NULL) {\r
132 return EFI_OUT_OF_RESOURCES;\r
133 }\r
134 CopyMem (NewRecord, StructureNode->Structure, OldBufferSize);\r
135 \r
136 \r
137 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
138 ASSERT_EFI_ERROR (Status);\r
139 \r
140 //\r
141 // try to use original handle to enlarge the buffer.\r
142 //\r
143 NewRecord->Length = NewLength;\r
144 Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord);\r
145 ASSERT_EFI_ERROR (Status);\r
146 FreePool (NewRecord);\r
147 \r
148 StructureNode->Structure = GetSmbiosBufferFromHandle (\r
149 StructureNode->SmbiosHandle, \r
150 StructureNode->SmbiosType, \r
151 NULL\r
152 );\r
153 GetSmbiosStructureSize (\r
154 StructureNode->Structure,\r
155 &StructureNode->StructureSize,\r
156 &CountOfString\r
157 );\r
158 return EFI_SUCCESS;\r
159}\r
160\r
2788ff51 161/**\r
162 Update the structure buffer of a structure node in SMBIOS database.\r
163 The function lead the structure pointer for SMBIOS record changed.\r
164 \r
165 @param StructureNode The structure node whose structure buffer is to be enlarged.\r
166 @param NewRecord The new SMBIOS record.\r
167 \r
168**/\r
169VOID\r
170SmbiosUpdateStructureBuffer (\r
171 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
172 IN EFI_SMBIOS_TABLE_HEADER *NewRecord\r
173 )\r
174{\r
175 EFI_SMBIOS_PROTOCOL *Smbios;\r
176 EFI_STATUS Status;\r
177 UINT8 CountOfString;\r
178 \r
179 Smbios = GetSmbiosProtocol();\r
180 ASSERT (Smbios != NULL);\r
181 \r
182 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
183 ASSERT_EFI_ERROR (Status);\r
184 \r
185 //\r
186 // try to use original handle to enlarge the buffer.\r
187 //\r
188 Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord);\r
189 ASSERT_EFI_ERROR (Status);\r
190 \r
191 StructureNode->Structure = GetSmbiosBufferFromHandle (\r
192 StructureNode->SmbiosHandle, \r
193 StructureNode->SmbiosType, \r
194 NULL\r
195 );\r
196 GetSmbiosStructureSize (\r
197 StructureNode->Structure,\r
198 &StructureNode->StructureSize,\r
199 &CountOfString\r
200 );\r
201 return ;\r
202}\r
203\r
024b1029 204/**\r
205 Fill a standard Smbios string field. \r
206 \r
207 This function will convert the unicode string to single byte chars, and only\r
208 English language is supported.\r
209 This function changes the Structure pointer value of the structure node, \r
210 which should be noted by Caller.\r
211 \r
212 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
213 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
214 @param RecordData RecordData buffer will be filled.\r
215 @param RecordDataSize The size of RecordData buffer.\r
216 \r
217 @retval EFI_INVALID_PARAMETER RecordDataSize is too larger\r
218 @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string\r
219 @retval EFI_SUCCESS Sucess append string for a SMBIOS record.\r
220**/\r
221EFI_STATUS\r
222SmbiosFldString (\r
223 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
224 IN UINT32 Offset,\r
225 IN VOID *RecordData,\r
226 IN UINT32 RecordDataSize\r
227 )\r
228{\r
229 EFI_STATUS Status;\r
230 UINT16 *Data;\r
231 CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH];\r
232 UINT8 CountOfStrings;\r
233 UINTN OrigStringNumber;\r
234 EFI_SMBIOS_PROTOCOL *Smbios;\r
235 EFI_SMBIOS_HANDLE SmbiosHandle;\r
236 UINT32 OrigStructureSize;\r
237 UINTN NewStructureSize;\r
238 EFI_SMBIOS_TABLE_HEADER *NewRecord;\r
239 UINT32 StringLength;\r
240 \r
241 Status = EFI_SUCCESS;\r
242 OrigStringNumber = 0;\r
243 OrigStructureSize = 0;\r
244\r
245 //\r
246 // if we have a NULL token,\r
247 //\r
248 if (0 == *((STRING_REF *) RecordData)) {\r
249 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;\r
250 return EFI_SUCCESS;\r
251 }\r
252 \r
253 //\r
254 // Get the String from the Hii Database\r
255 //\r
256 Data = HiiGetPackageString (\r
257 &(StructureNode->ProducerName),\r
258 *((EFI_STRING_ID *) RecordData),\r
259 NULL\r
260 );\r
261 if (Data == NULL) {\r
262 return EFI_INVALID_PARAMETER;\r
263 }\r
264\r
265 StringLength = (UINT32)StrLen (Data);\r
266 //\r
267 // Count the string size including the terminating 0.\r
268 //\r
269 if (StringLength == 0) {\r
270 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;\r
271 FreePool (Data);\r
272 return EFI_SUCCESS;\r
273 }\r
274 \r
275 if (StringLength > SMBIOS_STRING_MAX_LENGTH) {\r
276 //\r
277 // Too long a string\r
278 //\r
279 FreePool (Data);\r
280 return EFI_INVALID_PARAMETER;\r
281 }\r
282 \r
283 Smbios = GetSmbiosProtocol();\r
284 ASSERT (Smbios != NULL);\r
285 \r
286 //\r
287 // Convert Unicode string to Ascii string which only supported by SMBIOS.\r
288 //\r
289 ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH);\r
290 UnicodeStrToAsciiStr (Data, AsciiData);\r
291 \r
292 //\r
293 // if the field at offset is already filled with some value,\r
294 // find out the string it points to\r
295 //\r
296 OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset);\r
297 if (OrigStringNumber != 0) {\r
298 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n", \r
299 OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData)); \r
300 \r
301 //\r
302 // If original string number is not zero, just update string\r
303 //\r
304 Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData);\r
305 if (EFI_ERROR (Status)) {\r
306 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n", \r
307 OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType));\r
308 ASSERT_EFI_ERROR (Status);\r
309 return Status;\r
310 }\r
311 } else {\r
312 //\r
313 // If the string has not been filled in SMBIOS database, remove it and add again\r
314 // with string appended.\r
315 //\r
316 Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings);\r
317 ASSERT_EFI_ERROR (Status);\r
318 \r
319 if (CountOfStrings == 0) {\r
320 NewStructureSize = OrigStructureSize + StringLength;\r
321 } else {\r
322 NewStructureSize = OrigStructureSize + StringLength + 1;\r
323 }\r
324 \r
325 NewRecord = AllocateZeroPool (NewStructureSize);\r
326 if (NewRecord == NULL) {\r
327 return EFI_OUT_OF_RESOURCES;\r
328 }\r
329 CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize);\r
330 \r
331 //\r
332 // Copy new string into tail of original SMBIOS record buffer.\r
333 //\r
334 if (CountOfStrings == 0) {\r
335 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData);\r
336 } else {\r
337 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData);\r
338 }\r
339 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n", \r
340 StructureNode->SmbiosType, Offset, CountOfStrings + 1));\r
341 //\r
342 // Update string reference number\r
343 //\r
344 *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1);\r
345 SmbiosHandle = StructureNode->SmbiosHandle;\r
346 \r
347 //\r
348 // Remove original SMBIOS record and add new one\r
349 //\r
350 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
351 ASSERT_EFI_ERROR (Status);\r
352 \r
353 //\r
354 // Add new SMBIOS record\r
355 //\r
356 Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord);\r
357 ASSERT_EFI_ERROR (Status);\r
358 \r
359 StructureNode->SmbiosHandle = SmbiosHandle;\r
360 \r
361 FreePool (NewRecord);\r
362 }\r
363 \r
364 //\r
365 // The SMBIOS record buffer maybe re-allocated in SMBIOS database,\r
366 // so update cached buffer pointer in DataHub structure list.\r
367 //\r
368 StructureNode->Structure = GetSmbiosBufferFromHandle (\r
369 StructureNode->SmbiosHandle, \r
370 StructureNode->SmbiosType,\r
371 NULL\r
372 );\r
373 ASSERT (StructureNode->Structure != NULL);\r
374 \r
375 //\r
376 // The string update action maybe lead the record is re-allocated in SMBIOS database\r
377 // so update cached record pointer\r
378 //\r
379 Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings);\r
380 ASSERT_EFI_ERROR (Status);\r
381 \r
382 return EFI_SUCCESS;\r
383}\r
384\r
385/**\r
386 Find a handle that matches the Link Data and the target Smbios type.\r
387 \r
388 @param TargetType the Smbios type\r
389 @param SubClass the SubClass\r
390 @param LinkData Specifies Instance, SubInstance and ProducerName\r
391 @param Handle the HandleNum found \r
392 \r
393 @retval EFI_NOT_FOUND Can not find the record according to handle\r
394 @retval EFI_SUCCESS Success to find the handle\r
395**/\r
396EFI_STATUS\r
397SmbiosFindHandle (\r
398 IN UINT8 TargetType,\r
399 IN EFI_GUID *SubClass,\r
400 IN EFI_INTER_LINK_DATA *LinkData,\r
401 IN OUT UINT16 *HandleNum\r
402 )\r
403{\r
404 LIST_ENTRY *Link;\r
405 SMBIOS_STRUCTURE_NODE *StructureNode;\r
406\r
407 StructureNode = NULL;\r
408\r
409 //\r
410 // Find out the matching handle\r
411 //\r
412 for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {\r
413 StructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);\r
414 if (StructureNode->Structure->Type == TargetType &&\r
415 CompareGuid (&(StructureNode->SubClass), SubClass) &&\r
416 StructureNode->Instance == LinkData->Instance &&\r
417 StructureNode->SubInstance == LinkData->SubInstance\r
418 ) {\r
419 break;\r
420 }\r
421 }\r
422\r
234980f6 423 if (Link == &mStructureList || StructureNode == NULL) {\r
024b1029 424 return EFI_NOT_FOUND;\r
425 } else {\r
426 *HandleNum = StructureNode->Structure->Handle;\r
427 return EFI_SUCCESS;\r
428 }\r
429}\r
430\r
431/**\r
432 Fill the inter link field for a SMBIOS recorder.\r
433 \r
434 Some SMBIOS recorder need to reference the handle of another SMBIOS record. But\r
435 maybe another SMBIOS record has not been added, so put the InterLink request into\r
436 a linked list and the interlink will be fixedup when a new SMBIOS record is added.\r
437 \r
438 @param StructureNode Point to SMBIOS_STRUCTURE_NODE which reference another record's handle\r
439 @param LinkSmbiosNodeOffset The offset in this record for holding the handle of another SMBIOS record\r
440 @param LinkSmbiosType The type of SMBIOS record want to be linked.\r
441 @param InterLink Point to EFI_INTER_LINK_DATA will be put linked list.\r
442 @param SubClassGuid The guid of subclass for linked SMBIOS record.\r
443 \r
444 @retval EFI_SUCESS The linked record is found and no need fixup in future.\r
445 @retval !EFI_SUCESS The linked record can not be found and InterLink is put a fixing-p linked list.\r
446**/\r
447EFI_STATUS\r
448SmbiosFldInterLink (\r
449 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
450 IN UINT16 LinkSmbiosNodeOffset,\r
451 IN UINT8 LinkSmbiosType,\r
452 IN EFI_INTER_LINK_DATA *InterLink,\r
453 IN EFI_GUID *SubClassGuid\r
454 )\r
455{\r
456 EFI_STATUS Status;\r
457 SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;\r
458 UINT16 StructureHandle;\r
459\r
460 Status = EFI_SUCCESS;\r
461 LinkDataFixupNode = NULL;\r
462\r
463 Status = SmbiosFindHandle (\r
464 LinkSmbiosType, // Smbios type\r
465 SubClassGuid,\r
466 InterLink,\r
467 &StructureHandle\r
468 );\r
469 if (!EFI_ERROR (Status)) {\r
470 //\r
471 // Set the handle\r
472 //\r
473 CopyMem (\r
474 (UINT8 *) (StructureNode->Structure) + LinkSmbiosNodeOffset,\r
475 &StructureHandle,\r
476 sizeof (EFI_SMBIOS_HANDLE)\r
477 );\r
478 } else {\r
479 //\r
480 // Hang this in the link data fixup node\r
481 //\r
482 LinkDataFixupNode = AllocateZeroPool (sizeof (SMBIOS_LINK_DATA_FIXUP_NODE));\r
bd1a4d18 483 if (LinkDataFixupNode == NULL) {\r
024b1029 484 return EFI_OUT_OF_RESOURCES;\r
485 }\r
486\r
487 LinkDataFixupNode->Signature = SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE;\r
488 LinkDataFixupNode->Offset = LinkSmbiosNodeOffset;\r
489 LinkDataFixupNode->TargetType = LinkSmbiosType;\r
490 CopyMem (\r
491 &LinkDataFixupNode->SubClass,\r
492 SubClassGuid,\r
493 sizeof (EFI_GUID)\r
494 );\r
495 CopyMem (\r
496 &LinkDataFixupNode->LinkData,\r
497 InterLink,\r
498 sizeof (EFI_INTER_LINK_DATA)\r
499 );\r
500 InsertTailList (\r
501 &StructureNode->LinkDataFixup,\r
502 &(LinkDataFixupNode->Link)\r
503 );\r
504 }\r
505\r
506 return Status;\r
507}\r
508\r
509/**\r
510 Field Filling Function. Transform an EFI_EXP_BASE10_DATA to a word, with 'Mega'\r
511 as the unit.\r
512 \r
513 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
514 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
515 @param RecordData RecordData buffer will be filled.\r
516 @param RecordDataSize The size of RecordData buffer.\r
517 \r
518 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
519 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
520**/\r
521EFI_STATUS\r
522SmbiosFldBase10ToWordWithMega (\r
523 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
524 IN UINT32 Offset,\r
525 IN VOID *RecordData,\r
526 IN UINT32 RecordDataSize\r
527 )\r
528{\r
529 EFI_EXP_BASE10_DATA *Base10Data;\r
530 INT16 Value;\r
531 INT16 Exponent;\r
532\r
533 if (RecordDataSize != sizeof (EFI_EXP_BASE10_DATA)) {\r
534 return EFI_INVALID_PARAMETER;\r
535 }\r
536\r
537 Base10Data = RecordData;\r
538 Value = Base10Data->Value;\r
539 Exponent = Base10Data->Exponent;\r
540\r
541 Exponent -= 6;\r
542 while (Exponent != 0) {\r
543 if (Exponent > 0) {\r
544 Value = (INT16) (Value * 10);\r
545 Exponent--;\r
546 } else {\r
547 Value = (INT16) (Value / 10);\r
548 Exponent++;\r
549 }\r
550 }\r
551\r
552 CopyMem (\r
553 (UINT8 *) (StructureNode->Structure) + Offset,\r
554 &Value,\r
555 2\r
556 );\r
557\r
558 return EFI_SUCCESS;\r
559}\r
560\r
561/**\r
562 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 'Kilo'\r
563 as the unit. Granularity implemented for Cache Size.\r
564 \r
565 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
566 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
567 @param RecordData RecordData buffer will be filled.\r
568 @param RecordDataSize The size of RecordData buffer.\r
569 \r
570 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
571 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
572**/\r
573EFI_STATUS\r
574SmbiosFldBase2ToWordWithKilo (\r
575 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
576 IN UINT32 Offset,\r
577 IN VOID *RecordData,\r
578 IN UINT32 RecordDataSize\r
579 )\r
580{\r
581 EFI_EXP_BASE2_DATA *Base2Data;\r
582 UINT32 Value;\r
583 UINT16 Exponent;\r
584\r
585 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
586 return EFI_INVALID_PARAMETER;\r
587 }\r
588\r
589 Base2Data = RecordData;\r
590 Value = Base2Data->Value;\r
591 Exponent = Base2Data->Exponent;\r
592\r
593 Exponent -= 10;\r
594 Value <<= Exponent;\r
595 \r
596 //\r
597 // Implement cache size granularity\r
598 //\r
599 if(Value >= 0x8000) {\r
600 Value >>= 6;\r
601 Value |= 0x8000;\r
602 }\r
603 \r
604 CopyMem (\r
605 (UINT8 *) (StructureNode->Structure) + Offset,\r
606 &Value,\r
607 2\r
608 );\r
609\r
610 return EFI_SUCCESS;\r
611}\r
612\r
613/**\r
614 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'\r
615 as the unit.\r
616 \r
617 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
618 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
619 @param RecordData RecordData buffer will be filled.\r
620 @param RecordDataSize The size of RecordData buffer.\r
621 \r
622 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
623 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
624**/\r
625EFI_STATUS\r
626SmbiosFldBase2ToByteWith64K (\r
627 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
628 IN UINT32 Offset,\r
629 IN VOID *RecordData,\r
630 IN UINT32 RecordDataSize\r
631 )\r
632{\r
633 EFI_EXP_BASE2_DATA *Base2Data;\r
634 UINT16 Value;\r
635 UINT16 Exponent;\r
636\r
637 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
638 return EFI_INVALID_PARAMETER;\r
639 }\r
640\r
641 Base2Data = RecordData;\r
642 Value = Base2Data->Value;\r
643 Exponent = Base2Data->Exponent;\r
644 Exponent -= 16;\r
645 Value <<= Exponent;\r
646\r
647 CopyMem (\r
648 (UINT8 *) (StructureNode->Structure) + Offset,\r
649 &Value,\r
650 1\r
651 );\r
652\r
653 return EFI_SUCCESS;\r
654}\r
655\r
656/**\r
657 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 10exp-9\r
658 as the unit.\r
659 \r
660 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
661 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
662 @param RecordData RecordData buffer will be filled.\r
663 @param RecordDataSize The size of RecordData buffer.\r
664 \r
665 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
666 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
667**/\r
668EFI_STATUS\r
669SmbiosFldBase10ToByteWithNano (\r
670 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
671 IN UINT32 Offset,\r
672 IN VOID *RecordData,\r
673 IN UINT32 RecordDataSize\r
674 )\r
675{\r
676 EFI_EXP_BASE10_DATA *Base10Data;\r
677 INT16 Value;\r
678 INT16 Exponent;\r
679\r
680 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
681 return EFI_INVALID_PARAMETER;\r
682 }\r
683\r
684 Base10Data = RecordData;\r
685 Value = Base10Data->Value;\r
686 Exponent = Base10Data->Exponent;\r
687\r
688 Exponent += 9;\r
689 while (Exponent != 0) {\r
690 if (Exponent > 0) {\r
691 Value = (INT16) (Value * 10);\r
692 Exponent--;\r
693 } else {\r
694 Value = (INT16) (Value / 10);\r
695 Exponent++;\r
696 }\r
697 }\r
698\r
699 * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) Value;\r
700\r
701 return EFI_SUCCESS;\r
702}\r
703\r
704/**\r
705 Field Filling Function: truncate record data to byte and fill in the\r
706 field as indicated by Offset.\r
707 \r
708 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
709 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
710 @param RecordData RecordData buffer will be filled.\r
711 @param RecordDataSize The size of RecordData buffer.\r
712 \r
713 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
714 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
715**/\r
716EFI_STATUS\r
717SmbiosFldTruncateToByte (\r
718 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
719 IN UINT32 Offset,\r
720 IN VOID *RecordData,\r
721 IN UINT32 RecordDataSize\r
722 )\r
723{\r
724 EFI_STATUS Status;\r
725\r
726 Status = EFI_SUCCESS;\r
727\r
728 //\r
729 // Truncate the data to 8 bits\r
730 //\r
731 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) (*(UINT8 *) RecordData);\r
732\r
733 return Status;\r
734}\r
735\r
736/**\r
737 Field Filling Function: truncate record data to byte and fill in the\r
738 field as indicated by Offset.\r
739 \r
740 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
741 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
742 @param RecordData RecordData buffer will be filled.\r
743 @param RecordDataSize The size of RecordData buffer.\r
744 \r
745 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
746 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
747**/\r
748EFI_STATUS\r
749SmbiosFldTruncateToWord (\r
750 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
751 IN UINT32 Offset,\r
752 IN VOID *RecordData,\r
753 IN UINT32 RecordDataSize\r
754 )\r
755{\r
756 EFI_STATUS Status;\r
757\r
758 Status = EFI_SUCCESS;\r
759\r
760 //\r
761 // Truncate the data to 8 bits\r
762 //\r
763 CopyMem (\r
764 (UINT8 *) (StructureNode->Structure) + Offset,\r
765 RecordData,\r
766 2\r
767 );\r
768\r
769 return Status;\r
770}\r
771\r
772/**\r
773 Check if OEM structure has included 2 trailing 0s in data record.\r
774 \r
775 @param RecordData Point to record data will be checked.\r
776 @param RecordDataSize The size of record data.\r
777 \r
778 @retval 0 2 trailing 0s exist in unformatted section\r
779 @retval 1 1 trailing 0 exists at the end of unformatted section\r
780 @retval -1 There is no 0 at the end of unformatted section\r
781**/\r
782INT8\r
783SmbiosCheckTrailingZero (\r
784 IN VOID *RecordData,\r
785 IN UINT32 RecordDataSize\r
786 )\r
787{\r
788 SMBIOS_STRUCTURE *Smbios;\r
789 CHAR8 *Start;\r
790 CHAR8 *End;\r
791 \r
792 Smbios = (SMBIOS_STRUCTURE *) RecordData;\r
793 \r
794 //\r
795 // Skip over formatted section\r
796 //\r
797 Start = (CHAR8 *) ((UINT8 *) Smbios + Smbios->Length);\r
798 End = (CHAR8 *) RecordData + RecordDataSize;\r
799 \r
800 //\r
801 // Unformatted section exists\r
802 //\r
803 while (Start < End - 1) {\r
804 //\r
805 // Avoid unaligned issue on IPF\r
806 //\r
807 if ((*Start == 0) && (*(Start + 1) == 0)) {\r
808 //\r
809 // 2 trailing 0s exist in unformatted section\r
810 //\r
811 return 0;\r
812 }\r
813 Start++;\r
814 }\r
815 \r
816 if (Start == End - 1) {\r
817 //\r
818 // Check if there has been already 1 trailing 0\r
819 //\r
820 if (*Start == 0) {\r
821 return 1;\r
822 } \r
823 }\r
824 \r
825 //\r
826 // There is no 0 at the end of unformatted section\r
827 //\r
828 return -1;\r
829}\r