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 
00028 
00029 
00030 #include <sys/idt.h>
00031 #include <sys/gdt.h>
00032 #include <sys/io.h>
00033 #include <ubixos/sched.h>
00034 #include <isa/8259.h>
00035 #include <lib/kprintf.h>
00036 #include <lib/kmalloc.h>
00037 #include <vmm/vmm.h>
00038 #include <ubixos/syscall.h>
00039 #include <ubixos/kpanic.h>
00040 #include <ubixos/endtask.h>
00041 #include <string.h>
00042 
00043 #define FP_TO_LINEAR(seg, off) ((void*) ((((uInt16) (seg)) << 4) + ((uInt16) (off))))
00044 
00045 static ubixDescriptorTable(ubixIDT, 256) { };
00046 
00047 static struct {
00048   unsigned short limit __attribute__((packed));
00049   union descriptorTableUnion *idt __attribute__((packed));
00050   } loadidt = {
00051     (256 * sizeof(union descriptorTableUnion) - 1), ubixIDT
00052     };
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 int idt_init() {
00064   int i = 0x0;
00065 
00066   struct tssStruct *sfTSS  = (struct tssStruct *)0x6200;
00067   struct tssStruct *gpfTSS = (struct tssStruct *)0x4200;
00068 
00069   
00070 
00071   for (i = 0x0; i < 256; i++) {
00072     setVector(intNull, i, dPresent + dInt + dDpl3);
00073     }
00074 
00075   
00076   asm volatile(
00077     "cli                      \n"
00078     "lidt (%0)                \n"  
00079     "pushfl                   \n"  
00080     "andl $0xffffbfff,(%%esp)  \n"
00081     "popfl                    \n"
00082     "sti                      \n"
00083     :
00084     : "r" ((char *)&loadidt)
00085     );
00086 
00087   
00088   setVector(_int0, 0, dPresent + dInt + dDpl0);
00089   setVector(_int1, 1, dPresent + dInt + dDpl0);
00090   setVector(_int2, 2, dPresent + dInt + dDpl0);
00091   setVector(_int3, 3, dPresent + dInt + dDpl0);
00092   setVector(_int4, 4, dPresent + dInt + dDpl0);
00093   setVector(_int5, 5, dPresent + dInt + dDpl0);
00094   setVector(_int6, 6, dPresent + dInt + dDpl0);
00095   setVector(_int7,7,dPresent + dInt + dDpl0);
00096   setTaskVector(8,dPresent + dTask + dDpl0, 0x40);
00097   setVector(_int9, 9, dPresent + dInt + dDpl0);
00098   setVector(_int10, 10, dPresent + dInt + dDpl0);
00099   setVector(_int11, 11, dPresent + dInt + dDpl0);
00100   setVector(_int12, 12, dPresent + dInt + dDpl0);
00101   setTaskVector(13, dPresent + dTask + dDpl0, 0x38);
00102   setVector(_vmm_pageFault, 14, dPresent + dInt + dDpl0);
00103   setVector(_sysCall, 128, dPresent + dTrap + dDpl3);
00104   setVector(_sysCall_new, 0x81, dPresent + dTrap + dDpl3);
00105   
00106   setVector(timerInt, 0x68, (dInt + dPresent + dDpl0));
00107 
00108 
00109   gpfTSS->back_link    = 0x0;
00110   gpfTSS->esp0         = 0x0;
00111   gpfTSS->ss0          = 0x0;
00112   gpfTSS->esp1         = 0x0;
00113   gpfTSS->ss1          = 0x0;
00114   gpfTSS->esp2         = 0x0;
00115   gpfTSS->ss2          = 0x0;
00116   gpfTSS->cr3          = (unsigned int)kernelPageDirectory;
00117   gpfTSS->eip          = (unsigned int)&_int13;
00118   gpfTSS->eflags       = 0x206;
00119   gpfTSS->esp          = 0x1D000;
00120   gpfTSS->ebp          = 0x1D000;
00121   gpfTSS->esi          = 0x0;
00122   gpfTSS->edi          = 0x0;
00123   gpfTSS->es           = 0x10;
00124   gpfTSS->cs           = 0x08;
00125   gpfTSS->ss           = 0x10;
00126   gpfTSS->ds           = 0x10;
00127   gpfTSS->fs           = 0x10;
00128   gpfTSS->gs           = 0x10;
00129   gpfTSS->ldt          = 0x0;
00130   gpfTSS->trace_bitmap = 0x0000;
00131   gpfTSS->io_map       = 0x8000;
00132   
00133   memset(sfTSS,0x0,sizeof(struct tssStruct));
00134   sfTSS->cr3           = (unsigned int)kernelPageDirectory;
00135   sfTSS->eip           = (unsigned int)&_int8;
00136   sfTSS->eflags        = 0x206;
00137   sfTSS->esp           = 0x1C000;
00138   sfTSS->ebp           = 0x1C000;
00139   sfTSS->es            = 0x10;
00140   sfTSS->cs            = 0x08;
00141   sfTSS->ss            = 0x10;
00142   sfTSS->ds            = 0x10;
00143   sfTSS->fs            = 0x10;
00144   sfTSS->gs            = 0x10;
00145   sfTSS->io_map        = 0x8000;
00146 
00147   
00148   kprintf("idt0 - Address: [0x%X]\n", &ubixIDT);
00149 
00150   
00151   return (0x0);
00152   }
00153 
00154 
00155 
00156 void setVector(void *handler, unsigned char interrupt, unsigned short controlMajor) {
00157   unsigned short  codesegment = 0x08;
00158   asm             volatile ("movw %%cs,%0":"=g" (codesegment));
00159 
00160   ubixIDT[interrupt].gate.offsetLow = (unsigned short)(((unsigned long)handler) & 0xffff);
00161   ubixIDT[interrupt].gate.selector = codesegment;
00162   ubixIDT[interrupt].gate.access = controlMajor;
00163   ubixIDT[interrupt].gate.offsetHigh = (unsigned short)(((unsigned long)handler) >> 16);
00164 }
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 void 
00174 setTaskVector(uInt8 interrupt, uInt16 controlMajor, uInt8 selector)
00175 {
00176   uInt16          codesegment = 0x08;
00177   asm             volatile ("movw %%cs,%0":"=g" (codesegment));
00178 
00179   ubixIDT[interrupt].gate.offsetLow = 0x0;
00180   ubixIDT[interrupt].gate.selector = selector;
00181   ubixIDT[interrupt].gate.access = controlMajor;
00182   ubixIDT[interrupt].gate.offsetHigh = 0x0;
00183 }
00184 
00185 
00186 
00187 void intNull() {
00188   kprintf("Invalid Interrupt[%i]\n",_current->id);
00189 
00190 
00191 
00192 
00193 
00194 
00195   }
00196 
00197 void _int0() {
00198   kpanic("int0: Divide-by-Zero [%i]\n",_current->id);
00199   endTask(_current->id);
00200   sched_yield();
00201   }
00202 
00203 void _int1() {
00204   kpanic("int1: Debug exception [%i]\n",_current->id);
00205   endTask(_current->id);
00206   sched_yield();
00207   }
00208 
00209 void _int2() {
00210   kpanic("int2: unknown error [%i]\n",_current->id);
00211   endTask(_current->id);
00212   sched_yield();
00213   }
00214 
00215 void _int3() {
00216   kpanic("int3: Breakpoint [%i]\n",_current->id);
00217   endTask(_current->id);
00218   sched_yield();
00219   }
00220 
00221 void _int4(){
00222   kpanic("int4: Overflow [%i]\n",_current->id);
00223   endTask(_current->id);
00224   sched_yield();
00225   }
00226 
00227 void  _int5() {
00228   kpanic("int5: Bounds check [%i]\n",_current->id);
00229   endTask(_current->id);
00230   sched_yield();
00231   }
00232 
00233 void _int6() {
00234   kpanic("int6: Invalid opcode! [%i]\n",_current->id);
00235   endTask(_current->id);
00236   sched_yield();
00237   }
00238 
00239 void _int8() {
00240   struct tssStruct *sfTSS  = (struct tssStruct *)0x6200;
00241   kpanic("int8: Double Fault! [%i]\n",_current->id);
00242   sfTSS->cr3           = (unsigned int)kernelPageDirectory;
00243   sfTSS->eip           = (unsigned int)&_int8;
00244   sfTSS->eflags        = 0x206;
00245   sfTSS->esp           = 0x1C000;
00246   sfTSS->ebp           = 0x1C000;
00247   sfTSS->es            = 0x10;
00248   sfTSS->cs            = 0x08;
00249   sfTSS->ss            = 0x10;
00250   sfTSS->ds            = 0x10;
00251   sfTSS->fs            = 0x10;
00252   sfTSS->gs            = 0x10;
00253   sfTSS->io_map        = 0x8000;
00254   while (1);
00255  }
00256 
00257 void _int9() {
00258   kpanic("int9: Coprocessor Segment Overrun! [%i]\n",_current->id);
00259   endTask(_current->id);
00260   sched_yield();
00261   }
00262 
00263 void _int10() {
00264   kpanic("int10: Invalid TSS! [%i]\n",_current->id);
00265   endTask(_current->id);
00266   sched_yield();
00267   }
00268 
00269 void _int11() {
00270   kpanic("int11: Segment Not Present! [%i]\n",_current->id);
00271   endTask(_current->id);
00272   sched_yield();
00273   }
00274 
00275 void _int12() {
00276   kpanic("int12: Stack-Segment Fault! [%i]\n",_current->id);
00277   endTask(_current->id);
00278   sched_yield();
00279   }
00280 
00281 void _int13() {
00282   uInt8          *ip = 0x0;
00283   uInt16         *stack = 0x0, *ivt = 0x0;
00284   uInt32         *stack32 = 0x0;
00285   bool            isOperand32 = FALSE, isAddress32 = FALSE;
00286   struct tssStruct *gpfTSS = (struct tssStruct *)0x4200;
00287 
00288   irqDisable(0x0);
00289   
00290   gpfTSS->eip            = (unsigned int)&_int13;
00291   gpfTSS->esp            = 0x1D000;
00292   gpfTSS->ebp            = 0x1D000;
00293   gpfTSS->eflags         = 0x206;
00294   
00295   ip      = FP_TO_LINEAR(_current->tss.cs, _current->tss.eip);
00296   ivt = (uInt16 *) 0x0;
00297   stack   = (uInt16 *) FP_TO_LINEAR(_current->tss.ss,_current->tss.esp);
00298   stack32 = (uInt32 *) stack;
00299 
00300 gpfStart:
00301   switch (ip[0]) {
00302   case 0xCD:                    
00303     switch (ip[1]) {
00304     case 0x69:
00305       kprintf("Exit Bios [0x%X]\n",_current->id);
00306       _current->state = DEAD;
00307       break;
00308     case 0x20:
00309     case 0x21:
00310       kpanic("GPF OP 0x20/0x21\n");
00311       break;
00312     default:
00313       stack -= 3;
00314       _current->tss.esp = ((_current->tss.esp & 0xffff) - 6) & 0xffff;
00315       stack[0] = (uInt16) (_current->tss.eip + 2);
00316       stack[1] = _current->tss.cs; stack[2] = (uInt16) _current->tss.eflags;
00317       if (_current->oInfo.v86If)
00318         stack[2] |= EFLAG_IF;
00319       else
00320         stack[2] &= ~EFLAG_IF;
00321       _current->tss.cs  = ivt[ip[1] * 2 + 1] & 0xFFFF;
00322       _current->tss.eip    = ivt[ip[1] * 2] & 0xFFFF;
00323       break;
00324     }
00325     break;
00326   case 0x66:
00327     isOperand32 = TRUE;
00328     ip++;
00329     _current->tss.eip = (uInt16) (_current->tss.eip + 1); 
00330     goto gpfStart;
00331     break;
00332   case 0x67:
00333     isAddress32 = TRUE;
00334     ip++;
00335     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00336     goto gpfStart;
00337     break;
00338   case 0xF0:
00339     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00340     kpanic("GPF OP 0xF0\n");
00341     break;
00342   case 0x9C:
00343     if (isOperand32 == TRUE) {
00344       _current->tss.esp = ((_current->tss.esp & 0xffff) - 4) & 0xffff;
00345       stack32--;
00346      stack32[0] = _current->tss.eflags & 0xDFF;
00347      if (_current->oInfo.v86If == TRUE) 
00348        stack32[0] |= EFLAG_IF;
00349      else stack32[0] &= ~EFLAG_IF;
00350     } else {
00351       _current->tss.esp = ((_current->tss.esp & 0xffff) - 2) & 0xffff;
00352       stack--;
00353 
00354        stack[0] = (uInt16) _current->tss.eflags;
00355        if (_current->oInfo.v86If == TRUE) stack[0] |= EFLAG_IF;
00356        else stack[0] &= ~EFLAG_IF;
00357        _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00358        
00359     }
00360     break;
00361   case 0x9D:
00362     if (isOperand32 == TRUE) {
00363       _current->tss.eflags = EFLAG_IF | EFLAG_VM | (stack32[0] & 0xDFF);
00364       _current->oInfo.v86If = (stack32[0] & EFLAG_IF) != 0;
00365       _current->tss.esp = ((_current->tss.esp & 0xffff) + 4) & 0xffff;
00366     } else {
00367       _current->tss.eflags = EFLAG_IF | EFLAG_VM | stack[0];
00368       _current->oInfo.v86If = (stack[0] & EFLAG_IF) != 0;
00369       _current->tss.esp = ((_current->tss.esp & 0xffff) + 2) & 0xffff;
00370     }
00371     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00372     
00373     break;
00374   case 0xFA:
00375     _current->oInfo.v86If = FALSE;
00376     _current->tss.eflags &= ~EFLAG_IF;
00377     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00378     _current->oInfo.timer = 0x1;
00379     break;
00380   case 0xFB:
00381     _current->oInfo.v86If = TRUE;
00382     _current->tss.eflags |= EFLAG_IF;
00383     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00384     _current->oInfo.timer = 0x0;
00385     
00386     break;
00387   case 0xCF:
00388     _current->tss.eip = stack[0];
00389     _current->tss.cs = stack[1];
00390     _current->tss.eflags = EFLAG_IF | EFLAG_VM | stack[2];
00391     _current->oInfo.v86If = (stack[2] & EFLAG_IF) != 0;
00392     _current->tss.esp = ((_current->tss.esp & 0xffff) + 6) & 0xffff;
00393     
00394     break;
00395   case 0xEC:                    
00396     _current->tss.eax = (_current->tss.eax & ~0xFF) | inportByte(_current->tss.edx);
00397     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00398     break;
00399   case 0xED:                    
00400     _current->tss.eax = (_current->tss.eax & ~0xFFFF) | inportWord(_current->tss.edx);
00401     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00402     break;
00403   case 0xEE:                    
00404     outportByte(_current->tss.edx, _current->tss.eax & 0xFF);
00405     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00406     break;
00407   case 0xEF:
00408     outportWord(_current->tss.edx, _current->tss.eax);
00409     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00410     break;
00411   case 0xF4:
00412     _current->tss.eip = (uInt16) (_current->tss.eip + 1);
00413     break;
00414   default:                      
00415      kprintf("NonHandled OpCode [0x%X:0x%X]\n",_current->id,ip[0]);
00416      _current->state = DEAD;
00417     break;
00418     }
00419   irqEnable(0);
00420   while (1);
00421   }
00422 
00423 
00424 void mathStateRestore() {
00425   if (_usedMath != 0x0) {
00426     asm(
00427       "fnsave %0"
00428       :
00429       : "m" (_usedMath->i387)
00430       );
00431     }
00432   if (_current->usedMath != 0x0) {
00433     asm(
00434       "frstor %0"
00435       :
00436       : "m" (_current->i387)
00437       );
00438     }
00439   else {
00440     asm("fninit");
00441     _current->usedMath = 0x1;
00442     }
00443 
00444   _usedMath=_current;
00445 
00446   
00447   }
00448 
00449 void _int7();
00450 asm(
00451   ".globl _int7              \n"
00452   "_int7:                    \n"
00453   "  pushl %eax              \n"
00454   "  clts                    \n"
00455   "  movl _current,%eax      \n"
00456   "  cmpl _usedMath,%eax     \n"
00457   "  je mathDone             \n"
00458   "  call mathStateRestore   \n"
00459   "mathDone:                 \n"
00460   "  popl %eax               \n"
00461   "  iret                    \n"
00462   );
00463 
00464 
00465 
00466