IBNOS
interrupt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Michael Müller
3  * Copyright (c) 2014, Sebastian Lackner
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #include <interrupt/interrupt.h>
29 #include <hardware/gdt.h>
30 #include <memory/physmem.h>
31 
32 #include <process/object.h>
33 #include <process/process.h>
34 #include <process/thread.h>
35 #include <process/semaphore.h>
36 #include <process/pipe.h>
37 #include <process/event.h>
38 #include <process/timer.h>
39 #include <process/filesystem.h>
40 
41 #include <loader/elf.h>
42 #include <console/console.h>
43 #include <util/util.h>
44 #include <syscall.h>
45 
70 static interrupt_callback interruptTable[IDT_MAX_COUNT];
71 
83 uint32_t dispatchInterrupt(uint32_t interrupt, uint32_t error, struct thread *t)
84 {
85  uint32_t status = INTERRUPT_UNHANDLED;
86 
87  /*
88  consoleWriteString("interrupt(");
89  consoleWriteHex32(interrupt);
90  consoleWriteString(", ");
91  consoleWriteHex32(error);
92  consoleWriteString(", ");
93  consoleWriteHex32((uint32_t)t);
94  consoleWriteString(")\n");
95  */
96 
97  if (interruptTable[interrupt])
98  status = interruptTable[interrupt](interrupt, error, t);
99 
100  if (t && status == INTERRUPT_UNHANDLED)
101  {
102  t->task.ebx = -2; /* terminate with exit code -2 */
103  status = INTERRUPT_EXIT_PROCESS;
104  }
105 
106  return status;
107 }
108 
123 uint32_t interrupt_0x07(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
124 {
125  /* we currently do not handle kernel errors */
126  if (!t) return INTERRUPT_UNHANDLED;
127  if (t != lastFPUthread)
128  {
129  asm volatile("clts");
130 
131  /* backup context of last fpu thread */
132  if (lastFPUthread)
133  asm volatile("fnsave %0; fwait" : "=m" (lastFPUthread->fpu));
134 
135  /* fpu was never initialized */
136  if (t->fpuInitialized)
137  {
138  t->fpu.statusWord &= t->fpu.controlWord | 0xff80;
139  asm volatile("frstor %0" : : "m" (t->fpu) );
140  }
141  else
142  {
143  asm volatile("fninit");
144  t->fpuInitialized = true;
145  }
146 
147  /* Remember that we restored the FPU the last time */
148  lastFPUthread = t;
149  }
151 }
152 
153 uint32_t interrupt_0x10(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
154 {
155  /* we currently do not handle kernel errors */
156  if (!t) return INTERRUPT_UNHANDLED;
157  assert(t == lastFPUthread);
158 
159  asm volatile("clts");
160  asm volatile("fnsave %0; fwait" : "=m" (lastFPUthread->fpu));
161 
162  /*
163  if (lastFPUthread->fpu.statusWord & 1)
164  consoleWriteString("FPU invalid operation\n");
165  if (lastFPUthread->fpu.statusWord & 2)
166  consoleWriteString("FPU denormalized operand\n");
167  if (lastFPUthread->fpu.statusWord & 4)
168  consoleWriteString("FPU zero division\n");
169  if (lastFPUthread->fpu.statusWord & 8)
170  consoleWriteString("FPU overflow\n");
171  if (lastFPUthread->fpu.statusWord & 16)
172  consoleWriteString("FPU underflow\n");
173  if (lastFPUthread->fpu.statusWord & 32)
174  consoleWriteString("FPU precision\n");
175  if (lastFPUthread->fpu.statusWord & 64)
176  consoleWriteString("FPU stack fault\n");
177  if (lastFPUthread->fpu.statusWord & 128)
178  consoleWriteString("FPU interrupt handler\n");
179  */
180 
181  return INTERRUPT_UNHANDLED;
182 }
183 
198 uint32_t interrupt_0x80(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
199 {
200  /* we don't expect any syscalls while running in the kernel */
201  if (!t) return INTERRUPT_UNHANDLED;
202 
203  uint32_t status = INTERRUPT_CONTINUE_EXECUTION;
204  uint32_t syscall = t->task.eax;
205  struct userMemory k;
206  struct process *p = t->process;
207 
208  /* return (-1) if the command is not found or an error occurs */
209  t->task.eax = -1;
210 
211  switch (syscall)
212  {
213  case SYSCALL_YIELD:
214  t->task.eax = 0;
215  status = INTERRUPT_YIELD;
216  break;
217 
219  status = INTERRUPT_EXIT_PROCESS;
220  break;
221 
222  case SYSCALL_EXIT_THREAD:
223  status = INTERRUPT_EXIT_THREAD;
224  break;
225 
227  t->task.eax = handleAllocate(&p->handles, &p->obj);
228  break;
229 
231  t->task.eax = handleAllocate(&p->handles, &t->obj);
232  break;
233 
235  t->task.eax = timerGetTimestamp();
236  break;
237 
239  if (ACCESS_USER_MEMORY_STRUCT(&k, p, (void *)t->task.ebx, t->task.ecx, sizeof(struct processInfo), true))
240  {
241  t->task.eax = processInfo((struct processInfo *)k.addr, t->task.ecx);
242  RELEASE_USER_MEMORY(&k);
243  }
244  break;
245 
247  {
248  struct file *f = fileSystemIsValidFile(handleGet(&p->handles, t->task.ebx));
249  if (f)
250  {
251  struct thread *old_t, *__old_t;
252  struct process old_p;
253  struct taskContext *task;
254  struct userMemory k2;
255 
256  assert(p->pageDirectory);
257  assert(!t->blocked);
258  assert(t->process == p);
259 
260  /* backup and reset pageDirectory */
261  old_p.pageDirectory = p->pageDirectory;
262  memcpy(old_p.pageTables, p->pageTables, sizeof(p->pageTables));
263  old_p.entryPoint = p->entryPoint;
264  p->pageDirectory = NULL;
265 
266  /* realloc paging table */
268  pagingMapRemoteMemory(p, NULL, (void *)USERMODE_KERNELSTACK_ADDRESS, kernelStack, 1, true, false); /* kernelstack */
269  pagingMapRemoteMemory(p, NULL, (void *)USERMODE_GDT_ADDRESS, (void *)USERMODE_GDT_ADDRESS, GDT_MAX_PAGES, false, false); /* gdt */
270  pagingMapRemoteMemory(p, NULL, (void *)USERMODE_IDT_ADDRESS, (void *)USERMODE_IDT_ADDRESS, 1, false, false); /* idt */
271  pagingMapRemoteMemory(p, NULL, (void *)USERMODE_INTJMP_ADDRESS, intJmpTable_user, 1, false, false); /* intjmp */
272  pagingMapRemoteMemory(p, NULL, (void *)USERMODE_TASK_ADDRESS, (void *)USERMODE_TASK_ADDRESS, 1, false, false); /* task */
273 
274  /* load target process */
275  if (!elfLoadBinary(p, f->buffer, f->size))
276  {
278  p->pageDirectory = old_p.pageDirectory;
279  memcpy(p->pageTables, old_p.pageTables, sizeof(p->pageTables));
280  p->entryPoint = old_p.entryPoint;
281  break;
282  }
283 
284  /* make commandline arguments available in new process */
285  if (ACCESS_USER_MEMORY(&k2, &old_p, (void *)t->task.ecx, t->task.edx, true))
286  {
289  if (p->user_programArgumentsBase && ACCESS_USER_MEMORY(&k, p, p->user_programArgumentsBase, t->task.edx, true))
290  {
291  memcpy(k.addr, k2.addr, t->task.edx);
292  RELEASE_USER_MEMORY(&k);
293  }
294  RELEASE_USER_MEMORY(&k2);
295  }
296  else
297  {
299  p->user_programArgumentsBase = NULL;
300  }
301 
302  /* make environment variables available in new process */
303  if (ACCESS_USER_MEMORY(&k2, &old_p, (void *)t->task.esi, t->task.edi, true))
304  {
305 
308  if (p->user_environmentVariablesBase && ACCESS_USER_MEMORY(&k, p, p->user_environmentVariablesBase, t->task.edi, true))
309  {
310  memcpy(k.addr, k2.addr, t->task.edi);
311  RELEASE_USER_MEMORY(&k);
312  }
313  RELEASE_USER_MEMORY(&k2);
314  }
315  else
316  {
319  }
320 
321  /* free paging table of old process */
323 
324  /* shutdown all other threads */
325  LL_FOR_EACH_SAFE(old_t, __old_t, &p->threads, struct thread, entry_process)
326  {
327  if (t != old_t) objectShutdown(old_t, -3);
328  }
329 
330  /* reinitialize the thread t */
331  t->fpuInitialized = false;
332 
335 
338 
339  /* initialize the cpu registers */
340  task = &t->task;
341  memset(task, 0, sizeof(*task));
342  task->prevTask = 0;
345  task->esp1 = 0;
346  task->ss1 = 0;
347  task->esp2 = 0;
348  task->ss2 = 0;
349  task->cr3 = pagingGetPhysMem(NULL, p->pageDirectory) << PAGE_BITS;
350  task->eip = (uint32_t)p->entryPoint;
351  task->eflags = (1 << 9); /* Enable interrupts */
352 
353  task->eax = 0;
354  task->ecx = 0;
355  task->edx = 0;
356  task->ebx = 0;
357  task->esp = (uint32_t)t->user_ring3StackBase + (t->user_ring3StackLength << PAGE_BITS);
358  task->ebp = 0;
359  task->esi = 0;
360  task->edi = 0;
367  task->ldt = 0;
368  task->iomap = sizeof(*task);
369 
370  /* process has now been replaced! */
371  }
372  }
373  break;
374 
376  t->task.eax = (uint32_t)t->user_threadLocalBase;
377  break;
378 
381  break;
382 
384  t->task.eax = (uint32_t)p->user_programArgumentsBase;
385  break;
386 
389  break;
390 
392  t->task.eax = (uint32_t)p->user_environmentVariablesBase;
393  break;
394 
397  break;
398 
400  t->task.eax = (uint32_t)pagingTryAllocatePhysMem(p, t->task.ebx, true, true);
401  break;
402 
404  t->task.eax = (uint32_t)pagingTryReleaseUserMem(p, (void *)t->task.ebx, t->task.ecx);
405  break;
406 
407  case SYSCALL_FORK:
408  {
409  struct process *new_p = processCreate(p);
410  if (new_p)
411  {
412  struct thread *new_t = threadCreate(new_p, t, NULL);
413  if (new_t)
414  {
415  t->task.eax = handleAllocate(&p->handles, &new_p->obj);
416  new_t->task.eax = 0;
417  objectRelease(new_t);
418  }
419  objectRelease(new_p);
420  }
421  }
422  break;
423 
425  {
426  struct thread *new_t = threadCreate(p, NULL, (void *)t->task.ebx);
427  if (new_t)
428  {
429  t->task.eax = handleAllocate(&p->handles, &new_t->obj);
430  new_t->task.eax = t->task.ecx;
431  new_t->task.ebx = t->task.edx;
432  new_t->task.ecx = t->task.esi;
433  new_t->task.edx = t->task.edi;
434  objectRelease(new_t);
435  }
436  }
437  break;
438 
440  {
441  struct event *new_e = eventCreate(t->task.ebx);
442  if (new_e)
443  {
444  t->task.eax = handleAllocate(&p->handles, &new_e->obj);
445  objectRelease(new_e);
446  }
447  }
448  break;
449 
451  {
452  struct semaphore *new_s = semaphoreCreate(t->task.ebx);
453  if (new_s)
454  {
455  t->task.eax = handleAllocate(&p->handles, &new_s->obj);
456  objectRelease(new_s);
457  }
458  }
459  break;
460 
461  case SYSCALL_CREATE_PIPE:
462  {
463  struct pipe *new_p = pipeCreate();
464  if (new_p)
465  {
466  t->task.eax = handleAllocate(&p->handles, &new_p->obj);
467  objectRelease(new_p);
468  }
469  }
470  break;
471 
473  {
474  struct timer *new_t = timerCreate(t->task.ebx);
475  if (new_t)
476  {
477  t->task.eax = handleAllocate(&p->handles, &new_t->obj);
478  objectRelease(new_t);
479  }
480  }
481  break;
482 
483  case SYSCALL_OBJECT_DUP:
484  {
485  struct object *obj = handleGet(&p->handles, t->task.ebx);
486  if (!obj) break;
487  t->task.eax = handleAllocate(&p->handles, obj);
488  }
489  break;
490 
491  case SYSCALL_OBJECT_DUP2:
492  {
493  struct object *obj = handleGet(&p->handles, t->task.ebx);
494  if (!obj) break;
495  t->task.eax = handleSet(&p->handles, t->task.ecx, obj);
496  }
497  break;
498 
500  t->task.eax = (handleGet(&p->handles, t->task.ebx) != NULL);
501  break;
502 
504  {
505  struct object *obj1 = handleGet(&p->handles, t->task.ebx);
506  struct object *obj2 = handleGet(&p->handles, t->task.ecx);
507  if (obj1 || obj2) t->task.eax = (obj1 == obj2);
508  }
509  break;
510 
512  t->task.eax = handleRelease(&p->handles, t->task.ebx);
513  break;
514 
516  {
517  struct object *obj = handleGet(&p->handles, t->task.ebx);
518  t->task.eax = (obj != NULL);
519  if (obj) __objectShutdown(obj, t->task.ecx);
520  if (obj == &t->obj || obj == &p->obj) status = INTERRUPT_YIELD;
521  }
522  break;
523 
525  {
526  struct object *obj = handleGet(&p->handles, t->task.ebx);
527  if (!obj) break;
528  t->task.eax = __objectGetStatus(obj, t->task.ecx);
529  }
530  break;
531 
532  case SYSCALL_OBJECT_WAIT:
533  {
534  struct object *obj = handleGet(&p->handles, t->task.ebx);
535  if (!obj) break;
536  status = threadWait(t, obj, t->task.ecx);
537  }
538  break;
539 
541  {
542  struct object *obj = handleGet(&p->handles, t->task.ebx);
543  t->task.eax = (obj != NULL);
544  if (obj) __objectSignal(obj, t->task.ecx);
545  }
546  break;
547 
549  {
550  struct object *obj = handleGet(&p->handles, t->task.ebx);
551  if (!obj) break;
552  if (ACCESS_USER_MEMORY(&k, p, (void *)t->task.ecx, t->task.edx, false))
553  {
554  t->task.eax = __objectWrite(obj, k.addr, t->task.edx);
555  RELEASE_USER_MEMORY(&k);
556  }
557  }
558  break;
559 
560  case SYSCALL_OBJECT_READ:
561  {
562  struct object *obj = handleGet(&p->handles, t->task.ebx);
563  if (!obj) break;
564  if (ACCESS_USER_MEMORY(&k, p, (void *)t->task.ecx, t->task.edx, true))
565  {
566  t->task.eax = __objectRead(obj, k.addr, t->task.edx);
567  RELEASE_USER_MEMORY(&k);
568  }
569  }
570  break;
571 
573  {
574  struct object *obj = handleGet(&p->handles, t->task.ebx);
575  struct object *subObj = handleGet(&p->handles, t->task.ecx);
576  t->task.eax = (obj && subObj) ? __objectAttachObj(obj, subObj, t->task.edx, t->task.esi) : false;
577  }
578  break;
579 
581  {
582  struct object *obj = handleGet(&p->handles, t->task.ebx);
583  if (!obj) break;
584  t->task.eax = __objectDetachObj(obj, t->task.ecx);
585  }
586  break;
587 
589  if (ACCESS_USER_MEMORY(&k, p, (void *)t->task.ebx, t->task.ecx, true))
590  {
592  RELEASE_USER_MEMORY(&k);
593  t->task.eax = t->task.ecx;
594  }
595  break;
596 
598  if (ACCESS_USER_MEMORY_STRUCT(&k, p, (void *)t->task.ebx, t->task.ecx, sizeof(uint16_t), true))
599  {
601  RELEASE_USER_MEMORY(&k);
602  t->task.eax = t->task.ecx;
603  }
604  break;
605 
607  consoleClear();
608  break;
609 
611  t->task.eax = consoleGetSize();
612  break;
613 
616  break;
617 
619  t->task.eax = consoleGetColor();
620  break;
621 
624  break;
625 
628  break;
629 
632  break;
633 
636  break;
637 
640  break;
641 
643  t->task.eax = consoleGetFlags();
644  break;
645 
647  {
649  if (ACCESS_USER_MEMORY(&k, p, (void *)t->task.ecx, t->task.edx, true))
650  {
651  struct file *new_f = fileSystemSearchFile(directory, k.addr, t->task.edx, t->task.esi);
652  if (new_f)
653  {
654  t->task.eax = handleAllocate(&p->handles, &new_f->obj);
655  objectRelease(new_f);
656  }
657  }
658  }
659  break;
660 
662  {
664  if (ACCESS_USER_MEMORY(&k, p, (void *)t->task.ecx, t->task.edx, true))
665  {
666  struct directory *new_d = fileSystemSearchDirectory(directory, k.addr, t->task.edx, t->task.esi);
667  if (new_d)
668  {
669  t->task.eax = handleAllocate(&p->handles, &new_d->obj);
670  objectRelease(new_d);
671  }
672  }
673  }
674  break;
675 
677  {
678  struct file *f;
679  struct directory *d;
680  struct object *obj = handleGet(&p->handles, t->task.ebx);
681 
682  /* if the argument is a file object */
683  f = fileSystemIsValidFile(obj);
684  if (f)
685  {
686  struct openedFile *new_h = fileOpen(f);
687  if (new_h)
688  {
689  t->task.eax = handleAllocate(&p->handles, &new_h->obj);
690  objectRelease(new_h);
691  }
692  break;
693  }
694 
695  /* if the argument is a directory object */
697  if (d)
698  {
699  struct openedDirectory *new_h = directoryOpen(d);
700  if (new_h)
701  {
702  t->task.eax = handleAllocate(&p->handles, &new_h->obj);
703  objectRelease(new_h);
704  }
705  break;
706  }
707  }
708  break;
709 
710  default:
711  status = INTERRUPT_UNHANDLED;
712  break;
713  }
714 
715  return status;
716 }
717 
727 bool interruptReserve(uint32_t interrupt, interrupt_callback callback)
728 {
729  assert(interrupt < IDT_MAX_COUNT);
730  if (interruptTable[interrupt])
731  return false;
732 
733  interruptTable[interrupt] = callback;
734  return true;
735 }
736 
742 void interruptFree(uint32_t interrupt)
743 {
744  interruptTable[interrupt] = NULL;
745 }
746 
747 /* interrupt table */
748 static interrupt_callback interruptTable[IDT_MAX_COUNT] =
749 {
750  /* 0x00 */ NULL,
751  /* 0x01 */ NULL,
752  /* 0x02 */ NULL,
753  /* 0x03 */ NULL,
754  /* 0x04 */ NULL,
755  /* 0x05 */ NULL,
756  /* 0x06 */ NULL,
757  /* 0x07 */ interrupt_0x07,
758  /* 0x08 */ NULL,
759  /* 0x09 */ NULL,
760  /* 0x0a */ NULL,
761  /* 0x0b */ NULL,
762  /* 0x0c */ NULL,
763  /* 0x0d */ NULL,
764  /* 0x0e */ interrupt_0x0E, /* defined in paging.c */
765  /* 0x0f */ NULL,
766  /* 0x10 */ interrupt_0x10,
767  /* 0x11 */ NULL,
768  /* 0x12 */ NULL,
769  /* 0x13 */ NULL,
770  /* 0x14 */ NULL,
771  /* 0x15 */ NULL,
772  /* 0x16 */ NULL,
773  /* 0x17 */ NULL,
774  /* 0x18 */ NULL,
775  /* 0x19 */ NULL,
776  /* 0x1a */ NULL,
777  /* 0x1b */ NULL,
778  /* 0x1c */ NULL,
779  /* 0x1d */ NULL,
780  /* 0x1e */ NULL,
781  /* 0x1f */ NULL,
782  /* 0x20 */ NULL,
783  /* 0x21 */ NULL,
784  /* 0x22 */ NULL,
785  /* 0x23 */ NULL,
786  /* 0x24 */ NULL,
787  /* 0x25 */ NULL,
788  /* 0x26 */ NULL,
789  /* 0x27 */ NULL,
790  /* 0x28 */ NULL,
791  /* 0x29 */ NULL,
792  /* 0x2a */ NULL,
793  /* 0x2b */ NULL,
794  /* 0x2c */ NULL,
795  /* 0x2d */ NULL,
796  /* 0x2e */ NULL,
797  /* 0x2f */ NULL,
798  /* 0x30 */ NULL,
799  /* 0x31 */ NULL,
800  /* 0x32 */ NULL,
801  /* 0x33 */ NULL,
802  /* 0x34 */ NULL,
803  /* 0x35 */ NULL,
804  /* 0x36 */ NULL,
805  /* 0x37 */ NULL,
806  /* 0x38 */ NULL,
807  /* 0x39 */ NULL,
808  /* 0x3a */ NULL,
809  /* 0x3b */ NULL,
810  /* 0x3c */ NULL,
811  /* 0x3d */ NULL,
812  /* 0x3e */ NULL,
813  /* 0x3f */ NULL,
814  /* 0x40 */ NULL,
815  /* 0x41 */ NULL,
816  /* 0x42 */ NULL,
817  /* 0x43 */ NULL,
818  /* 0x44 */ NULL,
819  /* 0x45 */ NULL,
820  /* 0x46 */ NULL,
821  /* 0x47 */ NULL,
822  /* 0x48 */ NULL,
823  /* 0x49 */ NULL,
824  /* 0x4a */ NULL,
825  /* 0x4b */ NULL,
826  /* 0x4c */ NULL,
827  /* 0x4d */ NULL,
828  /* 0x4e */ NULL,
829  /* 0x4f */ NULL,
830  /* 0x50 */ NULL,
831  /* 0x51 */ NULL,
832  /* 0x52 */ NULL,
833  /* 0x53 */ NULL,
834  /* 0x54 */ NULL,
835  /* 0x55 */ NULL,
836  /* 0x56 */ NULL,
837  /* 0x57 */ NULL,
838  /* 0x58 */ NULL,
839  /* 0x59 */ NULL,
840  /* 0x5a */ NULL,
841  /* 0x5b */ NULL,
842  /* 0x5c */ NULL,
843  /* 0x5d */ NULL,
844  /* 0x5e */ NULL,
845  /* 0x5f */ NULL,
846  /* 0x60 */ NULL,
847  /* 0x61 */ NULL,
848  /* 0x62 */ NULL,
849  /* 0x63 */ NULL,
850  /* 0x64 */ NULL,
851  /* 0x65 */ NULL,
852  /* 0x66 */ NULL,
853  /* 0x67 */ NULL,
854  /* 0x68 */ NULL,
855  /* 0x69 */ NULL,
856  /* 0x6a */ NULL,
857  /* 0x6b */ NULL,
858  /* 0x6c */ NULL,
859  /* 0x6d */ NULL,
860  /* 0x6e */ NULL,
861  /* 0x6f */ NULL,
862  /* 0x70 */ NULL,
863  /* 0x71 */ NULL,
864  /* 0x72 */ NULL,
865  /* 0x73 */ NULL,
866  /* 0x74 */ NULL,
867  /* 0x75 */ NULL,
868  /* 0x76 */ NULL,
869  /* 0x77 */ NULL,
870  /* 0x78 */ NULL,
871  /* 0x79 */ NULL,
872  /* 0x7a */ NULL,
873  /* 0x7b */ NULL,
874  /* 0x7c */ NULL,
875  /* 0x7d */ NULL,
876  /* 0x7e */ NULL,
877  /* 0x7f */ NULL,
878  /* 0x80 */ interrupt_0x80,
879  /* 0x81 */ NULL,
880  /* 0x82 */ NULL,
881  /* 0x83 */ NULL,
882  /* 0x84 */ NULL,
883  /* 0x85 */ NULL,
884  /* 0x86 */ NULL,
885  /* 0x87 */ NULL,
886  /* 0x88 */ NULL,
887  /* 0x89 */ NULL,
888  /* 0x8a */ NULL,
889  /* 0x8b */ NULL,
890  /* 0x8c */ NULL,
891  /* 0x8d */ NULL,
892  /* 0x8e */ NULL,
893  /* 0x8f */ NULL,
894  /* 0x90 */ NULL,
895  /* 0x91 */ NULL,
896  /* 0x92 */ NULL,
897  /* 0x93 */ NULL,
898  /* 0x94 */ NULL,
899  /* 0x95 */ NULL,
900  /* 0x96 */ NULL,
901  /* 0x97 */ NULL,
902  /* 0x98 */ NULL,
903  /* 0x99 */ NULL,
904  /* 0x9a */ NULL,
905  /* 0x9b */ NULL,
906  /* 0x9c */ NULL,
907  /* 0x9d */ NULL,
908  /* 0x9e */ NULL,
909  /* 0x9f */ NULL,
910  /* 0xa0 */ NULL,
911  /* 0xa1 */ NULL,
912  /* 0xa2 */ NULL,
913  /* 0xa3 */ NULL,
914  /* 0xa4 */ NULL,
915  /* 0xa5 */ NULL,
916  /* 0xa6 */ NULL,
917  /* 0xa7 */ NULL,
918  /* 0xa8 */ NULL,
919  /* 0xa9 */ NULL,
920  /* 0xaa */ NULL,
921  /* 0xab */ NULL,
922  /* 0xac */ NULL,
923  /* 0xad */ NULL,
924  /* 0xae */ NULL,
925  /* 0xaf */ NULL,
926  /* 0xb0 */ NULL,
927  /* 0xb1 */ NULL,
928  /* 0xb2 */ NULL,
929  /* 0xb3 */ NULL,
930  /* 0xb4 */ NULL,
931  /* 0xb5 */ NULL,
932  /* 0xb6 */ NULL,
933  /* 0xb7 */ NULL,
934  /* 0xb8 */ NULL,
935  /* 0xb9 */ NULL,
936  /* 0xba */ NULL,
937  /* 0xbb */ NULL,
938  /* 0xbc */ NULL,
939  /* 0xbd */ NULL,
940  /* 0xbe */ NULL,
941  /* 0xbf */ NULL,
942  /* 0xc0 */ NULL,
943  /* 0xc1 */ NULL,
944  /* 0xc2 */ NULL,
945  /* 0xc3 */ NULL,
946  /* 0xc4 */ NULL,
947  /* 0xc5 */ NULL,
948  /* 0xc6 */ NULL,
949  /* 0xc7 */ NULL,
950  /* 0xc8 */ NULL,
951  /* 0xc9 */ NULL,
952  /* 0xca */ NULL,
953  /* 0xcb */ NULL,
954  /* 0xcc */ NULL,
955  /* 0xcd */ NULL,
956  /* 0xce */ NULL,
957  /* 0xcf */ NULL,
958  /* 0xd0 */ NULL,
959  /* 0xd1 */ NULL,
960  /* 0xd2 */ NULL,
961  /* 0xd3 */ NULL,
962  /* 0xd4 */ NULL,
963  /* 0xd5 */ NULL,
964  /* 0xd6 */ NULL,
965  /* 0xd7 */ NULL,
966  /* 0xd8 */ NULL,
967  /* 0xd9 */ NULL,
968  /* 0xda */ NULL,
969  /* 0xdb */ NULL,
970  /* 0xdc */ NULL,
971  /* 0xdd */ NULL,
972  /* 0xde */ NULL,
973  /* 0xdf */ NULL,
974  /* 0xe0 */ NULL,
975  /* 0xe1 */ NULL,
976  /* 0xe2 */ NULL,
977  /* 0xe3 */ NULL,
978  /* 0xe4 */ NULL,
979  /* 0xe5 */ NULL,
980  /* 0xe6 */ NULL,
981  /* 0xe7 */ NULL,
982  /* 0xe8 */ NULL,
983  /* 0xe9 */ NULL,
984  /* 0xea */ NULL,
985  /* 0xeb */ NULL,
986  /* 0xec */ NULL,
987  /* 0xed */ NULL,
988  /* 0xee */ NULL,
989  /* 0xef */ NULL,
990  /* 0xf0 */ NULL,
991  /* 0xf1 */ NULL,
992  /* 0xf2 */ NULL,
993  /* 0xf3 */ NULL,
994  /* 0xf4 */ NULL,
995  /* 0xf5 */ NULL,
996  /* 0xf6 */ NULL,
997  /* 0xf7 */ NULL,
998  /* 0xf8 */ NULL,
999  /* 0xf9 */ NULL,
1000  /* 0xfa */ NULL,
1001  /* 0xfb */ NULL,
1002  /* 0xfc */ NULL,
1003  /* 0xfd */ NULL,
1004  /* 0xfe */ NULL,
1005  /* 0xff */ NULL
1006 };
1007 
uint32_t size
Definition: filesystem.h:65
uint16_t statusWord
Definition: context.h:84
void * entryPoint
Definition: process.h:79
uint32_t ebx
Definition: context.h:55
bool interruptReserve(uint32_t interrupt, interrupt_callback callback)
Request an interrupt.
Definition: interrupt.c:727
void consoleWriteRawLen(const uint16_t *data, size_t count)
Write raw data with a fixed size to the console.
Definition: console.c:269
void pagingReleaseProcessPageTable(struct process *p)
Releases the page directory and page table of a specific process.
Definition: paging.c:1344
uint32_t consoleGetSize()
Returns the packed size of the console.
Definition: console.c:454
bool handleSet(struct handleTable *table, uint32_t handle, struct object *object)
Associates a handle (index) with a kernel object.
Definition: handle.c:168
struct thread * threadCreate(struct process *p, struct thread *original, void *eip)
Creates a new kernel thread object.
Definition: thread.c:80
uint8_t * buffer
Definition: filesystem.h:64
struct object * handleGet(struct handleTable *table, uint32_t handle)
Returns the kernel object associated to a handle.
Definition: handle.c:213
#define USERMODE_KERNELSTACK_LIMIT
Definition: gdt.h:99
#define USERMODE_IDT_ADDRESS
Definition: gdt.h:95
struct directory * fileSystemIsValidDirectory(struct object *obj)
Checks if a given object is of the type directory and casts it if possible.
Definition: filesystem.c:934
uint16_t fs
Definition: context.h:69
struct process * processCreate(struct process *original)
Creates a new kernel process object.
Definition: process.c:77
uint32_t interrupt_0x0E(uint32_t interrupt, uint32_t error, struct thread *t)
struct openedDirectory * directoryOpen(struct directory *directory)
Creates a new kernel openedDirectory object.
Definition: filesystem.c:699
uint16_t cs
Definition: context.h:63
struct openedFile * fileOpen(struct file *file)
Creates a new kernel openedFile object.
Definition: filesystem.c:513
void pagingAllocProcessPageTable(struct process *p)
Allocates the page directory and page table for a specific process.
Definition: paging.c:1236
uint16_t ss1
Definition: context.h:41
#define PAGE_MASK
Definition: physmem.h:36
#define assert(ex)
Definition: util.h:61
uint32_t eflags
Definition: context.h:50
struct file * fileSystemIsValidFile(struct object *obj)
Checks if a given object is of the type file and casts it if possible.
Definition: filesystem.c:960
uint16_t ss2
Definition: context.h:45
#define UNUSED
Definition: util.h:39
#define GDT_CPL_RING3
Definition: gdt.h:47
void * memset(void *ptr, int value, size_t num)
Fills a memory region with some specific byte value.
Definition: util.c:123
void * user_programArgumentsBase
Definition: process.h:82
uint32_t ecx
Definition: context.h:53
uint32_t edx
Definition: context.h:54
#define INTERRUPT_UNHANDLED
Definition: interrupt.h:46
#define objectShutdown(p, a)
Definition: object.h:111
uint32_t consoleGetHardwareCursor()
Get packed position of the hardware cursor.
Definition: console.c:513
uint16_t iomap
Definition: context.h:77
#define USERMODE_GDT_ADDRESS
Definition: gdt.h:94
bool fpuInitialized
Definition: thread.h:59
Definition: event.h:41
struct pagingEntry * pageDirectory
Definition: process.h:75
void * pagingAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user)
Allocates several pages of physical memory in a process.
Definition: paging.c:659
bool pagingTryReleaseUserMem(struct process *p, void *addr, uint32_t length)
Releases several pages of physical memory of a process.
Definition: paging.c:1615
#define DEFAULT_STACK_SIZE
Definition: thread.h:73
void * user_ring3StackBase
Definition: thread.h:62
struct thread * lastFPUthread
Definition: thread.c:45
#define PAGE_BITS
Definition: physmem.h:37
uint32_t processInfo(struct processInfo *info, uint32_t count)
Fills out the processInfo structure with information about each individual process.
Definition: process.c:265
Definition: timer.h:48
uint16_t controlWord
Definition: context.h:82
#define INTERRUPT_YIELD
Definition: interrupt.h:50
struct object obj
Definition: thread.h:49
void * intJmpTable_user
Definition: gdt.c:54
struct object obj
Definition: filesystem.h:70
uint32_t eax
Definition: context.h:52
uint32_t user_environmentVariablesLength
Definition: process.h:87
Definition: object.h:69
struct semaphore * semaphoreCreate(uint32_t value)
Creates a new kernel semaphore object.
Definition: semaphore.c:68
struct pipe * pipeCreate()
Creates a new kernel pipe object.
Definition: pipe.c:88
Definition: thread.h:47
struct object obj
Definition: process.h:64
struct event * eventCreate(bool wakeupAll)
Creates a new kernel event object.
Definition: event.c:92
#define USERMODE_KERNELSTACK_ADDRESS
Definition: gdt.h:93
struct GDTEntry * codeRing3
Definition: gdt.c:65
void * pagingTryAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user)
Tries to allocates several pages of physical memory in a process.
Definition: paging.c:736
Definition: pipe.h:41
void * user_threadLocalBase
Definition: thread.h:66
void consoleSetColor(uint8_t color)
Set the text and background color of the console.
Definition: console.c:113
uint32_t esi
Definition: context.h:58
struct GDTEntry * dataRing0
Definition: gdt.c:64
bool elfLoadBinary(struct process *p, void *addr, uint32_t length)
Loads an ELF executable stored in the memory into a process.
Definition: elf.c:104
uint32_t user_threadLocalLength
Definition: thread.h:67
void * kernelStack
Definition: gdt.c:42
#define INTERRUPT_EXIT_PROCESS
Definition: interrupt.h:54
struct object obj
Definition: semaphore.h:43
struct directory * fileSystemSearchDirectory(struct directory *directory, char *path, uint32_t pathLength, bool create)
Opens or creates a directory.
Definition: filesystem.c:1004
#define DEFAULT_TLB_SIZE
Definition: thread.h:74
uint16_t prevTask
Definition: context.h:33
struct object obj
Definition: filesystem.h:78
uint32_t(* interrupt_callback)(uint32_t interrupt, uint32_t error, struct thread *t)
Definition: interrupt.h:59
void * user_environmentVariablesBase
Definition: process.h:86
struct pagingEntry * pageTables[PAGETABLE_COUNT]
Definition: process.h:76
struct linkedList threads
Definition: process.h:72
uint32_t esp2
Definition: context.h:44
uint32_t user_programArgumentsLength
Definition: process.h:83
struct object obj
Definition: filesystem.h:57
uint32_t gdtGetEntryOffset(struct GDTEntry *entry, uint32_t ring)
Determines the offset of a GDT entry.
Definition: gdt.c:537
struct object obj
Definition: event.h:43
uint32_t cr3
Definition: context.h:48
void consoleClear()
Clear the screen contents.
Definition: console.c:90
uint8_t consoleGetColor()
Get current color.
Definition: console.c:124
uint32_t eip
Definition: context.h:49
void * memcpy(void *destination, const void *source, size_t num)
Copies a block of memory from source to destination.
Definition: util.c:141
void consoleSetHardwareCursor(uint8_t x, uint8_t y)
Set the position of the hardware cursor.
Definition: console.c:498
uint32_t interrupt_0x80(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
Interrupt which handles Syscalls.
Definition: interrupt.c:198
struct GDTEntry * dataRing3
Definition: gdt.c:66
uint16_t gs
Definition: context.h:71
struct timer * timerCreate(bool wakeupAll)
Creates a new kernel timer object.
Definition: timer.c:111
struct object obj
Definition: pipe.h:43
uint32_t esp0
Definition: context.h:36
uint32_t interrupt_0x07(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
Coprocessor / FPU not available handler.
Definition: interrupt.c:123
struct fpuContext fpu
Definition: thread.h:70
struct process * process
Definition: thread.h:54
void * addr
Definition: paging.h:112
uint32_t pagingGetPhysMem(struct process *p, void *addr)
Returns the physical page index for a virtual address.
Definition: paging.c:1111
uint16_t ss0
Definition: context.h:37
uint16_t ldt
Definition: context.h:74
bool handleRelease(struct handleTable *table, uint32_t handle)
Releases the object associated with a handle.
Definition: handle.c:227
#define GDT_CPL_RING0
Definition: gdt.h:46
uint32_t consoleGetCursorPos()
Get packed position of the text cursor.
Definition: console.c:388
void consoleWriteStringLen(const char *str, size_t len)
Write a string with a fixed size to the console.
Definition: console.c:254
uint32_t interrupt_0x10(UNUSED uint32_t interrupt, UNUSED uint32_t error, struct thread *t)
Definition: interrupt.c:153
struct handleTable handles
Definition: process.h:90
#define INTERRUPT_CONTINUE_EXECUTION
Definition: interrupt.h:48
bool consoleSetCursorPos(uint8_t x, uint8_t y)
Set the position of the text cursor.
Definition: console.c:371
#define objectRelease(p)
Definition: object.h:97
uint16_t ds
Definition: context.h:67
uint32_t esp1
Definition: context.h:40
uint32_t dispatchInterrupt(uint32_t interrupt, uint32_t error, struct thread *t)
Handle an incoming interrupt.
Definition: interrupt.c:83
#define IDT_MAX_COUNT
Definition: gdt.h:86
#define GDT_MAX_PAGES
Definition: gdt.h:74
void consoleSetFlags(uint32_t flags)
Set console flags.
Definition: console.c:554
struct object obj
Definition: timer.h:50
#define LL_FOR_EACH_SAFE(element, next_element, list, type, field)
Allows to iterate a linkedList similar to a for-loop (safe when deleting elements).
Definition: list.h:148
struct object obj
Definition: filesystem.h:45
#define INTERRUPT_EXIT_THREAD
Definition: interrupt.h:52
uint32_t handleAllocate(struct handleTable *table, struct object *object)
Allocates a handle (index) for a specific kernel object.
Definition: handle.c:117
uint16_t es
Definition: context.h:61
uint32_t edi
Definition: context.h:59
uint16_t ss
Definition: context.h:65
struct taskContext task
Definition: thread.h:69
void interruptFree(uint32_t interrupt)
Free a previously requested interrupt.
Definition: interrupt.c:742
uint32_t ebp
Definition: context.h:57
uint32_t threadWait(struct thread *t, struct object *obj, uint32_t mode)
Makes a kernel thread object wait for some waitable object.
Definition: thread.c:388
struct file * fileSystemSearchFile(struct directory *directory, char *path, uint32_t pathLength, bool create)
Opens or creates a file.
Definition: filesystem.c:1092
#define USERMODE_TASK_ADDRESS
Definition: gdt.h:97
uint64_t timerGetTimestamp()
Returns the current kernel timestamp.
Definition: timer.c:325
void * pagingMapRemoteMemory(struct process *dst_p, struct process *src_p, void *dst_addr, void *src_addr, uint32_t length, bool rw, bool user)
Maps some virtual memory from one process to another one.
Definition: paging.c:1150
uint32_t user_ring3StackLength
Definition: thread.h:63
#define USERMODE_INTJMP_ADDRESS
Definition: gdt.h:96
uint32_t esp
Definition: context.h:56
bool blocked
Definition: thread.h:51
uint32_t consoleGetFlags()
Get console flags.
Definition: console.c:564