Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
5.3 KiB

  1. /*** smbios.c - System Management BIOS support
  2. *
  3. * Author: Yan Leshinsky (YanL)
  4. * Created 10/04/98
  5. *
  6. * MODIFICATION HISTORY
  7. */
  8. #include "wubiosp.h"
  9. /*** Function prototypes
  10. */
  11. PPNPBIOSINIT CM_LOCAL GetPNPBIOSINIT(void);
  12. PSMBIOSENTRY CM_LOCAL GetSMBIOSENTRY(void);
  13. PBYTE CM_LOCAL NextTable(PBYTE pMem);
  14. #pragma CM_PAGEABLE_DATA
  15. /*** Globals
  16. */
  17. static PSMBIOSENTRY g_pSMBIOS = (PSMBIOSENTRY)0xffffffff;
  18. #pragma CM_PAGEABLE_CODE
  19. /*** SmbStructSize - Init SMBIOS and return max table size
  20. *
  21. * ENTRY
  22. * None
  23. *
  24. * EXIT-SUCCESS
  25. * TRUE
  26. * EXIT-FAILURE
  27. * FALSE
  28. *
  29. *
  30. */
  31. DWORD CM_INTERNAL SmbStructSize(void)
  32. {
  33. TRACENAME("SmbStructSize")
  34. DWORD dwMaxTableSize = 0;
  35. ENTER(2, ("SmbStructSize()\n"));
  36. if ((PSMBIOSENTRY)0xffffffff == g_pSMBIOS)
  37. {
  38. // Find Struct
  39. g_pSMBIOS = GetSMBIOSENTRY();
  40. }
  41. if (g_pSMBIOS)
  42. {
  43. dwMaxTableSize = (DWORD)(g_pSMBIOS->wMaxStructSize);
  44. }
  45. EXIT(2, ("SmbStructSize()=%x\n", dwMaxTableSize));
  46. return dwMaxTableSize;
  47. }
  48. /*** SmbCopyStruct - Do BIOS init
  49. *
  50. * ENTRY
  51. * dwType - Structure type (from SMBIOS spec)
  52. * pbBuff -> buffer
  53. * dwLen - buffer length
  54. *
  55. * EXIT
  56. * None
  57. *
  58. */
  59. CM_VXD_RESULT CM_INTERNAL SmbCopyStruct(DWORD dwType, PBYTE pbBuff, DWORD dwLen)
  60. {
  61. TRACENAME("SmbCopyStruct")
  62. CM_VXD_RESULT rc = ERROR_GEN_FAILURE;
  63. ENTER(2, ("SmbCopyStruct()\n"));
  64. if ((PSMBIOSENTRY)0xffffffff == g_pSMBIOS)
  65. {
  66. // Find Struct
  67. g_pSMBIOS = GetSMBIOSENTRY();
  68. }
  69. // Check if we are inited
  70. if ( 0 != g_pSMBIOS && (DWORD)(g_pSMBIOS->wMaxStructSize) <= dwLen)
  71. {
  72. // Map table
  73. PBYTE pTable = _MapPhysToLinear(g_pSMBIOS->dwStructTableAddress, g_pSMBIOS->wStructTableLength, 0);
  74. if ((PBYTE)0xffffffff != pTable)
  75. {
  76. WORD wTblCounter = g_pSMBIOS->wNumberOfStructs;
  77. while (wTblCounter --)
  78. {
  79. PBYTE pNextTable = NextTable(pTable);
  80. if ((BYTE)dwType == ((PSMBIOSHEADER)pTable)->bType)
  81. {
  82. // Do copy
  83. memcpy(pbBuff, pTable, pNextTable - pTable);
  84. rc = ERROR_SUCCESS;
  85. //break;
  86. }
  87. pTable = pNextTable;
  88. }
  89. }
  90. }
  91. EXIT(2, ("SmbCopyStruct()=%x\n", rc));
  92. return rc;
  93. }
  94. /*** PnpOEMID - Find PNPBIOSINIT and extract OEM id From it
  95. *
  96. * ENTRY
  97. * None
  98. *
  99. * EXIT-SUCCESS
  100. * DWORD id
  101. * EXIT-FAILURE
  102. * 0
  103. *
  104. *
  105. */
  106. DWORD CM_INTERNAL PnpOEMID(void)
  107. {
  108. TRACENAME("PnpOEMID")
  109. static PPNPBIOSINIT pPnPBIOS = (PPNPBIOSINIT)0xffffffff;
  110. DWORD dwID = 0;
  111. ENTER(2, ("PnpOEMID()\n"));
  112. if ((PPNPBIOSINIT)0xffffffff == pPnPBIOS)
  113. {
  114. pPnPBIOS = GetPNPBIOSINIT();
  115. }
  116. if (pPnPBIOS)
  117. {
  118. dwID = pPnPBIOS->dwOEMID;
  119. }
  120. EXIT(2, ("PnpOEMID() dwID = %08X\n", dwID));
  121. return dwID;
  122. }
  123. /*** GetInitTable - Find PNPBIOSINIT structure
  124. *
  125. * ENTRY
  126. * None
  127. *
  128. * EXIT-SUCCESS
  129. * returns the PNPBIOSINIT pointer
  130. * EXIT-FAILURE
  131. * returns NULL
  132. *
  133. *
  134. */
  135. PPNPBIOSINIT CM_LOCAL GetPNPBIOSINIT(void)
  136. {
  137. TRACENAME("GetPNPBIOSINIT")
  138. PPNPBIOSINIT pInitTableRet = NULL;
  139. PBYTE pMem;
  140. ENTER(2, ("GetPNPBIOSINIT()\n"));
  141. // Map start address
  142. pMem = _MapPhysToLinear(SMBIOS_SEARCH_RANGE_BEGIN, SMBIOS_SEARCH_RANGE_LENGTH, 0);
  143. if (pMem != (PBYTE)0xffffffff)
  144. {
  145. // Loop counter;
  146. int nCounter = SMBIOS_SEARCH_RANGE_LENGTH / SMBIOS_SEARCH_INTERVAL;
  147. CM_FOREVER
  148. {
  149. PPNPBIOSINIT pInitTable = (PPNPBIOSINIT)pMem;
  150. if ((PNP_SIGNATURE == pInitTable->dwSignature) && (0 == CheckSum(pMem, pInitTable->bLength)))
  151. {
  152. // Check length
  153. if (pInitTable->bLength<sizeof(PNPBIOSINIT))
  154. {
  155. DBG_ERR(("PnP BIOS Structure size %2X is less than %2X",
  156. pInitTable->bLength, sizeof(PNPBIOSINIT)));
  157. break;
  158. }
  159. // Check version
  160. if (pInitTable->bRevision<0x10)
  161. {
  162. DBG_ERR(("PnP BIOS Revision %2X is less than 1.0",
  163. pInitTable->bRevision));
  164. break;
  165. }
  166. pInitTableRet = pInitTable;
  167. break;
  168. }
  169. pMem += SMBIOS_SEARCH_INTERVAL;
  170. if ((--nCounter)==0)
  171. {
  172. DBG_ERR(("Could not find BIOS Init structure"));
  173. break;
  174. }
  175. }
  176. }
  177. EXIT(2, ("GetPNPBIOSINIT() pInitTable = %08X\n", pInitTableRet));
  178. return pInitTableRet;
  179. }
  180. /*** GetInitTable - Find SMBIOSENTRY structure
  181. *
  182. * ENTRY
  183. * None
  184. *
  185. * EXIT-SUCCESS
  186. * returns the SMBIOSENTRY pointer
  187. * EXIT-FAILURE
  188. * returns NULL
  189. *
  190. *
  191. */
  192. PSMBIOSENTRY CM_LOCAL GetSMBIOSENTRY(void)
  193. {
  194. TRACENAME("GetSMBIOSENTRY")
  195. PSMBIOSENTRY pEntryTableRet = NULL;
  196. PBYTE pMem;
  197. ENTER(2, ("GetSMBIOSENTRY()\n"));
  198. // Map start address
  199. pMem = _MapPhysToLinear(SMBIOS_SEARCH_RANGE_BEGIN, SMBIOS_SEARCH_RANGE_LENGTH, 0);
  200. if (pMem != (PBYTE)0xffffffff)
  201. {
  202. // Loop counter;
  203. int nCounter = SMBIOS_SEARCH_RANGE_LENGTH / SMBIOS_SEARCH_INTERVAL;
  204. CM_FOREVER
  205. {
  206. PSMBIOSENTRY pEntryTable = (PSMBIOSENTRY)pMem;
  207. if ((SM_SIGNATURE == pEntryTable->dwSignature) && (0 == CheckSum(pMem, pEntryTable->bLength)))
  208. {
  209. // Check length
  210. if (pEntryTable->bLength<sizeof(SMBIOSENTRY))
  211. {
  212. DBG_ERR(("SMBIOS Structure size %2X is less than %2X",
  213. pEntryTable->bLength, sizeof(SMBIOSENTRY)));
  214. break;
  215. }
  216. pEntryTableRet = pEntryTable;
  217. break;
  218. }
  219. pMem += SMBIOS_SEARCH_INTERVAL;
  220. if ((--nCounter)==0)
  221. {
  222. DBG_ERR(("Could not find BIOS Init structure"));
  223. break;
  224. }
  225. }
  226. }
  227. EXIT(2, ("GetSMBIOSENTRY()\n"));
  228. return pEntryTableRet;
  229. }
  230. PBYTE CM_LOCAL NextTable(PBYTE pMem)
  231. {
  232. pMem += ((PSMBIOSHEADER)pMem)->bLength;
  233. while ( *(PWORD)pMem)
  234. pMem ++;
  235. return pMem + 2;
  236. }