smbios.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*++
  2. Copyright (c) 2000 Intel Corporation
  3. Module Name:
  4. Smbios.c
  5. Abstract:
  6. Lib fucntions for SMBIOS. Used to get system serial number and GUID
  7. Revision History
  8. --*/
  9. #include "lib.h"
  10. /*
  11. * We convert 32 bit values to pointers. In 64 bit mode the compiler will issue a
  12. * warning stating that the value is too small for the pointer:
  13. * "warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]"
  14. * we can safely ignore them here.
  15. */
  16. #ifdef __GNUC__
  17. #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
  18. #endif
  19. EFI_STATUS
  20. LibGetSmbiosSystemGuidAndSerialNumber (
  21. IN EFI_GUID *SystemGuid,
  22. OUT CHAR8 **SystemSerialNumber
  23. )
  24. {
  25. EFI_STATUS Status;
  26. SMBIOS_STRUCTURE_TABLE *SmbiosTable;
  27. SMBIOS_STRUCTURE_POINTER Smbios;
  28. SMBIOS_STRUCTURE_POINTER SmbiosEnd;
  29. UINT16 Index;
  30. Status = LibGetSystemConfigurationTable(&SMBIOSTableGuid, (VOID**)&SmbiosTable);
  31. if (EFI_ERROR(Status)) {
  32. return EFI_NOT_FOUND;
  33. }
  34. Smbios.Hdr = (SMBIOS_HEADER *)SmbiosTable->TableAddress;
  35. SmbiosEnd.Raw = (UINT8 *)((UINTN)SmbiosTable->TableAddress + SmbiosTable->TableLength);
  36. for (Index = 0; Index < SmbiosTable->TableLength ; Index++) {
  37. if (Smbios.Hdr->Type == 1) {
  38. if (Smbios.Hdr->Length < 0x19) {
  39. //
  40. // Older version did not support Guid and Serial number
  41. //
  42. continue;
  43. }
  44. //
  45. // SMBIOS tables are byte packed so we need to do a byte copy to
  46. // prevend alignment faults on IA-64.
  47. CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof(EFI_GUID));
  48. *SystemSerialNumber = LibGetSmbiosString(&Smbios, Smbios.Type1->SerialNumber);
  49. return EFI_SUCCESS;
  50. }
  51. //
  52. // Make Smbios point to the next record
  53. //
  54. LibGetSmbiosString (&Smbios, -1);
  55. if (Smbios.Raw >= SmbiosEnd.Raw) {
  56. //
  57. // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.
  58. // given this we must double check against the lenght of
  59. /// the structure. My home PC has this bug.ruthard
  60. //
  61. return EFI_SUCCESS;
  62. }
  63. }
  64. return EFI_SUCCESS;
  65. }
  66. CHAR8*
  67. LibGetSmbiosString (
  68. IN SMBIOS_STRUCTURE_POINTER *Smbios,
  69. IN UINT16 StringNumber
  70. )
  71. /*++
  72. Return SMBIOS string given the string number.
  73. Arguments:
  74. Smbios - Pointer to SMBIOS structure
  75. StringNumber - String number to return. -1 is used to skip all strings and
  76. point to the next SMBIOS structure.
  77. Returns:
  78. Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1
  79. --*/
  80. {
  81. UINT16 Index;
  82. CHAR8 *String;
  83. //
  84. // Skip over formatted section
  85. //
  86. String = (CHAR8 *)(Smbios->Raw + Smbios->Hdr->Length);
  87. //
  88. // Look through unformated section
  89. //
  90. for (Index = 1; Index <= StringNumber; Index++) {
  91. if (StringNumber == Index) {
  92. return String;
  93. }
  94. //
  95. // Skip string
  96. //
  97. for (; *String != 0; String++);
  98. String++;
  99. if (*String == 0) {
  100. //
  101. // If double NULL then we are done.
  102. // Retrun pointer to next structure in Smbios.
  103. // if you pass in a -1 you will always get here
  104. //
  105. Smbios->Raw = (UINT8 *)++String;
  106. return NULL;
  107. }
  108. }
  109. return NULL;
  110. }