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 } 830