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