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 }
get_current_proc
volatile process_t * get_current_proc(void)
Получить текущий обработчик процесса
Definition: scheduler.c:125
registers
Definition: common.h:59