Leaked source code of windows server 2003
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.

761 lines
24 KiB

  1. /*++
  2. Copyright (c) 1990, 1991 Microsoft Corporation
  3. Module Name:
  4. hwpbiosc.c
  5. Abstract:
  6. This modules contains PnP BIOS C supporting routines
  7. Author:
  8. Shie-Lin Tzong (shielint) 20-Apr-1995
  9. Environment:
  10. Real mode.
  11. Revision History:
  12. Doug Fritz (dfritz) 02-Oct-1997
  13. - Add: get docking station info from PnP BIOS and pass to NTLDR
  14. Alan Warwick (alanwar) 10-Feb-1998
  15. - Add: get SMBIOS tables from PnP BIOS and pass to NTLDR
  16. --*/
  17. #include "hwdetect.h"
  18. #include <string.h>
  19. #include "smbios.h"
  20. #include "pnpbios.h"
  21. //
  22. // Some global variables referenced by other routines
  23. //
  24. BOOLEAN SystemHas8259 = FALSE;
  25. BOOLEAN SystemHas8253 = FALSE;
  26. USHORT HwSMBIOSStructureLength(
  27. FPSMBIOS_STRUCT_HEADER StructHeader,
  28. USHORT MaxStructLen
  29. )
  30. {
  31. USHORT length;
  32. UCHAR type;
  33. FPUCHAR stringPtr;
  34. type = StructHeader->Type;
  35. length = StructHeader->Length;
  36. //
  37. // The length of an SMBIOS structure can be computed by adding the size
  38. // specified in the structure header plus the space used by the string
  39. // table that immediately follows the structure header. The size of the
  40. // string table is determined by scanning for a double NUL. A problem is
  41. // that those structures that do not contain strings do not have a
  42. // double NUL to indicate an empty string table. However since we do
  43. // initialize the entire buffer to 0 before calling the bios there
  44. // will always be a double nul at the end regardless of how the bios
  45. // fills writes the structure.
  46. stringPtr = (FPUCHAR)StructHeader + StructHeader->Length;
  47. //
  48. // Loop one byte at a time until double NUL is found
  49. while ((*((FPUSHORT)stringPtr) != 0) && (length < MaxStructLen))
  50. {
  51. stringPtr++;
  52. length++;
  53. }
  54. #if DBG
  55. if (length == MaxStructLen)
  56. {
  57. BlPrint("HwSMBIOSStructureLength: structure overflow 0x%x\n", length);
  58. }
  59. #endif
  60. return(length);
  61. }
  62. USHORT HwGetSMBIOSInfo(
  63. ENTRY_POINT BiosEntry,
  64. USHORT RealModeDataBaseAddress,
  65. USHORT StructBufferSize,
  66. FPUCHAR StructBuffer
  67. )
  68. /*++
  69. Routine Description:
  70. This routine determine if SMBIOS information is available in the system
  71. and if so then collect the size needed for all of the information and
  72. actually collect the information.
  73. The SMBIOS tables are packed into a buffer end to end. The length of each
  74. SMBIOS table is determined by the length in the structure header plus
  75. any memory used by the stirng space immediately after the fixed portion
  76. of the structure. The string space is terminated by a double NUL. However
  77. some structure types do not contain strings and thus do not have a
  78. string space so the length of the structure is simply the length specified
  79. in the structure header. However this routine will append a double NUL
  80. to those structures anyway so that the total length of each structure
  81. within the buffer can be determined by finding the first double NUL after
  82. the length declared in the structure header.
  83. Arguments:
  84. BiosEntry is the real mode entrypoint to the PnP bios
  85. RealModeDataBaseAddress
  86. StructBufferSize is the maximum number of bytes available to write in
  87. StructBuffer
  88. StructBuffer is the buffer in which to write the SMBIOS data. If this is
  89. NULL then only the size needed to write the data is determined.
  90. Return Value:
  91. Size of SMBIOS structures
  92. --*/
  93. {
  94. USHORT retCode;
  95. USHORT numberStructures;
  96. USHORT maxStructSize;
  97. ULONG dmiStorageBase;
  98. USHORT dmiStorageSize;
  99. UCHAR dmiBiosRevision;
  100. ULONG romAddr, romEnd;
  101. FPSMBIOS_EPS_HEADER header;
  102. FPDMIBIOS_EPS_HEADER dmiHeader;
  103. FPUCHAR current;
  104. UCHAR sum;
  105. USHORT j;
  106. USHORT structCount;
  107. USHORT structNumber;
  108. USHORT dmiStorageSegment;
  109. USHORT totalStructSize = 0;
  110. USHORT checkLength;
  111. FPSMBIOS_STRUCT_HEADER structHeader;
  112. USHORT length, lengthNeeded;
  113. FPUCHAR tempStructBuffer;
  114. #if DBG
  115. BlPrint("GetSMBIOSInfo: Determining SMBIOS - Try for table\n");
  116. #endif
  117. MAKE_FP(current, PNP_BIOS_START);
  118. romAddr = PNP_BIOS_START;
  119. romEnd = PNP_BIOS_END;
  120. checkLength = 0;
  121. while (romAddr < romEnd) {
  122. header = (FPSMBIOS_EPS_HEADER)current;
  123. dmiHeader = (FPDMIBIOS_EPS_HEADER)current;
  124. if ((dmiHeader->Signature2[0] == '_') &&
  125. (dmiHeader->Signature2[1] == 'D') &&
  126. (dmiHeader->Signature2[2] == 'M') &&
  127. (dmiHeader->Signature2[3] == 'I') &&
  128. (dmiHeader->Signature2[4] == '_')) {
  129. #if DBG
  130. BlPrint("GetSMBIOSInfo: found _DMI_ anchor string installation %lx\n",
  131. dmiHeader);
  132. #endif
  133. checkLength = sizeof(DMIBIOS_EPS_HEADER);
  134. } else if (header->Signature[0] == '_' &&
  135. header->Signature[1] == 'S' &&
  136. header->Signature[2] == 'M' &&
  137. header->Signature[3] == '_' &&
  138. header->Length >= sizeof(SMBIOS_EPS_HEADER) &&
  139. header->Signature2[0] == '_' &&
  140. header->Signature2[1] == 'D' &&
  141. header->Signature2[2] == 'M' &&
  142. header->Signature2[3] == 'I' &&
  143. header->Signature2[4] == '_' ) {
  144. #if DBG
  145. BlPrint("GetSMBIOSInfo: found _SM_ anchor string installation %lx\n",
  146. header);
  147. #endif
  148. checkLength = header->Length;
  149. dmiHeader = (FPDMIBIOS_EPS_HEADER)&header->Signature2[0];
  150. }
  151. if (checkLength != 0)
  152. {
  153. sum = 0;
  154. for (j = 0; j < checkLength; j++) {
  155. sum += current[j];
  156. }
  157. if (sum == 0) {
  158. break;
  159. }
  160. #if DBG
  161. BlPrint("GetSMBIOSInfo: Checksum fails\n");
  162. #endif
  163. checkLength = 0;
  164. }
  165. romAddr += PNP_BIOS_HEADER_INCREMENT;
  166. MAKE_FP(current, romAddr);
  167. }
  168. if (romAddr >= romEnd) {
  169. //
  170. // We could not find the table so try the calling method
  171. dmiBiosRevision = 0;
  172. numberStructures = 0;
  173. retCode = BiosEntry(GET_DMI_INFORMATION,
  174. (FPUCHAR)&dmiBiosRevision,
  175. (FPUSHORT)&numberStructures,
  176. (FPUSHORT)&maxStructSize,
  177. (FPULONG)&dmiStorageBase,
  178. (FPUSHORT)&dmiStorageSize,
  179. RealModeDataBaseAddress);
  180. if ((retCode != DMI_SUCCESS) ||
  181. (dmiBiosRevision < 0x20))
  182. {
  183. #if DBG
  184. BlPrint("GetSMBIOSInfo: GET_DMI_INFORMATION failed %x\n", retCode);
  185. #endif
  186. return(0);
  187. #if DBG
  188. } else {
  189. BlPrint("GetSMBIOSInfo: GET_DMI_INFORMATION\n");
  190. BlPrint(" BiosRevision %x Number Structures %x Structure Size %x\n", dmiBiosRevision, numberStructures, maxStructSize);
  191. BlPrint(" StorageBase %lx StorageSize %x\n", dmiStorageBase, dmiStorageSize);
  192. #endif
  193. }
  194. maxStructSize += 3;
  195. tempStructBuffer = HwAllocateHeap(maxStructSize, FALSE);
  196. if (tempStructBuffer == NULL)
  197. {
  198. #if DBG
  199. BlPrint("GetSMBIOSInfo: HwAllocateHeap(structureSize = 0x%x\n",
  200. maxStructSize);
  201. #endif
  202. return(0);
  203. }
  204. //
  205. // Loop calling Get_DMI_STRUCTURE to get next structure until we
  206. // hit the end of structure or receive an error.
  207. structCount = 0;
  208. structNumber = 0;
  209. dmiStorageSegment = (USHORT)(dmiStorageBase >> 4);
  210. while ((structCount < numberStructures) &&
  211. (retCode == DMI_SUCCESS) &&
  212. (structNumber != 0xffff))
  213. {
  214. _fmemset(tempStructBuffer, 0, maxStructSize);
  215. retCode = BiosEntry(GET_DMI_STRUCTURE,
  216. (FPUSHORT)&structNumber,
  217. (FPUCHAR)tempStructBuffer,
  218. dmiStorageSegment,
  219. RealModeDataBaseAddress
  220. );
  221. #if DBG
  222. BlPrint("GetSMBIOSInfo: GET_DMI_STRUCTURE --> %x\n", retCode);
  223. #endif
  224. if (retCode == DMI_SUCCESS)
  225. {
  226. structCount++;
  227. structHeader = (FPSMBIOS_STRUCT_HEADER)tempStructBuffer;
  228. length = HwSMBIOSStructureLength(structHeader, maxStructSize);
  229. lengthNeeded = length + 2;
  230. if (StructBuffer != NULL)
  231. {
  232. //
  233. // if caller wants the data then lets copy into it buffer
  234. if (StructBufferSize >= lengthNeeded)
  235. {
  236. _fmemcpy(StructBuffer,
  237. tempStructBuffer,
  238. length);
  239. *((FPUSHORT)&StructBuffer[length]) = 0;
  240. StructBufferSize -= lengthNeeded;
  241. StructBuffer += lengthNeeded;
  242. totalStructSize += lengthNeeded;
  243. #if DBG
  244. } else {
  245. BlPrint("GetSMBIOSInfo: Struct too large 0x%x bytes left\n",
  246. StructBufferSize);
  247. #endif
  248. }
  249. } else {
  250. //
  251. // Caller is only interested in length required
  252. totalStructSize += lengthNeeded;
  253. }
  254. #if DBG
  255. BlPrint("GetSMBIOSInfo: Number 0x%x Type 0x%x Length 0x%x/0x%x Handle 0x%x\n",
  256. structNumber,
  257. structHeader->Type,
  258. structHeader->Length,
  259. length,
  260. structHeader->Handle);
  261. for (j = 0; j < structHeader->Length; j = j + 16)
  262. {
  263. BlPrint(" %x %x %x %x %x %x %x %x\n %x %x %x %x %x %x %x %x\n",
  264. structHeader->Data[j],
  265. structHeader->Data[j+1],
  266. structHeader->Data[j+2],
  267. structHeader->Data[j+3],
  268. structHeader->Data[j+4],
  269. structHeader->Data[j+5],
  270. structHeader->Data[j+6],
  271. structHeader->Data[j+7],
  272. structHeader->Data[j+8],
  273. structHeader->Data[j+9],
  274. structHeader->Data[j+10],
  275. structHeader->Data[j+11],
  276. structHeader->Data[j+12],
  277. structHeader->Data[j+13],
  278. structHeader->Data[j+14],
  279. structHeader->Data[j]+15);
  280. }
  281. for (j = structHeader->Length; j < length; j++)
  282. {
  283. BlPrint("%c", structHeader->Data[j-sizeof(SMBIOS_STRUCT_HEADER)]);
  284. if (structHeader->Data[j-sizeof(SMBIOS_STRUCT_HEADER)] == 0)
  285. {
  286. BlPrint("\n");
  287. }
  288. }
  289. BlPrint("\n");
  290. #endif
  291. }
  292. #if DBG
  293. while ( !HwGetKey() ) ; // wait until key pressed to continue
  294. #endif
  295. }
  296. HwFreeHeap(maxStructSize);
  297. #if DBG
  298. BlPrint("GetSMBIOSInfo: %x/%x structures read, total size 0x%x\n",
  299. structCount, numberStructures, totalStructSize);
  300. #endif
  301. #if DBG
  302. } else {
  303. if ((FPVOID)dmiHeader != (FPVOID)header)
  304. {
  305. BlPrint("GetSMBIOSInfo: _SM_ Structure Table\n");
  306. BlPrint(" Length %x MajorVersion %x MinorVersion %x\n",
  307. header->Length, header->MajorVersion, header->MinorVersion);
  308. BlPrint(" MaximumStructureSize %x EntryPointRevision %x StructureTableLength %x\n",
  309. header->MaximumStructureSize, header->EntryPointRevision, header->StructureTableLength);
  310. BlPrint(" StructureTableAddress %x NumberStructures %x Revision %x\n",
  311. header->StructureTableAddress, header->NumberStructures, header->Revision);
  312. } else {
  313. BlPrint("GetSMBIOSInfo: _DMI_ Structure Table\n");
  314. BlPrint(" StructureTableLength %x\n",
  315. dmiHeader->StructureTableLength);
  316. BlPrint(" StructureTableAddress %x NumberStructures %x Revision %x\n",
  317. dmiHeader->StructureTableAddress, dmiHeader->NumberStructures, dmiHeader->Revision);
  318. }
  319. #endif
  320. }
  321. #if DBG
  322. while ( !HwGetKey() ) ; // wait until key pressed to continue
  323. #endif
  324. return(totalStructSize);
  325. }
  326. #if 0
  327. VOID
  328. HwDisablePnPBiosDevnode(
  329. ENTRY_POINT biosEntry,
  330. FPPNP_BIOS_INSTALLATION_CHECK header,
  331. UCHAR node,
  332. FPPNP_BIOS_DEVICE_NODE deviceNode
  333. )
  334. {
  335. USHORT control = GET_CURRENT_CONFIGURATION;
  336. USHORT retCode;
  337. FPUCHAR buffer;
  338. USHORT i;
  339. UCHAR code;
  340. #if 0
  341. BlPrint("DisablePnPBiosDevnode: found it\n");
  342. while ( !HwGetKey() ) ; // wait until key pressed to continue
  343. buffer = (FPUCHAR)deviceNode;
  344. for (i = 0; i < deviceNode->Size; i++) {
  345. BlPrint("%x ", *buffer++);
  346. if ( ((i+1)%16) == 0) {
  347. BlPrint("\n");
  348. }
  349. }
  350. BlPrint("\n");
  351. #endif
  352. //
  353. // Zero out allocated resources
  354. //
  355. buffer = (FPUCHAR)(deviceNode+1);
  356. if (deviceNode->Size <= sizeof(PNP_BIOS_DEVICE_NODE)) {
  357. return;
  358. }
  359. for (i = 0; i < (deviceNode->Size - sizeof(PNP_BIOS_DEVICE_NODE)); i++) {
  360. code = *buffer;
  361. #define PNP_BIOS_END_TAG 0x79
  362. if (code == PNP_BIOS_END_TAG) {
  363. //
  364. // found END TAG
  365. // write checksum
  366. //
  367. *(++buffer) = (UCHAR) (0 - PNP_BIOS_END_TAG);
  368. break;
  369. }
  370. *buffer++ = 0;
  371. }
  372. #if 0
  373. buffer = (FPUCHAR)deviceNode;
  374. for (i = 0; i < deviceNode->Size; i++) {
  375. BlPrint("%x ", *buffer++);
  376. if ( ((i+1)%16) == 0) {
  377. BlPrint("\n");
  378. }
  379. }
  380. BlPrint("\n");
  381. while ( !HwGetKey() ) ; // wait until key pressed to continue
  382. #endif
  383. retCode = biosEntry(PNP_BIOS_SET_DEVICE_NODE,
  384. node,
  385. deviceNode,
  386. control,
  387. header->RealModeDataBaseAddress
  388. );
  389. #if DBG
  390. if (retCode != 0) {
  391. BlPrint("HwDisablePnPBiosDevnode: PnP Bios func 2 returns failure = %x.\n", retCode);
  392. }
  393. #endif
  394. }
  395. #endif
  396. //
  397. // Global Variable within NTDETECT
  398. // - structure definition in dockinfo.h
  399. // - extern declaration in hwdetect.h
  400. // - used in hwpbios.c and hwdetect.c
  401. //
  402. BOOLEAN
  403. HwGetPnpBiosSystemData(
  404. IN FPUCHAR *Configuration,
  405. OUT PUSHORT PnPBiosLength,
  406. OUT PUSHORT SMBIOSLength,
  407. IN OUT FPDOCKING_STATION_INFO DockInfo
  408. )
  409. /*++
  410. Routine Description:
  411. This routine checks if PNP BIOS is present in the machine. If yes, it
  412. also create a registry descriptor to collect the BIOS data.
  413. Arguments:
  414. Configuration - Supplies a variable to receive the PNP BIOS data.
  415. PnPBiosLength - Supplies a variable to receive the size of the PnP Bios
  416. data (Does not include HEADER)
  417. SMBIOSBiosLength - Supplies a variable to receive the size of the SMBIOS
  418. data (Does not include HEADER). Total size of buffer
  419. returned is in *Configuration is (*PnPBiosLength +
  420. *SMBIOSLength + 2 * DATA_HEADER_SIZE)
  421. DockInfo -
  422. Return Value:
  423. A value of TRUE is returned if success. Otherwise, a value of
  424. FALSE is returned.
  425. --*/
  426. {
  427. ULONG romAddr, romEnd;
  428. FPUCHAR current;
  429. FPPNP_BIOS_INSTALLATION_CHECK header;
  430. UCHAR sum, node = 0;
  431. UCHAR currentNode;
  432. USHORT i, totalSize = 0, nodeSize, numberNodes, retCode;
  433. ENTRY_POINT biosEntry;
  434. FPPNP_BIOS_DEVICE_NODE deviceNode;
  435. USHORT control = GET_CURRENT_CONFIGURATION;
  436. USHORT sMBIOSBufferSize;
  437. FPUCHAR sMBIOSBuffer;
  438. //
  439. // Perform PNP BIOS installation Check
  440. //
  441. MAKE_FP(current, PNP_BIOS_START);
  442. romAddr = PNP_BIOS_START;
  443. romEnd = PNP_BIOS_END;
  444. while (romAddr < romEnd) {
  445. header = (FPPNP_BIOS_INSTALLATION_CHECK)current;
  446. if (header->Signature[0] == '$' && header->Signature[1] == 'P' &&
  447. header->Signature[2] == 'n' && header->Signature[3] == 'P' &&
  448. header->Length >= sizeof(PNP_BIOS_INSTALLATION_CHECK)) {
  449. #if DBG
  450. BlPrint("GetPnpBiosData: find Pnp installation\n");
  451. #endif
  452. sum = 0;
  453. for (i = 0; i < header->Length; i++) {
  454. sum += current[i];
  455. }
  456. if (sum == 0) {
  457. break;
  458. }
  459. #if DBG
  460. BlPrint("GetPnpBiosData: Checksum fails\n");
  461. #endif
  462. }
  463. romAddr += PNP_BIOS_HEADER_INCREMENT;
  464. MAKE_FP(current, romAddr);
  465. }
  466. if (romAddr >= romEnd) {
  467. return FALSE;
  468. }
  469. #if DBG
  470. BlPrint("PnP installation check at %lx\n", romAddr);
  471. #endif
  472. //
  473. // Determine how much space we will need and allocate heap space
  474. //
  475. totalSize += sizeof(PNP_BIOS_INSTALLATION_CHECK);
  476. biosEntry = *(ENTRY_POINT far *)&header->RealModeEntryOffset;
  477. //
  478. // Determine size needed for SMBIOS data
  479. sMBIOSBufferSize = HwGetSMBIOSInfo(biosEntry,
  480. header->RealModeDataBaseAddress,
  481. 0,
  482. NULL);
  483. if (sMBIOSBufferSize > MAXSMBIOS20SIZE)
  484. {
  485. #if DBG
  486. BlPrint("GetPnpBiosData: SMBIOS data structures are too large 0x%x bytes\n",
  487. sMBIOSBufferSize);
  488. while ( !HwGetKey() ) ; // wait until key pressed to continue
  489. #endif
  490. sMBIOSBufferSize = 0;
  491. }
  492. retCode = biosEntry(PNP_BIOS_GET_NUMBER_DEVICE_NODES,
  493. (FPUSHORT)&numberNodes,
  494. (FPUSHORT)&nodeSize,
  495. header->RealModeDataBaseAddress
  496. );
  497. if (retCode != 0) {
  498. #if DBG
  499. BlPrint("GetPnpBiosData: PnP Bios GetNumberNodes func returns failure %x.\n", retCode);
  500. #endif
  501. return FALSE;
  502. }
  503. #if DBG
  504. BlPrint("GetPnpBiosData: Pnp Bios GetNumberNodes returns %x nodes\n", numberNodes);
  505. #endif
  506. deviceNode = (FPPNP_BIOS_DEVICE_NODE) HwAllocateHeap(nodeSize, FALSE);
  507. if (!deviceNode) {
  508. #if DBG
  509. BlPrint("GetPnpBiosData: Out of heap space.\n");
  510. #endif
  511. return FALSE;
  512. }
  513. while (node != 0xFF) {
  514. retCode = biosEntry(PNP_BIOS_GET_DEVICE_NODE,
  515. (FPUCHAR)&node,
  516. deviceNode,
  517. control,
  518. header->RealModeDataBaseAddress
  519. );
  520. if (retCode != 0) {
  521. #if DBG
  522. BlPrint("GetPnpBiosData: PnP Bios GetDeviceNode func returns failure = %x.\n", retCode);
  523. #endif
  524. HwFreeHeap((ULONG)nodeSize);
  525. return FALSE;
  526. }
  527. #if DBG
  528. BlPrint("GetPnpBiosData: PnpBios GetDeviceNode returns nodesize %x for node %x\n", deviceNode->Size, node);
  529. #endif
  530. totalSize += deviceNode->Size;
  531. }
  532. #if DBG
  533. BlPrint("GetPnpBiosData: PnpBios total size of nodes %x\n", totalSize);
  534. #endif
  535. HwFreeHeap((ULONG)nodeSize); // Free temporary buffer
  536. *PnPBiosLength = totalSize;
  537. *SMBIOSLength = sMBIOSBufferSize;
  538. //
  539. // Allocate enough room for 2 HWPARTIAL_RESOURCE_DESCRIPTORS (one for
  540. // PnP bios and one for SMBios) plus room to keep the data.
  541. totalSize += sMBIOSBufferSize + DATA_HEADER_SIZE + sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR);
  542. current = (FPUCHAR) HwAllocateHeap(totalSize, FALSE);
  543. if (!current) {
  544. #if DBG
  545. BlPrint("GetPnpBiosData: Out of heap space.\n");
  546. #endif
  547. return FALSE;
  548. }
  549. //
  550. // Collect PnP Bios installation check data and device node data.
  551. //
  552. _fmemcpy (current + DATA_HEADER_SIZE,
  553. (FPUCHAR)header,
  554. sizeof(PNP_BIOS_INSTALLATION_CHECK)
  555. );
  556. deviceNode = (FPPNP_BIOS_DEVICE_NODE)(current + DATA_HEADER_SIZE +
  557. sizeof(PNP_BIOS_INSTALLATION_CHECK));
  558. node = 0;
  559. while (node != 0xFF) {
  560. currentNode = node;
  561. retCode = biosEntry(PNP_BIOS_GET_DEVICE_NODE,
  562. (FPUCHAR)&node,
  563. deviceNode,
  564. control,
  565. header->RealModeDataBaseAddress
  566. );
  567. if (retCode != 0) {
  568. #if DBG
  569. BlPrint("GetPnpBiosData: PnP Bios func 1 returns failure = %x.\n", retCode);
  570. #endif
  571. HwFreeHeap((ULONG)totalSize);
  572. return FALSE;
  573. }
  574. //
  575. // Record the existance of certain devices for the benefit of other
  576. // routines in ntdetect. For example, the pccard irq detection code
  577. // uses the PIC and an 8237... this insures that we actually have
  578. // those devices.
  579. //
  580. if (deviceNode->ProductId == 0xd041) { // PNP0000
  581. SystemHas8259 = TRUE;
  582. } else if (deviceNode->ProductId == 0x1d041) { // PNP0100
  583. SystemHas8253 = TRUE;
  584. }
  585. deviceNode = (FPPNP_BIOS_DEVICE_NODE)((FPUCHAR)deviceNode + deviceNode->Size);
  586. }
  587. //
  588. // Collect SMBIOS Data, skipping over PartialDescriptor which is filled in
  589. // by the caller of this routine
  590. if (sMBIOSBufferSize != 0)
  591. {
  592. sMBIOSBuffer = (FPUCHAR)deviceNode;
  593. sMBIOSBuffer += sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR);
  594. retCode = HwGetSMBIOSInfo(biosEntry,
  595. header->RealModeDataBaseAddress,
  596. sMBIOSBufferSize,
  597. sMBIOSBuffer);
  598. #if DBG
  599. BlPrint("SMBIOS asked for 0x%x bytes and filled 0x%x bytes into %lx\n",
  600. sMBIOSBufferSize, retCode, sMBIOSBuffer);
  601. #endif
  602. }
  603. *Configuration = current;
  604. //
  605. // call PnP BIOS to get docking station information
  606. //
  607. DockInfo->ReturnCode = biosEntry(PNP_BIOS_GET_DOCK_INFORMATION,
  608. (FPUCHAR) DockInfo,
  609. header->RealModeDataBaseAddress
  610. );
  611. #if DBG
  612. BlPrint("\npress any key to continue...\n");
  613. while ( !HwGetKey() ) ; // wait until key pressed to continue
  614. clrscrn();
  615. BlPrint("*** DockInfo - BEGIN ***\n\n");
  616. BlPrint("ReturnCode= 0x%x (Other fields undefined if ReturnCode != 0)\n",
  617. DockInfo->ReturnCode
  618. );
  619. BlPrint(" 0x0000 = SUCCESS (docked)\n");
  620. BlPrint(" 0x0082 = FUNCTION_NOT_SUPPORTED\n");
  621. BlPrint(" 0x0087 = SYSTEM_NOT_DOCKED\n");
  622. BlPrint(" 0x0089 = UNABLE_TO_DETERMINE_DOCK_CAPABILITIES\n\n");
  623. BlPrint("DockID = 0x%lx\n", DockInfo->DockID);
  624. BlPrint(" 0xFFFFFFFF if product has no identifier (DockID)\n\n");
  625. BlPrint("SerialNumber = 0x%lx\n", DockInfo->SerialNumber);
  626. BlPrint(" 0 if docking station has no SerialNumber\n\n");
  627. BlPrint("Capabilities = 0x%x\n" , DockInfo->Capabilities);
  628. BlPrint(" Bits 15:3 - reserved (0)\n");
  629. BlPrint(" Bits 2:1 - docking: 00=cold, 01=warm, 10=hot, 11=reserved\n");
  630. BlPrint(" Bit 0 - docking/undocking: 0=surprise style, 1=vcr style\n\n");
  631. BlPrint("*** DockInfo - END ***\n\n");
  632. BlPrint("press any key to continue...\n");
  633. while ( !HwGetKey() ) ; // wait until key pressed to continue
  634. clrscrn();
  635. #endif // DBG
  636. return TRUE;
  637. }