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.

460 lines
12 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: debug.c
  8. *
  9. * Debug helper routines.
  10. *
  11. * Copyright (c) 1992-1998 Microsoft Corporation
  12. *
  13. \**************************************************************************/
  14. #include "precomp.h"
  15. #if DBG
  16. ////////////////////////////////////////////////////////////////////////////
  17. // DEBUGGING INITIALIZATION CODE
  18. //
  19. // When you're bringing up your display for the first time, you can
  20. // recompile with 'DebugLevel' set to 100. That will cause absolutely
  21. // all DISPDBG messages to be displayed on the kernel debugger (this
  22. // is known as the "PrintF Approach to Debugging" and is about the only
  23. // viable method for debugging driver initialization code).
  24. LONG DebugLevel = 0; // Set to '100' to debug initialization code
  25. // (the default is '0')
  26. ////////////////////////////////////////////////////////////////////////////
  27. LONG gcFifo = 0; // Number of currently free FIFO entries
  28. BOOL gbCrtcCriticalSection = FALSE;
  29. // Have we acquired the CRTC register
  30. // critical section?
  31. #define LARGE_LOOP_COUNT 10000000
  32. ////////////////////////////////////////////////////////////////////////////
  33. // Miscellaneous Driver Debug Routines
  34. ////////////////////////////////////////////////////////////////////////////
  35. /*****************************************************************************
  36. *
  37. * Routine Description:
  38. *
  39. * This function is variable-argument, level-sensitive debug print
  40. * routine.
  41. * If the specified debug level for the print statement is lower or equal
  42. * to the current debug level, the message will be printed.
  43. *
  44. * Arguments:
  45. *
  46. * DebugPrintLevel - Specifies at which debugging level the string should
  47. * be printed
  48. *
  49. * DebugMessage - Variable argument ascii c string
  50. *
  51. * Return Value:
  52. *
  53. * None.
  54. *
  55. ***************************************************************************/
  56. VOID
  57. DebugPrint(
  58. LONG DebugPrintLevel,
  59. PCHAR DebugMessage,
  60. ...
  61. )
  62. {
  63. va_list ap;
  64. va_start(ap, DebugMessage);
  65. if (DebugPrintLevel <= DebugLevel)
  66. {
  67. EngDebugPrint(STANDARD_DEBUG_PREFIX, DebugMessage, ap);
  68. EngDebugPrint("", "\n", ap);
  69. }
  70. va_end(ap);
  71. } // DebugPrint()
  72. /******************************Public*Routine******************************\
  73. * VOID vCheckDataComplete
  74. \**************************************************************************/
  75. VOID vCheckDataReady(
  76. PDEV* ppdev)
  77. {
  78. ASSERTDD((IO_GP_STAT(ppdev) & HARDWARE_BUSY),
  79. "Not ready for data transfer.");
  80. }
  81. /******************************Public*Routine******************************\
  82. * VOID vCheckDataComplete
  83. \**************************************************************************/
  84. VOID vCheckDataComplete(
  85. PDEV* ppdev)
  86. {
  87. LONG i;
  88. // We loop because it may take a while for the hardware to finish
  89. // digesting all the data we transferred:
  90. for (i = LARGE_LOOP_COUNT; i > 0; i--)
  91. {
  92. if (!(IO_GP_STAT(ppdev) & HARDWARE_BUSY))
  93. return;
  94. }
  95. RIP("Data transfer not complete.");
  96. }
  97. /******************************Public*Routine******************************\
  98. * VOID vOutFifoW
  99. \**************************************************************************/
  100. VOID vOutFifoW(
  101. VOID* p,
  102. ULONG v)
  103. {
  104. gcFifo--;
  105. if (gcFifo < 0)
  106. {
  107. gcFifo = 0;
  108. RIP("Incorrect FIFO wait count");
  109. }
  110. WRITE_PORT_USHORT(p, (USHORT)v);
  111. }
  112. /******************************Public*Routine******************************\
  113. * VOID vOutFifoPseudoD
  114. \**************************************************************************/
  115. VOID vOutFifoPseudoD(
  116. PDEV* ppdev,
  117. VOID* p,
  118. ULONG v)
  119. {
  120. ULONG ulMiscState;
  121. ASSERTDD(!(ppdev->flCaps & CAPS_MM_IO),
  122. "No pseudo 32-bit writes when using memory-mapped I/O");
  123. ASSERTDD(ppdev->iBitmapFormat == BMF_32BPP,
  124. "We're trying to do 32bpp output while not in 32bpp mode");
  125. IO_GP_WAIT(ppdev); // Wait so we don't interfere with any
  126. // pending commands waiting on the
  127. // FIFO
  128. IO_READ_SEL(ppdev, 6); // We'll be reading index 0xE
  129. IO_GP_WAIT(ppdev); // Wait until that's processed
  130. IO_RD_REG_DT(ppdev, ulMiscState); // Read ulMiscState
  131. ASSERTDD((ulMiscState & 0x10) == 0,
  132. "Register select flag is out of sync");
  133. gcFifo -= 2;
  134. if (gcFifo < 0)
  135. {
  136. gcFifo = 0;
  137. RIP("Incorrect FIFO wait count");
  138. }
  139. OUT_PSEUDO_DWORD(p, v);
  140. }
  141. /******************************Public*Routine******************************\
  142. * VOID vWriteFifoW
  143. \**************************************************************************/
  144. VOID vWriteFifoW(
  145. VOID* p,
  146. ULONG v)
  147. {
  148. gcFifo--;
  149. if (gcFifo < 0)
  150. {
  151. gcFifo = 0;
  152. RIP("Incorrect FIFO wait count");
  153. }
  154. WRITE_REGISTER_USHORT(p, (USHORT) v);
  155. }
  156. /******************************Public*Routine******************************\
  157. * VOID vWriteFifoD
  158. \**************************************************************************/
  159. VOID vWriteFifoD(
  160. VOID* p,
  161. ULONG v)
  162. {
  163. gcFifo--;
  164. if (gcFifo < 0)
  165. {
  166. gcFifo = 0;
  167. RIP("Incorrect FIFO wait count");
  168. }
  169. WRITE_REGISTER_ULONG(p, v);
  170. }
  171. /******************************Public*Routine******************************\
  172. * VOID vIoFifoWait
  173. \**************************************************************************/
  174. VOID vIoFifoWait(
  175. PDEV* ppdev,
  176. LONG level)
  177. {
  178. LONG i;
  179. ASSERTDD((level > 0) && (level <= 8), "Illegal wait level");
  180. gcFifo = level;
  181. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  182. {
  183. if (!(IO_FIFO_BUSY(ppdev, level)))
  184. return;
  185. }
  186. RIP("vIoFifoWait timeout -- The hardware is in a funky state.");
  187. }
  188. /******************************Public*Routine******************************\
  189. * VOID vMmFifoWait
  190. \**************************************************************************/
  191. VOID vMmFifoWait(
  192. PDEV* ppdev,
  193. BYTE* pjMmBase,
  194. LONG level)
  195. {
  196. LONG i;
  197. // We only enabled MM I/O on the 864/964 and newer, so we can wait
  198. // for up to 13 FIFO slots:
  199. ASSERTDD((level > 0) && (level <= 13), "Illegal wait level");
  200. gcFifo = level;
  201. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  202. {
  203. if (!(MM_FIFO_BUSY(ppdev, pjMmBase, level)))
  204. return;
  205. }
  206. RIP("vMmFifoWait timeout -- The hardware is in a funky state.");
  207. }
  208. /******************************Public*Routine******************************\
  209. * VOID vNwFifoWait
  210. \**************************************************************************/
  211. VOID vNwFifoWait(
  212. PDEV* ppdev,
  213. BYTE* pjMmBase,
  214. LONG level)
  215. {
  216. LONG i;
  217. ASSERTDD((level > 0) && (level <= 13), "Illegal wait level");
  218. gcFifo = level;
  219. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  220. {
  221. if (!(NW_FIFO_BUSY(ppdev, pjMmBase, level)))
  222. return;
  223. }
  224. RIP("vNwFifoWait timeout -- The hardware is in a funky state.");
  225. }
  226. /******************************Public*Routine******************************\
  227. * VOID vDbgFakeWait
  228. \**************************************************************************/
  229. VOID vDbgFakeWait(
  230. PDEV* ppdev,
  231. BYTE* pjMmBase,
  232. LONG level)
  233. {
  234. gcFifo = level;
  235. }
  236. /******************************Public*Routine******************************\
  237. * VOID vIoGpWait
  238. \**************************************************************************/
  239. VOID vIoGpWait(
  240. PDEV* ppdev)
  241. {
  242. LONG i;
  243. gcFifo = (ppdev->flCaps & CAPS_16_ENTRY_FIFO) ? 16 : 8;
  244. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  245. {
  246. if (!(IO_GP_STAT(ppdev) & HARDWARE_BUSY))
  247. return; // It isn't busy
  248. }
  249. RIP("vIoGpWait timeout -- The hardware is in a funky state.");
  250. }
  251. /******************************Public*Routine******************************\
  252. * VOID vNwGpWait
  253. \**************************************************************************/
  254. VOID vNwGpWait(
  255. PDEV* ppdev,
  256. BYTE* pjMmBase)
  257. {
  258. LONG i;
  259. gcFifo = 16;
  260. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  261. {
  262. if (!NW_GP_BUSY(ppdev, pjMmBase))
  263. return; // It isn't busy
  264. }
  265. RIP("vNwGpWait timeout -- The hardware is in a funky state.");
  266. }
  267. /******************************Public*Routine******************************\
  268. * VOID vIoAllEmpty
  269. \**************************************************************************/
  270. VOID vIoAllEmpty(
  271. PDEV* ppdev)
  272. {
  273. LONG i;
  274. ASSERTDD(ppdev->flCaps & CAPS_16_ENTRY_FIFO,
  275. "Can't call ALL_EMPTY on chips with 8-deep FIFOs");
  276. gcFifo = 16;
  277. for (i = LARGE_LOOP_COUNT; i != 0; i--)
  278. {
  279. if (IO_GP_STAT(ppdev) & GP_ALL_EMPTY) // Not implemented on 911/924s
  280. return;
  281. }
  282. RIP("ALL_EMPTY timeout -- The hardware is in a funky state.");
  283. }
  284. /******************************Public*Routines*****************************\
  285. * UCHAR jInp() - INP()
  286. * USHORT wInpW() - INPW()
  287. * VOID vOutp() - OUTP()
  288. * VOID vOutpW() - OUTPW()
  289. *
  290. * Debug thunks for general I/O routines. This is used primarily to verify
  291. * that any code accessing the CRTC register has grabbed the CRTC critical
  292. * section (necessary because with GCAPS_ASYNCMOVE, DrvMovePointer calls
  293. * may happen at any time, and they need to access the CRTC register).
  294. *
  295. \**************************************************************************/
  296. UCHAR jInp(BYTE* pjIoBase, ULONG p)
  297. {
  298. if (((p == CRTC_INDEX) || (p == CRTC_DATA)) &&
  299. (!gbCrtcCriticalSection))
  300. {
  301. RIP("Must have acquired CRTC critical section to access CRTC register");
  302. }
  303. CP_EIEIO();
  304. return((UCHAR) READ_PORT_UCHAR(pjIoBase + (p)));
  305. }
  306. USHORT wInpW(BYTE* pjIoBase, ULONG p)
  307. {
  308. if (((p == CRTC_INDEX) || (p == CRTC_DATA)) &&
  309. (!gbCrtcCriticalSection))
  310. {
  311. RIP("Must have acquired CRTC critical section to access CRTC register");
  312. }
  313. CP_EIEIO();
  314. return(READ_PORT_USHORT(pjIoBase + (p)));
  315. }
  316. VOID vOutp(BYTE* pjIoBase, ULONG p, ULONG v)
  317. {
  318. if (((p == CRTC_INDEX) || (p == CRTC_DATA)) &&
  319. (!gbCrtcCriticalSection))
  320. {
  321. RIP("Must have acquired CRTC critical section to access CRTC register");
  322. }
  323. CP_EIEIO();
  324. WRITE_PORT_UCHAR((PUCHAR)((ULONG_PTR)(pjIoBase + p)), (UCHAR)(v));
  325. CP_EIEIO();
  326. }
  327. VOID vOutpW(BYTE* pjIoBase, ULONG p, ULONG v)
  328. {
  329. if (((p == CRTC_INDEX) || (p == CRTC_DATA)) &&
  330. (!gbCrtcCriticalSection))
  331. {
  332. RIP("Must have acquired CRTC critical section to access CRTC register");
  333. }
  334. CP_EIEIO();
  335. WRITE_PORT_USHORT(pjIoBase + (p), (USHORT)(v));
  336. CP_EIEIO();
  337. }
  338. /******************************Public*Routine******************************\
  339. * VOID vAcquireCrtc()
  340. * VOID vReleaseCrtc()
  341. *
  342. * Debug thunks for grabbing the CRTC register critical section.
  343. *
  344. \**************************************************************************/
  345. VOID vAcquireCrtc(PDEV* ppdev)
  346. {
  347. EngAcquireSemaphore(ppdev->csCrtc);
  348. if (gbCrtcCriticalSection)
  349. RIP("Had already acquired Critical Section");
  350. gbCrtcCriticalSection = TRUE;
  351. }
  352. VOID vReleaseCrtc(PDEV* ppdev)
  353. {
  354. // 80x/805i/928 and 928PCI chips have a bug where if I/O registers
  355. // are left unlocked after accessing them, writes to memory with
  356. // similar addresses can cause writes to I/O registers. The problem
  357. // registers are 0x40, 0x58, 0x59 and 0x5c. We will simply always
  358. // leave the index set to an innocuous register (namely, the text
  359. // mode cursor start scan line):
  360. OUTP(ppdev->pjIoBase, CRTC_INDEX, 0xa);
  361. if (!gbCrtcCriticalSection)
  362. RIP("Hadn't yet acquired Critical Section");
  363. gbCrtcCriticalSection = FALSE;
  364. EngReleaseSemaphore(ppdev->csCrtc);
  365. }
  366. ////////////////////////////////////////////////////////////////////////////
  367. #endif // DBG