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.

419 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. trap.c
  5. Author:
  6. Thomas Parslow [TomP] Mar-01-90
  7. Abstract:
  8. General purpose trap handler for 80386 boot loader. When built in
  9. debugger is present, output is redirected to the com port. When no
  10. debugger is present, output goes to the display.
  11. --*/
  12. #include "su.h"
  13. extern
  14. USHORT
  15. InDebugger;
  16. extern
  17. UCHAR
  18. GDTregister;
  19. extern
  20. UCHAR
  21. IDTregister;
  22. extern
  23. VOID
  24. OutPort(
  25. USHORT
  26. );
  27. extern
  28. USHORT
  29. InPort(
  30. VOID
  31. );
  32. extern
  33. VOID
  34. ReEnterDebugger(
  35. VOID
  36. );
  37. extern
  38. USHORT
  39. TssKernel;
  40. extern
  41. USHORT
  42. Redirect;
  43. extern
  44. VOID RealMode(
  45. VOID
  46. );
  47. VOID
  48. TrapHandler(
  49. IN ULONG,
  50. IN USHORT
  51. );
  52. VOID
  53. DumpProcessorContext(
  54. VOID
  55. );
  56. VOID
  57. DumpSystemRegisters(
  58. VOID
  59. );
  60. VOID
  61. DumpCommonRegisters(
  62. VOID
  63. );
  64. VOID
  65. DisplayFlags(
  66. ULONG f
  67. );
  68. VOID
  69. DumpTSS(
  70. VOID
  71. );
  72. ULONG
  73. GetAddress(
  74. VOID
  75. );
  76. VOID
  77. GetNumber(
  78. PCHAR cp
  79. );
  80. USHORT
  81. GetChar(
  82. VOID
  83. );
  84. VOID
  85. DumpAddress(
  86. ULONG
  87. );
  88. #define PG_FAULT_MSG " =================== PAGE FAULT ================================= \n\n"
  89. #define DBL_FAULT_MSG " ================== DOUBLE FAULT ================================ \n\n"
  90. #define GP_FAULT_MSG " ============== GENERAL PROTECTION FAULT ======================== \n\n"
  91. #define STK_OVERRUN_MSG " ===== STACK SEGMENT OVERRUN or NOT PRESENT FAULT =============== \n\n"
  92. #define EX_FAULT_MSG " ===================== EXCEPTION ================================ \n\n"
  93. #define DEBUG_EXCEPTION "\nDEBUG TRAP "
  94. #define ishex(x) ( ( x >= '0' && x <= '9') || (x >= 'A' && x <= 'F') || (x >= 'a' && x <= 'f') )
  95. //
  96. // Global Trap Frame Pointer
  97. //
  98. PTF TrapFrame=0;
  99. VOID
  100. TrapHandler(
  101. IN ULONG Padding,
  102. IN USHORT TF_base
  103. )
  104. /*++
  105. Routine Description:
  106. Prints minimal trap information
  107. Arguments:
  108. 386 Trap Frame on Stack
  109. Environment:
  110. 16-bit protect mode only.
  111. --*/
  112. {
  113. //
  114. // Initialize global trap frame pointer and print trap number
  115. //
  116. TrapFrame = (PTF)&TF_base;
  117. //
  118. // Fix esp to point to where it pointed before trap
  119. //
  120. TrapFrame->Fesp += 24;
  121. BlPrint("\n TRAP %lx ",TrapFrame->TrapNum);
  122. //
  123. // Print the trap specific header and display processor context
  124. //
  125. switch(TrapFrame->TrapNum) {
  126. case 1:
  127. case 3:
  128. puts( DEBUG_EXCEPTION );
  129. DumpCommonRegisters();
  130. break;
  131. case 8:
  132. puts( DBL_FAULT_MSG );
  133. DumpTSS();
  134. break;
  135. case 12:
  136. puts( STK_OVERRUN_MSG );
  137. DumpProcessorContext();
  138. break;
  139. case 13:
  140. puts( GP_FAULT_MSG );
  141. DumpProcessorContext();
  142. break;
  143. case 14:
  144. puts( PG_FAULT_MSG );
  145. BlPrint("** At linear address %lx\n",TrapFrame->Fcr2);
  146. DumpProcessorContext();
  147. break;
  148. default :
  149. puts( EX_FAULT_MSG );
  150. DumpProcessorContext();
  151. break;
  152. }
  153. RealMode();
  154. while (1); //**** WAITFOREVER *** //
  155. }
  156. VOID
  157. DumpProcessorContext(
  158. VOID
  159. )
  160. /*++
  161. Routine Description:
  162. Dumps all the processors registers. Called whenever a trap or fault
  163. occurs.
  164. Arguments:
  165. None
  166. Returns:
  167. Nothing
  168. --*/
  169. {
  170. DumpSystemRegisters();
  171. DumpCommonRegisters();
  172. }
  173. VOID
  174. DumpSystemRegisters(
  175. VOID
  176. )
  177. /*++
  178. Routine Description:
  179. Dumps (writes to the display or com poirt) the x86 processor control
  180. registers only. Does not dump the common registers (see
  181. DumpCommonRegisters)
  182. Arguments:
  183. None
  184. Returns:
  185. Nothing
  186. --*/
  187. {
  188. BlPrint("\n tr=%x cr0=%lx cr2=%lx cr3=%lx\n",
  189. TrapFrame->Ftr,TrapFrame->Fcr0,TrapFrame->Fcr2,TrapFrame->Fcr3);
  190. BlPrint(" gdt limit=%x base=%lx idt limit=%x base=%lx\n",
  191. *(PUSHORT)&GDTregister,*(PULONG)(&GDTregister + 2),
  192. *(PUSHORT)&IDTregister,*(PULONG)(&IDTregister + 2));
  193. }
  194. VOID
  195. DumpCommonRegisters(
  196. VOID
  197. )
  198. /*++
  199. Routine Description:
  200. Dumps (writes to the display or com poirt) the x86 processor
  201. commond registers only.
  202. Arguments:
  203. None
  204. Returns:
  205. Nothing
  206. --*/
  207. {
  208. USHORT err;
  209. //
  210. // Is the error code valid or just a padding dword
  211. //
  212. if ((TrapFrame->TrapNum == 8) || (TrapFrame->TrapNum >= 10 && TrapFrame->TrapNum <= 14) )
  213. err = (USHORT)TrapFrame->Error;
  214. else
  215. err = 0;
  216. //
  217. // Display the processor's common registers
  218. //
  219. BlPrint("\n cs:eip=%x:%lx ss:esp=%x:%lx errcode=%x\n",
  220. (USHORT)(TrapFrame->Fcs & 0xffff),TrapFrame->Feip,(USHORT)TrapFrame->Fss,TrapFrame->Fesp,err);
  221. DisplayFlags(TrapFrame->Feflags);
  222. BlPrint(" eax=%lx ebx=%lx ecx=%lx edx=%lx",TrapFrame->Feax,TrapFrame->Febx,TrapFrame->Fecx,TrapFrame->Fedx);
  223. BlPrint(" ds=%x es=%x\n",TrapFrame->Fds,TrapFrame->Fes);
  224. BlPrint(" edi=%lx esi=%lx ebp=%lx cr0=%lx",TrapFrame->Fedi,TrapFrame->Fesi,TrapFrame->Febp,TrapFrame->Fcr0);
  225. BlPrint(" fs=%x gs=%x\n",TrapFrame->Ffs,TrapFrame->Fgs);
  226. }
  227. VOID
  228. DisplayFlags(
  229. ULONG f
  230. )
  231. /*++
  232. Routine Description:
  233. Writes the value of the key flags in the flags register to
  234. the display or com port.
  235. Arguments:
  236. f - the 32bit flags word
  237. Returns:
  238. Nothing
  239. --*/
  240. {
  241. BlPrint(" flags=%lx ",f);
  242. if (f & FLAG_CF) puts("Cy "); else puts("NoCy ");
  243. if (f & FLAG_ZF) puts("Zr "); else puts("NoZr ");
  244. if (f & FLAG_IE) puts("IntEn"); else puts("IntDis ");
  245. if (f & FLAG_DF) puts("Up "); else puts("Down ");
  246. if (f & FLAG_TF) puts("TrapEn \n"); else puts("TrapDis \n");
  247. }
  248. VOID
  249. DumpTSS(
  250. VOID
  251. )
  252. /*++
  253. Routine Description:
  254. Writes the contents of the TSS to the display or com port when
  255. called after a double fault.
  256. Arguments:
  257. None
  258. Returns:
  259. Nothing
  260. --*/
  261. {
  262. PTSS_FRAME pTss;
  263. // FP_SEG(Fp) = Fcs;
  264. // FP_OFF(Fp) = Fip;
  265. pTss = (PTSS_FRAME) &TssKernel;
  266. //
  267. // Dump the outgoing TSS
  268. //
  269. BlPrint("Link %x\n",pTss->Link);
  270. BlPrint("Esp0 %x\n",pTss->Esp0);
  271. BlPrint("SS0 %x\n",pTss->SS0);
  272. BlPrint("Esp1 %lx\n",pTss->Esp1);
  273. BlPrint("Cr3 %lx\n",pTss->Cr3);
  274. BlPrint("Eip %lx\n",pTss->Eip);
  275. BlPrint("Eflg %lx\n",pTss->Eflags);
  276. BlPrint("Eax %lx\n",pTss->Eax);
  277. BlPrint("Ebx %lx\n",pTss->Ebx);
  278. BlPrint("Ecx %lx\n",pTss->Ecx);
  279. BlPrint("Edx %lx\n",pTss->Edx);
  280. BlPrint("Esp %lx\n",pTss->Esp);
  281. BlPrint("Ebp %lx\n",pTss->Ebp);
  282. BlPrint("Esi %lx\n",pTss->Esi);
  283. BlPrint("Edi %lx\n",pTss->Edi);
  284. BlPrint("ES %x\n",pTss->ES);
  285. BlPrint("CS %x\n",pTss->CS);
  286. BlPrint("SS %x\n",pTss->SS);
  287. BlPrint("DS %x\n",pTss->DS);
  288. BlPrint("FS %x\n",pTss->FS);
  289. BlPrint("GS %x\n",pTss->GS);
  290. BlPrint("Ldt %x\n",pTss->Ldt);
  291. RealMode();
  292. while(1);
  293. }
  294. // END OF FILE