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/memset.hpp"
00030 #include "src/memory/align.hpp"
00031 #include "src/memory/alloc4k.hpp"
00032 #include "src/memory/heap.hpp"
00033 #include "src/memory/pager.hpp"
00034 #include "src/common/io.hpp"
00035 #include "src/thread/thread.hpp"
00036 #include "src/thread/process.hpp"
00037 #include "src/thread/scheduler.hpp"
00038 #include "src/arch/x86/interr.hpp"
00039 #include "src/arch/x86/except_c.hpp"
00040 #include "src/arch/x86/irq.hpp"
00041
00042
00043 void (*exc)();
00044 void (*irq_h)();
00045
00046 namespace Arch {
00047 namespace x86 {
00048 namespace Interr {
00049
00050
00051 list_t* int_lists[0x31];
00052 int (*first_routine[0x31])(except2_t*);
00053 const char *except_names[0x20] =
00054 {"division error", "unhandled debug exception", "non-maskable interrupt",
00055 "unhandled breakpoint", "overflow", "bounds check", "invalid opcode",
00056 "coprocessor not availlable", "double fault", "coprocessor segment overrun",
00057 "invalid TSS", "segment not present", "stack exception","General Protection Fault",
00058 "invalid page fault", "unhandled unknown", "coprocessor error", "alignment check",
00059 "machine check", "SIMD floating-point exception", "unhandled unknown",
00060 "unhandled unknown", "unhandled unknown", "unhandled unknown","unhandled unknown",
00061 "unhandled unknown", "unhandled unknown", "unhandled unknown","unhandled unknown",
00062 "unhandled unknown", "unhandled unknown", "unhandled unknown"};
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 bool inInterruptHandler=false;
00073
00074 bool isInInterruptHandler() {
00075 return inInterruptHandler;
00076 }
00077
00078 char stackSpace[STACKSZ*STACKCNT];
00079 char *stackPtr[STACKCNT]={&stackSpace[STACKSZ*1],&stackSpace[STACKSZ*2],
00080 &stackSpace[STACKSZ*3],&stackSpace[STACKSZ*4],
00081 &stackSpace[STACKSZ*5],&stackSpace[STACKSZ*6],
00082 &stackSpace[STACKSZ*7],&stackSpace[STACKSZ*8],
00083 &stackSpace[STACKSZ*9],&stackSpace[STACKSZ*10],
00084 &stackSpace[STACKSZ*11],&stackSpace[STACKSZ*12],
00085 &stackSpace[STACKSZ*13],&stackSpace[STACKSZ*14],
00086 &stackSpace[STACKSZ*15],&stackSpace[STACKSZ*16]};
00087 uint32 volatile stackVac=0;
00088 char *stack1;
00089 char *reta;
00090 struct chh_t cd1;
00091
00092
00093
00094
00095 void chain2(struct chh_t *code);
00096 void chain_handler(struct chh_t code)
00097 {
00098
00099
00100 asm volatile("mov %%ebp, %%eax":"=a"(reta));
00101 memmove(&cd1, &code, sizeof(struct chh_t));
00102
00103 if(stackVac>=STACKCNT)
00104 sysfail("no free stacks for the interrupt");
00105
00106 stack1= stackPtr[stackVac];
00107 stackVac++;
00108
00109
00110 asm volatile ("mov %%eax, %%esp"::"a"(stack1-sizeof(struct except2_t)));
00111 asm volatile("mov %esp, %ebp");
00112
00113
00114 chain2(&code);
00115 }
00116
00117 void chain2(struct chh_t *code)
00118 {
00119 char StackCopy[CHAINHANDLERSTACKCOPY];
00120
00121
00122 if (code->cs != GDT::code_sel_kernel)
00123 memmove(&StackCopy,reta, CHAINHANDLERSTACKCOPY);
00124
00125 struct except2_t *cd2=(struct except2_t*)stack1;
00126
00127 memmove(&cd2->r,&cd1.r, sizeof(struct reg_dump));
00128 cd2->c1=cd1.c1;
00129 cd2->c2=cd1.c2;
00130 cd2->ebp=cd1.ebp;
00131 cd2->stack=stack1;
00132 cd2->reta=reta;
00133 cd2->eip=cd1.eip;
00134 cd2->cs=cd1.cs;
00135 cd2->eflags=cd1.eflags;
00136 if (cd2->cs == GDT::code_sel_kernel) {
00137 cd2->ss= GDT::data_sel_kernel;
00138 cd2->esp= cd2->r.r_temp_esp;
00139 } else {
00140 cd2->esp=*(uint32*)(reta+sizeof(struct chh_t)+sizeof(int)*2);
00141 cd2->ss=*(uint32*)((uint32)&code+sizeof(code)+sizeof(int)*3);
00142 }
00143
00144 asm volatile("movl %%cr2, %%eax":"=a"(cd2->cr2));
00145
00146
00147 if (::Thread::Scheduler::multitasking_running)
00148 current_thread->env.cd= cd2;
00149 inInterruptHandler=true;
00150
00151 list_t *item;
00152
00153 if ( !((((uint32*)(first_routine))[cd2->c1])&&
00154 (((first_routine[cd2->c1](cd2)) == ESUCCESS))) )
00155
00156 for (item = int_lists[cd2->c1];item; item = item -> next)
00157 if((item->proc(cd2) == ESUCCESS)) break;
00158 asm volatile("cli");
00159
00160 inInterruptHandler=false;
00161
00162
00163 if (cd2->c1 >= 0x20) IOPorts::outb(0x20, 0x20);
00164 if (cd2->c1 >= 0x28) IOPorts::outb(0xa0, 0x20);
00165
00166
00167 stackVac--;
00168 stackPtr[stackVac]=cd2->stack;
00169 if (::Thread::Scheduler::multitasking_running)
00170 current_thread->env.cd= NULL;
00171
00172
00173 if (code->cs != GDT::code_sel_kernel)
00174 memmove(cd2->reta, StackCopy, CHAINHANDLERSTACKCOPY);
00175
00176 memmove((char*)cd2->reta+CHAINREGCOPY, &cd2->r, sizeof(struct reg_dump));
00177
00178 asm volatile ("mov %%eax, %%ebp"::"a"(cd2->reta));
00179
00180
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 uint32 add2interr_chain(uint32 int_no, int(*proc)(except2_t*))
00201 {
00202 list_t *item;
00203
00204
00205 item = (list_t*) Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN, FAC_INTERR|FAC_EXCLIST, NULL);
00206 item -> next = int_lists[int_no];
00207 item -> proc = proc;
00208 int_lists[int_no] = item;
00209
00210 return (uint32) item;
00211
00212
00213 }
00214
00215
00216 void install_first_routine(uint32 n, uint32 (*proc)(except2_t*))
00217 {
00218
00219 ((uint32*)first_routine)[n]=(uint32)proc;
00220 }
00221
00222
00223 uint32 del_chainHdl(uint32 int_no, uint32 ptr)
00224 {
00225 list_t *item, *prev;
00226
00227 prev = (list_t*) NULL;
00228 item = int_lists[int_no];
00229 while (item)
00230 {
00231
00232 if (item == (list_t*) ptr)
00233 {
00234
00235 if (prev) prev->next = item -> next;
00236 else
00237
00238 int_lists[int_no] = item -> next;
00239
00240 Memory::Heap::heap0.free(item);
00241 return ESUCCESS;
00242 }
00243 prev = item;
00244 item = item -> next;
00245 }
00246 return (uint32)EINVAL;
00247 }
00248
00249
00250 int Exception(except2_t *code)
00251 {
00252 asm volatile("cli");
00253 TTYDisableLock=true;
00254
00255 alert ("\nSYSFAIL");
00256 alert(" (sysfail_dbg=");
00257 alert2(sysfail_dbg);
00258 alert(")");
00259 alert ("\nexception condition #");
00260 coutb (code->c1);
00261 write_bochs_num(code->c1, 16, 256, 'A');
00262 alert ("- ");
00263 alert ((char*) except_names[code->c1]);
00264 alert("\n%eip=0x");alert(code->eip);
00265
00266
00267
00268
00269
00270
00271
00272 panic();
00273 return ESUCCESS;
00274 }
00275
00276
00277 int PageFault(except2_t *code)
00278 {
00279 asm volatile("cli");
00280 TTYDisableLock=true;
00281 static int level=0;
00282 level++;
00283 if (level==2)
00284 sysfail("double invalid page fault");
00285 if (level==3)
00286 {
00287 alert("\ntriple invalid page fault");
00288 asm volatile ("cli\nhlt");
00289 }
00290 alert("\nSYSFAIL");
00291 alert(" (sysfail_dbg=");
00292 alert2(sysfail_dbg);
00293 alert(")");
00294 alert("\npage fault, %eip=0x");
00295 alert(code->eip);
00296 alert(", %cr2=0x");alert(code->cr2);
00297
00298 if (code->cs == Arch::x86::GDT::code_sel_kernel)
00299
00300 alert(" PF ");
00301 debug_dump_call_trace(code->eip, code->r.r_ebp);
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 for(;;);
00328 return ESUCCESS;
00329 }
00330
00331
00332 void double_fault()
00333 {
00334 TTYDisableLock=true;
00335
00336 (*(uint8*)0xb8004)='D'; (*(uint8*)0xb8005)=' ';
00337 (*(uint8*)0xb8006)='F'; (*(uint8*)0xb8007)=' ';
00338 (*(uint8*)0xb8008)='E'; (*(uint8*)0xb8009)=' ';
00339 (*(uint8*)0xb800a)='X'; (*(uint8*)0xb800b)=' ';
00340
00341 alert("\nSYSFAIL\ndouble fault\n");
00342 alert(" (sysfail_dbg=");
00343 alert2(sysfail_dbg);
00344 alert(")\n");
00345 alert( mem_ksize);
00346
00347 asm volatile ("cli\nhlt");
00348 for(;;);
00349 }
00350
00351
00352 void stack_fault()
00353 {
00354 TTYDisableLock=true;
00355 struct
00356 {
00357
00358 uint32 old_ebp;
00359
00360 uint32 thread_eip;
00361 uint32 thread_cs;
00362 uint32 thread_eflags;
00363
00364 uint32 thread_3_esp;
00365 uint32 thread_3_ss;
00366 } *stack_frame;
00367
00368
00369 asm volatile ("mov %%ebp, %%eax": "=a" (stack_frame));
00370
00371 (*(uint8*)0xb8004)='S'; (*(uint8*)0xb8005)=' ';
00372 (*(uint8*)0xb8006)='F'; (*(uint8*)0xb8007)=' ';
00373 (*(uint8*)0xb8008)='E'; (*(uint8*)0xb8009)=' ';
00374 (*(uint8*)0xb800a)='X'; (*(uint8*)0xb800b)=' ';
00375
00376 alert("\nSYSFAIL\nstack fault\n");
00377 alert(" (sysfail_dbg=");
00378 alert2(sysfail_dbg);
00379 alert(")\n");
00380 alert((uint32)stack_frame);
00381 alert((char*)¤t_thread->name);
00382
00383
00384 debug_heap_stats(&::Thread::heap);
00385
00386 asm volatile ("cli\nhlt");
00387 for(;;);
00388 }
00389
00390
00391 int Irq_H(except2_t *code)
00392 {
00393
00394 return ESUCCESS;
00395 }
00396
00397 extern "C" int SysEnter(except2_t *code);
00398
00399
00400 void init_int_chains(idt_service *ptr)
00401 {
00402 uint32 n;
00403
00404 for (n=0; n<0x30; n++)
00405 ((uint32*)&first_routine)[n] = NULL;
00406
00407 #ifndef DISABLE_EXCEPTIONS
00408
00409 ptr->set_int(0x00, &intr0x00, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00410 ptr->set_int(0x01, &intr0x01, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00411 ptr->set_int(0x02, &intr0x02, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00412 ptr->set_int(0x03, &intr0x03, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00413 ptr->set_int(0x04, &intr0x04, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00414 ptr->set_int(0x05, &intr0x05, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00415 ptr->set_int(0x06, &intr0x06, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00416 ptr->set_int(0x07, &intr0x07, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00417
00418 ptr->set_int(0x08, NULL, Arch::x86::GDT::tss_sel_kernel_df, 0x8500);
00419 ptr->set_int(0x09, &intr0x09, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00420 ptr->set_int(0x0a, &intr0x0a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00421 ptr->set_int(0x0b, &intr0x0b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00422
00423 ptr->set_int(0x0c, NULL, Arch::x86::GDT::tss_sel_kernel_sf, 0x8500);
00424 ptr->set_int(0x0d, &intr0x0d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00425
00426 ptr->set_int(0x0f, &intr0x0f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00427 ptr->set_int(0x10, &intr0x10, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00428 ptr->set_int(0x11, &intr0x11, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00429 ptr->set_int(0x12, &intr0x12, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00430 ptr->set_int(0x13, &intr0x13, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00431 ptr->set_int(0x14, &intr0x14, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00432 ptr->set_int(0x15, &intr0x15, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00433 ptr->set_int(0x16, &intr0x16, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00434 ptr->set_int(0x17, &intr0x17, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00435 ptr->set_int(0x18, &intr0x18, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00436 ptr->set_int(0x19, &intr0x19, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00437 ptr->set_int(0x1a, &intr0x1a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00438 ptr->set_int(0x1b, &intr0x1b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00439 ptr->set_int(0x1c, &intr0x1c, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00440 ptr->set_int(0x1d, &intr0x1d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00441 ptr->set_int(0x1e, &intr0x1e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00442 ptr->set_int(0x1f, &intr0x1f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00443 #endif
00444 ptr->set_int(0x0e, &intr0x0e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00445
00446 ptr->set_int(0x20, &intr0x20, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00447 ptr->set_int(0x21, &intr0x21, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00448 ptr->set_int(0x22, &intr0x22, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00449 ptr->set_int(0x23, &intr0x23, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00450 ptr->set_int(0x24, &intr0x24, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00451 ptr->set_int(0x25, &intr0x25, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00452 ptr->set_int(0x26, &intr0x26, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00453 ptr->set_int(0x27, &intr0x27, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00454 ptr->set_int(0x28, &intr0x28, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00455 ptr->set_int(0x29, &intr0x29, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00456 ptr->set_int(0x2a, &intr0x2a, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00457 ptr->set_int(0x2b, &intr0x2b, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00458 ptr->set_int(0x2c, &intr0x2c, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00459 ptr->set_int(0x2d, &intr0x2d, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00460 ptr->set_int(0x2e, &intr0x2e, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00461 ptr->set_int(0x2f, &intr0x2f, Arch::x86::GDT::code_sel_kernel, DEF_INT_FLAGS);
00462
00463
00464 ptr->install_except((void(*)())&chain_handler);
00465
00466
00467 for (n=0; n<0x20; n++)
00468 {
00469 int_lists[n] = (list_t*)Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN,FAC_INTERR|FAC_EXCLIST, NULL);
00470 int_lists[n]->next = 0;
00471 int_lists[n]->proc = &Exception;
00472 }
00473
00474
00475 int_lists[INT_PF]->proc= &PageFault;
00476
00477
00478 for (n=0x20; n<0x30; n++)
00479 {
00480 int_lists[n] = (list_t*)Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN,FAC_INTERR|FAC_EXCLIST, NULL);
00481 int_lists[n]->next = 0;
00482 int_lists[n]->proc = &Irq_H;
00483 }
00485
00486
00487 int_lists[SYSENT]= (list_t*)Memory::Heap::heap0.malloc(sizeof(list_t),NO_ALIGN,FAC_INTERR|FAC_EXCLIST, NULL);
00488 int_lists[SYSENT]->next = 0;
00489 int_lists[SYSENT]->proc = &SysEnter;
00490 }
00491
00492
00493 void done_int_chains()
00494 {
00495
00496 __asm__ __volatile__ ("cli");
00497
00498 IOPorts::outb(DEF_PIC_M_PORT+1, 0xff);
00499 IOPorts::outb(DEF_PIC_S_PORT+1, 0xff);
00500
00501 uint32 n;
00502 list_t *item, *temp;
00503
00504 for (n=0; n< 0x30; n++)
00505 {
00506 item = int_lists[n];
00507 while (item)
00508 {
00509 temp = item -> next;
00510 Memory::Heap::heap0.free(item);
00511 item = temp;
00512 }
00513 }
00514 }
00515
00516
00517 };
00518 };
00519 };
00520
00521
00522
00523
00524
00525
00526