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