00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00028
00029
00030
00031
00032 tss->eflags = 0x00000202L;
00033 tss->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
00051
00052
00053
00054
00055 tss->eflags = 0x00000202L;
00056 tss->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
00068
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);
00105
00106
00107
00108 createGate(&IDT, 128, 0x0, task->selector | 3, D_TASK + D_DPL3);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 return;
00123 }
00124
00125 int taskNotBusy(Task *task) {
00126 char *desc;
00127 int temp;
00128
00129
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
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
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
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 }