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.

845 lines
23 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. resource.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. VOID
  17. dumpPnPResources(
  18. IN ULONG_PTR Address
  19. )
  20. /*++
  21. Routine Description:
  22. This routine processes the ACPI version of a PnP resource list given
  23. the address that it starts at
  24. Arguments:
  25. Address - The Starting address
  26. Return Value:
  27. NULL
  28. --*/
  29. {
  30. BOOL success;
  31. PUCHAR dataBuffer = NULL;
  32. UCHAR currentTag;
  33. ULONG_PTR currentAddress = Address;
  34. ULONG i;
  35. ULONG indentLevel = 0;
  36. ULONG returnLength;
  37. ULONG tagCount = 0;
  38. USHORT increment;
  39. //
  40. // repeat forever
  41. //
  42. while (1) {
  43. //
  44. // Allow a way to end this
  45. //
  46. if (CheckControlC()) {
  47. break;
  48. }
  49. //
  50. // Read the current tag
  51. //
  52. success = ReadMemory(
  53. currentAddress,
  54. &currentTag,
  55. sizeof(UCHAR),
  56. &returnLength
  57. );
  58. if (!success || returnLength != sizeof(UCHAR)) {
  59. dprintf(
  60. "dumpPnPResources: could not read tag at 0x%08lx\n",
  61. currentAddress
  62. );
  63. return;
  64. }
  65. //
  66. // Determine what we are looking at
  67. //
  68. if ( !(currentTag & LARGE_RESOURCE_TAG)) {
  69. //
  70. // We are looking at a small tag
  71. //
  72. increment = (USHORT) (currentTag & SMALL_TAG_SIZE_MASK) + 1;
  73. currentTag &= SMALL_TAG_MASK;
  74. } else {
  75. //
  76. // We are looking at a large Tag. We must read the length as
  77. // the next short in memory
  78. //
  79. success = ReadMemory(
  80. currentAddress + 1,
  81. &increment,
  82. sizeof(USHORT),
  83. &returnLength
  84. );
  85. if (!success || returnLength != sizeof(USHORT)) {
  86. dprintf(
  87. "dumpPnPResources: could not read increment at 0x%08lx\n",
  88. currentAddress + 1
  89. );
  90. break;
  91. }
  92. //
  93. // Account for the increment
  94. //
  95. increment += 3;
  96. }
  97. //
  98. // Allocate space for the buffer
  99. //
  100. if (increment > 1) {
  101. dataBuffer = LocalAlloc( LPTR, increment);
  102. if (dataBuffer == NULL) {
  103. dprintf(
  104. "dumpPnPResources: could not allocate 0x%x bytes\n",
  105. (increment - 1)
  106. );
  107. }
  108. //
  109. // Read the data into the buffer
  110. //
  111. success = ReadMemory(
  112. currentAddress,
  113. dataBuffer,
  114. increment,
  115. &returnLength
  116. );
  117. if (!success || returnLength != (ULONG) increment) {
  118. dprintf(
  119. "dumpPnPResources: read buffer at 0x%08lx (0x%x)\n",
  120. currentAddress,
  121. increment
  122. );
  123. LocalFree( dataBuffer );
  124. return;
  125. }
  126. }
  127. //
  128. // Indent the tag
  129. //
  130. for (i = 0; i < indentLevel; i++) {
  131. dprintf("| ");
  132. }
  133. //
  134. // What tag are we looking at
  135. //
  136. switch (currentTag) {
  137. case TAG_IRQ: {
  138. PPNP_IRQ_DESCRIPTOR res = (PPNP_IRQ_DESCRIPTOR) dataBuffer;
  139. USHORT mask = res->IrqMask;
  140. USHORT interrupt = 0;
  141. dprintf("%d - TAG_IRQ -", tagCount );
  142. for( ;mask; interrupt++, mask >>= 1) {
  143. if (mask & 1) {
  144. dprintf(" %d", interrupt );
  145. }
  146. }
  147. if ( (res->Tag & SMALL_TAG_SIZE_MASK) == 3) {
  148. if (res->Information & PNP_IRQ_LATCHED) {
  149. dprintf(" Lat");
  150. }
  151. if (res->Information & PNP_IRQ_LEVEL) {
  152. dprintf(" Lvl");
  153. }
  154. if (res->Information & PNP_IRQ_SHARED) {
  155. dprintf(" Shr");
  156. } else {
  157. dprintf(" Exc");
  158. }
  159. } else {
  160. dprintf(" Edg Sha");
  161. }
  162. dprintf("\n");
  163. break;
  164. }
  165. case TAG_EXTENDED_IRQ: {
  166. PPNP_EXTENDED_IRQ_DESCRIPTOR res =
  167. (PPNP_EXTENDED_IRQ_DESCRIPTOR) dataBuffer;
  168. UCHAR tableCount = 0;
  169. UCHAR tableSize = res->TableSize;
  170. dprintf("%d - TAG_EXTENDED_IRQ -", tagCount );
  171. for (; tableCount < tableSize; tableCount++) {
  172. dprintf(" %d", res->Table[tableCount] );
  173. }
  174. if (res->Flags & PNP_EXTENDED_IRQ_MODE) {
  175. dprintf(" Lat");
  176. }
  177. if (res->Flags & PNP_EXTENDED_IRQ_POLARITY ) {
  178. dprintf(" Edg");
  179. }
  180. if (res->Flags & PNP_EXTENDED_IRQ_SHARED) {
  181. dprintf(" Shr");
  182. } else {
  183. dprintf(" Exc");
  184. }
  185. if (res->Flags & PNP_EXTENDED_IRQ_RESOURCE_CONSUMER_ONLY) {
  186. dprintf(" Con");
  187. } else {
  188. dprintf(" Prod Con");
  189. }
  190. dprintf("\n");
  191. break;
  192. }
  193. case TAG_DMA: {
  194. PPNP_DMA_DESCRIPTOR res = (PPNP_DMA_DESCRIPTOR) dataBuffer;
  195. UCHAR channel = 0;
  196. UCHAR mask = res->ChannelMask;
  197. dprintf("%d - TAG_DMA -", tagCount );
  198. for (; mask; channel++, mask >>= 1) {
  199. if (mask & 1) {
  200. dprintf(" %d", channel);
  201. }
  202. }
  203. switch( (res->Flags & PNP_DMA_SIZE_MASK) ) {
  204. case PNP_DMA_SIZE_8:
  205. dprintf(" 8bit");
  206. break;
  207. case PNP_DMA_SIZE_8_AND_16:
  208. dprintf(" 8-16bit");
  209. break;
  210. case PNP_DMA_SIZE_16:
  211. dprintf(" 16bit");
  212. break;
  213. case PNP_DMA_SIZE_RESERVED:
  214. default:
  215. dprintf(" ??bit");
  216. break;
  217. }
  218. if (res->Flags & PNP_DMA_BUS_MASTER) {
  219. dprintf(" BM");
  220. }
  221. switch( (res->Flags & PNP_DMA_TYPE_MASK) ) {
  222. default:
  223. case PNP_DMA_TYPE_COMPATIBLE:
  224. dprintf(" Com");
  225. break;
  226. case PNP_DMA_TYPE_A:
  227. dprintf(" A");
  228. break;
  229. case PNP_DMA_TYPE_B:
  230. dprintf(" B");
  231. break;
  232. case PNP_DMA_TYPE_F:
  233. dprintf(" F");
  234. }
  235. dprintf("\n");
  236. break;
  237. }
  238. case TAG_START_DEPEND:
  239. indentLevel++;
  240. dprintf("%d - TAG_START_DEPEND\n", tagCount);
  241. break;
  242. case TAG_END_DEPEND:
  243. indentLevel = 0;
  244. dprintf("%d - TAG_END_DEPEND\n", tagCount);
  245. break;
  246. case TAG_IO: {
  247. PPNP_PORT_DESCRIPTOR res = (PPNP_PORT_DESCRIPTOR) dataBuffer;
  248. dprintf(
  249. "%d - TAG_IO - 0x%x-0x%x A:0x%x L:0x%x",
  250. tagCount,
  251. res->MinimumAddress,
  252. res->MaximumAddress,
  253. res->Alignment,
  254. res->Length
  255. );
  256. switch (res->Information & PNP_PORT_DECODE_MASK) {
  257. default:
  258. case PNP_PORT_10_BIT_DECODE:
  259. dprintf(" 10bit");
  260. break;
  261. case PNP_PORT_16_BIT_DECODE:
  262. dprintf(" 16bit");
  263. break;
  264. }
  265. dprintf("\n");
  266. break;
  267. }
  268. case TAG_IO_FIXED: {
  269. PPNP_FIXED_PORT_DESCRIPTOR res =
  270. (PPNP_FIXED_PORT_DESCRIPTOR) dataBuffer;
  271. dprintf(
  272. "%d - TAG_FIXED_IO - 0x%x L:0x%x\n",
  273. tagCount,
  274. res->MinimumAddress,
  275. res->Length
  276. );
  277. break;
  278. }
  279. case TAG_MEMORY: {
  280. PPNP_MEMORY_DESCRIPTOR res =
  281. (PPNP_MEMORY_DESCRIPTOR) dataBuffer;
  282. dprintf(
  283. "%d - TAG_MEMORY24 - 0x%x-0x%x A:0x%x L:0x%x",
  284. tagCount,
  285. res->MinimumAddress,
  286. res->MaximumAddress,
  287. res->Alignment,
  288. res->MemorySize
  289. );
  290. if (res->Information & PNP_MEMORY_READ_WRITE) {
  291. dprintf(" RW");
  292. } else {
  293. dprintf(" R");
  294. }
  295. break;
  296. }
  297. case TAG_MEMORY32: {
  298. PPNP_MEMORY32_DESCRIPTOR res =
  299. (PPNP_MEMORY32_DESCRIPTOR) dataBuffer;
  300. dprintf(
  301. "%d - TAG_MEMORY32 - 0x%x-0x%x A:0x%x L:0x%x",
  302. tagCount,
  303. res->MinimumAddress,
  304. res->MaximumAddress,
  305. res->Alignment,
  306. res->MemorySize
  307. );
  308. if (res->Information & PNP_MEMORY_READ_WRITE) {
  309. dprintf(" RW");
  310. } else {
  311. dprintf(" R");
  312. }
  313. break;
  314. }
  315. case TAG_MEMORY32_FIXED: {
  316. PPNP_FIXED_MEMORY32_DESCRIPTOR res =
  317. (PPNP_FIXED_MEMORY32_DESCRIPTOR) dataBuffer;
  318. dprintf(
  319. "%d - TAG_FIXED_MEMORY32 - 0x%x L:0x%x",
  320. tagCount,
  321. res->BaseAddress,
  322. res->MemorySize
  323. );
  324. if (res->Information & PNP_MEMORY_READ_WRITE) {
  325. dprintf(" RW");
  326. } else {
  327. dprintf(" R");
  328. }
  329. break;
  330. }
  331. case TAG_WORD_ADDRESS: {
  332. PPNP_WORD_ADDRESS_DESCRIPTOR res =
  333. (PPNP_WORD_ADDRESS_DESCRIPTOR) dataBuffer;
  334. dprintf("%d - TAG_WORD_ADDRESS -", tagCount);
  335. switch (res->RFlag) {
  336. case 0:
  337. //
  338. // Memory range
  339. //
  340. dprintf(
  341. "Mem 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  342. res->MinimumAddress,
  343. res->MaximumAddress,
  344. res->Granularity,
  345. res->TranslationAddress,
  346. res->AddressLength
  347. );
  348. if (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_READ_WRITE) {
  349. dprintf(" RW");
  350. } else {
  351. dprintf(" R");
  352. }
  353. switch (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_MASK) {
  354. default:
  355. case PNP_ADDRESS_TYPE_MEMORY_NONCACHEABLE:
  356. dprintf(" NC");
  357. break;
  358. case PNP_ADDRESS_TYPE_MEMORY_CACHEABLE:
  359. dprintf(" C");
  360. break;
  361. case PNP_ADDRESS_TYPE_MEMORY_WRITE_COMBINE:
  362. dprintf(" WC");
  363. break;
  364. case PNP_ADDRESS_TYPE_MEMORY_PREFETCHABLE:
  365. dprintf(" PC");
  366. break;
  367. }
  368. break;
  369. case 1:
  370. //
  371. // IO range
  372. //
  373. dprintf(
  374. "IO 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  375. res->MinimumAddress,
  376. res->MaximumAddress,
  377. res->Granularity,
  378. res->TranslationAddress,
  379. res->AddressLength
  380. );
  381. if (res->TFlag & PNP_ADDRESS_TYPE_IO_ISA_RANGE) {
  382. dprintf(" ISA");
  383. }
  384. if (res->TFlag & PNP_ADDRESS_TYPE_IO_NON_ISA_RANGE) {
  385. dprintf(" Non-ISA");
  386. }
  387. break;
  388. case 2:
  389. dprintf(
  390. "Bus 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  391. res->MinimumAddress,
  392. res->MaximumAddress,
  393. res->Granularity,
  394. res->TranslationAddress,
  395. res->AddressLength
  396. );
  397. break;
  398. } // switch( buffer->RFlag )
  399. //
  400. // Global Flags
  401. //
  402. if (res->GFlag & PNP_ADDRESS_FLAG_CONSUMED_ONLY) {
  403. dprintf(" Consumed");
  404. }
  405. if (res->GFlag & PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE) {
  406. dprintf(" Subtractive");
  407. }
  408. if (res->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED) {
  409. dprintf(" MinFixed");
  410. }
  411. if (res->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {
  412. dprintf(" MaxFixed");
  413. }
  414. if (increment > sizeof(PNP_WORD_ADDRESS_DESCRIPTOR) + 1) {
  415. dprintf(
  416. " %d<-%s",
  417. dataBuffer[sizeof(PNP_WORD_ADDRESS_DESCRIPTOR)],
  418. &(dataBuffer[sizeof(PNP_WORD_ADDRESS_DESCRIPTOR)+1])
  419. );
  420. }
  421. dprintf("\n");
  422. break;
  423. }
  424. case TAG_DOUBLE_ADDRESS: {
  425. PPNP_DWORD_ADDRESS_DESCRIPTOR res =
  426. (PPNP_DWORD_ADDRESS_DESCRIPTOR) dataBuffer;
  427. dprintf("%d - TAG_DWORD_ADDRESS -", tagCount);
  428. switch (res->RFlag) {
  429. case 0:
  430. //
  431. // Memory range
  432. //
  433. dprintf(
  434. "Mem 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  435. res->MinimumAddress,
  436. res->MaximumAddress,
  437. res->Granularity,
  438. res->TranslationAddress,
  439. res->AddressLength
  440. );
  441. if (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_READ_WRITE) {
  442. dprintf(" RW");
  443. } else {
  444. dprintf(" R");
  445. }
  446. switch (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_MASK) {
  447. default:
  448. case PNP_ADDRESS_TYPE_MEMORY_NONCACHEABLE:
  449. dprintf(" NC");
  450. break;
  451. case PNP_ADDRESS_TYPE_MEMORY_CACHEABLE:
  452. dprintf(" C");
  453. break;
  454. case PNP_ADDRESS_TYPE_MEMORY_WRITE_COMBINE:
  455. dprintf(" WC");
  456. break;
  457. case PNP_ADDRESS_TYPE_MEMORY_PREFETCHABLE:
  458. dprintf(" PC");
  459. break;
  460. }
  461. break;
  462. case 1:
  463. //
  464. // IO range
  465. //
  466. dprintf(
  467. "IO 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  468. res->MinimumAddress,
  469. res->MaximumAddress,
  470. res->Granularity,
  471. res->TranslationAddress,
  472. res->AddressLength
  473. );
  474. if (res->TFlag & PNP_ADDRESS_TYPE_IO_ISA_RANGE) {
  475. dprintf(" ISA");
  476. }
  477. if (res->TFlag & PNP_ADDRESS_TYPE_IO_NON_ISA_RANGE) {
  478. dprintf(" Non-ISA");
  479. }
  480. break;
  481. case 2:
  482. dprintf(
  483. "Bus 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  484. res->MinimumAddress,
  485. res->MaximumAddress,
  486. res->Granularity,
  487. res->TranslationAddress,
  488. res->AddressLength
  489. );
  490. break;
  491. } // switch( buffer->RFlag )
  492. //
  493. // Global Flags
  494. //
  495. if (res->GFlag & PNP_ADDRESS_FLAG_CONSUMED_ONLY) {
  496. dprintf(" Consumed");
  497. }
  498. if (res->GFlag & PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE) {
  499. dprintf(" Subtractive");
  500. }
  501. if (res->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED) {
  502. dprintf(" MinFixed");
  503. }
  504. if (res->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {
  505. dprintf(" MaxFixed");
  506. }
  507. if (increment > sizeof(PNP_DWORD_ADDRESS_DESCRIPTOR) + 1) {
  508. dprintf(
  509. " %d<-%s",
  510. (UCHAR) dataBuffer[sizeof(PNP_DWORD_ADDRESS_DESCRIPTOR)],
  511. &(dataBuffer[sizeof(PNP_DWORD_ADDRESS_DESCRIPTOR)+1])
  512. );
  513. }
  514. dprintf("\n");
  515. break;
  516. }
  517. case TAG_QUAD_ADDRESS: {
  518. PPNP_QWORD_ADDRESS_DESCRIPTOR res =
  519. (PPNP_QWORD_ADDRESS_DESCRIPTOR) dataBuffer;
  520. dprintf("%d - TAG_QWORD_ADDRESS -", tagCount);
  521. switch (res->RFlag) {
  522. case 0:
  523. //
  524. // Memory range
  525. //
  526. dprintf(
  527. "Mem 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  528. res->MinimumAddress,
  529. res->MaximumAddress,
  530. res->Granularity,
  531. res->TranslationAddress,
  532. res->AddressLength
  533. );
  534. if (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_READ_WRITE) {
  535. dprintf(" RW");
  536. } else {
  537. dprintf(" R");
  538. }
  539. switch (res->TFlag & PNP_ADDRESS_TYPE_MEMORY_MASK) {
  540. default:
  541. case PNP_ADDRESS_TYPE_MEMORY_NONCACHEABLE:
  542. dprintf(" NC");
  543. break;
  544. case PNP_ADDRESS_TYPE_MEMORY_CACHEABLE:
  545. dprintf(" C");
  546. break;
  547. case PNP_ADDRESS_TYPE_MEMORY_WRITE_COMBINE:
  548. dprintf(" WC");
  549. break;
  550. case PNP_ADDRESS_TYPE_MEMORY_PREFETCHABLE:
  551. dprintf(" PC");
  552. break;
  553. }
  554. break;
  555. case 1:
  556. //
  557. // IO range
  558. //
  559. dprintf(
  560. "IO 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  561. res->MinimumAddress,
  562. res->MaximumAddress,
  563. res->Granularity,
  564. res->TranslationAddress,
  565. res->AddressLength
  566. );
  567. if (res->TFlag & PNP_ADDRESS_TYPE_IO_ISA_RANGE) {
  568. dprintf(" ISA");
  569. }
  570. if (res->TFlag & PNP_ADDRESS_TYPE_IO_NON_ISA_RANGE) {
  571. dprintf(" Non-ISA");
  572. }
  573. break;
  574. case 2:
  575. dprintf(
  576. "Bus 0x%x-0x%x A:0x%x T:0x%x L:0x%x",
  577. res->MinimumAddress,
  578. res->MaximumAddress,
  579. res->Granularity,
  580. res->TranslationAddress,
  581. res->AddressLength
  582. );
  583. break;
  584. } // switch( buffer->RFlag )
  585. //
  586. // Global Flags
  587. //
  588. if (res->GFlag & PNP_ADDRESS_FLAG_CONSUMED_ONLY) {
  589. dprintf(" Consumed");
  590. }
  591. if (res->GFlag & PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE) {
  592. dprintf(" Subtractive");
  593. }
  594. if (res->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED) {
  595. dprintf(" MinFixed");
  596. }
  597. if (res->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {
  598. dprintf(" MaxFixed");
  599. }
  600. if (increment > sizeof(PNP_QWORD_ADDRESS_DESCRIPTOR) + 1) {
  601. dprintf(
  602. " %d<-%s",
  603. (UCHAR) dataBuffer[sizeof(PNP_QWORD_ADDRESS_DESCRIPTOR)],
  604. &(dataBuffer[sizeof(PNP_QWORD_ADDRESS_DESCRIPTOR)+1])
  605. );
  606. }
  607. dprintf("\n");
  608. break;
  609. }
  610. case TAG_END:
  611. dprintf("%d - TAG_END\n", tagCount);
  612. if (dataBuffer) {
  613. LocalFree(dataBuffer );
  614. }
  615. return;
  616. default:
  617. dprintf("%d - TAG_UNKNOWN %d\n", tagCount, currentTag );
  618. break;
  619. } // switch
  620. //
  621. // Free the buffer if it was allocated
  622. //
  623. if (dataBuffer != NULL) {
  624. LocalFree( dataBuffer );
  625. dataBuffer = NULL;
  626. }
  627. //
  628. // Update the current address and tag number
  629. //
  630. tagCount++;
  631. currentAddress += increment;
  632. } // while
  633. }