SayoriOS  0.3.3
cpu_isr.c
См. документацию.
1 
10 #include "sys/cpu_isr.h"
11 #include "sys/logo.h"
12 #include "sys/unwind.h"
13 #include <io/ports.h>
14 #include "sys/scheduler.h"
15 #include <io/status_loggers.h>
16 
17 _Noreturn void sod_screen_legacy(registers_t regs, char* title, char* msg, uint32_t code) {
18  qemu_err("=== ЯДРО УПАЛО =======================================\n");
19  qemu_err("| ");
20  qemu_err("| Наименование: %s",title);
21  qemu_err("| Код ошибки: %x",code);
22  qemu_err("| Сообщение: %s",msg);
23  qemu_err("| EAX: %x",regs.eax);
24  qemu_err("| EBX: %x",regs.ebx);
25  qemu_err("| ECX: %x",regs.ecx);
26  qemu_err("| EDX: %x",regs.edx);
27  qemu_err("| ESP: %x",regs.esp);
28  qemu_err("| EBP: %x",regs.ebp);
29  qemu_err("| EIP: %x",regs.eip);
30  qemu_err("| EFLAGS: %x",regs.eflags);
31  qemu_err("| ");
32  qemu_err("======================================================\n");
33 
34  /* extern char _temp_funcname[1024]; */
35 
36  /* bool exists = get_func_name_by_addr(regs.eip); */
37 
38  /* qemu_err("Failed on: %s", exists ? _temp_funcname : "???"); */
39 
40  unwind_stack(10);
41 
42  /* heap_dump(); */
43 
44  qemu_err("PROCESS CAUSED THE EXCEPTION: nr. %d", get_current_proc()->pid);
45 
46  if(get_current_proc()->pid != 0) {
47  qemu_note("EXIT HERE");
48  blyat_fire();
49  }
50 
51  __asm__ volatile("cli"); // Disable interrupts
52  __asm__ volatile("hlt"); // Halt
53 
54  while(1) {
55  __asm__ volatile("nop");
56  }
57 }
58 
59 _Noreturn void bsod_screen(registers_t regs, char* title, char* msg, uint32_t code){
60  qemu_log("=== ЯДРО УПАЛО =======================================\n");
61  qemu_log("| ");
62  qemu_log("| Наименование: %s",title);
63  qemu_log("| Код ошибки: %x",code);
64  qemu_log("| Сообщение: %s",msg);
65  qemu_log("| EAX: %x",regs.eax);
66  qemu_log("| EBX: %x",regs.ebx);
67  qemu_log("| ECX: %x",regs.ecx);
68  qemu_log("| EDX: %x",regs.edx);
69  qemu_log("| ESP: %x",regs.esp);
70  qemu_log("| EBP: %x",regs.ebp);
71  qemu_log("| EIP: %x",regs.eip);
72  qemu_log("| EFLAGS: %x",regs.eflags);
73  qemu_log("| ");
74  qemu_log("======================================================\n");
75 
76  qemu_err("PROCESS CAUSED THE EXCEPTION: nr. %d", get_current_proc()->pid);
77 
78  unwind_stack(10);
79 
80  __asm__ volatile("cli"); // Disable interrupts
81  __asm__ volatile("hlt"); // Halt
82 
83  while(1) {
84  __asm__ volatile("nop");
85  }
86 }
87 
88 void print_regs(registers_t regs){
89  qemu_log("EAX = %x", regs.eax);
90  qemu_log("EBX = %x", regs.ebx);
91  qemu_log("ECX = %x", regs.ecx);
92  qemu_log("EDX = %x", regs.edx);
93  qemu_log("ESP = %x", regs.esp);
94  qemu_log("EBP = %x", regs.ebp);
95  qemu_log("EIP = %x", regs.eip);
96  qemu_log("EFLAGS = %x", regs.eflags);
97 }
98 
99 void division_by_zero(registers_t regs)
100 {
101  qemu_log("Exception: DIVISION BY ZERO\n");
102  print_regs(regs); bsod_screen(regs,"CRITICAL_ERROR_DZ_DIVISION_BY_ZERO","Деление на ноль",regs.eax);
103 }
104 
105 void fault_opcode(registers_t regs){
106  qemu_log("FAULT OPERATION CODE...\n");
107  print_regs(regs); bsod_screen(regs,"CRITICAL_ERROR_UD_FAULT_OPERATION_CODE","Невалидный код",regs.eax);
108 }
109 
110 void double_error(registers_t regs){
111  qemu_log("Exception: DOUBLE EXCEPTION\n");
112  qemu_log("Error code: %d", regs.err_code); bsod_screen(regs,"CRITICAL_ERROR_DF_DOUBLE_EXCEPTION","Двойное исключение",regs.err_code);
113 }
114 
115 void invalid_tss(registers_t regs){
116  uint32_t ext = regs.err_code & EXT_BIT;
117  uint32_t idt = regs.err_code & IDT_BIT;
118  uint32_t ti = regs.err_code & TI_BIT;
119  uint32_t selector = regs.err_code & ERR_CODE_MASK;
120 
121  qemu_log("Exception: INVALID TSS\n");
122  qemu_log("cause of error: ");
123 
124  char* msg = "Недействительный TSS";
125  if (ext) {
126  qemu_log("HARDWARE INTERRUPT\n");
127  msg = "Аппаратное прерывание";
128  }
129 
130  if (idt) {
131  qemu_log("IDT GATE\n");
132  msg = "Шлюз IDT";
133  }
134 
135  if (ti) {
136  qemu_log("LDT GATE\n");
137  msg = "Шлюз LDT";
138  }
139 
140  qemu_log("Invalid selector: %d", selector);
141  bsod_screen(regs, "CRITICAL_ERROR_TS_INVALID_TS", msg, selector);
142 }
143 
144 void segment_is_not_available(registers_t regs){
145  uint32_t ext = regs.err_code & EXT_BIT;
146  uint32_t idt = regs.err_code & IDT_BIT;
147  uint32_t ti = regs.err_code & TI_BIT;
148  uint32_t selector = regs.err_code & ERR_CODE_MASK;
149 
150  qemu_log("Exception: SEGMENT IS'T AVAILABLE\n");
151  qemu_log("cause of error: ");
152 
153  char* msg = "СЕГМЕНТ НЕДОСТУПЕН";
154  if (ext)
155  {
156  qemu_log("HARDWARE INTERRUPT\n");
157  msg = "Аппаратное прерывание";
158  }
159 
160  if (idt)
161  {
162  qemu_log("IDT GATE\n");
163  msg = "Шлюз IDT";
164  }
165 
166  if (ti)
167  {
168  qemu_log("LDT GATE\n");
169  msg = "Шлюз LDT";
170  }
171 
172  qemu_log("Invalid selector: %d", selector);
173  bsod_screen(regs,"CRITICAL_ERROR_NP_SEGMENT_IST_AVAILABLE", msg, selector);
174 }
175 
176 void stack_error(registers_t regs){
177  qemu_log("Exception: STACK ERROR\n");
178  qemu_log("Error code: %d ", regs.err_code);
179  bsod_screen(regs,"CRITICAL_ERROR_SS_STACK_ERROR","Ошибка стека",regs.err_code);
180 }
181 
182 void general_protection_error(registers_t regs) {
183  qemu_log("Exception: GENERAL PROTECTION ERROR\n");
184  qemu_log("Error code: %d", regs.err_code);
185 
186  bsod_screen(regs,"CRITICAL_ERROR_GP_GENERAL_PROTECTION", "Общая ошибка защиты", regs.err_code);
187 }
188 
189 void page_fault(registers_t regs){
190  uint32_t fault_addr = read_cr2();
191  int present = !(regs.err_code & 0x1); /* Page not present */
192  uint32_t rw = regs.err_code & 0x2; /* Page is read only */
193  uint32_t user = regs.err_code & 0x4; /* User mode */
194  uint32_t reserved = regs.err_code & 0x8; /* Reserved bits is wrote */
195  uint32_t id = regs.err_code & 0x10; /* Instruction fetch */
196  qemu_log("Page fault: ");
197  char* msg = "Переполнение памяти буфера";
198  if (present){
199  qemu_log("NOT PRESENT, ");
200  msg = "Память по данному адресу недоступна";
201  }
202  if (rw){
203  qemu_log("READ ONLY, ");
204  msg = "Память только для чтения";
205  }
206  if (user){
207  qemu_log("USER MODE, ");
208  msg = "Память только для пользователя";
209  }
210  if (reserved){
211  qemu_log("WRITING TO RESERVED BITS, ");
212  msg = "Попытка записи в зарез. биты";
213  }
214  if (id){
215  qemu_log("EIP error ");
216  msg = "Ошибка EIP";
217  }
218  qemu_log("at address (virtual) %x",fault_addr);
219 
220  tty_printf("Process nr.%d caused page fault: ", get_current_proc()->pid);
221  if (present){
222  tty_printf("NOT PRESENT, ");
223  }
224  if (rw){
225  tty_printf("READ ONLY, ");
226  }
227  if (user){
228  tty_printf("USER MODE, ");
229  }
230  if (reserved){
231  tty_printf("WRITING TO RESERVED BITS, ");
232  }
233  if (id){
234  tty_printf("EIP error ");
235  }
236  tty_printf("at address (virtual) %x",fault_addr);
237 
238 
239  // Prevent kmallocs (in bsod_screen()) in Page Fault
240  sod_screen_legacy(regs, "CRITICAL_ERROR_PF_PAGE_FAULT", msg, fault_addr);
241 }
242 
243 void fpu_fault(registers_t regs){
244  qemu_log("Exception: FPU_FAULT\n");
245  qemu_log("Error code: %d ", regs.err_code);
246  bsod_screen(regs, "CRITICAL_ERROR_FPU_FAULT", "Ошибка FPU", regs.err_code);
247 }
volatile process_t * get_current_proc(void)
Получить текущий обработчик процесса
Definition: scheduler.c:125