UbixOS  2.0
idt.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <ubixos/syscall.h>
30 #include <ubixos/syscall_posix.h>
31 #include <sys/idt.h>
32 #include <sys/gdt.h>
33 #include <sys/io.h>
34 #include <ubixos/sched.h>
35 #include <isa/8259.h>
36 #include <lib/kprintf.h>
37 #include <lib/kmalloc.h>
38 #include <vmm/vmm.h>
39 #include <ubixos/kpanic.h>
40 #include <ubixos/endtask.h>
41 #include <string.h>
42 #include <sys/trap.h>
43 
44 #define FP_TO_LINEAR(seg, off) ((void*) ((((uint16_t) (seg)) << 4) + ((uint16_t) (off))))
45 
46 static uint32_t gpfStack = 0x0;
47 
48 void intNull();
49 
50 void _divideError();
51 void __divideError(struct trapframe *);
52 
53 void _debug();
54 void __debug(struct trapframe *);
55 
56 void _nmi();
57 void __nmi(struct trapframe *);
58 
59 static void _int3();
60 static void _int4();
61 static void _int5();
62 static void _int6();
63 static void _int7();
64 
65 void _doubleFault();
66 void __doubleFault(struct trapframe *);
67 
68 static void _int9();
69 static void _int10();
70 static void _int11();
71 static void _int12();
72 
73 void _gpf();
74 void __gpf(struct trapframe *);
75 
76 void _floatingPoint();
77 void __floatingPoint(struct trapframe *);
78 
79 void _alignmentCheck();
80 void __alignmentCheck(struct trapframe *);
81 
82 void _machineCheck();
83 void __machineCheck(struct trapframe *);
84 
85 void _simd();
86 void __simd(struct trapframe *);
87 
88 void _virtualization();
89 void __virtualization(struct trapframe *);
90 
91 void _security();
92 void __security(struct trapframe *);
93 
94 static ubixDescriptorTable(ubixIDT, 256) {};
95 
96 static struct {
97  unsigned short limit __attribute__((packed));
98  union descriptorTableUnion *idt __attribute__((packed));
99 } loadidt = { (256 * sizeof(union descriptorTableUnion) - 1), ubixIDT };
100 
101 /************************************************************************
102 
103  Function: int idtInit()
104  Description: This function is used to enable our IDT subsystem
105  Notes:
106 
107  02/20/2004 - Approved for quality
108 
109  ************************************************************************/
110 int idt_init() {
111  struct tssStruct *sfTSS = (struct tssStruct *) 0x6200;
112  struct tssStruct *gpfTSS = (struct tssStruct *) 0x5200;
113 
114  /* Load the IDT into the system */
115  asm volatile(
116  "cli \n"
117  "lidt (%0) \n" /* Load the IDT */
118  "pushfl \n" /* Clear the NT flag */
119  "andl $0xffffbfff,(%%esp) \n"
120  "popfl \n"
121  "sti \n"
122  :
123  : "r" ((char *)&loadidt)
124  );
125 
126  for (int i = 0;i < 256;i++)
128 
129  /* Set up the basic vectors for the reserved ints */
132  setVector(_nmi, 2, dPresent + dInt + dDpl0);
133  setVector(_int3, 3, dPresent + dInt + dDpl0);
134  setVector(_int4, 4, dPresent + dInt + dDpl0);
135  setVector(_int5, 5, dPresent + dInt + dDpl0);
136  setVector(_int6, 6, dPresent + dTrap + dDpl0);
137  setVector(_int7, 7, dPresent + dInt + dDpl0);
139  //setTaskVector(8, dPresent + dTask + dDpl0, 0x40);
140  setVector(_int9, 9, dPresent + dInt + dDpl0);
141  setVector(_int10, 10, dPresent + dInt + dDpl0);
142  setVector(_int11, 11, dPresent + dInt + dDpl0);
143  setVector(_int12, 12, dPresent + dInt + dDpl0);
144  //setVector(_gpf, 13, dPresent + dInt + dDpl0);
145  setTaskVector(13, dPresent + dTask + dDpl0, 0x38);
150  setVector(_simd, 19, dPresent + dInt + dDpl0);
154  setVector(_sys_call, 0x81, dPresent + dTrap + dDpl3);
155  setVector(timerInt, 0x68, (dInt + dPresent + dDpl0));
156 
157  memset(gpfTSS, 0x0, sizeof(struct tssStruct));
158 
159  gpfStack = 0x1D000;//(uint32_t)vmm_getFreeKernelPage(sysID, 1) + (PAGE_SIZE - 0x4);
160 
161  gpfTSS->back_link = 0x0;
162  gpfTSS->esp0 = 0x0;
163  gpfTSS->ss0 = 0x0;
164  gpfTSS->esp1 = 0x0;
165  gpfTSS->ss1 = 0x0;
166  gpfTSS->esp2 = 0x0;
167  gpfTSS->ss2 = 0x0;
168  gpfTSS->cr3 = (unsigned int) kernelPageDirectory;
169  gpfTSS->eip = (unsigned int) &_gpf;
170  gpfTSS->eflags = 0x206;
171  gpfTSS->esp = gpfStack; //0x1D000;
172  gpfTSS->ebp = 0x0; // 0x1D000;
173  gpfTSS->esi = 0x0;
174  gpfTSS->edi = 0x0;
175  gpfTSS->es = 0x10;
176  gpfTSS->cs = 0x08;
177  gpfTSS->ss = 0x10;
178  gpfTSS->ds = 0x10;
179  gpfTSS->fs = 0x10;
180  gpfTSS->gs = 0x10;
181  gpfTSS->ldt = 0x0;
182  gpfTSS->trace_bitmap = 0x0000;
183  gpfTSS->io_map = 0x8000;
184 
185  /*
186  memset(sfTSS, 0x0, sizeof(struct tssStruct));
187  sfTSS->cr3 = (unsigned int) kernelPageDirectory;
188  sfTSS->eip = (unsigned int) &__int8;
189  sfTSS->eflags = 0x206;
190  sfTSS->esp = 0x1C000;
191  sfTSS->ebp = 0x1C000;
192  sfTSS->es = 0x10;
193  sfTSS->cs = 0x08;
194  sfTSS->ss = 0x10;
195  sfTSS->ds = 0x10;
196  sfTSS->fs = 0x10;
197  sfTSS->gs = 0x10;
198  sfTSS->io_map = 0x8000;
199  */
200 
201  /* Print out information for the IDT */
202  kprintf("idt0 - Address: [0x%X]\n", &ubixIDT);
203 
204  /* Return so we know all went well */
205  return (0x0);
206 }
207 
208 /* Sets Up IDT Vector */
209 void setVector(void *handler, unsigned char interrupt, unsigned short controlMajor) {
210  unsigned short codesegment = 0x08;
211  asm volatile ("movw %%cs,%0":"=g" (codesegment));
212 
213  ubixIDT[interrupt].gate.offsetLow = (unsigned short) (((unsigned long) handler) & 0xffff);
214  ubixIDT[interrupt].gate.selector = codesegment;
215  ubixIDT[interrupt].gate.access = controlMajor;
216  ubixIDT[interrupt].gate.offsetHigh = (unsigned short) (((unsigned long) handler) >> 16);
217 }
218 
219 /************************************************************************
220 
221  Function: void setTaskVector(uInt8,uInt16,uInt8);
222  Description: This Function Sets Up An IDT Task Vector
223  Notes:
224 
225  ************************************************************************/
226 void setTaskVector(uInt8 interrupt, uInt16 controlMajor, uInt8 selector) {
227  uInt16 codesegment = 0x08;
228  asm volatile ("movw %%cs,%0":"=g" (codesegment));
229 
230  ubixIDT[interrupt].gate.offsetLow = 0x0;
231  ubixIDT[interrupt].gate.selector = selector;
232  ubixIDT[interrupt].gate.access = controlMajor;
233  ubixIDT[interrupt].gate.offsetHigh = 0x0;
234 }
235 
236 /* Null Intterupt Descriptor */
237 void _intNull(struct trapframe *frame) {
238  die_if_kernel("invalid exception", frame, 0x0);
239 }
240 
241 asm(
242  ".globl intNull \n"
243  "intNull: \n"
244  " pushl $0x0 \n"
245  " pushl $0x0 \n"
246  " pushal \n" /* Save all registers */
247  " push %ds \n"
248  " push %es \n"
249  " push %fs \n"
250  " push %gs \n"
251  " push %esp \n"
252  " call _intNull \n"
253  " pop %gs \n"
254  " pop %fs \n"
255  " pop %es \n"
256  " pop %ds \n"
257  " popal \n"
258  " iret \n"
259 );
260 
261 void __divideError(struct trapframe *frame) {
262  die_if_kernel("Divid-by-Zero", frame, 0);
263  endTask(_current->id);
264  sched_yield();
265 }
266 
267 asm(
268  ".globl _divideError \n"
269  "_divideError: \n"
270  " pushl $0x0 \n"
271  " pushl $0x6 \n"
272  " pushal \n" /* Save all registers */
273  " push %ds \n"
274  " push %es \n"
275  " push %fs \n"
276  " push %gs \n"
277  " push %esp \n"
278  " call _divideError \n"
279  " pop %gs \n"
280  " pop %fs \n"
281  " pop %es \n"
282  " pop %ds \n"
283  " popal \n"
284  " iret \n"
285 );
286 
287 void __debug(struct trapframe *frame) {
288  die_if_kernel("debug", frame, 0x2);
289  endTask(_current->id);
290  sched_yield();
291 }
292 
293 asm(
294  ".globl _debug \n"
295  "_debug: \n"
296  " pushl $0x0 \n"
297  " pushl $0x6 \n"
298  " pushal \n" /* Save all registers */
299  " push %ds \n"
300  " push %es \n"
301  " push %fs \n"
302  " push %gs \n"
303  " push %esp \n"
304  " call _debug \n"
305  " pop %gs \n"
306  " pop %fs \n"
307  " pop %es \n"
308  " pop %ds \n"
309  " popal \n"
310  " iret \n"
311 );
312 
313 void __nmi(struct trapframe *frame) {
314  die_if_kernel("nmi", frame, 0x2);
315  endTask(_current->id);
316  sched_yield();
317 }
318 
319 asm(
320  ".globl _nmi \n"
321  "_nmi: \n"
322  " pushl $0x0 \n"
323  " pushl $0x6 \n"
324  " pushal \n" /* Save all registers */
325  " push %ds \n"
326  " push %es \n"
327  " push %fs \n"
328  " push %gs \n"
329  " push %esp \n"
330  " call _nmi \n"
331  " pop %gs \n"
332  " pop %fs \n"
333  " pop %es \n"
334  " pop %ds \n"
335  " popal \n"
336  " iret \n"
337 );
338 
339 
340 static void _int3() {
341  kpanic("int3: Breakpoint [%i]\n", _current->id);
342  endTask(_current->id);
343  sched_yield();
344 }
345 
346 static void _int4() {
347  kpanic("int4: Overflow [%i]\n", _current->id);
348  endTask(_current->id);
349  sched_yield();
350 }
351 
352 static void _int5() {
353  kpanic("int5: Bounds check [%i]\n", _current->id);
354  endTask(_current->id);
355  sched_yield();
356 }
357 
358 void __int6(struct trapframe *frame) {
359  die_if_kernel("invalid_opcode", frame, 6);
360  endTask(_current->id);
361  sched_yield();
362 }
363 
364 asm(
365  ".globl _int6 \n"
366  "_int6: \n"
367  " pushl $0x0 \n"
368  " pushl $0x6 \n"
369  " pushal \n" /* Save all registers */
370  " push %ds \n"
371  " push %es \n"
372  " push %fs \n"
373  " push %gs \n"
374  " push %esp \n"
375  " call __int6 \n"
376  " pop %gs \n"
377  " pop %fs \n"
378  " pop %es \n"
379  " pop %ds \n"
380  " popal \n"
381  " iret \n" /* Exit interrupt */
382 );
383 
384 void __doubleFault(struct trapframe *frame) {
385  die_if_kernel("double fault", frame, 0x8);
386  endTask(_current->id);
387  sched_yield();
388 }
389 
390 asm(
391  ".globl _doubleFault \n"
392  "_doubleFault: \n"
393  " pushl $0x8 \n"
394  " pushal \n" /* Save all registers */
395  " push %ds \n"
396  " push %es \n"
397  " push %fs \n"
398  " push %gs \n"
399  " push %esp \n"
400  " call __doubleFault \n"
401  " pop %gs \n"
402  " pop %fs \n"
403  " pop %es \n"
404  " pop %ds \n"
405  " popal \n"
406  " iret \n" /* Exit interrupt */
407 );
408 
409 static void _int9() {
410  kpanic("int9: Coprocessor Segment Overrun! [%i]\n", _current->id);
411  endTask(_current->id);
412  sched_yield();
413 }
414 
415 static void _int10() {
416  kpanic("int10: Invalid TSS! [%i]\n", _current->id);
417  endTask(_current->id);
418  sched_yield();
419 }
420 
421 static void _int11() {
422  kpanic("int11: Segment Not Present! [%i]\n", _current->id);
423  endTask(_current->id);
424  sched_yield();
425 }
426 
427 static void _int12() {
428  kpanic("int12: Stack-Segment Fault! [%i]\n", _current->id);
429  endTask(_current->id);
430  sched_yield();
431 }
432 
433 void __gpf(struct trapframe *frame) {
434  uint8_t *ip = 0x0;
435  uint16_t *stack = 0x0, *ivt = 0x0;
436  uint32_t *stack32 = 0x0;
437  bool isOperand32 = FALSE, isAddress32 = FALSE;
438 
439  struct tssStruct *gpfTSS = (struct tssStruct *) 0x5200;
440 
441  gpfEnter:
442  kprintf("DF");
444 
445  ivt = (uint16_t *) 0x0;
446 
448  stack32 = (uint32_t *) stack;
449 
450  gpfStart: switch (ip[0]) {
451  case 0xCD: /* INT n */
452  switch (ip[1]) {
453  case 0x69:
454  kprintf("Exit Bios [0x%X]\n", _current->id);
455  //while (1) asm("hlt");
456  _current->state = DEAD;
457  break;
458  case 0x20:
459  case 0x21:
460  kpanic("GPF OP 0x20/0x21\n");
461  break;
462  default:
463  stack -= 3;
464  _current->tss.esp = ((_current->tss.esp & 0xffff) - 6) & 0xffff;
465  stack[0] = (uint16_t) (_current->tss.eip + 2);
466  stack[1] = _current->tss.cs;
467  stack[2] = (uint16_t) _current->tss.eflags;
468  if (_current->oInfo.v86If)
469  stack[2] |= EFLAG_IF;
470  else
471  stack[2] &= ~EFLAG_IF;
472 
473  _current->tss.cs = ivt[ip[1] * 2 + 1] & 0xFFFF;
474  _current->tss.eip = ivt[ip[1] * 2] & 0xFFFF;
475  break;
476  }
477  break;
478  case 0x66:
479  isOperand32 = TRUE;
480  ip++;
481  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
482  kprintf("0x66");
483  goto gpfStart;
484  break;
485  case 0x67:
486  isAddress32 = TRUE;
487  ip++;
488  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
489  kprintf("0x67");
490  goto gpfStart;
491  break;
492  case 0xF0:
493  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
494  kpanic("GPF OP 0xF0\n");
495  break;
496  case 0x9C:
497  if (isOperand32 == TRUE) {
498  _current->tss.esp = ((_current->tss.esp & 0xffff) - 4) & 0xffff;
499  stack32--;
500  stack32[0] = _current->tss.eflags & 0xDFF;
501  if (_current->oInfo.v86If == TRUE)
502  stack32[0] |= EFLAG_IF;
503  else
504  stack32[0] &= ~EFLAG_IF;
505  }
506  else {
507  _current->tss.esp = ((_current->tss.esp & 0xffff) - 2) & 0xffff;
508  stack--;
509 
510  stack[0] = (uInt16) _current->tss.eflags;
511  if (_current->oInfo.v86If == TRUE)
512  stack[0] |= EFLAG_IF;
513  else
514  stack[0] &= ~EFLAG_IF;
515  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
516 
517  }
518  break;
519  case 0x9D:
520  if (isOperand32 == TRUE) {
521  _current->tss.eflags = EFLAG_IF | EFLAG_VM | (stack32[0] & 0xDFF);
522  _current->oInfo.v86If = (stack32[0] & EFLAG_IF) != 0;
523  _current->tss.esp = ((_current->tss.esp & 0xffff) + 4) & 0xffff;
524  }
525  else {
526  _current->tss.eflags = EFLAG_IF | EFLAG_VM | stack[0];
527  _current->oInfo.v86If = (stack[0] & EFLAG_IF) != 0;
528  _current->tss.esp = ((_current->tss.esp & 0xffff) + 2) & 0xffff;
529  }
530  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
531  /* kprintf("popf [0x%X]\n",_current->id); */
532  break;
533  case 0xFA:
536  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
537  _current->oInfo.timer = 0x1;
538  break;
539  case 0xFB:
542  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
543  _current->oInfo.timer = 0x0;
544  /* kprintf("sti [0x%X]\n",_current->id); */
545  break;
546  case 0xCF:
547  _current->tss.eip = stack[0];
548  _current->tss.cs = stack[1];
549  _current->tss.eflags = EFLAG_IF | EFLAG_VM | stack[2];
550  _current->oInfo.v86If = (stack[2] & EFLAG_IF) != 0;
551  _current->tss.esp = ((_current->tss.esp & 0xffff) + 6) & 0xffff;
552  kprintf("iret [0x%X]\n",_current->id);
553  break;
554  case 0xEC: /* IN AL,DX */
555  _current->tss.eax = (_current->tss.eax & ~0xFF) | inportByte(_current->tss.edx);
556  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
557  break;
558  case 0xED: /* IN AX,DX */
559  _current->tss.eax = (_current->tss.eax & ~0xFFFF) | inportWord(_current->tss.edx);
560  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
561  break;
562  case 0xEE: /* OUT DX,AL */
564  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
565  break;
566  case 0xEF:
568  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
569  break;
570  case 0xF4:
571  _current->tss.eip = (uInt16) (_current->tss.eip + 1);
572  break;
573  default: /* something wrong */
574  kprintf("NonHandled OpCode [0x%X:0x%X]\n", _current->id, ip[0]);
575  //_current->state = DEAD;
576  break;
577  }
578  kprintf("RET1");
579  irqEnable(0);
580  sched_yield();
581  kprintf("RET2");
582  goto gpfEnter;
583 }
584 
585 asm(
586  ".globl _gpf \n"
587  "_gpf: \n"
588  " cli \n"
589  " pushl $0x13 \n"
590  " pushal \n" /* Save all registers */
591  " push %ds \n"
592  " push %es \n"
593  " push %fs \n"
594  " push %gs \n"
595  " push %esp \n"
596  " call __gpf \n"
597  " add $0x4,%esp \n"
598  " mov %esp,%eax \n"
599  " pop %gs \n"
600  " pop %fs \n"
601  " pop %es \n"
602  " pop %ds \n"
603  " popal \n"
604  " sti \n"
605  " iret \n" /* Exit interrupt */
606 );
607 
608 
609 void __floatingPoint(struct trapframe *frame) {
610  die_if_kernel("floating point", frame, 0x10);
611  endTask(_current->id);
612  sched_yield();
613 }
614 
615 asm(
616  ".globl _floatingPoint \n"
617  "_floatingPoint: \n"
618  " pushl $0x0 \n"
619  " pushl $0x10 \n"
620  " pushal \n" /* Save all registers */
621  " push %ds \n"
622  " push %es \n"
623  " push %fs \n"
624  " push %gs \n"
625  " push %esp \n"
626  " call __floatingPoint \n"
627  " pop %gs \n"
628  " pop %fs \n"
629  " pop %es \n"
630  " pop %ds \n"
631  " popal \n"
632  " iret \n"
633 );
634 
635 void __alignmentCheck(struct trapframe *frame) {
636  die_if_kernel("alignment check", frame, 0x11);
637  endTask(_current->id);
638  sched_yield();
639 }
640 
641 asm(
642  ".globl _alignmentCheck \n"
643  "_alignmentCheck: \n"
644  " pushl $0x11 \n"
645  " pushal \n" /* Save all registers */
646  " push %ds \n"
647  " push %es \n"
648  " push %fs \n"
649  " push %gs \n"
650  " push %esp \n"
651  " call __alignmentCheck \n"
652  " pop %gs \n"
653  " pop %fs \n"
654  " pop %es \n"
655  " pop %ds \n"
656  " popal \n"
657  " iret \n"
658 );
659 
660 void __machineCheck(struct trapframe *frame) {
661  die_if_kernel("machine check", frame, 0x12);
662  endTask(_current->id);
663  sched_yield();
664 }
665 
666 asm(
667  ".globl _machineCheck \n"
668  "_machineCheck: \n"
669  " pushl $0x0\n"
670  " pushl $0x12 \n"
671  " pushal \n" /* Save all registers */
672  " push %ds \n"
673  " push %es \n"
674  " push %fs \n"
675  " push %gs \n"
676  " push %esp \n"
677  " call __machineCheck \n"
678  " pop %gs \n"
679  " pop %fs \n"
680  " pop %es \n"
681  " pop %ds \n"
682  " popal \n"
683  " iret \n"
684 );
685 
686 void __simd(struct trapframe *frame) {
687  die_if_kernel("simd", frame, 0x13);
688  endTask(_current->id);
689  sched_yield();
690 }
691 
692 asm(
693  ".globl _simd \n"
694  "_simd: \n"
695  " iret\n"
696  " pushl $0x0\n"
697  " pushl $0x13 \n"
698  " pushal \n" /* Save all registers */
699  " push %ds \n"
700  " push %es \n"
701  " push %fs \n"
702  " push %gs \n"
703  " push %esp \n"
704  " call __simd \n"
705  " pop %gs \n"
706  " pop %fs \n"
707  " pop %es \n"
708  " pop %ds \n"
709  " popal \n"
710  " iret \n"
711 );
712 
713 void __virtualization(struct trapframe *frame) {
714  die_if_kernel("virtualization", frame, 0x14);
715  endTask(_current->id);
716  sched_yield();
717 }
718 
719 asm(
720  ".globl _virtualization \n"
721  "_virtualization: \n"
722  " pushl $0x0 \n"
723  " pushl $0x14 \n"
724  " pushal \n" /* Save all registers */
725  " push %ds \n"
726  " push %es \n"
727  " push %fs \n"
728  " push %gs \n"
729  " push %esp \n"
730  " call __virtualization \n"
731  " pop %gs \n"
732  " pop %fs \n"
733  " pop %es \n"
734  " pop %ds \n"
735  " popal \n"
736  " iret \n"
737 );
738 
739 void __security(struct trapframe *frame) {
740  die_if_kernel("security exception", frame, 0x1E);
741  endTask(_current->id);
742  sched_yield();
743 }
744 
745 asm(
746  ".globl _security \n"
747  "_security: \n"
748  " pushl $0x1E \n"
749  " pushal \n" /* Save all registers */
750  " push %ds \n"
751  " push %es \n"
752  " push %fs \n"
753  " push %gs \n"
754  " push %esp \n"
755  " call __security\n"
756  " pop %gs \n"
757  " pop %fs \n"
758  " pop %es \n"
759  " pop %ds \n"
760  " popal \n"
761  " iret \n"
762 );
763 
764 /* Removed static however this is the only place it's called from */
765 void mathStateRestore() {
766  if (_usedMath != 0x0) {
767  asm(
768  "fnsave %0"
769  :
770  : "m" (_usedMath->i387)
771  );
772  }
773  if (_current->usedMath != 0x0) {
774  asm(
775  "frstor %0"
776  :
777  : "m" (_current->i387)
778  );
779  }
780  else {
781  asm("fninit");
782  _current->usedMath = 0x1;
783  }
784 
786 
787  //Return
788 }
789 
790 
791 asm(
792  ".globl _int7 \n"
793  "_int7: \n"
794  " pushl %eax \n"
795  " clts \n"
796  " movl _current,%eax \n"
797  " cmpl _usedMath,%eax \n"
798  " je mathDone \n"
799  " call mathStateRestore \n"
800  "mathDone: \n"
801  " popl %eax \n"
802  " iret \n"
803 );
8259.h
_nmi
void _nmi()
setTaskVector
void setTaskVector(uInt8 interrupt, uInt16 controlMajor, uInt8 selector)
Definition: idt.c:224
__attribute__
union descriptorTableUnion __attribute__
gdt.h
intNull
void intNull()
_divideError
void _divideError()
_usedMath
kTask_t * _usedMath
Definition: sched.c:51
tssStruct::eip
long eip
Definition: tss.h:47
__gpf
void __gpf(struct trapframe *)
Definition: idt.c:431
dTask
#define dTask
Definition: gdt.h:45
trap.h
dPresent
#define dPresent
Definition: gdt.h:54
__nmi
void __nmi(struct trapframe *)
Definition: idt.c:311
TRUE
Definition: types.h:82
_security
void _security()
string.h
_alignmentCheck
void _alignmentCheck()
idt.h
uInt16
unsigned short int uInt16
Definition: objgfx30.h:48
outportWord
void outportWord(unsigned int, unsigned short)
outputut one word to specified port
Definition: io.c:103
tssStruct::edx
long edx
Definition: tss.h:49
tssStruct::ss1
short ss1
Definition: tss.h:41
_floatingPoint
void _floatingPoint()
_machineCheck
void _machineCheck()
tssStruct::ldt
short ldt
Definition: tss.h:66
__int6
void __int6(struct trapframe *frame)
Definition: idt.c:356
outportByte
void outportByte(unsigned int, unsigned char)
outputut one byte to specified port
Definition: io.c:72
FALSE
Definition: types.h:82
__debug
void __debug(struct trapframe *)
Definition: idt.c:285
tssStruct::ds
short ds
Definition: tss.h:60
tssStruct::eflags
long eflags
Definition: tss.h:48
vmm.h
tssStruct::esp0
long esp0
Definition: tss.h:37
tssStruct::back_link
short back_link
Definition: tss.h:35
idt_init
int idt_init()
Definition: idt.c:109
endtask.h
taskStruct::tss
struct tssStruct tss
Definition: sched.h:67
_gpf
void _gpf()
syscall.h
tssStruct::ss0
short ss0
Definition: tss.h:38
sched.h
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
osInfo::v86If
bool v86If
Definition: sched.h:53
_doubleFault
void _doubleFault()
tssStruct::ss2
short ss2
Definition: tss.h:44
tssStruct::esp
long esp
Definition: tss.h:50
inportByte
unsigned char inportByte(unsigned int)
input one byte from specified port
Definition: io.c:38
uint16_t
__uint16_t uint16_t
Definition: types.h:45
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
timerInt
void timerInt()
_sys_call
void _sys_call()
_simd
void _simd()
kprintf.h
__doubleFault
void __doubleFault(struct trapframe *)
Definition: idt.c:382
kernelPageDirectory
uint32_t * kernelPageDirectory
Definition: paging.c:41
uInt8
unsigned char uInt8
Definition: objgfx30.h:47
EFLAG_IF
#define EFLAG_IF
Definition: bioscall.h:35
tssStruct::ss
short ss
Definition: tss.h:58
descriptorTableUnion
Definition: gdt.h:83
tssStruct::esp1
long esp1
Definition: tss.h:40
osInfo::timer
uInt8 timer
Definition: sched.h:51
uint32_t
__uint32_t uint32_t
Definition: types.h:46
ubixDescriptorTable
ubixDescriptorTable(ubixGDT, 11)
Definition: main.c:92
__simd
void __simd(struct trapframe *)
Definition: idt.c:684
trapframe
Definition: trap.h:34
dTrap
#define dTrap
Definition: gdt.h:46
tssStruct
Definition: tss.h:34
taskStruct::usedMath
uInt16 usedMath
Definition: sched.h:76
tssStruct::es
short es
Definition: tss.h:54
__security
void __security(struct trapframe *)
Definition: idt.c:737
DEAD
Definition: sched.h:47
taskStruct::i387
struct i387Struct i387
Definition: sched.h:68
syscall_posix.h
mathStateRestore
void mathStateRestore()
Definition: idt.c:763
_sys_call_posix
void _sys_call_posix()
endTask
void endTask(pidType)
Definition: endtask.c:44
inportWord
unsigned short inportWord(unsigned int)
input one word from specified port
Definition: io.c:55
__machineCheck
void __machineCheck(struct trapframe *)
Definition: idt.c:658
__virtualization
void __virtualization(struct trapframe *)
Definition: idt.c:711
_current
kTask_t * _current
Definition: sched.c:50
selector
unsigned short selector
Definition: gdt.h:81
tssStruct::cs
short cs
Definition: tss.h:56
_debug
void _debug()
_intNull
void _intNull(struct trapframe *frame)
Definition: idt.c:235
tssStruct::fs
short fs
Definition: tss.h:62
dInt
#define dInt
Definition: gdt.h:43
tssStruct::edi
long edi
Definition: tss.h:53
__divideError
void __divideError(struct trapframe *)
Definition: idt.c:259
tssStruct::io_map
short io_map
Definition: tss.h:69
tssStruct::ebp
long ebp
Definition: tss.h:51
__alignmentCheck
void __alignmentCheck(struct trapframe *)
Definition: idt.c:633
__floatingPoint
void __floatingPoint(struct trapframe *)
Definition: idt.c:607
taskStruct::state
tState state
Definition: sched.h:72
io.h
die_if_kernel
void die_if_kernel(char *str, struct trapframe *regs, long err)
Definition: trap.c:59
memset
void * memset(void *dst, int c, size_t length)
tssStruct::esi
long esi
Definition: tss.h:52
_vmm_pageFault
void _vmm_pageFault()
irqEnable
void irqEnable(uInt16 irqNo)
setVector
void setVector(void *handler, unsigned char interrupt, unsigned short controlMajor)
Definition: idt.c:208
tssStruct::trace_bitmap
short trace_bitmap
Definition: tss.h:68
uint8_t
__uint8_t uint8_t
Definition: types.h:44
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
FP_TO_LINEAR
#define FP_TO_LINEAR(seg, off)
Definition: idt.c:44
tssStruct::cr3
long cr3
Definition: tss.h:46
tssStruct::esp2
long esp2
Definition: tss.h:43
dDpl0
#define dDpl0
Definition: gdt.h:53
tssStruct::gs
short gs
Definition: tss.h:64
EFLAG_VM
#define EFLAG_VM
Definition: bioscall.h:37
kmalloc.h
taskStruct::oInfo
struct osInfo oInfo
Definition: sched.h:69
tssStruct::eax
long eax
Definition: tss.h:49
_virtualization
void _virtualization()
sched_yield
void sched_yield()
Definition: sched.c:244
dDpl3
#define dDpl3
Definition: gdt.h:50