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.

2655 lines
63 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. acpi.c
  5. Abstract:
  6. WinDbg Extension Api for interpretting ACPI data structures
  7. Author:
  8. Stephane Plante (splante) 21-Mar-1997
  9. Based on Code by:
  10. Peter Wieland (peterwie) 16-Oct-1995
  11. Environment:
  12. User Mode.
  13. Revision History:
  14. --*/
  15. #include "pch.h"
  16. extern FILE *outputFile;
  17. BOOL
  18. ReadPhysicalOrVirtual(
  19. IN ULONG_PTR Address,
  20. IN PVOID Buffer,
  21. IN ULONG Size,
  22. IN OUT PULONG ReturnLength,
  23. IN BOOL Virtual
  24. )
  25. /*++
  26. Routine Description:
  27. This is a way to abstract out the differences between ROM images
  28. and mapped memory
  29. Arguments:
  30. Address - Where (either physical, or virtual) the buffer is located
  31. Buffer - Address of where to copy the memory to
  32. Size - How many bytes to copy (maximum)
  33. ReturnLength - How many bytes where copied
  34. Virtual - False if this is physical memory
  35. --*/
  36. {
  37. BOOL status = TRUE;
  38. PHYSICAL_ADDRESS physicalAddress = { 0L, 0L };
  39. if (Virtual) {
  40. status = ReadMemory(
  41. Address,
  42. Buffer,
  43. Size,
  44. ReturnLength
  45. );
  46. } else {
  47. physicalAddress.QuadPart = Address;
  48. ReadPhysical(
  49. physicalAddress.QuadPart,
  50. Buffer,
  51. Size,
  52. ReturnLength
  53. );
  54. }
  55. if (ReturnLength && *ReturnLength != Size) {
  56. //
  57. // Didn't get enough memory
  58. //
  59. status = FALSE;
  60. }
  61. return status;
  62. }
  63. VOID
  64. dumpAcpiGpeInformation(
  65. VOID
  66. )
  67. {
  68. ACPIInformation acpiInformation;
  69. BOOL status;
  70. UCHAR gpeEnable[MAX_GPE_BUFFER_SIZE];
  71. UCHAR gpeCurEnable[MAX_GPE_BUFFER_SIZE];
  72. UCHAR gpeWakeEnable[MAX_GPE_BUFFER_SIZE];
  73. UCHAR gpeIsLevel[MAX_GPE_BUFFER_SIZE];
  74. UCHAR gpeHandlerType[MAX_GPE_BUFFER_SIZE];
  75. UCHAR gpeWakeHandler[MAX_GPE_BUFFER_SIZE];
  76. UCHAR gpeSpecialHandler[MAX_GPE_BUFFER_SIZE];
  77. UCHAR gpePending[MAX_GPE_BUFFER_SIZE];
  78. UCHAR gpeMap[MAX_GPE_BUFFER_SIZE * 8];
  79. UCHAR gpeRunMethod[MAX_GPE_BUFFER_SIZE];
  80. UCHAR gpeComplete[MAX_GPE_BUFFER_SIZE];
  81. ULONG_PTR address;
  82. ULONG acpiGpeRunning;
  83. ULONG acpiGpeWorkDone;
  84. ULONG returnLength;
  85. ULONG size;
  86. ULONG value = 0;
  87. ULONG i;
  88. //
  89. // Get the ACPI Information Table
  90. //
  91. status = GetUlongPtr("ACPI!AcpiInformation", &address);
  92. if (!status) {
  93. dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiInformation\n");
  94. return;
  95. }
  96. status = ReadMemory(
  97. address,
  98. &acpiInformation,
  99. sizeof(ACPIInformation),
  100. &returnLength
  101. );
  102. if (!status || returnLength != sizeof(ACPIInformation)) {
  103. dprintf(
  104. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  105. sizeof(ACPIInformation),
  106. address
  107. );
  108. return;
  109. }
  110. //
  111. // Read the current masks from the OS
  112. //
  113. status = GetUlongPtr("ACPI!GpeEnable", &address);
  114. if (!status) {
  115. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeEnable\n");
  116. return;
  117. }
  118. status = ReadMemory(
  119. address,
  120. gpeEnable,
  121. acpiInformation.GpeSize,
  122. &returnLength
  123. );
  124. if (!status || returnLength != acpiInformation.GpeSize) {
  125. dprintf(
  126. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  127. acpiInformation.GpeSize,
  128. address
  129. );
  130. return;
  131. }
  132. status = GetUlongPtr("ACPI!GpeCurEnable", &address);
  133. if (!status) {
  134. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeCurEnable\n");
  135. return;
  136. }
  137. status = ReadMemory(
  138. address,
  139. gpeCurEnable,
  140. acpiInformation.GpeSize,
  141. &returnLength
  142. );
  143. if (!status || returnLength != acpiInformation.GpeSize) {
  144. dprintf(
  145. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  146. acpiInformation.GpeSize,
  147. address
  148. );
  149. return;
  150. }
  151. status = GetUlongPtr("ACPI!GpeWakeEnable", &address);
  152. if (!status) {
  153. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeWakeEnable\n");
  154. return;
  155. }
  156. status = ReadMemory(
  157. address,
  158. gpeWakeEnable,
  159. acpiInformation.GpeSize,
  160. &returnLength
  161. );
  162. if (!status || returnLength != acpiInformation.GpeSize) {
  163. dprintf(
  164. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  165. acpiInformation.GpeSize,
  166. address
  167. );
  168. return;
  169. }
  170. status = GetUlongPtr("ACPI!GpeIsLevel", &address);
  171. if (!status) {
  172. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeIsLevel\n");
  173. return;
  174. }
  175. status = ReadMemory(
  176. address,
  177. gpeIsLevel,
  178. acpiInformation.GpeSize,
  179. &returnLength
  180. );
  181. if (!status || returnLength != acpiInformation.GpeSize) {
  182. dprintf(
  183. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  184. acpiInformation.GpeSize,
  185. address
  186. );
  187. return;
  188. }
  189. status = GetUlongPtr("ACPI!GpeHandlerType", &address);
  190. if (!status) {
  191. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeHandlerType\n");
  192. return;
  193. }
  194. status = ReadMemory(
  195. address,
  196. gpeHandlerType,
  197. acpiInformation.GpeSize,
  198. &returnLength
  199. );
  200. if (!status || returnLength != acpiInformation.GpeSize) {
  201. dprintf(
  202. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  203. acpiInformation.GpeSize,
  204. address
  205. );
  206. return;
  207. }
  208. status = GetUlongPtr("ACPI!GpeWakeHandler", &address);
  209. if (!status) {
  210. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeWakeHandler\n");
  211. return;
  212. }
  213. status = ReadMemory(
  214. address,
  215. gpeWakeHandler,
  216. acpiInformation.GpeSize,
  217. &returnLength
  218. );
  219. if (!status || returnLength != acpiInformation.GpeSize) {
  220. dprintf(
  221. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  222. acpiInformation.GpeSize,
  223. address
  224. );
  225. return;
  226. }
  227. status = GetUlongPtr("ACPI!GpeSpecialHandler", &address);
  228. if (!status) {
  229. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeSpecialHandler\n");
  230. return;
  231. }
  232. status = ReadMemory(
  233. address,
  234. gpeSpecialHandler,
  235. acpiInformation.GpeSize,
  236. &returnLength
  237. );
  238. if (!status || returnLength != acpiInformation.GpeSize) {
  239. dprintf(
  240. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  241. acpiInformation.GpeSize,
  242. address
  243. );
  244. return;
  245. }
  246. status = GetUlongPtr("ACPI!GpePending", &address);
  247. if (!status) {
  248. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
  249. return;
  250. }
  251. status = ReadMemory(
  252. address,
  253. gpePending,
  254. acpiInformation.GpeSize,
  255. &returnLength
  256. );
  257. if (!status || returnLength != acpiInformation.GpeSize) {
  258. dprintf(
  259. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  260. acpiInformation.GpeSize,
  261. address
  262. );
  263. return;
  264. }
  265. status = GetUlongPtr("ACPI!GpeRunMethod", &address);
  266. if (!status) {
  267. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
  268. return;
  269. }
  270. status = ReadMemory(
  271. address,
  272. gpeRunMethod,
  273. acpiInformation.GpeSize,
  274. &returnLength
  275. );
  276. if (!status || returnLength != acpiInformation.GpeSize) {
  277. dprintf(
  278. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  279. acpiInformation.GpeSize,
  280. address
  281. );
  282. return;
  283. }
  284. status = GetUlongPtr("ACPI!GpeComplete", &address);
  285. if (!status) {
  286. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpePending\n");
  287. return;
  288. }
  289. status = ReadMemory(
  290. address,
  291. gpeComplete,
  292. acpiInformation.GpeSize,
  293. &returnLength
  294. );
  295. if (!status || returnLength != acpiInformation.GpeSize) {
  296. dprintf(
  297. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  298. acpiInformation.GpeSize,
  299. address
  300. );
  301. return;
  302. }
  303. status = GetUlongPtr("ACPI!GpeMap", &address);
  304. if (!status) {
  305. dprintf("dumpAcpiGpeInformation: Could not read ACPI!GpeMap\n");
  306. return;
  307. }
  308. status = ReadMemory(
  309. address,
  310. gpeMap,
  311. (acpiInformation.GpeSize * 8),
  312. &returnLength
  313. );
  314. if (!status || returnLength != (ULONG) (acpiInformation.GpeSize * 8) ) {
  315. dprintf(
  316. "dumpAcpiGpeInformation: Could not read %x bytes at %x\n",
  317. (acpiInformation.GpeSize * 8),
  318. address
  319. );
  320. return;
  321. }
  322. status = GetUlong( "ACPI!AcpiGpeDpcRunning", &acpiGpeRunning );
  323. if (status == FALSE) {
  324. dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiGpeDpcRunning\n");
  325. return;
  326. }
  327. status = GetUlong( "ACPI!AcpiGpeWorkDone", &acpiGpeWorkDone );
  328. if (status == FALSE) {
  329. dprintf("dumpAcpiGpeInformation: Could not read ACPI!AcpiGpeDpcRunning\n");
  330. return;
  331. }
  332. dprintf("ACPI General Purpose Events\n");
  333. dprintf(" + AcpiGpeDpcRunning = %s\n", (acpiGpeRunning ? "TRUE" : "FALSE" ) );
  334. dprintf(" + AcpiGpeWorkDone = %s\n", (acpiGpeRunning ? "TRUE" : "FALSE" ) );
  335. dprintf(
  336. " Register Size: %d bytes\n",
  337. (acpiInformation.Gpe0Size + acpiInformation.Gpe1Size)
  338. );
  339. dprintf(" Status Register: ");
  340. for (i = acpiInformation.Gpe1Size; i > 0; i--) {
  341. size = 1;
  342. ReadIoSpace( (ULONG) acpiInformation.GP1_BLK + (i - 1), &value, &size );
  343. if (!size) {
  344. }
  345. dprintf(" %02x", value );
  346. }
  347. for (i = acpiInformation.Gpe0Size; i > 0; i--) {
  348. size = 1;
  349. ReadIoSpace( (ULONG) acpiInformation.GP0_BLK + (i - 1), &value, &size );
  350. if (!size) {
  351. value = 0;
  352. }
  353. dprintf(" %02x", value );
  354. }
  355. dprintf("\n");
  356. dprintf(" Enable Register: ");
  357. for (i = acpiInformation.Gpe1Size; i > 0; i--) {
  358. size = 1;
  359. ReadIoSpace( (ULONG) acpiInformation.GP1_ENABLE + (i - 1), &value, &size );
  360. if (!size) {
  361. value = 0;
  362. }
  363. dprintf(" %02x", value );
  364. }
  365. for (i = acpiInformation.Gpe0Size; i > 0; i--) {
  366. size = 1;
  367. ReadIoSpace( (ULONG) acpiInformation.GP0_ENABLE + (i - 1), &value, &size );
  368. if (!size) {
  369. value = 0;
  370. }
  371. dprintf(" %02x", value );
  372. }
  373. dprintf("\n");
  374. dprintf(" OS Enable Mask: ");
  375. for (i = acpiInformation.GpeSize; i > 0; i--) {
  376. dprintf(" %02x", gpeEnable[i-1] );
  377. }
  378. dprintf("\n");
  379. dprintf(" OS Current Mask: ");
  380. for (i = acpiInformation.GpeSize; i > 0; i--) {
  381. dprintf(" %02x", gpeCurEnable[i-1] );
  382. }
  383. dprintf("\n");
  384. dprintf(" OS Wake Mask: ");
  385. for (i = acpiInformation.GpeSize; i > 0; i--) {
  386. dprintf(" %02x", gpeWakeEnable[i-1] );
  387. }
  388. dprintf("\n");
  389. dprintf(" GPE Level Type: ");
  390. for (i = acpiInformation.GpeSize; i > 0; i--) {
  391. dprintf(" %02x", gpeIsLevel[i-1] );
  392. }
  393. dprintf("\n");
  394. dprintf(" GPE Handler Type: ");
  395. for (i = acpiInformation.GpeSize; i > 0; i--) {
  396. dprintf(" %02x", gpeHandlerType[i-1] );
  397. }
  398. dprintf("\n");
  399. dprintf(" GPE Wake Handler: ");
  400. for (i = acpiInformation.GpeSize; i > 0; i--) {
  401. dprintf(" %02x", gpeWakeHandler[i-1] );
  402. }
  403. dprintf("\n");
  404. dprintf(" Special GPEs : ");
  405. for (i = acpiInformation.GpeSize; i > 0; i--) {
  406. dprintf(" %02x", gpeSpecialHandler[i-1] );
  407. }
  408. dprintf("\n");
  409. dprintf(" Pending GPEs : ");
  410. for (i = acpiInformation.GpeSize; i > 0; i--) {
  411. dprintf(" %02x", gpePending[i-1] );
  412. }
  413. dprintf("\n");
  414. dprintf(" RunMethod GPEs : ");
  415. for (i = acpiInformation.GpeSize; i > 0; i--) {
  416. dprintf(" %02x", gpeRunMethod[i-1] );
  417. }
  418. dprintf("\n");
  419. dprintf(" Complete GPEs : ");
  420. for (i = acpiInformation.GpeSize; i > 0; i--) {
  421. dprintf(" %02x", gpeComplete[i-1] );
  422. }
  423. dprintf("\n");
  424. dprintf(" GPE Map : ");
  425. for (i = 0 ; i < (ULONG) (acpiInformation.GpeSize * 8); i++) {
  426. dprintf(" %02x", gpeMap[i]);
  427. if ( ((i+1) % 16) == 0) {
  428. dprintf("\n ");
  429. }
  430. }
  431. dprintf("\n");
  432. }
  433. VOID
  434. dumpAcpiInformation(
  435. VOID
  436. )
  437. {
  438. BOOL status;
  439. ACPIInformation acpiInformation;
  440. ULONG_PTR address;
  441. ULONG returnLength;
  442. ULONG size;
  443. ULONG value;
  444. ULONG i;
  445. status = GetUlongPtr( "ACPI!AcpiInformation", &address );
  446. if (status == FALSE) {
  447. dprintf("dumpAcpiInformation: Could not read ACPI!AcpiInformation\n");
  448. return;
  449. }
  450. status = ReadMemory(
  451. address,
  452. &acpiInformation,
  453. sizeof(ACPIInformation),
  454. &returnLength
  455. );
  456. if (!status || returnLength != sizeof(ACPIInformation)) {
  457. dprintf(
  458. "dumpAcpiInformation: Could not read %x bytes at %x\n",
  459. sizeof(ACPIInformation),
  460. address
  461. );
  462. return;
  463. }
  464. dprintf("ACPIInformation (%08lx)\n", address);
  465. dprintf(
  466. " RSDT - %x\n",
  467. acpiInformation.RootSystemDescTable
  468. );
  469. dprintf(
  470. " FADT - %x\n",
  471. acpiInformation.FixedACPIDescTable
  472. );
  473. dprintf(
  474. " FACS - %x\n",
  475. acpiInformation.FirmwareACPIControlStructure
  476. );
  477. dprintf(
  478. " DSDT - %x\n",
  479. acpiInformation.DiffSystemDescTable
  480. );
  481. dprintf(
  482. " GlobalLock - %x\n",
  483. acpiInformation.GlobalLock
  484. );
  485. dprintf(
  486. " GlobalLockQueue - F - %x B - %x\n",
  487. acpiInformation.GlobalLockQueue.Flink,
  488. acpiInformation.GlobalLockQueue.Blink
  489. );
  490. dprintf(
  491. " GlobalLockQueueLock - %x\n",
  492. acpiInformation.GlobalLockQueueLock
  493. );
  494. dprintf(
  495. " GlobalLockOwnerContext - %x\n",
  496. acpiInformation.GlobalLockOwnerContext
  497. );
  498. dprintf(
  499. " GlobalLockOwnerDepth - %x\n",
  500. acpiInformation.GlobalLockOwnerDepth
  501. );
  502. dprintf(
  503. " ACPIOnly - %s\n",
  504. (acpiInformation.ACPIOnly ? "TRUE" : "FALSE" )
  505. );
  506. dprintf(
  507. " PM1a_BLK - %x",
  508. acpiInformation.PM1a_BLK
  509. );
  510. if (acpiInformation.PM1a_BLK) {
  511. size = 4;
  512. value = 0;
  513. ReadIoSpace( (ULONG) acpiInformation.PM1a_BLK, &value, &size );
  514. if (size) {
  515. dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
  516. dumpPM1StatusRegister( value, 5 );
  517. } else {
  518. dprintf(" (N/A)\n" );
  519. }
  520. } else {
  521. dprintf(" (N/A)\n");
  522. }
  523. dprintf(
  524. " PM1b_BLK - %x",
  525. acpiInformation.PM1b_BLK
  526. );
  527. if (acpiInformation.PM1b_BLK) {
  528. size = 4;
  529. value = 0;
  530. ReadIoSpace( (ULONG) acpiInformation.PM1b_BLK, &value, &size );
  531. if (size) {
  532. dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
  533. dumpPM1StatusRegister( value, 5 );
  534. } else {
  535. dprintf(" (N/A)\n" );
  536. }
  537. } else {
  538. dprintf(" (N/A)\n" );
  539. }
  540. dprintf(
  541. " PM1a_CTRL_BLK - %x",
  542. acpiInformation.PM1a_CTRL_BLK
  543. );
  544. if (acpiInformation.PM1a_CTRL_BLK) {
  545. size = 2;
  546. value = 0;
  547. ReadIoSpace( (ULONG) acpiInformation.PM1a_CTRL_BLK, &value, &size );
  548. if (size) {
  549. dprintf(" (%04x)\n", (value & 0xFFFF) );
  550. dumpPM1ControlRegister( value, 5 );
  551. } else {
  552. dprintf(" (N/A)\n" );
  553. }
  554. } else {
  555. dprintf(" (N/A)\n" );
  556. }
  557. dprintf(
  558. " PM1b_CTRL_BLK - %x",
  559. acpiInformation.PM1b_CTRL_BLK
  560. );
  561. if (acpiInformation.PM1b_CTRL_BLK) {
  562. size = 2;
  563. value = 0;
  564. ReadIoSpace( (ULONG) acpiInformation.PM1b_CTRL_BLK, &value, &size );
  565. if (size) {
  566. dprintf(" (%04x)\n", (value & 0xFFFF));
  567. dumpPM1ControlRegister( value, 5 );
  568. } else {
  569. dprintf(" (N/A)\n" );
  570. }
  571. } else {
  572. dprintf(" (N/A)\n" );
  573. }
  574. dprintf(
  575. " PM2_CTRL_BLK - %x",
  576. acpiInformation.PM2_CTRL_BLK
  577. );
  578. if (acpiInformation.PM2_CTRL_BLK) {
  579. size = 1;
  580. value = 0;
  581. ReadIoSpace( (ULONG) acpiInformation.PM2_CTRL_BLK, &value, &size );
  582. if (size) {
  583. dprintf(" (%02x)\n", (value & 0xFF) );
  584. if (value & 0x1) {
  585. dprintf(" 0 - ARB_DIS\n");
  586. }
  587. } else {
  588. dprintf(" (N/A)\n");
  589. }
  590. } else {
  591. dprintf(" (N/A)\n");
  592. }
  593. dprintf(
  594. " PM_TMR - %x",
  595. acpiInformation.PM_TMR
  596. );
  597. if (acpiInformation.PM_TMR) {
  598. size = 4;
  599. value = 0;
  600. ReadIoSpace( (ULONG) acpiInformation.PM_TMR, &value, &size );
  601. if (size) {
  602. dprintf(" (%08lx)\n", value );
  603. } else {
  604. dprintf(" (N/A)\n");
  605. }
  606. } else {
  607. dprintf(" (N/A)\n");
  608. }
  609. dprintf(
  610. " GP0_BLK - %x",
  611. acpiInformation.GP0_BLK
  612. );
  613. if (acpiInformation.GP0_BLK) {
  614. for(i = 0; i < acpiInformation.Gpe0Size; i++) {
  615. size = 1;
  616. value = 0;
  617. ReadIoSpace( (ULONG) acpiInformation.GP0_BLK + i, &value, &size );
  618. if (size) {
  619. dprintf(" (%02x)", value );
  620. } else {
  621. dprintf(" (N/A)" );
  622. }
  623. }
  624. dprintf("\n");
  625. } else {
  626. dprintf(" (N/A)\n");
  627. }
  628. dprintf(
  629. " GP0_ENABLE - %x",
  630. acpiInformation.GP0_ENABLE
  631. );
  632. if (acpiInformation.GP0_ENABLE) {
  633. for(i = 0; i < acpiInformation.Gpe0Size; i++) {
  634. size = 1;
  635. value = 0;
  636. ReadIoSpace( (ULONG) acpiInformation.GP0_ENABLE + i, &value, &size );
  637. if (size) {
  638. dprintf(" (%02x)", value );
  639. } else {
  640. dprintf(" (N/A)" );
  641. }
  642. }
  643. dprintf("\n");
  644. } else {
  645. dprintf(" (N/A)\n");
  646. }
  647. dprintf(
  648. " GP0_LEN - %x\n",
  649. acpiInformation.GP0_LEN
  650. );
  651. dprintf(
  652. " GP0_SIZE - %x\n",
  653. acpiInformation.Gpe0Size
  654. );
  655. dprintf(
  656. " GP1_BLK - %x",
  657. acpiInformation.GP1_BLK
  658. );
  659. if (acpiInformation.GP1_BLK) {
  660. for(i = 0; i < acpiInformation.Gpe0Size; i++) {
  661. size = 1;
  662. value = 0;
  663. ReadIoSpace( (ULONG) acpiInformation.GP1_BLK + i, &value, &size );
  664. if (size) {
  665. dprintf(" (%02x)", value );
  666. } else {
  667. dprintf(" (N/A)" );
  668. }
  669. }
  670. dprintf("\n");
  671. } else {
  672. dprintf(" (N/A)\n");
  673. }
  674. dprintf(
  675. " GP1_ENABLE - %x",
  676. acpiInformation.GP1_ENABLE
  677. );
  678. if (acpiInformation.GP1_ENABLE) {
  679. for(i = 0; i < acpiInformation.Gpe0Size; i++) {
  680. size = 1;
  681. value = 0;
  682. ReadIoSpace( (ULONG) acpiInformation.GP1_ENABLE + i, &value, &size );
  683. if (size) {
  684. dprintf(" (%02x)", value );
  685. } else {
  686. dprintf(" (N/A)" );
  687. }
  688. }
  689. dprintf("\n");
  690. } else {
  691. dprintf(" (N/A)\n");
  692. }
  693. dprintf(
  694. " GP1_LEN - %x\n",
  695. acpiInformation.GP1_LEN
  696. );
  697. dprintf(
  698. " GP1_SIZE - %x\n",
  699. acpiInformation.Gpe1Size
  700. );
  701. dprintf(
  702. " GP1_BASE_INDEX - %x\n",
  703. acpiInformation.GP1_Base_Index
  704. );
  705. dprintf(
  706. " GPE_SIZE - %x\n",
  707. acpiInformation.GpeSize
  708. );
  709. dprintf(
  710. " PM1_EN_BITS - %04x\n",
  711. acpiInformation.pm1_en_bits
  712. );
  713. dumpPM1StatusRegister( ( (ULONG) acpiInformation.pm1_en_bits << 16), 5 );
  714. dprintf(
  715. " PM1_WAKE_MASK - %04x\n",
  716. acpiInformation.pm1_wake_mask
  717. );
  718. dumpPM1StatusRegister( ( (ULONG) acpiInformation.pm1_wake_mask << 16), 5 );
  719. dprintf(
  720. " C2_LATENCY - %x\n",
  721. acpiInformation.c2_latency
  722. );
  723. dprintf(
  724. " C3_LATENCY - %x\n",
  725. acpiInformation.c3_latency
  726. );
  727. dprintf(
  728. " ACPI_FLAGS - %x\n",
  729. acpiInformation.ACPI_Flags
  730. );
  731. if (acpiInformation.ACPI_Flags & C2_SUPPORTED) {
  732. dprintf(" %2d - C2_SUPPORTED\n", C2_SUPPORTED_BIT);
  733. }
  734. if (acpiInformation.ACPI_Flags & C3_SUPPORTED) {
  735. dprintf(" %2d - C3_SUPPORTED\n", C3_SUPPORTED_BIT);
  736. }
  737. if (acpiInformation.ACPI_Flags & C3_PREFERRED) {
  738. dprintf(" %2d - C3_PREFERRED\n", C3_PREFERRED_BIT);
  739. }
  740. dprintf(
  741. " ACPI_CAPABILITIES - %x\n",
  742. acpiInformation.ACPI_Capabilities
  743. );
  744. if (acpiInformation.ACPI_Capabilities & CSTATE_C1) {
  745. dprintf(" %2d - CSTATE_C1\n", CSTATE_C1_BIT );
  746. } if (acpiInformation.ACPI_Capabilities & CSTATE_C2) {
  747. dprintf(" %2d - CSTATE_C2\n", CSTATE_C2_BIT );
  748. } if (acpiInformation.ACPI_Capabilities & CSTATE_C3) {
  749. dprintf(" %2d - CSTATE_C3\n", CSTATE_C3_BIT );
  750. }
  751. }
  752. #if 0
  753. VOID
  754. dumpDSDT(
  755. IN ULONG_PTR Address,
  756. IN PUCHAR Name
  757. )
  758. /*++
  759. Routine Description:
  760. This dumps the DSDT at the specified address
  761. Arguments:
  762. The address where the DSDT is located at
  763. Return Value:
  764. None
  765. --*/
  766. {
  767. BOOL status;
  768. BOOL virtualMemory;
  769. DESCRIPTION_HEADER dsdtHeader;
  770. NTSTATUS result;
  771. PDSDT dsdt;
  772. ULONG returnLength;
  773. ULONG index;
  774. //
  775. // Determine if we have virtual or physical memory
  776. //
  777. for (index = 0; index < 2; index++) {
  778. status = ReadPhysicalOrVirtual(
  779. Address,
  780. &dsdtHeader,
  781. sizeof(DESCRIPTION_HEADER),
  782. &returnLength,
  783. (BOOL) index
  784. );
  785. if (!status) {
  786. continue;
  787. } else if (dsdtHeader.Signature != DSDT_SIGNATURE &&
  788. dsdtHeader.Signature != SSDT_SIGNATURE &&
  789. dsdtHeader.Signature != PSDT_SIGNATURE ) {
  790. continue;
  791. } else {
  792. break;
  793. }
  794. }
  795. //
  796. // This will set the policy for the rest of the operation
  797. //
  798. switch (index) {
  799. case 0:
  800. virtualMemory = FALSE;
  801. break;
  802. case 1:
  803. virtualMemory = TRUE;
  804. break;
  805. default:
  806. if (!status) {
  807. dprintf(
  808. "dumpDSDT: Could only read 0x%08lx of 0x%08lx bytes\n",
  809. returnLength,
  810. sizeof(DESCRIPTION_HEADER)
  811. );
  812. } else {
  813. dprintf(
  814. "dumpDSDT: Unknown Signature 0x%08lx\n",
  815. dsdtHeader.Signature
  816. );
  817. dumpHeader( Address, &dsdtHeader, TRUE );
  818. }
  819. return;
  820. } // switch
  821. //
  822. // Do we have a correctly sized data structure
  823. //
  824. dsdt = LocalAlloc( LPTR, dsdtHeader.Length );
  825. if (dsdt == NULL) {
  826. dprintf(
  827. "dumpDSDT: Could not allocate %#08lx bytes\n",
  828. Address,
  829. dsdtHeader.Length
  830. );
  831. dumpHeader( Address, &dsdtHeader, TRUE );
  832. return;
  833. }
  834. //
  835. // Read the data
  836. //
  837. status = ReadPhysicalOrVirtual(
  838. Address,
  839. dsdt,
  840. dsdtHeader.Length,
  841. &returnLength,
  842. virtualMemory
  843. );
  844. if (!status) {
  845. dprintf(
  846. "dumpDSDT: Read %#08lx of %#08lx bytes\n",
  847. Address,
  848. returnLength,
  849. dsdtHeader.Length
  850. );
  851. dumpHeader( Address, &dsdtHeader, TRUE );
  852. LocalFree( dsdt );
  853. return;
  854. } else if (dsdt->Header.Signature != DSDT_SIGNATURE &&
  855. dsdt->Header.Signature != SSDT_SIGNATURE &&
  856. dsdt->Header.Signature != PSDT_SIGNATURE) {
  857. dprintf(
  858. "dumpDSDT: Unkown Signature (%#08lx)\n",
  859. dsdt->Header.Signature
  860. );
  861. dumpHeader( Address, &dsdtHeader, TRUE );
  862. LocalFree( dsdt );
  863. return;
  864. }
  865. //
  866. // Load the DSDT into the unassembler
  867. //
  868. if (!IsDSDTLoaded()) {
  869. result = UnAsmLoadDSDT(
  870. (PUCHAR) dsdt
  871. );
  872. if (!NT_SUCCESS(result)) {
  873. dprintf(
  874. "dumpDSDT: Could not load DSDT %08lx because %08lx\n",
  875. dsdt,
  876. result
  877. );
  878. return;
  879. }
  880. result = UnAsmLoadXSDTEx();
  881. if (!NT_SUCCESS(result)) {
  882. dprintf(
  883. "dumpDSDT: Could not load XSDTs because %08lx\n",
  884. result
  885. );
  886. return;
  887. }
  888. }
  889. if (Name == NULL) {
  890. result = UnAsmDSDT(
  891. (PUCHAR) dsdt,
  892. DisplayPrint,
  893. Address,
  894. 0
  895. );
  896. } else {
  897. outputFile = fopen( Name, "w");
  898. if (outputFile == NULL) {
  899. dprintf("dumpDSDT: Could not open file \"%s\"\n", Name );
  900. } else {
  901. result = UnAsmDSDT(
  902. (PUCHAR) dsdt,
  903. FilePrint,
  904. Address,
  905. 0
  906. );
  907. fflush( outputFile );
  908. fclose( outputFile );
  909. }
  910. }
  911. if (!NT_SUCCESS(result)) {
  912. dprintf("dumpDSDT: Unasm Error 0x%08lx\n", result );
  913. }
  914. LocalFree( dsdt );
  915. return;
  916. }
  917. #endif
  918. VOID
  919. dumpFACS(
  920. IN ULONG_PTR Address
  921. )
  922. /*++
  923. Routine Description:
  924. This dumps the FADT at the specified address
  925. Arguments:
  926. The address where the FADT is located at
  927. Return Value:
  928. NONE
  929. --*/
  930. {
  931. BOOL status;
  932. FACS facs;
  933. ULONG index;
  934. ULONG returnLength;
  935. //
  936. // Read the data
  937. //
  938. dprintf("FACS - %#08lx\n", Address);
  939. for (index = 0; index < 2; index++) {
  940. status = ReadPhysicalOrVirtual(
  941. Address,
  942. &facs,
  943. sizeof(FACS),
  944. &returnLength,
  945. (BOOL) index
  946. );
  947. if (!status || facs.Signature != FACS_SIGNATURE) {
  948. continue;
  949. } else {
  950. break;
  951. }
  952. }
  953. //
  954. // This will set the policy for the rest of the operation
  955. //
  956. switch (index) {
  957. default:
  958. break;
  959. case 2:
  960. if (!status) {
  961. dprintf(
  962. "dumpFACS: Could only read 0x%08lx of 0x%08lx bytes\n",
  963. returnLength,
  964. sizeof(FACS)
  965. );
  966. } else {
  967. dprintf(
  968. "dumpFACS: Invalid Signature 0x%08lx != FACS_SIGNATURE\n",
  969. facs.Signature
  970. );
  971. }
  972. return;
  973. } // switch
  974. //
  975. // Dump the table
  976. //
  977. memset( Buffer, 0, 2048 );
  978. memcpy( Buffer, &(facs.Signature), sizeof(ULONG) );
  979. dprintf(
  980. " Signature: %s\n"
  981. " Length: %#08lx\n"
  982. " Hardware Signature: %#08lx\n"
  983. " Firmware Wake Vector: %#08lx\n"
  984. " Global Lock : %#08lx\n",
  985. Buffer,
  986. facs.Length,
  987. facs.HardwareSignature,
  988. facs.pFirmwareWakingVector,
  989. facs.GlobalLock
  990. );
  991. if ( (facs.GlobalLock & GL_PENDING) ) {
  992. dprintf(" Request for Ownership Pending\n");
  993. }
  994. if ( (facs.GlobalLock & GL_OWNER) ) {
  995. dprintf(" Global Lock is Owned\n");
  996. }
  997. dprintf(" Flags: %#08lx\n", facs.Flags );
  998. if ( (facs.Flags & FACS_S4BIOS_SUPPORTED) ) {
  999. dprintf(" S4BIOS_REQ Supported\n");
  1000. }
  1001. return;
  1002. }
  1003. VOID
  1004. dumpFADT(
  1005. IN ULONG_PTR Address
  1006. )
  1007. /*++
  1008. Routine Description:
  1009. This dumps the FADT at the specified address
  1010. Arguments:
  1011. The address where the FADT is located at
  1012. Return Value:
  1013. NONE
  1014. --*/
  1015. {
  1016. BOOL status;
  1017. BOOL virtualMemory;
  1018. DESCRIPTION_HEADER fadtHeader;
  1019. FADT fadt;
  1020. ULONG fadtLength;
  1021. ULONG returnLength;
  1022. ULONG index;
  1023. PCHAR addressSpace;
  1024. //
  1025. // First check to see if we find the correct things
  1026. //
  1027. dprintf("FADT - ");
  1028. for (index = 0; index < 2; index++) {
  1029. status = ReadPhysicalOrVirtual(
  1030. Address,
  1031. &fadtHeader,
  1032. sizeof(DESCRIPTION_HEADER),
  1033. &returnLength,
  1034. (BOOL) index
  1035. );
  1036. if (!status || fadtHeader.Signature != FADT_SIGNATURE) {
  1037. continue;
  1038. } else {
  1039. break;
  1040. }
  1041. }
  1042. //
  1043. // This will set the policy for the rest of the operation
  1044. //
  1045. switch (index) {
  1046. case 0:
  1047. virtualMemory = FALSE;
  1048. break;
  1049. case 1:
  1050. virtualMemory = TRUE;
  1051. break;
  1052. default:
  1053. if (!status) {
  1054. dprintf(
  1055. "dumpFADT: Could only read 0x%08lx of 0x%08lx bytes\n",
  1056. returnLength,
  1057. sizeof(DESCRIPTION_HEADER)
  1058. );
  1059. } else {
  1060. dprintf(
  1061. "dumpFADT: Invalid Signature 0x%08lx != FADT_SIGNATURE\n",
  1062. fadtHeader.Signature
  1063. );
  1064. dumpHeader( Address, &fadtHeader, TRUE );
  1065. }
  1066. return;
  1067. } // switch
  1068. if (fadtHeader.Revision == 1) {
  1069. fadtLength = FADT_REV_1_SIZE; // 116
  1070. } else if (fadtHeader.Revision == 2) {
  1071. fadtLength = FADT_REV_2_SIZE; // 129
  1072. } else {
  1073. fadtLength = sizeof(FADT);
  1074. }
  1075. //
  1076. // Do we have a correctly sized data structure
  1077. //
  1078. if (fadtHeader.Length < fadtLength) {
  1079. dprintf(
  1080. "dumpFADT: Length (%#08lx) is not the size of the FADT (%#08lx)\n",
  1081. Address,
  1082. fadtHeader.Length,
  1083. fadtLength
  1084. );
  1085. dumpHeader( Address, &fadtHeader, TRUE );
  1086. return;
  1087. }
  1088. //
  1089. // Read the data
  1090. //
  1091. status = ReadPhysicalOrVirtual(
  1092. Address,
  1093. &fadt,
  1094. fadtLength,
  1095. &returnLength,
  1096. virtualMemory
  1097. );
  1098. if (!status) {
  1099. dprintf(
  1100. "dumpFADT: Read %#08lx of %#08lx bytes\n",
  1101. Address,
  1102. returnLength,
  1103. sizeof(FADT)
  1104. );
  1105. dumpHeader( Address, &fadtHeader, TRUE );
  1106. return;
  1107. } else if (fadt.Header.Signature != FADT_SIGNATURE) {
  1108. dprintf(
  1109. "%#08lx: Signature (%#08lx) != fadt_SIGNATURE (%#08lx)\n",
  1110. Address,
  1111. fadt.Header.Signature,
  1112. FADT_SIGNATURE
  1113. );
  1114. dumpHeader( Address, &fadtHeader, TRUE );
  1115. return;
  1116. }
  1117. //
  1118. // Dump the table
  1119. //
  1120. dumpHeader( Address, &(fadt.Header), TRUE );
  1121. dprintf(
  1122. "FADT - BODY - %#08lx\n"
  1123. " FACS: 0x%08lx\n"
  1124. " DSDT: 0x%08lx\n"
  1125. " Int Model: %s\n"
  1126. " SCI Vector: 0x%03x\n"
  1127. " SMI Port: 0x%08lx\n"
  1128. " ACPI On Value: 0x%03x\n"
  1129. " ACPI Off Value: 0x%03x\n"
  1130. " SMI CMD For S4 State: 0x%03x\n"
  1131. " PM1A Event Block: 0x%08lx\n"
  1132. " PM1B Event Block: 0x%08lx\n"
  1133. " PM1 Event Length: 0x%03x\n"
  1134. " PM1A Control Block: 0x%08lx\n"
  1135. " PM1B Control Block: 0x%08lx\n"
  1136. " PM1 Control Length: 0x%03x\n"
  1137. " PM2 Control Block: 0x%08lx\n"
  1138. " PM2 Control Length: 0x%03x\n"
  1139. " PM Timer Block: 0x%08lx\n"
  1140. " PM Timer Length: 0x%03x\n"
  1141. " GP0 Block: 0x%08lx\n"
  1142. " GP0 Length: 0x%03x\n"
  1143. " GP1 Block: 0x%08lx\n"
  1144. " GP1 Length: 0x%08lx\n"
  1145. " GP1 Base: 0x%08lx\n"
  1146. " C2 Latency: 0x%05lx\n"
  1147. " C3 Latency: 0x%05lx\n"
  1148. " Memory Flush Size: 0x%05lx\n"
  1149. " Memory Flush Stride: 0x%05lx\n"
  1150. " Duty Cycle Index: 0x%03x\n"
  1151. " Duty Cycle Index Width: 0x%03x\n"
  1152. " Day Alarm Index: 0x%03x\n"
  1153. " Month Alarm Index: 0x%03x\n"
  1154. " Century byte (CMOS): 0x%03x\n"
  1155. " Boot Architecture: 0x%04x\n"
  1156. " Flags: 0x%08lx\n",
  1157. Address + sizeof(DESCRIPTION_HEADER),
  1158. fadt.facs,
  1159. fadt.dsdt,
  1160. (fadt.int_model == 0 ? "Dual PIC" : "Multiple APIC" ),
  1161. fadt.sci_int_vector,
  1162. fadt.smi_cmd_io_port,
  1163. fadt.acpi_on_value,
  1164. fadt.acpi_off_value,
  1165. fadt.s4bios_req,
  1166. fadt.pm1a_evt_blk_io_port,
  1167. fadt.pm1b_evt_blk_io_port,
  1168. fadt.pm1_evt_len,
  1169. fadt.pm1a_ctrl_blk_io_port,
  1170. fadt.pm1b_ctrl_blk_io_port,
  1171. fadt.pm1_ctrl_len,
  1172. fadt.pm2_ctrl_blk_io_port,
  1173. fadt.pm2_ctrl_len,
  1174. fadt.pm_tmr_blk_io_port,
  1175. fadt.pm_tmr_len,
  1176. fadt.gp0_blk_io_port,
  1177. fadt.gp0_blk_len,
  1178. fadt.gp1_blk_io_port,
  1179. fadt.gp1_blk_len,
  1180. fadt.gp1_base,
  1181. fadt.lvl2_latency,
  1182. fadt.lvl3_latency,
  1183. #ifndef _IA64_ // XXTF
  1184. fadt.flush_size,
  1185. fadt.flush_stride,
  1186. fadt.duty_offset,
  1187. fadt.duty_width,
  1188. #endif
  1189. fadt.day_alarm_index,
  1190. fadt.month_alarm_index,
  1191. fadt.century_alarm_index,
  1192. #ifndef _IA64_ // XXTF
  1193. fadt.boot_arch,
  1194. #endif
  1195. fadt.flags
  1196. );
  1197. if (fadt.flags & WRITEBACKINVALIDATE_WORKS) {
  1198. dprintf(" Write Back Invalidate is supported\n");
  1199. }
  1200. if (fadt.flags & WRITEBACKINVALIDATE_DOESNT_INVALIDATE) {
  1201. dprintf(" Write Back Invalidate doesn't invalidate the caches\n");
  1202. }
  1203. if (fadt.flags & SYSTEM_SUPPORTS_C1) {
  1204. dprintf(" System cupports C1 Power state on all processors\n");
  1205. }
  1206. if (fadt.flags & P_LVL2_UP_ONLY) {
  1207. dprintf(" System supports C2 in MP and UP configurations\n");
  1208. }
  1209. if (fadt.flags & PWR_BUTTON_GENERIC) {
  1210. dprintf(" Power Button is treated as a generic feature\n");
  1211. }
  1212. if (fadt.flags & SLEEP_BUTTON_GENERIC) {
  1213. dprintf(" Sleep Button is treated as a generic feature\n");
  1214. }
  1215. if (fadt.flags & RTC_WAKE_GENERIC) {
  1216. dprintf(" RTC Wake is not supported in fixed register space\n");
  1217. }
  1218. if (fadt.flags & RTC_WAKE_FROM_S4) {
  1219. dprintf(" RTC Wake can work from an S4 state\n");
  1220. }
  1221. if (fadt.flags & TMR_VAL_EXT) {
  1222. dprintf(" TMR_VAL implemented as 32-bit value\n");
  1223. }
  1224. #ifndef _IA64_ // XXTF
  1225. if (fadt.Header.Revision > 1) {
  1226. if (!(fadt.boot_arch & LEGACY_DEVICES)) {
  1227. dprintf(" The machine does not contain legacy ISA devices\n");
  1228. }
  1229. if (!(fadt.boot_arch & I8042)) {
  1230. dprintf(" The machine does not contain a legacy i8042\n");
  1231. }
  1232. if (fadt.flags & RESET_CAP) {
  1233. dprintf(" The reset register is supported\n");
  1234. dprintf(" Reset Val: %x\n", fadt.reset_val);
  1235. switch (fadt.reset_reg.AddressSpaceID) {
  1236. case 0:
  1237. addressSpace = "Memory";
  1238. break;
  1239. case 1:
  1240. addressSpace = "I/O";
  1241. break;
  1242. case 2:
  1243. addressSpace = "PCIConfig";
  1244. break;
  1245. default:
  1246. addressSpace = "undefined";
  1247. }
  1248. dprintf(" Reset register: %s - %08x'%08x\n",
  1249. addressSpace,
  1250. fadt.reset_reg.Address.HighPart,
  1251. fadt.reset_reg.Address.LowPart
  1252. );
  1253. }
  1254. }
  1255. #endif
  1256. return;
  1257. }
  1258. VOID
  1259. dumpGBL(
  1260. ULONG Verbose
  1261. )
  1262. /*++
  1263. Routine Description:
  1264. This routine reads in all the system tables and prints out
  1265. what the ACPI Good Bios List Entry for this machine should
  1266. be
  1267. Arguments:
  1268. None
  1269. Return Value:
  1270. None
  1271. --*/
  1272. {
  1273. ACPIInformation inf;
  1274. BOOL status;
  1275. DESCRIPTION_HEADER hdr;
  1276. ULONG64 dateAddress;
  1277. PRSDTINFORMATION info;
  1278. PUCHAR tempPtr;
  1279. ULONG i;
  1280. ULONG numElements;
  1281. ULONG returnLength;
  1282. ULONG size;
  1283. ULONG_PTR address;
  1284. ULONG_PTR address2;
  1285. //
  1286. // Remember where the date address is stored
  1287. //
  1288. dateAddress = 0xFFFF5;
  1289. //
  1290. // Make sure that we can read the pointer
  1291. //
  1292. address2 = GetExpression( "ACPI!RsdtInformation" );
  1293. if (!address2) {
  1294. dprintf("dumpGBL: Could not find RsdtInformation\n");
  1295. return;
  1296. }
  1297. status = GetUlongPtr( "ACPI!RsdtInformation", &address );
  1298. if (status == FALSE || !address) {
  1299. dprintf("dumpGBL: No RsdtInformation present\n");
  1300. return;
  1301. }
  1302. //
  1303. // Read the ACPInformation table, so that we know where the RSDT lives
  1304. //
  1305. status = GetUlongPtr( "ACPI!AcpiInformation", &address2 );
  1306. if (status == FALSE || !address2) {
  1307. dprintf("dumpGBL: Could not read AcpiInformation\n");
  1308. return;
  1309. }
  1310. status = ReadMemory( address2, &inf, sizeof(ACPIInformation), &returnLength );
  1311. if (!status || returnLength != sizeof(ACPIInformation)) {
  1312. dprintf("dumpGBL: Could not read AcpiInformation- %d %x\n", status, returnLength);
  1313. return;
  1314. }
  1315. //
  1316. // Read in the header for the RSDT
  1317. //
  1318. address2 = (ULONG_PTR) inf.RootSystemDescTable;
  1319. status = ReadMemory( address2, &hdr, sizeof(DESCRIPTION_HEADER), &returnLength );
  1320. if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
  1321. dprintf("dumpGBL: Could not read RSDT @%x - %d %x\n", address2, status, returnLength );
  1322. return;
  1323. }
  1324. //
  1325. // The number of elements in the table is the first entry
  1326. // in the structure
  1327. //
  1328. status = ReadMemory(address, &numElements, sizeof(ULONG), &returnLength);
  1329. if (status == FALSE || returnLength != sizeof(ULONG) ) {
  1330. dprintf("dumpGBL: Could not read RsdtInformation\n");
  1331. return;
  1332. }
  1333. //
  1334. // If there are no elements, then return
  1335. //
  1336. if (numElements == 0) {
  1337. dprintf("dumpGBL: No tables the RsdtInformation\n");
  1338. return;
  1339. }
  1340. //
  1341. // Allocate the table, and read in all the pointers
  1342. //
  1343. size = sizeof(RSDTINFORMATION) + ( (numElements - 1) * sizeof(RSDTELEMENT) );
  1344. info = LocalAlloc( LPTR, size );
  1345. if (info == NULL) {
  1346. dprintf("dumpGBL: Could not allocate %x bytes for table\n", size);
  1347. return;
  1348. }
  1349. //
  1350. // Read the entire table
  1351. //
  1352. status = ReadMemory(
  1353. address,
  1354. info,
  1355. size,
  1356. &returnLength
  1357. );
  1358. if (!status || returnLength != size) {
  1359. dprintf("dumpGBL: Could not read RsdtInformation Table\n");
  1360. return;
  1361. }
  1362. //
  1363. // Dump a header so that people know what this is
  1364. //
  1365. memset( Buffer, 0, 2048 );
  1366. ReadPhysical( dateAddress, Buffer, 8, &returnLength );
  1367. dprintf("\nGood Bios List Entry --- Machine BIOS Date %s\n\n", Buffer);
  1368. memset( Buffer, 0, 2048 );
  1369. memcpy( Buffer, hdr.OEMID, 6);
  1370. tempPtr = Buffer;
  1371. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1372. memcpy( tempPtr, hdr.OEMTableID, 8 );
  1373. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1374. ReadPhysical( dateAddress, tempPtr, 8, &returnLength );
  1375. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1376. //
  1377. // This is the entry name
  1378. //
  1379. dprintf("[%s]\n", Buffer );
  1380. //
  1381. // Dump the all the tables that are loaded in the RSDT table
  1382. //
  1383. for (i = 0; i < numElements; i++) {
  1384. if (!(info->Tables[i].Flags & RSDTELEMENT_MAPPED) ) {
  1385. continue;
  1386. }
  1387. dumpGBLEntry( (ULONG_PTR) info->Tables[i].Address, Verbose );
  1388. }
  1389. //
  1390. // Dump the entry for the RSDT
  1391. //
  1392. dumpGBLEntry( (ULONG_PTR) inf.RootSystemDescTable, Verbose );
  1393. //
  1394. // Add some whitespace
  1395. //
  1396. dprintf("\n");
  1397. //
  1398. // Free the RSDT information structure
  1399. //
  1400. LocalFree( info );
  1401. //
  1402. // Done
  1403. //
  1404. return;
  1405. }
  1406. VOID
  1407. dumpGBLEntry(
  1408. IN ULONG_PTR Address,
  1409. IN ULONG Verbose
  1410. )
  1411. /*++
  1412. Routine Description:
  1413. This routine actually prints the rule for the table at the
  1414. specified address
  1415. Arguments:
  1416. Address - where the table is located
  1417. Return Value:
  1418. None
  1419. --*/
  1420. {
  1421. BOOL status;
  1422. DESCRIPTION_HEADER header;
  1423. ULONG returnLength;
  1424. UCHAR tableId[7];
  1425. UCHAR entryId[20];
  1426. //
  1427. // Read the header for the table
  1428. //
  1429. status = ReadMemory(
  1430. Address,
  1431. &header,
  1432. sizeof(DESCRIPTION_HEADER),
  1433. &returnLength
  1434. );
  1435. if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
  1436. dprintf("dumpGBLEntry: %x - can't read header\n", Address );
  1437. return;
  1438. }
  1439. //
  1440. // Don't print out a table unless its the FACP or we are being verbose
  1441. //
  1442. if (!(Verbose & VERBOSE_2) && header.Signature != FADT_SIGNATURE) {
  1443. return;
  1444. }
  1445. //
  1446. // Initialize the table id field
  1447. //
  1448. memset( tableId, 0, 7 );
  1449. tableId[0] = '\"';
  1450. memcpy( &tableId[1], &(header.Signature), sizeof(ULONG) );
  1451. strcat( tableId, "\"" );
  1452. //
  1453. // Get the entry ready for the OEM Id
  1454. //
  1455. memset( entryId, 0, 20 );
  1456. entryId[0] = '\"';
  1457. memcpy( &entryId[1], header.OEMID, 6 );
  1458. strcat( entryId, "\"");
  1459. dprintf("AcpiOemId=%s,%s\n", tableId, entryId );
  1460. //
  1461. // Get the entry ready for the OEM Table Id
  1462. //
  1463. memset( entryId, 0, 20 );
  1464. entryId[0] = '\"';
  1465. memcpy( &entryId[1], header.OEMTableID, 8 );
  1466. strcat( entryId, "\"");
  1467. dprintf("AcpiOemTableId=%s,%s\n", tableId, entryId );
  1468. //
  1469. // Get the entry ready for the OEM Revision
  1470. //
  1471. dprintf("AcpiOemRevision=\">=\",%s,%x\n", tableId, header.OEMRevision );
  1472. //
  1473. // Get the entry ready for the ACPI revision
  1474. //
  1475. if (header.Revision != 1) {
  1476. dprintf("AcpiRevision=\">=\",%s,%x\n", tableId, header.Revision );
  1477. }
  1478. //
  1479. // Get the entry ready for the ACPI Creator Revision
  1480. //
  1481. dprintf("AcpiCreatorRevision=\">=\",%s,%x\n", tableId, header.CreatorRev );
  1482. }
  1483. VOID
  1484. dumpHeader(
  1485. IN ULONG_PTR Address,
  1486. IN PDESCRIPTION_HEADER Header,
  1487. IN BOOLEAN Verbose
  1488. )
  1489. /*++
  1490. Routine Description:
  1491. This function dumps out a table header
  1492. Arugments:
  1493. Address - Where the table is located
  1494. Header - The table header
  1495. Verbose - How much information to give
  1496. Return Value:
  1497. NULL
  1498. --*/
  1499. {
  1500. memset( Buffer, 0, 2048 );
  1501. memcpy( Buffer, &(Header->Signature), sizeof(ULONG) );
  1502. if (Verbose) {
  1503. dprintf(
  1504. "HEADER - %#08lx\n"
  1505. " Signature: %s\n"
  1506. " Length: 0x%08lx\n"
  1507. " Revision: 0x%02x\n"
  1508. " Checksum: 0x%02x\n",
  1509. Address,
  1510. Buffer,
  1511. Header->Length,
  1512. Header->Revision,
  1513. Header->Checksum
  1514. );
  1515. memset( Buffer, 0, 7 );
  1516. memcpy( Buffer, Header->OEMID, 6 );
  1517. dprintf(" OEMID: %s\n", Buffer );
  1518. memcpy( Buffer, Header->OEMTableID, 8 );
  1519. dprintf(" OEMTableID: %s\n", Buffer );
  1520. dprintf(" OEMRevision: 0x%08lx\n", Header->OEMRevision );
  1521. memset( Buffer, 0, 8 );
  1522. memcpy( Buffer, Header->CreatorID, 4 );
  1523. dprintf(" CreatorID: %s\n", Buffer );
  1524. dprintf(" CreatorRev: 0x%08lx\n", Header->CreatorRev );
  1525. } else {
  1526. dprintf(
  1527. " %s @(%#08lx) Rev: %#03x Len: %#08lx",
  1528. Buffer,
  1529. Address,
  1530. Header->Revision,
  1531. Header->Length
  1532. );
  1533. memset( Buffer, 0, sizeof(ULONG) );
  1534. memcpy( Buffer, Header->OEMTableID, 8 );
  1535. dprintf(" TableID: %s\n", Buffer );
  1536. }
  1537. return;
  1538. }
  1539. VOID
  1540. dumpMAPIC(
  1541. IN ULONG_PTR Address
  1542. )
  1543. /*++
  1544. Routine Description:
  1545. This dumps the multiple apic table
  1546. Arguments:
  1547. Address of the table
  1548. Return Value:
  1549. None
  1550. --*/
  1551. {
  1552. BOOL hasMPSFlags;
  1553. BOOL status;
  1554. BOOL virtualMemory;
  1555. DESCRIPTION_HEADER mapicHeader;
  1556. PIOAPIC ioApic;
  1557. PISA_VECTOR interruptSourceOverride;
  1558. PMAPIC mapic;
  1559. PIO_NMISOURCE nmiSource;
  1560. PLOCAL_NMISOURCE localNmiSource;
  1561. PPROCLOCALAPIC localApic;
  1562. PUCHAR buffer;
  1563. PUCHAR limit;
  1564. ULONG index;
  1565. ULONG returnLength;
  1566. ULONG flags;
  1567. //
  1568. // First check to see if we find the correct things
  1569. //
  1570. dprintf("MAPIC - ");
  1571. for (index = 0; index < 2; index++) {
  1572. status = ReadPhysicalOrVirtual(
  1573. Address,
  1574. &mapicHeader,
  1575. sizeof(DESCRIPTION_HEADER),
  1576. &returnLength,
  1577. (BOOL) index
  1578. );
  1579. if (!status || mapicHeader.Signature != APIC_SIGNATURE) {
  1580. continue;
  1581. } else {
  1582. break;
  1583. }
  1584. }
  1585. //
  1586. // This will set the policy for the rest of the operation
  1587. //
  1588. switch (index) {
  1589. case 0:
  1590. virtualMemory = FALSE;
  1591. break;
  1592. case 1:
  1593. virtualMemory = TRUE;
  1594. break;
  1595. default:
  1596. if (!status) {
  1597. dprintf(
  1598. "dumpMAPIC: Could only read 0x%08lx of 0x%08lx bytes\n",
  1599. returnLength,
  1600. sizeof(DESCRIPTION_HEADER)
  1601. );
  1602. } else {
  1603. dprintf(
  1604. "dumpMAPIC: Invalid Signature 0x%08lx != ACPI_SIGNATURE\n",
  1605. mapicHeader.Signature
  1606. );
  1607. dumpHeader( Address, &mapicHeader, TRUE );
  1608. }
  1609. return;
  1610. } // switch
  1611. //
  1612. // Do we have a correctly sized data structure
  1613. //
  1614. mapic = LocalAlloc( LPTR, mapicHeader.Length );
  1615. if (mapic == NULL) {
  1616. dprintf(
  1617. "%#08lx: Could not allocate %#08lx bytes\n",
  1618. Address,
  1619. mapicHeader.Length
  1620. );
  1621. dumpHeader( Address, &mapicHeader, TRUE );
  1622. return;
  1623. }
  1624. //
  1625. // Read the data
  1626. //
  1627. status = ReadPhysicalOrVirtual(
  1628. Address,
  1629. mapic,
  1630. mapicHeader.Length,
  1631. &returnLength,
  1632. virtualMemory
  1633. );
  1634. if (!status) {
  1635. dprintf(
  1636. "dumpMAPIC: Read %#08lx of %#08lx bytes\n",
  1637. Address,
  1638. returnLength,
  1639. mapicHeader.Length
  1640. );
  1641. dumpHeader( Address, &mapicHeader, TRUE );
  1642. LocalFree( mapic );
  1643. return;
  1644. }
  1645. //
  1646. // At this point, we are confident that everything worked
  1647. //
  1648. dumpHeader( Address, &(mapic->Header), TRUE );
  1649. dprintf("MAPIC - BODY - %#08lx\n", Address + sizeof(DESCRIPTION_HEADER) );
  1650. dprintf(" Local APIC Address: %#08lx\n", mapic->LocalAPICAddress );
  1651. dprintf(" Flags: %#08lx\n", mapic->Flags );
  1652. if (mapic->Flags & PCAT_COMPAT) {
  1653. dprintf(" PC-AT dual 8259 compatible setup\n");
  1654. }
  1655. buffer = (PUCHAR) &(mapic->APICTables[0]);
  1656. limit = (PUCHAR) ( (ULONG_PTR)mapic + mapic->Header.Length );
  1657. while (buffer < limit) {
  1658. //
  1659. // Assume that no flags are set
  1660. //
  1661. hasMPSFlags = FALSE;
  1662. //
  1663. // Lets see what kind of table we have?
  1664. //
  1665. localApic = (PPROCLOCALAPIC) buffer;
  1666. ioApic = (PIOAPIC) buffer;
  1667. interruptSourceOverride = (PISA_VECTOR) buffer;
  1668. nmiSource = (PIO_NMISOURCE) buffer;
  1669. localNmiSource = (PLOCAL_NMISOURCE) buffer;
  1670. //
  1671. // Is it a localApic?
  1672. //
  1673. if (localApic->Type == PROCESSOR_LOCAL_APIC) {
  1674. buffer += localApic->Length;
  1675. dprintf(
  1676. " Processor Local Apic\n"
  1677. " ACPI Processor ID: 0x%02x\n"
  1678. " APIC ID: 0x%02x\n"
  1679. " Flags: 0x%08lx\n",
  1680. localApic->ACPIProcessorID,
  1681. localApic->APICID,
  1682. localApic->Flags
  1683. );
  1684. if (localApic->Flags & PLAF_ENABLED) {
  1685. dprintf(" Processor is Enabled\n");
  1686. }
  1687. if (localApic->Length != PROCESSOR_LOCAL_APIC_LENGTH) {
  1688. dprintf(
  1689. " Local Apic has length 0x%x instead of 0x%x\n",
  1690. localApic->Length,
  1691. PROCESSOR_LOCAL_APIC_LENGTH
  1692. );
  1693. break;
  1694. }
  1695. } else if (ioApic->Type == IO_APIC) {
  1696. buffer += ioApic->Length;
  1697. dprintf(
  1698. " IO Apic\n"
  1699. " IO APIC ID: 0x%02x\n"
  1700. " IO APIC ADDRESS: 0x%08lx\n"
  1701. " System Vector Base: 0x%08lx\n",
  1702. ioApic->IOAPICID,
  1703. ioApic->IOAPICAddress,
  1704. ioApic->SystemVectorBase
  1705. );
  1706. if (ioApic->Length != IO_APIC_LENGTH) {
  1707. dprintf(
  1708. " IO Apic has length 0x%x instead of 0x%x\n",
  1709. ioApic->Length,
  1710. IO_APIC_LENGTH
  1711. );
  1712. break;
  1713. }
  1714. } else if (interruptSourceOverride->Type == ISA_VECTOR_OVERRIDE) {
  1715. buffer += interruptSourceOverride->Length;
  1716. dprintf(
  1717. " Interrupt Source Override\n"
  1718. " Bus: 0x%02x\n"
  1719. " Source: 0x%02x\n"
  1720. " Global Interrupt: 0x%08lx\n"
  1721. " Flags: 0x%04x\n",
  1722. interruptSourceOverride->Bus,
  1723. interruptSourceOverride->Source,
  1724. interruptSourceOverride->GlobalSystemInterruptVector,
  1725. interruptSourceOverride->Flags
  1726. );
  1727. if (interruptSourceOverride->Length != ISA_VECTOR_OVERRIDE_LENGTH) {
  1728. dprintf(
  1729. " Interrupt Source Override has length 0x%x instead of 0x%x\n",
  1730. interruptSourceOverride->Length,
  1731. ISA_VECTOR_OVERRIDE_LENGTH
  1732. );
  1733. break;
  1734. }
  1735. hasMPSFlags = TRUE;
  1736. flags = interruptSourceOverride->Flags;
  1737. } else if (nmiSource->Type == IO_NMI_SOURCE) {
  1738. buffer += nmiSource->Length;
  1739. dprintf(
  1740. " Non Maskable Interrupt Source - on I/O APIC\n"
  1741. " Flags: 0x%02x\n"
  1742. " Global Interrupt: 0x%08lx\n",
  1743. nmiSource->Flags,
  1744. nmiSource->GlobalSystemInterruptVector
  1745. );
  1746. if (nmiSource->Length != IO_NMI_SOURCE_LENGTH) {
  1747. dprintf(
  1748. " Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
  1749. nmiSource->Length,
  1750. IO_NMI_SOURCE_LENGTH
  1751. );
  1752. break;
  1753. }
  1754. hasMPSFlags = TRUE;
  1755. flags = nmiSource->Flags;
  1756. } else if (localNmiSource->Type == LOCAL_NMI_SOURCE) {
  1757. buffer += localNmiSource->Length;
  1758. dprintf(
  1759. " Non Maskable Interrupt Source - local to processor\n"
  1760. " Flags: 0x%04x\n"
  1761. " Processor: 0x%02x %s\n"
  1762. " LINTIN: 0x%02x\n",
  1763. localNmiSource->Flags,
  1764. localNmiSource->ProcessorID,
  1765. localNmiSource->ProcessorID == 0xff ? "(all)" : "",
  1766. localNmiSource->LINTIN
  1767. );
  1768. if (localNmiSource->Length != LOCAL_NMI_SOURCE_LENGTH) {
  1769. dprintf(
  1770. " Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
  1771. localNmiSource->Length,
  1772. IO_NMI_SOURCE_LENGTH
  1773. );
  1774. break;
  1775. }
  1776. hasMPSFlags = TRUE;
  1777. flags = localNmiSource->Flags;
  1778. } else {
  1779. dprintf(" UNKOWN RECORD\n");
  1780. dprintf(" Length: 0x%8lx\n", ioApic->Length );
  1781. buffer += ioApic->Length;
  1782. }
  1783. //
  1784. // Do we have any flags to dump out?
  1785. //
  1786. if (hasMPSFlags) {
  1787. switch (flags & PO_BITS) {
  1788. case POLARITY_HIGH:
  1789. dprintf(" POLARITY_HIGH\n");
  1790. break;
  1791. case POLARITY_LOW:
  1792. dprintf(" POLARITY_LOW\n");
  1793. break;
  1794. case POLARITY_CONFORMS_WITH_BUS:
  1795. dprintf(" POLARITY_CONFORMS_WITH_BUS\n");
  1796. break;
  1797. default:
  1798. dprintf(" POLARITY_UNKNOWN\n");
  1799. break;
  1800. }
  1801. switch (flags & EL_BITS) {
  1802. case EL_EDGE_TRIGGERED:
  1803. dprintf(" EL_EDGE_TRIGGERED\n");
  1804. break;
  1805. case EL_LEVEL_TRIGGERED:
  1806. dprintf(" EL_LEVEL_TRIGGERED\n");
  1807. break;
  1808. case EL_CONFORMS_WITH_BUS:
  1809. dprintf(" EL_CONFORMS_WITH_BUS\n");
  1810. break;
  1811. default:
  1812. dprintf(" EL_UNKNOWN\n");
  1813. break;
  1814. }
  1815. }
  1816. }
  1817. LocalFree( mapic );
  1818. return;
  1819. }
  1820. VOID
  1821. dumpRSDT(
  1822. IN ULONG_PTR Address
  1823. )
  1824. /*++
  1825. Routine Description:
  1826. This search the dumps the RSDT table
  1827. Arguments:
  1828. Pointer to the table
  1829. Return Value:
  1830. NONE
  1831. --*/
  1832. {
  1833. BOOL status;
  1834. BOOL virtualMemory = FALSE;
  1835. DESCRIPTION_HEADER rsdtHeader;
  1836. PRSDT rsdt;
  1837. ULONG index;
  1838. ULONG numEntries;
  1839. ULONG returnLength;
  1840. dprintf("RSDT - ");
  1841. //
  1842. // Determine if we have virtual or physical memory
  1843. //
  1844. for (index = 0; index < 2; index++) {
  1845. status = ReadPhysicalOrVirtual(
  1846. Address,
  1847. &rsdtHeader,
  1848. sizeof(DESCRIPTION_HEADER),
  1849. &returnLength,
  1850. (BOOL) index
  1851. );
  1852. if (!status || rsdtHeader.Signature != RSDT_SIGNATURE) {
  1853. continue;
  1854. } else {
  1855. break;
  1856. }
  1857. }
  1858. //
  1859. // This will set the policy for the rest of the operation
  1860. //
  1861. switch (index) {
  1862. case 0:
  1863. virtualMemory = FALSE;
  1864. break;
  1865. case 1:
  1866. virtualMemory = TRUE;
  1867. break;
  1868. default:
  1869. if (!status) {
  1870. dprintf(
  1871. "dumpRSDT: Could only read 0x%08lx of 0x%08lx bytes\n",
  1872. returnLength,
  1873. sizeof(DESCRIPTION_HEADER)
  1874. );
  1875. } else {
  1876. dprintf(
  1877. "dumpRSDT: Invalid Signature 0x%08lx != RSDT_SIGNATURE\n",
  1878. rsdtHeader.Signature
  1879. );
  1880. dumpHeader( Address, &rsdtHeader, TRUE );
  1881. }
  1882. return;
  1883. } // switch
  1884. //
  1885. // Do we have a correctly sized data structure
  1886. //
  1887. rsdt = LocalAlloc( LPTR, rsdtHeader.Length );
  1888. if (rsdt == NULL) {
  1889. dprintf(
  1890. "dumpRSDT: Could not allocate %#08lx bytes\n",
  1891. Address,
  1892. rsdtHeader.Length
  1893. );
  1894. dumpHeader( Address, &rsdtHeader, TRUE );
  1895. return;
  1896. }
  1897. //
  1898. // Read the data
  1899. //
  1900. status = ReadPhysicalOrVirtual(
  1901. Address,
  1902. rsdt,
  1903. rsdtHeader.Length,
  1904. &returnLength,
  1905. virtualMemory
  1906. );
  1907. if (!status) {
  1908. dprintf(
  1909. "dumpRSDT: Read %#08lx of %#08lx bytes\n",
  1910. Address,
  1911. returnLength,
  1912. rsdtHeader.Length
  1913. );
  1914. dumpHeader( Address, &rsdtHeader, TRUE );
  1915. LocalFree( rsdt );
  1916. return;
  1917. } else if (rsdt->Header.Signature != RSDT_SIGNATURE) {
  1918. dprintf(
  1919. "dumpRSDT: Signature (%#08lx) != RSDT_SIGNATURE (%#08lx)\n",
  1920. Address,
  1921. rsdt->Header.Signature,
  1922. RSDT_SIGNATURE
  1923. );
  1924. dumpHeader( Address, &rsdtHeader, TRUE );
  1925. LocalFree( rsdt );
  1926. return;
  1927. }
  1928. //
  1929. // At this point, we are confident that everything worked
  1930. //
  1931. dumpHeader( Address, &(rsdt->Header), TRUE );
  1932. dprintf("RSDT - BODY - %#08lx\n", Address + sizeof(DESCRIPTION_HEADER) );
  1933. numEntries = ( rsdt->Header.Length - sizeof(DESCRIPTION_HEADER) ) /
  1934. sizeof(rsdt->Tables[0]);
  1935. for (index = 0; index < numEntries; index++) {
  1936. //
  1937. // Note: unless things radically change, the pointers in the
  1938. // rsdt will always point to bios memory!
  1939. //
  1940. status = ReadPhysicalOrVirtual(
  1941. rsdt->Tables[index],
  1942. &rsdtHeader,
  1943. sizeof(DESCRIPTION_HEADER),
  1944. &returnLength,
  1945. FALSE
  1946. );
  1947. if (!status || returnLength != sizeof(DESCRIPTION_HEADER)) {
  1948. dprintf(
  1949. "dumpRSDT: [%d:0x%08lx] - Read %#08lx of %#08lx bytes\n",
  1950. index,
  1951. rsdt->Tables[index],
  1952. returnLength,
  1953. sizeof(DESCRIPTION_HEADER)
  1954. );
  1955. continue;
  1956. }
  1957. dumpHeader( rsdt->Tables[index], &rsdtHeader, FALSE );
  1958. }
  1959. LocalFree( rsdt );
  1960. return;
  1961. }
  1962. BOOLEAN
  1963. findRSDT(
  1964. IN PULONG_PTR Address
  1965. )
  1966. /*++
  1967. Routine Description:
  1968. This searchs the memory on the target system for the RSDT pointer
  1969. Arguments:
  1970. Address - Where to store the result
  1971. Return Value:
  1972. TRUE - If we found the RSDT
  1973. --*/
  1974. {
  1975. PHYSICAL_ADDRESS address = { 0L, 0L };
  1976. RSDP rsdp;
  1977. RSDT rsdt;
  1978. UCHAR index;
  1979. UCHAR sum;
  1980. ULONG limit;
  1981. ULONG returnLength;
  1982. ULONG start;
  1983. //
  1984. // Calculate the start and end of the search range
  1985. //
  1986. start = (ULONG) RSDP_SEARCH_RANGE_BEGIN;
  1987. limit = (ULONG) start + RSDP_SEARCH_RANGE_LENGTH - RSDP_SEARCH_INTERVAL;
  1988. dprintf( "Searching for RSDP.");
  1989. //
  1990. // Loop for a while
  1991. //
  1992. for (; start <= limit; start += RSDP_SEARCH_INTERVAL) {
  1993. if (start % (RSDP_SEARCH_INTERVAL * 100 ) == 0) {
  1994. dprintf(".");
  1995. }
  1996. //
  1997. // Read the data from the target
  1998. //
  1999. address.LowPart = start;
  2000. ReadPhysical( address.QuadPart, &rsdp, sizeof(RSDP), &returnLength);
  2001. if (returnLength != sizeof(RSDP)) {
  2002. dprintf(
  2003. "%#08lx: Read %#08lx of %#08lx bytes\n",
  2004. start,
  2005. returnLength,
  2006. sizeof(RSDP)
  2007. );
  2008. return FALSE;
  2009. }
  2010. //
  2011. // Is this a match?
  2012. //
  2013. if (rsdp.Signature != RSDP_SIGNATURE) {
  2014. continue;
  2015. }
  2016. //
  2017. // Check the checksum out
  2018. //
  2019. for (index = 0, sum = 0; index < sizeof(RSDP); index++) {
  2020. sum = (UCHAR) (sum + *( (UCHAR *) ( (ULONG_PTR) &rsdp + index ) ) );
  2021. }
  2022. if (sum != 0) {
  2023. continue;
  2024. }
  2025. //
  2026. // Found RSDP
  2027. //
  2028. dprintf("\nRSDP - %#08lx\n", start );
  2029. memset( Buffer, 0, 2048 );
  2030. memcpy( Buffer, &(rsdp.Signature), sizeof(ULONGLONG) );
  2031. dprintf(" Signature: %s\n", Buffer );
  2032. dprintf(" Checksum: %#03x\n", rsdp.Checksum );
  2033. memset( Buffer, 0, sizeof(ULONGLONG) );
  2034. memcpy( Buffer, rsdp.OEMID, 6 );
  2035. dprintf(" OEMID: %s\n", Buffer );
  2036. dprintf(" Reserved: %#03x\n", rsdp.Reserved );
  2037. dprintf(" RsdtAddress: %#08lx\n", rsdp.RsdtAddress );
  2038. //
  2039. // Done
  2040. //
  2041. *Address = rsdp.RsdtAddress;
  2042. return TRUE;
  2043. }
  2044. return FALSE;
  2045. }