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.

300 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. pic.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Santosh Jodh (santoshj) 29-June-1998
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #define PIC_MASTER_PORT0 0x20
  16. #define PIC_MASTER_PORT1 0x21
  17. #define PIC_SLAVE_PORT0 0xA0
  18. #define PIC_SLAVE_PORT1 0xA1
  19. #define ELCR_PORT0 0x4D0
  20. #define ELCR_PORT1 0x4D1
  21. VOID
  22. ShowMask (
  23. ULONG Mask
  24. )
  25. {
  26. ULONG interrupt;
  27. for ( interrupt = 0;
  28. interrupt <= 0x0F;
  29. interrupt++)
  30. {
  31. if (Mask & (1 << interrupt))
  32. dprintf(" Y");
  33. else
  34. dprintf(" .");
  35. }
  36. dprintf("\n");
  37. }
  38. BOOLEAN
  39. GetPICStatus (
  40. UCHAR Type,
  41. PULONG Status
  42. )
  43. {
  44. ULONG size;
  45. ULONG data;
  46. ULONG mask;
  47. //
  48. // Send OCW3 to master.
  49. //
  50. size = 1;
  51. WriteIoSpace64(PIC_MASTER_PORT0, Type, &size);
  52. //
  53. // Read master's status.
  54. //
  55. data = 0;
  56. size = 1;
  57. ReadIoSpace64(PIC_MASTER_PORT0, &data, &size);
  58. if (size == 1)
  59. {
  60. //
  61. // Send OCW3 to slave.
  62. //
  63. mask = data;
  64. size = 1;
  65. WriteIoSpace64(PIC_SLAVE_PORT0, Type, &size);
  66. //
  67. // Get the slave's status.
  68. //
  69. data = 0;
  70. size = 1;
  71. ReadIoSpace64(PIC_SLAVE_PORT0, &data, &size);
  72. if (size == 1)
  73. {
  74. mask |= (data << 8);
  75. *Status = mask;
  76. return (TRUE);
  77. }
  78. }
  79. *Status = 0;
  80. return (FALSE);
  81. }
  82. BOOLEAN
  83. GetELCRStatus(
  84. OUT PULONG Status
  85. )
  86. {
  87. ULONG data = 0;
  88. ULONG size = 1;
  89. ULONG mask = 0;
  90. *Status = 0;
  91. ReadIoSpace64(ELCR_PORT0, &data, &size);
  92. if (size == 1) {
  93. mask = data;
  94. ReadIoSpace64(ELCR_PORT1, &data, &size);
  95. if (size == 1) {
  96. mask |= (data << 8);
  97. *Status = mask;
  98. return TRUE;
  99. }
  100. }
  101. return FALSE;
  102. }
  103. DECLARE_API(pic)
  104. /*++
  105. Routine Description:
  106. Dumps PIC information.
  107. Input Parameters:
  108. args - Supplies the options.
  109. Return Value:
  110. None
  111. --*/
  112. {
  113. ULONG data;
  114. ULONG size;
  115. ULONG mask;
  116. ULONG64 addr;
  117. UCHAR halName[32];
  118. BOOL dumpElcr=FALSE;
  119. // X86_ONLY_API
  120. if (TargetMachine != IMAGE_FILE_MACHINE_I386) {
  121. dprintf("!pic is for X86 targets only.\n");
  122. return E_INVALIDARG;
  123. }
  124. if (strcmp(args, "-e")==0) {
  125. //
  126. // Here we trust that the user knows this machine architecture
  127. // such that the ELCR exists at these ports.
  128. //
  129. dumpElcr = TRUE;
  130. }else{
  131. //
  132. // Now lets see what HAL we are running. Currently
  133. // we can only dump the ELCR mask safely on ACPI (non-apic) machines
  134. // as ACPI has defined static ports for this.
  135. //
  136. addr = GetExpression("hal!HalName");
  137. if (addr == 0) {
  138. dprintf("Unable to use HAL symbols (hal!HalName), please verify symbols.\n");
  139. return E_INVALIDARG;
  140. }
  141. if (!xReadMemory(addr, &halName, sizeof(halName))) {
  142. dprintf("Failed to read HalName from host memory, quitting.\n");
  143. return E_INVALIDARG;
  144. }
  145. halName[sizeof(halName)-1] = '\0';
  146. if (strcmp(halName, "ACPI Compatible Eisa/Isa HAL")==0) {
  147. dumpElcr = TRUE;
  148. }
  149. }
  150. //
  151. // Display the title.
  152. //
  153. dprintf("----- IRQ Number ----- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
  154. //
  155. // Dump the Interrupt Service Register information.
  156. //
  157. dprintf("Physically in service:");
  158. if (GetPICStatus(0x0B, &mask))
  159. {
  160. ShowMask(mask);
  161. }
  162. else
  163. {
  164. dprintf("Error reading PIC!\n");
  165. }
  166. //
  167. // Dump the Interrupt Mask Register information.
  168. //
  169. dprintf("Physically masked: ");
  170. data = 0;
  171. size = 1;
  172. ReadIoSpace64(PIC_MASTER_PORT1, &data, &size);
  173. if (size == 1)
  174. {
  175. mask = data;
  176. data = 0;
  177. size = 1;
  178. ReadIoSpace64(PIC_SLAVE_PORT1, &data, &size);
  179. if (size == 1)
  180. {
  181. mask |= (data << 8);
  182. ShowMask(mask);
  183. }
  184. else
  185. {
  186. dprintf("Error reading PIC!\n");
  187. }
  188. }
  189. else
  190. {
  191. dprintf("Error reading PIC!\n");
  192. }
  193. //
  194. // Dump the Interrupt Request Register information.
  195. //
  196. dprintf("Physically requested: ");
  197. if (GetPICStatus(0x0A, &mask))
  198. {
  199. ShowMask(mask);
  200. }
  201. else
  202. {
  203. dprintf("Error reading PIC!\n");
  204. }
  205. if (dumpElcr) {
  206. //
  207. // Dump the Edge/Level Control Register information.
  208. //
  209. dprintf("Level Triggered: ");
  210. if (GetELCRStatus(&mask)) {
  211. ShowMask(mask);
  212. }else{
  213. dprintf("Error reading ELCR!\n");
  214. }
  215. }
  216. return S_OK;
  217. }