Main Page | Modules | File List | File Members

task.c

00001 /* ndk - [ task.c ]
00002  *
00003  * This file encompasses the ndk multitasking
00004  * code.  This code is currently being revamped
00005  * and will, eventually, be ported to an rZero
00006  * module to boot-time interchangeability.
00007  *
00008  * Please see:
00009  *   /doc/commonTaskStructure.kwd
00010  *
00011  * (c)2002 dcipher / neuraldk
00012  *           www.neuraldk.org
00013  */
00014 
00015 #include "task.h"
00016 
00017 Task *currentTask = NULL;
00018 Task *firstTask = NULL;
00019 
00020 void taskFillTSS(TSS *tss, long eip, long p0_esp, long p3_esp) {
00021   tss->ldtr = 0;
00022   tss->fs = tss->gs = SEL_P3_DATA | 3;
00023   tss->ds = tss->es = SEL_P3_DATA | 3;
00024   tss->ss = SEL_P3_STACK | 3;
00025   tss->cs = SEL_P3_CODE | 3;
00026   /*
00027   tss->fs = tss->gs = SEL_P0_DATA;
00028   tss->ds = tss->es = SEL_P0_DATA;
00029   tss->ss = SEL_P0_STACK;
00030   tss->cs = SEL_P0_CODE;
00031   */
00032   tss->eflags = 0x00000202L; //| 1 << 18;  // IOPL=0, STI, Alignment Check
00033   tss->esp = /*p0_esp;*/p3_esp;
00034   tss->eip = eip;
00035   tss->cr3 = getCR3();
00036 
00037   tss->esp0 = p0_esp;
00038   tss->ss0 = SEL_P0_STACK;
00039 
00040   tss->link = 0;
00041 }
00042 
00043 void taskFillTSSP0(TSS *tss, long eip, long p0_esp) {
00044   tss->ldtr = 0;
00045   tss->fs = tss->gs = SEL_P0_DATA;
00046   tss->ds = tss->es = SEL_P0_DATA;
00047   tss->ss = SEL_P0_STACK;
00048   tss->cs = SEL_P0_CODE;
00049   /*
00050   tss->fs = tss->gs = SEL_P0_DATA;
00051   tss->ds = tss->es = SEL_P0_DATA;
00052   tss->ss = SEL_P0_STACK;
00053   tss->cs = SEL_P0_CODE;
00054   */
00055   tss->eflags = 0x00000202L; //| 1 << 18;  // IOPL=0, STI, Alignment Check
00056   tss->esp = /*p0_esp;*/p0_esp;
00057   tss->eip = eip;
00058   tss->cr3 = getCR3();
00059 
00060   tss->esp0 = p0_esp;
00061   tss->ss0 = SEL_P0_STACK;
00062 
00063   tss->link = 0;
00064 }
00065 
00066 long taskFindEmptySelector(void) {
00067   // find first empty GDT entry (remember, GDT entry 0
00068   // is zero, but we don't want to use it, hense the 2)
00069   return arrayFindNthEmptyElement(&GDT, 2);
00070 }
00071 
00072 long taskCreateSelector(Task *task) {
00073   int selectorIndex = taskFindEmptySelector();
00074 
00075   task->selector = selectorIndex * 8;
00076 
00077   createDescriptor(&GDT, selectorIndex, task->tss, sizeof(TSS), D_TSS);
00078 }
00079 
00080 void taskCreate(Task *task, TSS *tss) {
00081   Task *llTask;
00082 
00083   task->tss = (long)tss;
00084   taskCreateSelector(task);
00085 
00086   if(firstTask == NULL) {
00087     firstTask = (Task *)task;
00088     currentTask = (Task *)task;
00089     return;
00090   }
00091 
00092   llTask = firstTask;
00093   while(llTask->next != NULL) llTask = (Task *)llTask->next;
00094   llTask->next = (long)task;
00095 
00096   return;
00097 }
00098 
00099 void taskCreateTaskGate(Task *task, TSS *tss) {
00100   Task *llTask;
00101   int selectorIndex;
00102 
00103   task->tss = (long)tss;
00104   taskCreateSelector(task);     // create selector in GDT
00105 
00106   //selectorIndex = 128;
00107   //task->selector = selectorIndex * 8;
00108   createGate(&IDT, 128, 0x0, task->selector | 3, D_TASK + D_DPL3);
00109 
00110   /* do not add take gate to linked list!!!
00111   if(firstTask == NULL) {
00112     firstTask = (Task *)task;
00113     currentTask = (Task *)task;
00114     return;
00115   }
00116 
00117   llTask = firstTask;
00118   while(llTask->next != NULL) llTask = (Task *)llTask->next;
00119   llTask->next = (long)task;
00120   */
00121 
00122   return;
00123 }
00124 
00125 int taskNotBusy(Task *task) {
00126   char *desc;
00127   int temp;
00128 
00129   /* check to see if current task's busy bit is set */
00130   desc  = (char *)arrayElementAt(&GDT, task->selector / 8);
00131   desc += 5;
00132   temp  = *desc;
00133   if(temp & 2) return 1;
00134   else return 0;
00135 }
00136 
00137 // -- NEW TASKING CODE --
00138 
00139 int taskNew(void *taskAddr, void *args, long flags) {
00140   char *newMem;
00141   TSS *tss;
00142   IOMap *iomap;
00143   Task *task;
00144   void *p0_stack, *p3_stack;
00145 
00146   if(flags & TASK_IOMAP) {
00147     //newMem = (char  *)memoryAllocPages(4);
00148     tss    = (TSS   *)(newMem);
00149     iomap  = (IOMap *)(newMem + sizeof(TSS));
00150     task   = (Task  *)(newMem + sizeof(TSSWithIOMap));
00151   } else {
00152     newMem = (char *)memoryAllocPage();
00153     tss    = (TSS  *)(newMem);
00154     task   = (Task *)(newMem + sizeof(TSS));
00155   }
00156 
00157   p0_stack = (void *)memoryAllocPage();
00158 
00159   if(flags & TASK_P0)
00160     taskFillTSSP0(tss, (long)taskAddr, (long)p0_stack + 4096);
00161   else {
00162     // allocate p3 stack... (is this needed?  Or will the task allocate its own?)
00163     p3_stack = (void *)memoryAllocPage();
00164     taskFillTSS(tss, (long)taskAddr, (long)p0_stack + 4096,
00165                                      (long)p3_stack + 4096);
00166   }
00167   taskCreate(task, tss);
00168   return 0;
00169 }

Generated on Sun Nov 21 18:26:11 2004 for ndk by doxygen 1.3.2