00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "src/common/shared.hpp"
00028 #include "src/arch/x86/gdt.hpp"
00029 #include "src/memory/align.hpp"
00030 #include "src/memory/alloc4k.hpp"
00031 #include "src/memory/heap.hpp"
00032 #include "src/memory/pager.hpp"
00033 #include "src/common/io.hpp"
00034 #include "src/thread/thread.hpp"
00035 #include "src/thread/process.hpp"
00036 #include "src/thread/scheduler.hpp"
00037 #include "src/arch/x86/interr.hpp"
00038 #include "src/arch/x86/except_c.hpp"
00039 #include "src/arch/x86/irq.hpp"
00040
00041
00042 void (*exc)();
00043 void (*irq_h)();
00044
00045 namespace Arch {
00046 namespace x86 {
00047 namespace Interr {
00048
00049
00050 list_t* int_lists[0x30];
00051 int (*first_routine[0x30])(except_t*);
00052 char *except_names[0x20] =
00053 {"division error", "unhandled debug exception", "non-maskable interrupt",
00054 "unhandled breakpoint", "overflow", "bounds check", "invalid opcode",
00055 "coprocessor not availlable", "double fault", "coprocessor segment overrun",
00056 "invalid TSS", "segment not present", "stack exception","General Protection Fault",
00057 "invalid page fault", "unhandled unknown", "coprocessor error", "alignment check",
00058 "machine check", "SIMD floating-point exception", "unhandled unknown",
00059 "unhandled unknown", "unhandled unknown", "unhandled unknown","unhandled unknown",
00060 "unhandled unknown", "unhandled unknown", "unhandled unknown","unhandled unknown",
00061 "unhandled unknown", "unhandled unknown", "unhandled unknown"};
00062
00063 extern "C" void pr (int i);
00064 void pr (int i)
00065 {
00066 cout("(");
00067 cout(i);
00068 cout(")");
00069 }
00070
00071 void chain_handler(except_t *code)
00072 {
00073 list_t *item;
00074 cout(" >");cout(code->uu.iret->code);
00075
00076 if ( !((((uint32*)(first_routine))[code->uu.iret->code])&&
00077 (((first_routine[code->uu.iret->code](code)) == ESUCCESS))) )
00078
00079 for (item = int_lists[code -> uu.iret->code];item; item = item -> next)
00080 if((item->proc(code) == ESUCCESS)) break;
00081
00082 if (code -> uu.iret->code >= 0x20) IOPorts::outb(0x20, 0x20);
00083 if (code ->uu.iret->code >= 0x28) IOPorts::outb(0xa0, 0x20);
00084 cout(" <");cout(code->uu.iret->code);
00085 }
00086
00087
00088 uint32 add2interr_chain(uint32 int_no, int(*proc)(except_t*))
00089 {
00090 list_t *item;
00091
00092
00093 item = (list_t*) Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN, FAC_INTERR|FAC_EXCLIST, NULL);
00094 item -> next = int_lists[int_no];
00095 item -> proc = proc;
00096 int_lists[int_no] = item;
00097
00098 return (uint32) item;
00099
00100
00101 }
00102
00103
00104 void install_first_routine(uint32 n, uint32 (*proc)(except_t*))
00105 {
00106
00107 ((uint32*)first_routine)[n]=(uint32)proc;
00108 }
00109
00110
00111 uint32 del_chainHdl(uint32 int_no, uint32 ptr)
00112 {
00113 list_t *item, *prev;
00114
00115 prev = (list_t*) NULL;
00116 item = int_lists[int_no];
00117 while (item)
00118 {
00119
00120 if (item == (list_t*) ptr)
00121 {
00122
00123 if (prev) prev->next = item -> next;
00124 else
00125
00126 int_lists[int_no] = item -> next;
00127
00128 Memory::Heap::heap0.free(item);
00129 return ESUCCESS;
00130 }
00131 prev = item;
00132 item = item -> next;
00133 }
00134 return (uint32)EINVAL;
00135 }
00136
00137
00138 int Exception(except_t *code)
00139 {
00140
00141 cout ("\nSYSFAIL");
00142 cout ("\nexception condition #");
00143 coutb (code->uu.iret->code);
00144 cout ("- ");
00145 cout ((char*) except_names[code->uu.iret->code]);
00146 kprintf(", eip: %x, val: %x\n", code->uu.iret->thread_eip, code->uu.iret->val);
00147
00148 if (code->uu.iret->thread_cs == Arch::x86::GDT::code_sel_kernel)
00149
00150 debug_dump_call_trace(code->uu.iret->thread_eip, code->uu.iret->regs.r_ebp);
00151
00152
00153 panic();
00154 return ESUCCESS;
00155 }
00156
00157
00158 int PageFault(except_t *code)
00159 {
00160 static int level=0;
00161 level++;
00162 if (level==2)
00163 sysfail("double invalid page fault");
00164 if (level==3)
00165 {
00166 cout("\ntriple invalid page fault");
00167 asm volatile ("cli\nhlt");
00168 }
00169 cout("\nSYSFAIL");
00170 cout("\npage fault, %eip=0x");
00171 cout(code->uu.iret->thread_eip);
00172 cout(", %cr2=0x");
00173 cout(code->cr2);
00174
00175 if (code->uu.iret->thread_cs == Arch::x86::GDT::code_sel_kernel)
00176
00177 debug_dump_call_trace(code->uu.iret->thread_eip, code->uu.iret->regs.r_ebp);
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 asm volatile ("cli\nhlt");
00203 return ESUCCESS;
00204 }
00205
00206
00207 void double_fault()
00208 {
00209
00210 (*(uint8*)0xb8004)='D'; (*(uint8*)0xb8005)=' ';
00211 (*(uint8*)0xb8006)='F'; (*(uint8*)0xb8007)=' ';
00212 (*(uint8*)0xb8008)='E'; (*(uint8*)0xb8009)=' ';
00213 (*(uint8*)0xb800a)='X'; (*(uint8*)0xb800b)=' ';
00214
00215 cout("\nSYSFAIL\ndouble fault\n");
00216 cout( mem_ksize);
00217
00218 asm volatile ("cli\nhlt");
00219 for(;;);
00220 }
00221
00222
00223 void stack_fault()
00224 {
00225 struct
00226 {
00227
00228 uint32 old_ebp;
00229
00230 uint32 thread_eip;
00231 uint32 thread_cs;
00232 uint32 thread_eflags;
00233
00234 uint32 thread_3_esp;
00235 uint32 thread_3_ss;
00236 } *stack_frame;
00237
00238
00239 asm volatile ("mov %%ebp, %%eax": "=a" (stack_frame));
00240
00241 (*(uint8*)0xb8004)='S'; (*(uint8*)0xb8005)=' ';
00242 (*(uint8*)0xb8006)='F'; (*(uint8*)0xb8007)=' ';
00243 (*(uint8*)0xb8008)='E'; (*(uint8*)0xb8009)=' ';
00244 (*(uint8*)0xb800a)='X'; (*(uint8*)0xb800b)=' ';
00245
00246 cout("\nSYSFAIL\nstack fault\n");
00247 cout((uint32)stack_frame);
00248 cout((char*)¤t_thread->name);
00249
00250
00251 debug_heap_stats(&::Thread::heap);
00252
00253 asm volatile ("cli\nhlt");
00254 for(;;);
00255 }
00256
00257
00258 int Irq_H(except_t *code)
00259 {
00260 return ESUCCESS;
00261 }
00262
00263
00264 void init_int_chains(idt_service *ptr)
00265 {
00266 uint32 n;
00267
00268 for (n=0; n<0x30; n++)
00269 ((uint32*)&first_routine)[n] = NULL;
00270
00271 #ifndef DISABLE_EXCEPTIONS
00272
00273 ptr->set_int(0x00, &intr0x00, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00274 ptr->set_int(0x01, &intr0x01, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00275 ptr->set_int(0x02, &intr0x02, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00276 ptr->set_int(0x03, &intr0x03, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00277 ptr->set_int(0x04, &intr0x04, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00278 ptr->set_int(0x05, &intr0x05, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00279 ptr->set_int(0x06, &intr0x06, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00280 ptr->set_int(0x07, &intr0x07, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00281
00282 ptr->set_int(0x08, NULL, Arch::x86::GDT::tss_sel_kernel_df, 0x8500);
00283 ptr->set_int(0x09, &intr0x09, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00284 ptr->set_int(0x0a, &intr0x0a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00285 ptr->set_int(0x0b, &intr0x0b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00286
00287 ptr->set_int(0x0c, NULL, Arch::x86::GDT::tss_sel_kernel_sf, 0x8500);
00288 ptr->set_int(0x0d, &intr0x0d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00289
00290 ptr->set_int(0x0f, &intr0x0f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00291 ptr->set_int(0x10, &intr0x10, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00292 ptr->set_int(0x11, &intr0x11, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00293 ptr->set_int(0x12, &intr0x12, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00294 ptr->set_int(0x13, &intr0x13, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00295 ptr->set_int(0x14, &intr0x14, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00296 ptr->set_int(0x15, &intr0x15, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00297 ptr->set_int(0x16, &intr0x16, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00298 ptr->set_int(0x17, &intr0x17, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00299 ptr->set_int(0x18, &intr0x18, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00300 ptr->set_int(0x19, &intr0x19, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00301 ptr->set_int(0x1a, &intr0x1a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00302 ptr->set_int(0x1b, &intr0x1b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00303 ptr->set_int(0x1c, &intr0x1c, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00304 ptr->set_int(0x1d, &intr0x1d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00305 ptr->set_int(0x1e, &intr0x1e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00306 ptr->set_int(0x1f, &intr0x1f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00307 #endif
00308 ptr->set_int(0x0e, &intr0x0e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00309
00310 ptr->set_int(0x20, &intr0x20, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00311 ptr->set_int(0x21, &intr0x21, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00312 ptr->set_int(0x22, &intr0x22, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00313 ptr->set_int(0x23, &intr0x23, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00314 ptr->set_int(0x24, &intr0x24, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00315 ptr->set_int(0x25, &intr0x25, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00316 ptr->set_int(0x26, &intr0x26, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00317 ptr->set_int(0x27, &intr0x27, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00318 ptr->set_int(0x28, &intr0x28, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00319 ptr->set_int(0x29, &intr0x29, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00320 ptr->set_int(0x2a, &intr0x2a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00321 ptr->set_int(0x2b, &intr0x2b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00322 ptr->set_int(0x2c, &intr0x2c, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00323 ptr->set_int(0x2d, &intr0x2d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00324 ptr->set_int(0x2e, &intr0x2e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00325 ptr->set_int(0x2f, &intr0x2f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00326
00327
00328 ptr->install_except((void(*)()) &chain_handler);
00329
00330
00331 for (n=0; n<0x20; n++)
00332 {
00333 int_lists[n] = (list_t*)Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN,FAC_INTERR|FAC_EXCLIST, NULL);
00334 int_lists[n]->next = 0;
00335 int_lists[n]->proc = &Exception;
00336 }
00337
00338 int_lists[INT_PF]->proc= &PageFault;
00339
00340
00341 for (n=0x20; n<0x30; n++)
00342 {
00343 int_lists[n] = (list_t*)Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN,FAC_INTERR|FAC_EXCLIST, NULL);
00344 int_lists[n]->next = 0;
00345 int_lists[n]->proc = &Irq_H;
00346 }
00347 }
00348
00349
00350 void done_int_chains()
00351 {
00352
00353 __asm__ __volatile__ ("cli");
00354
00355 IOPorts::outb(DEF_PIC_M_PORT+1, 0xff);
00356 IOPorts::outb(DEF_PIC_S_PORT+1, 0xff);
00357
00358 uint32 n;
00359 list_t *item, *temp;
00360
00361 for (n=0; n< 0x30; n++)
00362 {
00363 item = int_lists[n];
00364 while (item)
00365 {
00366 temp = item -> next;
00367 Memory::Heap::heap0.free(item);
00368 item = temp;
00369 }
00370 }
00371 }
00372
00373
00374 };
00375 };
00376 };
00377
00378
00379
00380
00381
00382
00383