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