]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/ConvLib.c
Rename DataHubSmBiosRecordsOnPiSmBiosThunk to PiSmbiosRecordOnDataHubSmbiosRecordThun...
[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, Intel Corporation
6 All rights reserved. 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 Fill a standard Smbios string field.
163
164 This function will convert the unicode string to single byte chars, and only
165 English language is supported.
166 This function changes the Structure pointer value of the structure node,
167 which should be noted by Caller.
168
169 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
170 @param Offset Offset of SMBIOS record which RecordData will be filled.
171 @param RecordData RecordData buffer will be filled.
172 @param RecordDataSize The size of RecordData buffer.
173
174 @retval EFI_INVALID_PARAMETER RecordDataSize is too larger
175 @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string
176 @retval EFI_SUCCESS Sucess append string for a SMBIOS record.
177 **/
178 EFI_STATUS
179 SmbiosFldString (
180 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
181 IN UINT32 Offset,
182 IN VOID *RecordData,
183 IN UINT32 RecordDataSize
184 )
185 {
186 EFI_STATUS Status;
187 UINT16 *Data;
188 CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH];
189 UINT8 CountOfStrings;
190 UINTN OrigStringNumber;
191 EFI_SMBIOS_PROTOCOL *Smbios;
192 EFI_SMBIOS_HANDLE SmbiosHandle;
193 UINT32 OrigStructureSize;
194 UINTN NewStructureSize;
195 EFI_SMBIOS_TABLE_HEADER *NewRecord;
196 UINT32 StringLength;
197
198 Status = EFI_SUCCESS;
199 OrigStringNumber = 0;
200 OrigStructureSize = 0;
201
202 //
203 // if we have a NULL token,
204 //
205 if (0 == *((STRING_REF *) RecordData)) {
206 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
207 return EFI_SUCCESS;
208 }
209
210 //
211 // Get the String from the Hii Database
212 //
213 Data = HiiGetPackageString (
214 &(StructureNode->ProducerName),
215 *((EFI_STRING_ID *) RecordData),
216 NULL
217 );
218 if (Data == NULL) {
219 return EFI_INVALID_PARAMETER;
220 }
221
222 StringLength = (UINT32)StrLen (Data);
223 //
224 // Count the string size including the terminating 0.
225 //
226 if (StringLength == 0) {
227 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;
228 FreePool (Data);
229 return EFI_SUCCESS;
230 }
231
232 if (StringLength > SMBIOS_STRING_MAX_LENGTH) {
233 //
234 // Too long a string
235 //
236 FreePool (Data);
237 return EFI_INVALID_PARAMETER;
238 }
239
240 Smbios = GetSmbiosProtocol();
241 ASSERT (Smbios != NULL);
242
243 //
244 // Convert Unicode string to Ascii string which only supported by SMBIOS.
245 //
246 ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH);
247 UnicodeStrToAsciiStr (Data, AsciiData);
248
249 //
250 // if the field at offset is already filled with some value,
251 // find out the string it points to
252 //
253 OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset);
254 if (OrigStringNumber != 0) {
255 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n",
256 OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData));
257
258 //
259 // If original string number is not zero, just update string
260 //
261 Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData);
262 if (EFI_ERROR (Status)) {
263 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n",
264 OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType));
265 ASSERT_EFI_ERROR (Status);
266 return Status;
267 }
268 } else {
269 //
270 // If the string has not been filled in SMBIOS database, remove it and add again
271 // with string appended.
272 //
273 Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings);
274 ASSERT_EFI_ERROR (Status);
275
276 if (CountOfStrings == 0) {
277 NewStructureSize = OrigStructureSize + StringLength;
278 } else {
279 NewStructureSize = OrigStructureSize + StringLength + 1;
280 }
281
282 NewRecord = AllocateZeroPool (NewStructureSize);
283 if (NewRecord == NULL) {
284 return EFI_OUT_OF_RESOURCES;
285 }
286 CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize);
287
288 //
289 // Copy new string into tail of original SMBIOS record buffer.
290 //
291 if (CountOfStrings == 0) {
292 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData);
293 } else {
294 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData);
295 }
296 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n",
297 StructureNode->SmbiosType, Offset, CountOfStrings + 1));
298 //
299 // Update string reference number
300 //
301 *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1);
302 SmbiosHandle = StructureNode->SmbiosHandle;
303
304 //
305 // Remove original SMBIOS record and add new one
306 //
307 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
308 ASSERT_EFI_ERROR (Status);
309
310 //
311 // Add new SMBIOS record
312 //
313 Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord);
314 ASSERT_EFI_ERROR (Status);
315
316 StructureNode->SmbiosHandle = SmbiosHandle;
317
318 FreePool (NewRecord);
319 }
320
321 //
322 // The SMBIOS record buffer maybe re-allocated in SMBIOS database,
323 // so update cached buffer pointer in DataHub structure list.
324 //
325 StructureNode->Structure = GetSmbiosBufferFromHandle (
326 StructureNode->SmbiosHandle,
327 StructureNode->SmbiosType,
328 NULL
329 );
330 ASSERT (StructureNode->Structure != NULL);
331
332 //
333 // The string update action maybe lead the record is re-allocated in SMBIOS database
334 // so update cached record pointer
335 //
336 Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings);
337 ASSERT_EFI_ERROR (Status);
338
339 return EFI_SUCCESS;
340 }
341
342 /**
343 Find a handle that matches the Link Data and the target Smbios type.
344
345 @param TargetType the Smbios type
346 @param SubClass the SubClass
347 @param LinkData Specifies Instance, SubInstance and ProducerName
348 @param Handle the HandleNum found
349
350 @retval EFI_NOT_FOUND Can not find the record according to handle
351 @retval EFI_SUCCESS Success to find the handle
352 **/
353 EFI_STATUS
354 SmbiosFindHandle (
355 IN UINT8 TargetType,
356 IN EFI_GUID *SubClass,
357 IN EFI_INTER_LINK_DATA *LinkData,
358 IN OUT UINT16 *HandleNum
359 )
360 {
361 LIST_ENTRY *Link;
362 SMBIOS_STRUCTURE_NODE *StructureNode;
363
364 StructureNode = NULL;
365
366 //
367 // Find out the matching handle
368 //
369 for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {
370 StructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);
371 if (StructureNode->Structure->Type == TargetType &&
372 CompareGuid (&(StructureNode->SubClass), SubClass) &&
373 StructureNode->Instance == LinkData->Instance &&
374 StructureNode->SubInstance == LinkData->SubInstance
375 ) {
376 break;
377 }
378 }
379
380 if (Link == &mStructureList) {
381 return EFI_NOT_FOUND;
382 } else {
383 *HandleNum = StructureNode->Structure->Handle;
384 return EFI_SUCCESS;
385 }
386 }
387
388 /**
389 Fill the inter link field for a SMBIOS recorder.
390
391 Some SMBIOS recorder need to reference the handle of another SMBIOS record. But
392 maybe another SMBIOS record has not been added, so put the InterLink request into
393 a linked list and the interlink will be fixedup when a new SMBIOS record is added.
394
395 @param StructureNode Point to SMBIOS_STRUCTURE_NODE which reference another record's handle
396 @param LinkSmbiosNodeOffset The offset in this record for holding the handle of another SMBIOS record
397 @param LinkSmbiosType The type of SMBIOS record want to be linked.
398 @param InterLink Point to EFI_INTER_LINK_DATA will be put linked list.
399 @param SubClassGuid The guid of subclass for linked SMBIOS record.
400
401 @retval EFI_SUCESS The linked record is found and no need fixup in future.
402 @retval !EFI_SUCESS The linked record can not be found and InterLink is put a fixing-p linked list.
403 **/
404 EFI_STATUS
405 SmbiosFldInterLink (
406 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
407 IN UINT16 LinkSmbiosNodeOffset,
408 IN UINT8 LinkSmbiosType,
409 IN EFI_INTER_LINK_DATA *InterLink,
410 IN EFI_GUID *SubClassGuid
411 )
412 {
413 EFI_STATUS Status;
414 SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;
415 UINT16 StructureHandle;
416
417 Status = EFI_SUCCESS;
418 LinkDataFixupNode = NULL;
419
420 Status = SmbiosFindHandle (
421 LinkSmbiosType, // Smbios type
422 SubClassGuid,
423 InterLink,
424 &StructureHandle
425 );
426 if (!EFI_ERROR (Status)) {
427 //
428 // Set the handle
429 //
430 CopyMem (
431 (UINT8 *) (StructureNode->Structure) + LinkSmbiosNodeOffset,
432 &StructureHandle,
433 sizeof (EFI_SMBIOS_HANDLE)
434 );
435 } else {
436 //
437 // Hang this in the link data fixup node
438 //
439 LinkDataFixupNode = AllocateZeroPool (sizeof (SMBIOS_LINK_DATA_FIXUP_NODE));
440 if (LinkDataFixupNode == NULL) {
441 return EFI_OUT_OF_RESOURCES;
442 }
443
444 LinkDataFixupNode->Signature = SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE;
445 LinkDataFixupNode->Offset = LinkSmbiosNodeOffset;
446 LinkDataFixupNode->TargetType = LinkSmbiosType;
447 CopyMem (
448 &LinkDataFixupNode->SubClass,
449 SubClassGuid,
450 sizeof (EFI_GUID)
451 );
452 CopyMem (
453 &LinkDataFixupNode->LinkData,
454 InterLink,
455 sizeof (EFI_INTER_LINK_DATA)
456 );
457 InsertTailList (
458 &StructureNode->LinkDataFixup,
459 &(LinkDataFixupNode->Link)
460 );
461 }
462
463 return Status;
464 }
465
466 /**
467 Field Filling Function. Transform an EFI_EXP_BASE10_DATA to a word, with 'Mega'
468 as the unit.
469
470 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
471 @param Offset Offset of SMBIOS record which RecordData will be filled.
472 @param RecordData RecordData buffer will be filled.
473 @param RecordDataSize The size of RecordData buffer.
474
475 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
476 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
477 **/
478 EFI_STATUS
479 SmbiosFldBase10ToWordWithMega (
480 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
481 IN UINT32 Offset,
482 IN VOID *RecordData,
483 IN UINT32 RecordDataSize
484 )
485 {
486 EFI_EXP_BASE10_DATA *Base10Data;
487 INT16 Value;
488 INT16 Exponent;
489
490 if (RecordDataSize != sizeof (EFI_EXP_BASE10_DATA)) {
491 return EFI_INVALID_PARAMETER;
492 }
493
494 Base10Data = RecordData;
495 Value = Base10Data->Value;
496 Exponent = Base10Data->Exponent;
497
498 Exponent -= 6;
499 while (Exponent != 0) {
500 if (Exponent > 0) {
501 Value = (INT16) (Value * 10);
502 Exponent--;
503 } else {
504 Value = (INT16) (Value / 10);
505 Exponent++;
506 }
507 }
508
509 CopyMem (
510 (UINT8 *) (StructureNode->Structure) + Offset,
511 &Value,
512 2
513 );
514
515 return EFI_SUCCESS;
516 }
517
518 /**
519 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 'Kilo'
520 as the unit. Granularity implemented for Cache Size.
521
522 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
523 @param Offset Offset of SMBIOS record which RecordData will be filled.
524 @param RecordData RecordData buffer will be filled.
525 @param RecordDataSize The size of RecordData buffer.
526
527 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
528 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
529 **/
530 EFI_STATUS
531 SmbiosFldBase2ToWordWithKilo (
532 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
533 IN UINT32 Offset,
534 IN VOID *RecordData,
535 IN UINT32 RecordDataSize
536 )
537 {
538 EFI_EXP_BASE2_DATA *Base2Data;
539 UINT32 Value;
540 UINT16 Exponent;
541
542 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
543 return EFI_INVALID_PARAMETER;
544 }
545
546 Base2Data = RecordData;
547 Value = Base2Data->Value;
548 Exponent = Base2Data->Exponent;
549
550 Exponent -= 10;
551 Value <<= Exponent;
552
553 //
554 // Implement cache size granularity
555 //
556 if(Value >= 0x8000) {
557 Value >>= 6;
558 Value |= 0x8000;
559 }
560
561 CopyMem (
562 (UINT8 *) (StructureNode->Structure) + Offset,
563 &Value,
564 2
565 );
566
567 return EFI_SUCCESS;
568 }
569
570 /**
571 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'
572 as the unit.
573
574 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
575 @param Offset Offset of SMBIOS record which RecordData will be filled.
576 @param RecordData RecordData buffer will be filled.
577 @param RecordDataSize The size of RecordData buffer.
578
579 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
580 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
581 **/
582 EFI_STATUS
583 SmbiosFldBase2ToByteWith64K (
584 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
585 IN UINT32 Offset,
586 IN VOID *RecordData,
587 IN UINT32 RecordDataSize
588 )
589 {
590 EFI_EXP_BASE2_DATA *Base2Data;
591 UINT16 Value;
592 UINT16 Exponent;
593
594 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
595 return EFI_INVALID_PARAMETER;
596 }
597
598 Base2Data = RecordData;
599 Value = Base2Data->Value;
600 Exponent = Base2Data->Exponent;
601 Exponent -= 16;
602 Value <<= Exponent;
603
604 CopyMem (
605 (UINT8 *) (StructureNode->Structure) + Offset,
606 &Value,
607 1
608 );
609
610 return EFI_SUCCESS;
611 }
612
613 /**
614 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 10exp-9
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 SmbiosFldBase10ToByteWithNano (
627 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
628 IN UINT32 Offset,
629 IN VOID *RecordData,
630 IN UINT32 RecordDataSize
631 )
632 {
633 EFI_EXP_BASE10_DATA *Base10Data;
634 INT16 Value;
635 INT16 Exponent;
636
637 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {
638 return EFI_INVALID_PARAMETER;
639 }
640
641 Base10Data = RecordData;
642 Value = Base10Data->Value;
643 Exponent = Base10Data->Exponent;
644
645 Exponent += 9;
646 while (Exponent != 0) {
647 if (Exponent > 0) {
648 Value = (INT16) (Value * 10);
649 Exponent--;
650 } else {
651 Value = (INT16) (Value / 10);
652 Exponent++;
653 }
654 }
655
656 * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) Value;
657
658 return EFI_SUCCESS;
659 }
660
661 /**
662 Field Filling Function: truncate record data to byte and fill in the
663 field as indicated by Offset.
664
665 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
666 @param Offset Offset of SMBIOS record which RecordData will be filled.
667 @param RecordData RecordData buffer will be filled.
668 @param RecordDataSize The size of RecordData buffer.
669
670 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
671 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
672 **/
673 EFI_STATUS
674 SmbiosFldTruncateToByte (
675 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
676 IN UINT32 Offset,
677 IN VOID *RecordData,
678 IN UINT32 RecordDataSize
679 )
680 {
681 EFI_STATUS Status;
682
683 Status = EFI_SUCCESS;
684
685 //
686 // Truncate the data to 8 bits
687 //
688 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) (*(UINT8 *) RecordData);
689
690 return Status;
691 }
692
693 /**
694 Field Filling Function: truncate record data to byte and fill in the
695 field as indicated by Offset.
696
697 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
698 @param Offset Offset of SMBIOS record which RecordData will be filled.
699 @param RecordData RecordData buffer will be filled.
700 @param RecordDataSize The size of RecordData buffer.
701
702 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid.
703 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.
704 **/
705 EFI_STATUS
706 SmbiosFldTruncateToWord (
707 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,
708 IN UINT32 Offset,
709 IN VOID *RecordData,
710 IN UINT32 RecordDataSize
711 )
712 {
713 EFI_STATUS Status;
714
715 Status = EFI_SUCCESS;
716
717 //
718 // Truncate the data to 8 bits
719 //
720 CopyMem (
721 (UINT8 *) (StructureNode->Structure) + Offset,
722 RecordData,
723 2
724 );
725
726 return Status;
727 }
728
729 /**
730 Check if OEM structure has included 2 trailing 0s in data record.
731
732 @param RecordData Point to record data will be checked.
733 @param RecordDataSize The size of record data.
734
735 @retval 0 2 trailing 0s exist in unformatted section
736 @retval 1 1 trailing 0 exists at the end of unformatted section
737 @retval -1 There is no 0 at the end of unformatted section
738 **/
739 INT8
740 SmbiosCheckTrailingZero (
741 IN VOID *RecordData,
742 IN UINT32 RecordDataSize
743 )
744 {
745 SMBIOS_STRUCTURE *Smbios;
746 CHAR8 *Start;
747 CHAR8 *End;
748
749 Smbios = (SMBIOS_STRUCTURE *) RecordData;
750
751 //
752 // Skip over formatted section
753 //
754 Start = (CHAR8 *) ((UINT8 *) Smbios + Smbios->Length);
755 End = (CHAR8 *) RecordData + RecordDataSize;
756
757 //
758 // Unformatted section exists
759 //
760 while (Start < End - 1) {
761 //
762 // Avoid unaligned issue on IPF
763 //
764 if ((*Start == 0) && (*(Start + 1) == 0)) {
765 //
766 // 2 trailing 0s exist in unformatted section
767 //
768 return 0;
769 }
770 Start++;
771 }
772
773 if (Start == End - 1) {
774 //
775 // Check if there has been already 1 trailing 0
776 //
777 if (*Start == 0) {
778 return 1;
779 }
780 }
781
782 //
783 // There is no 0 at the end of unformatted section
784 //
785 return -1;
786 }