trap.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #include "trap.h"
  2. #include "gate.h"
  3. #include <common/kprint.h>
  4. #include <debug/traceback/traceback.h>
  5. #include <process/process.h>
  6. #include <process/ptrace.h>
  7. #include <sched/sched.h>
  8. #include <arch/arch.h>
  9. extern void ignore_int();
  10. // 0 #DE 除法错误
  11. void do_divide_error(struct pt_regs *regs, unsigned long error_code)
  12. {
  13. // kerror("do_divide_error(0)");
  14. kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code,
  15. regs->rsp, regs->rip, rs_current_cpu_id(), rs_current_pcb_pid());
  16. traceback(regs);
  17. rs_process_do_exit(-1);
  18. }
  19. // 1 #DB 调试异常
  20. void do_debug(struct pt_regs *regs, unsigned long error_code)
  21. {
  22. printk("[ ");
  23. printk_color(RED, BLACK, "ERROR / TRAP");
  24. printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%d\n", error_code, regs->rsp, regs->rip,
  25. rs_current_pcb_cpuid(), rs_current_pcb_pid());
  26. while (1)
  27. hlt();
  28. }
  29. // 2 不可屏蔽中断
  30. void do_nmi(struct pt_regs *regs, unsigned long error_code)
  31. {
  32. printk("[ ");
  33. printk_color(BLUE, BLACK, "INT");
  34. printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
  35. rs_current_pcb_cpuid());
  36. while (1)
  37. hlt();
  38. }
  39. // 3 #BP 断点异常
  40. void do_int3(struct pt_regs *regs, unsigned long error_code)
  41. {
  42. printk("[ ");
  43. printk_color(YELLOW, BLACK, "TRAP");
  44. printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
  45. rs_current_pcb_cpuid());
  46. while (1)
  47. hlt();
  48. }
  49. // 4 #OF 溢出异常
  50. void do_overflow(struct pt_regs *regs, unsigned long error_code)
  51. {
  52. printk("[ ");
  53. printk_color(YELLOW, BLACK, "TRAP");
  54. printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  55. regs->rip, rs_current_pcb_cpuid());
  56. rs_process_do_exit(-1);
  57. }
  58. // 5 #BR 越界异常
  59. void do_bounds(struct pt_regs *regs, unsigned long error_code)
  60. {
  61. kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
  62. rs_current_pcb_cpuid());
  63. while (1)
  64. hlt();
  65. }
  66. // 6 #UD 无效/未定义的机器码
  67. void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code)
  68. {
  69. kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code,
  70. regs->rsp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
  71. traceback(regs);
  72. rs_process_do_exit(-1);
  73. }
  74. // 7 #NM 设备异常(FPU不存在)
  75. void do_dev_not_avaliable(struct pt_regs *regs, unsigned long error_code)
  76. {
  77. kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid=%d\n", error_code, regs->rsp,
  78. regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
  79. rs_process_do_exit(-1);
  80. }
  81. // 8 #DF 双重错误
  82. void do_double_fault(struct pt_regs *regs, unsigned long error_code)
  83. {
  84. printk("[ ");
  85. printk_color(RED, BLACK, "Terminate");
  86. printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  87. regs->rip, rs_current_pcb_cpuid());
  88. traceback(regs);
  89. rs_process_do_exit(-1);
  90. }
  91. // 9 协处理器越界(保留)
  92. void do_coprocessor_segment_overrun(struct pt_regs *regs, unsigned long error_code)
  93. {
  94. kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
  95. regs->rsp, regs->rip, rs_current_pcb_cpuid());
  96. rs_process_do_exit(-1);
  97. }
  98. // 10 #TS 无效的TSS段
  99. void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code)
  100. {
  101. printk("[");
  102. printk_color(RED, BLACK, "ERROR");
  103. printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  104. regs->rip, rs_current_pcb_cpuid());
  105. printk_color(YELLOW, BLACK, "Information:\n");
  106. // 解析错误码
  107. if (error_code & 0x01)
  108. printk("The exception occurred during delivery of an event external to the program.\n");
  109. if (error_code & 0x02)
  110. printk("Refers to a descriptor in the IDT.\n");
  111. else
  112. {
  113. if (error_code & 0x04)
  114. printk("Refers to a descriptor in the current LDT.\n");
  115. else
  116. printk("Refers to a descriptor in the GDT.\n");
  117. }
  118. printk("Segment Selector Index:%10x\n", error_code & 0xfff8);
  119. printk("\n");
  120. rs_process_do_exit(-1);
  121. }
  122. // 11 #NP 段不存在
  123. void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code)
  124. {
  125. kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  126. regs->rip, rs_current_pcb_cpuid());
  127. rs_process_do_exit(-1);
  128. }
  129. // 12 #SS SS段错误
  130. void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
  131. {
  132. kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  133. regs->rip, rs_current_pcb_cpuid());
  134. // kinfo("cs=%#04x, ds=%#04x, ss=%#04x", regs->cs, regs->ds, regs->ss);
  135. traceback(regs);
  136. rs_process_do_exit(-1);
  137. }
  138. // 13 #GP 通用保护性异常
  139. void do_general_protection(struct pt_regs *regs, unsigned long error_code)
  140. {
  141. kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code,
  142. regs->rsp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
  143. if (error_code & 0x01)
  144. printk_color(RED, BLACK,
  145. "The exception occurred during delivery of an event external to the program,such as an interrupt "
  146. "or an earlier exception.\n");
  147. if (error_code & 0x02)
  148. printk_color(RED, BLACK, "Refers to a gate descriptor in the IDT;\n");
  149. else
  150. printk_color(RED, BLACK, "Refers to a descriptor in the GDT or the current LDT;\n");
  151. if ((error_code & 0x02) == 0)
  152. if (error_code & 0x04)
  153. printk_color(RED, BLACK, "Refers to a segment or gate descriptor in the LDT;\n");
  154. else
  155. printk_color(RED, BLACK, "Refers to a descriptor in the current GDT;\n");
  156. printk_color(RED, BLACK, "Segment Selector Index:%#010x\n", error_code & 0xfff8);
  157. traceback(regs);
  158. rs_process_do_exit(-1);
  159. }
  160. // 14 #PF 页故障
  161. void do_page_fault(struct pt_regs *regs, unsigned long error_code)
  162. {
  163. cli();
  164. unsigned long cr2 = 0;
  165. #if ARCH(I386) || ARCH(X86_64)
  166. __asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory");
  167. #endif
  168. kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code,
  169. regs->rsp, regs->rbp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
  170. kerror("regs->rax = %#018lx\n", regs->rax);
  171. if (!(error_code & 0x01))
  172. printk_color(RED, BLACK, "Page Not-Present,\t");
  173. if (error_code & 0x02)
  174. printk_color(RED, BLACK, "Write Cause Fault,\t");
  175. else
  176. printk_color(RED, BLACK, "Read Cause Fault,\t");
  177. if (error_code & 0x04)
  178. printk_color(RED, BLACK, "Fault in user(3)\t");
  179. else
  180. printk_color(RED, BLACK, "Fault in supervisor(0,1,2)\t");
  181. if (error_code & 0x08)
  182. printk_color(RED, BLACK, ",Reserved Bit Cause Fault\t");
  183. if (error_code & 0x10)
  184. printk_color(RED, BLACK, ",Instruction fetch Cause Fault");
  185. printk_color(RED, BLACK, "\n");
  186. printk_color(RED, BLACK, "CR2:%#018lx\n", cr2);
  187. traceback(regs);
  188. sti();
  189. rs_process_do_exit(-1);
  190. // current_pcb->state = PROC_STOPPED;
  191. // sched();
  192. }
  193. // 15 Intel保留,请勿使用
  194. // 16 #MF x87FPU错误
  195. void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code)
  196. {
  197. kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  198. regs->rip, rs_current_pcb_cpuid());
  199. while (1)
  200. hlt();
  201. }
  202. // 17 #AC 对齐检测
  203. void do_alignment_check(struct pt_regs *regs, unsigned long error_code)
  204. {
  205. kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  206. regs->rip, rs_current_pcb_cpuid());
  207. rs_process_do_exit(-1);
  208. }
  209. // 18 #MC 机器检测
  210. void do_machine_check(struct pt_regs *regs, unsigned long error_code)
  211. {
  212. kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  213. regs->rip, rs_current_pcb_cpuid());
  214. rs_process_do_exit(-1);
  215. }
  216. // 19 #XM SIMD浮点异常
  217. void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code)
  218. {
  219. kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
  220. regs->rip, rs_current_pcb_cpuid());
  221. rs_process_do_exit(-1);
  222. }
  223. // 20 #VE 虚拟化异常
  224. void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
  225. {
  226. kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
  227. regs->rsp, regs->rip, rs_current_pcb_cpuid());
  228. rs_process_do_exit(-1);
  229. }
  230. // 21-21 Intel保留,请勿使用
  231. /**
  232. * @brief 当系统收到未知的中断时,执行此处理函数
  233. *
  234. * @param regs
  235. * @param error_code
  236. */
  237. void ignore_int_handler(struct pt_regs *regs, unsigned long error_code)
  238. {
  239. kwarn("Unknown interrupt or fault at RIP.\n");
  240. }
  241. void sys_vector_init()
  242. {
  243. #if ARCH(I386) || ARCH(X86_64)
  244. // 将idt重置为新的ignore_int入点(此前在head.S中有设置,
  245. // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP
  246. for (int i = 0; i < 256; ++i)
  247. set_intr_gate(i, 0, ignore_int);
  248. set_trap_gate(0, 0, divide_error);
  249. set_trap_gate(1, 0, debug);
  250. set_intr_gate(2, 0, nmi);
  251. set_system_trap_gate(3, 0, int3);
  252. set_system_trap_gate(4, 0, overflow);
  253. set_system_trap_gate(5, 0, bounds);
  254. set_trap_gate(6, 0, undefined_opcode);
  255. set_trap_gate(7, 0, dev_not_avaliable);
  256. set_trap_gate(8, 0, double_fault);
  257. set_trap_gate(9, 0, coprocessor_segment_overrun);
  258. set_trap_gate(10, 0, invalid_TSS);
  259. set_trap_gate(11, 0, segment_not_exists);
  260. set_trap_gate(12, 0, stack_segment_fault);
  261. set_trap_gate(13, 0, general_protection);
  262. set_trap_gate(14, 0, page_fault);
  263. // 中断号15由Intel保留,不能使用
  264. set_trap_gate(16, 0, x87_FPU_error);
  265. set_trap_gate(17, 0, alignment_check);
  266. set_trap_gate(18, 0, machine_check);
  267. set_trap_gate(19, 0, SIMD_exception);
  268. set_trap_gate(20, 0, virtualization_exception);
  269. // 中断号21-31由Intel保留,不能使用
  270. // 32-255为用户自定义中断内部
  271. #endif
  272. }