OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / mtask.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/mtask.c b/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/mtask.c
new file mode 100644 (file)
index 0000000..c681743
--- /dev/null
@@ -0,0 +1,284 @@
+\r
+#include "core.h"\r
+\r
+//FIFO\82É\82æ\82é\83^\83X\83N\82Ì\8e©\93®\8bN\93®\82Í\8aù\92è\82Å\97L\8cø\82Å\82·\82ª\81A\83^\83X\83N\82ª\96¾\8e¦\93I\82É\8eÀ\8ds\82³\82ê\82é\82Ü\82Å\82Í\96³\8cø\82É\82È\82Á\82Ä\82¢\82Ü\82·\81B\r
+//\83^\83X\83N\82ÍSTI\89º\82Å\8aJ\8en\82³\82ê\82Ü\82·\81i\8aO\95\94\8a\84\82è\8d\9e\82Ý\97L\8cø\81j\81B\r
+\r
+UI_TaskControl *Initialize_MultiTask_Control(IO_MemoryControl sysmemctrl)\r
+{\r
+       UI_TaskControl *ctrl;\r
+       UI_Task *maintask;\r
+\r
+       ctrl = Memory_Allocate(sysmemctrl, sizeof(UI_TaskControl));\r
+       ctrl->now = 0;\r
+       ctrl->sysmemctrl = sysmemctrl;\r
+\r
+       maintask = MultiTask_Task_Initialize(ctrl, 0);\r
+\r
+       Load_TR(maintask->selector << 3);\r
+\r
+       ctrl->start = maintask;\r
+       ctrl->now = maintask;\r
+\r
+       maintask->flags.linked = True;\r
+       maintask->flags.running = True;\r
+       maintask->flags.first_run = False;\r
+       FIFO32_Set_Task(maintask->fifo, maintask);\r
+\r
+       return ctrl;\r
+}\r
+\r
+UI_Task *MultiTask_Task_Initialize(UI_TaskControl *ctrl, uint tss_additional_size)\r
+{\r
+       UI_Task *task;\r
+\r
+       task = Memory_Allocate(ctrl->sysmemctrl, sizeof(UI_Task));\r
+       task->tss = Memory_Allocate(ctrl->sysmemctrl, sizeof(CPU_TaskStateSegment) + tss_additional_size);\r
+\r
+       task->tss->reserve00            = 0;\r
+       task->tss->reserve01            = 0;\r
+       task->tss->reserve02            = 0;\r
+       task->tss->reserve03            = 0;\r
+       task->tss->reserve04            = 0;\r
+       task->tss->reserve05            = 0;\r
+       task->tss->reserve06            = 0;\r
+       task->tss->reserve07            = 0;\r
+       task->tss->reserve08            = 0;\r
+       task->tss->reserve09            = 0;\r
+       task->tss->reserve10            = 0;\r
+       task->tss->reserve11            = 0;\r
+\r
+       task->tss->backlink             = 0;\r
+       task->tss->esp0                 = 0;\r
+       task->tss->ss0                  = 0;\r
+       task->tss->esp1                 = 0;\r
+       task->tss->ss1                  = 0;\r
+       task->tss->esp2                 = 0;\r
+       task->tss->ss2                  = 0;\r
+\r
+       task->tss->cr3                  = 0;\r
+       task->tss->eip                  = 0;\r
+       task->tss->eflags.eflags        = 0x00000202;   //bit1=True, IF=True\r
+\r
+       task->tss->eax                  = 0;\r
+       task->tss->ecx                  = 0;\r
+       task->tss->edx                  = 0;\r
+       task->tss->ebx                  = 0;\r
+       task->tss->esp                  = 0;\r
+       task->tss->ebp                  = 0;\r
+       task->tss->esi                  = 0;\r
+       task->tss->edi                  = 0;\r
+\r
+       task->tss->es                   = 0;\r
+       task->tss->cs                   = 0;\r
+       task->tss->ss                   = 0;\r
+       task->tss->ds                   = 0;\r
+       task->tss->fs                   = 0;\r
+       task->tss->gs                   = 0;\r
+\r
+       task->tss->ldtr                 = 0;\r
+       task->tss->flag_trap            = False;\r
+       task->tss->iomap_base           = 0x00004000;   //TSS\83\8a\83~\83b\83g\88È\8fã\82È\82ç\96³\8cø\r
+\r
+       task->selector = System_SegmentDescriptor_Set(sizeof(CPU_TaskStateSegment) + tss_additional_size - 1, (uint)task->tss, AR_TSS32);\r
+\r
+       task->next = 0;\r
+       task->count = 0;\r
+\r
+       task->fifo = FIFO32_Initialize(ctrl->sysmemctrl, TASK_FIFOSIZE);\r
+\r
+       task->flags.initialized = True;\r
+       task->flags.linked = False;\r
+       task->flags.first_run = True;\r
+\r
+       return task;\r
+}\r
+\r
+uint MultiTask_Internal_Task_SetLink(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       UI_Task **last;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       for(last = &ctrl->start; *last != Null; last = &(*last)->next){\r
+               if(*last == task){\r
+                       #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+                               debug("MultiTask_Internal_Task_SetLink:Task has already been linked(sel:0x%X).\n", task->selector);\r
+                       #endif\r
+                       return 1;\r
+               }\r
+       }\r
+       task->next = Null;\r
+       *last = task;\r
+       task->flags.linked = True;\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return 0;\r
+}\r
+\r
+uint MultiTask_Internal_Task_ClearLink(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       UI_Task **find;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       for(find = &ctrl->start; *find != task; find = &(*find)->next){\r
+               if(*find == Null){\r
+                       #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+                               debug("MultiTask_Internal_Task_ClearLink:Task not found(sel:0x%X).\n", task->selector);\r
+                       #endif\r
+                       return 1;\r
+               }\r
+       }\r
+       *find = task->next;\r
+       task->next = Null;\r
+       task->flags.linked = False;\r
+       task->flags.running = False;\r
+\r
+       if(ctrl->now == task){\r
+               MultiTask_TaskSwitch(ctrl);\r
+       }\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return 0;\r
+}\r
+\r
+void MultiTask_Task_Run(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       #ifdef CHNOSPROJECT_DEBUG_CALLLINK\r
+               debug("MultiTask_Task_Run:Called from[0x%08X].\n", *((uint *)(&ctrl - 1)));\r
+       #endif\r
+\r
+       #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+               debug("MultiTask_Task_Run:Start Running Rq(sel:0x%X).\n", task->selector);\r
+       #endif\r
+\r
+       if(task->flags.running){\r
+               #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+                       debug("MultiTask_Task_Run:Task has already been running(sel:0x%X).\n", task->selector);\r
+               #endif\r
+               return;\r
+       }\r
+\r
+       if(!task->flags.linked){\r
+               MultiTask_Internal_Task_SetLink(ctrl, task);\r
+       }\r
+\r
+       task->flags.running = True;\r
+\r
+       #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+               debug("MultiTask_Task_Run:Start Running(sel:0x%X).\n", task->selector);\r
+       #endif\r
+\r
+       if(task->flags.first_run){\r
+               #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+                       debug("MultiTask_Task_Run:FIFO task autorun is enabled.\n");\r
+               #endif\r
+               FIFO32_Set_Task(task->fifo, task);\r
+               task->flags.first_run = False;\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+void MultiTask_TaskSwitch(UI_TaskControl *ctrl)\r
+{\r
+       UI_Task *nexttask;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       for(nexttask = ctrl->now->next; ; nexttask = nexttask->next){\r
+               if(nexttask == Null){   //\83\8a\83\93\83N\8fI\92[\82É\97\88\82½\82ç\90æ\93ª\82Ö\8aª\82«\96ß\82·\r
+                       nexttask = ctrl->start;\r
+               }\r
+               if(nexttask == ctrl->now){      //\8eÀ\8ds\92\86\8fó\91Ô\82Ì\83^\83X\83N\82Í\8c»\8dÝ\8eÀ\8ds\92\86\82Ì\82±\82Ì\83^\83X\83N\82µ\82©\82È\82¢\82Ì\82Å\83^\83X\83N\83X\83C\83b\83`\82È\82µ\r
+                       return;\r
+               }\r
+               if(nexttask->flags.running){    //\8eÀ\8ds\92\86\8fó\91Ô\82Ì\82Ù\82©\82Ì\83^\83X\83N\82ª\8c©\82Â\82©\82Á\82½\82Ì\82Å\83^\83X\83N\83X\83C\83b\83`\r
+                       ctrl->now = nexttask;\r
+                       ctrl->now->count++;\r
+                       FarJMP(0, ctrl->now->selector << 3);\r
+                       break;\r
+               }\r
+       }\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Sleep(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       //CPL=0\89º\82ð\91z\92è\r
+\r
+       uint eflags;\r
+\r
+       if(task == ctrl->now && task == ctrl->start){   //\8e©\95ª\82ª\97B\88ê\96³\93ñ\82Ì\83^\83X\83N\82¾\82Á\82½\8fê\8d\87\81A\83X\83\8a\81[\83v\82Í\8eÀ\8ds\82Å\82«\82È\82¢\82Ì\82ÅHLT\82·\82é\r
+               eflags = IO_Load_EFlags();\r
+               IO_STIHLT();\r
+               IO_Store_EFlags(eflags);\r
+               return;\r
+       }\r
+\r
+       task->flags.running = False;\r
+\r
+       if(ctrl->now == task){\r
+               MultiTask_TaskSwitch(ctrl);\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Kill(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       //CPL=0\89º\82ð\91z\92è\r
+\r
+       if(task == ctrl->now && task == ctrl->start){   //\8e©\95ª\82ª\97B\88ê\96³\93ñ\82Ì\83^\83X\83N\82¾\82Á\82½\8fê\8d\87\81Akill\82ÍOS\8e©\91Ì\82Ì\8fI\97¹\82ð\88Ó\96¡\82·\82é\82Ì\82Å\81A\83A\83{\81[\83g\r
+               #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
+                       debug("MultiTask_Task_Stop:Attempted to stop last task. Abort.\n");\r
+               #endif\r
+               INT_3();\r
+               return;\r
+       }\r
+\r
+       MultiTask_Internal_Task_ClearLink(ctrl, task);\r
+\r
+       return;\r
+}\r
+/*\r
+void MultiTask_Task_Free(UI_TaskControl *ctrl, UI_Task *task)\r
+{\r
+       if(task->flags.linked){\r
+               MultiTask_Task_Kill(ctrl, task);\r
+       }\r
+\r
+}\r
+*/\r
+UI_Task *MultiTask_GetNowTask(UI_TaskControl *ctrl)\r
+{\r
+       return ctrl->now;\r
+}\r
+\r
+uint MultiTask_Push_Arguments(UI_Task *task, uint args, ...)\r
+{\r
+       uint *vargs;\r
+       uint i;\r
+\r
+       vargs = (uint *)(&args + 1);\r
+\r
+       task->tss->esp -= 4 * (args + 1);\r
+\r
+       for(i = 1; i < args + 1; i++){\r
+               *((uint *)(task->tss->esp + (i * 4))) = vargs[i - 1];\r
+       }\r
+\r
+       return 0;\r
+}\r