OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_009 / chnos / mtask.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_009/chnos/mtask.c b/CHNOSProject/chnos/tolset_chn_000/chnos_009/chnos/mtask.c
new file mode 100644 (file)
index 0000000..c31ace2
--- /dev/null
@@ -0,0 +1,258 @@
+\r
+#include "core.h"\r
+\r
+UI_TaskControl *taskctrl;\r
+\r
+void Initialise_MultiTask(void)\r
+{\r
+       taskctrl = MemoryBlock_Allocate_System(sizeof(UI_TaskControl));\r
+       MemoryBlock_Write_Description(taskctrl, "SystemTaskCtrl");\r
+\r
+       taskctrl->next = 0;\r
+\r
+       taskctrl->main = MultiTask_Task_Get("SystemMainTask");\r
+       taskctrl->main->tss.ldtr = 0;\r
+       taskctrl->idle->tss.iomap = 0x4000;\r
+       taskctrl->main->tss.cr3 = (uint)ADR_Paging_Directory;\r
+       Load_TR(taskctrl->main->selector << 3);\r
+       taskctrl->now = taskctrl->main;\r
+\r
+       taskctrl->idle = MultiTask_Task_Get("SystemIdleTask");\r
+       taskctrl->idle->tss.ldtr = 0;\r
+       taskctrl->idle->tss.iomap = 0x4000;\r
+       taskctrl->idle->tss.eip = (uint)&MultiTask_IdleTask;\r
+       taskctrl->idle->tss.eflags = 0x00000202;\r
+       taskctrl->idle->tss.esp = (uint)MemoryBlock_Allocate_System(64 * 1024) + 64 * 1024;\r
+       MemoryBlock_Write_Description((void *)(taskctrl->idle->tss.esp - 64 * 1024), "IdleTaskStack");\r
+       taskctrl->idle->tss.es = 1 * 8;\r
+       taskctrl->idle->tss.cs = 2 * 8;\r
+       taskctrl->idle->tss.ss = 1 * 8;\r
+       taskctrl->idle->tss.ds = 1 * 8;\r
+       taskctrl->idle->tss.fs = 1 * 8;\r
+       taskctrl->idle->tss.gs = 1 * 8;\r
+       taskctrl->idle->tss.cr3 = (uint)ADR_Paging_Directory;\r
+\r
+       MultiTask_Task_Run(taskctrl->idle);\r
+       MultiTask_Task_Run(taskctrl->main);\r
+\r
+       taskctrl->ts = Timer_Get(0, 0);\r
+       Timer_Set(taskctrl->ts, 2, once);\r
+       Timer_TaskSwitch_Set(taskctrl->ts);\r
+       Timer_Run(taskctrl->ts);\r
+\r
+       return;\r
+}\r
+\r
+UI_Task *MultiTask_Task_Get(const uchar *description)\r
+{\r
+       uint i;\r
+       UI_Task *task;\r
+\r
+       task = MemoryBlock_Allocate_System(sizeof(UI_Task));\r
+       MemoryBlock_Write_Description(task, "UI_Task");\r
+\r
+       task->tss.backlink      = 0;\r
+       task->tss.reserve00     = 0;\r
+       task->tss.esp0          = 0;\r
+       task->tss.ss0           = 0;\r
+       task->tss.reserve01     = 0;\r
+       task->tss.esp1          = 0;\r
+       task->tss.ss1           = 0;\r
+       task->tss.reserve02     = 0;\r
+       task->tss.esp2          = 0;\r
+       task->tss.ss2           = 0;\r
+       task->tss.reserve03     = 0;\r
+       task->tss.cr3           = 0;\r
+       task->tss.eip           = 0;\r
+       task->tss.eflags        = 0;\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
+       task->tss.es            = 0;\r
+       task->tss.reserve04     = 0;\r
+       task->tss.cs            = 0;\r
+       task->tss.reserve05     = 0;\r
+       task->tss.ss            = 0;\r
+       task->tss.reserve06     = 0;\r
+       task->tss.ds            = 0;\r
+       task->tss.reserve07     = 0;\r
+       task->tss.fs            = 0;\r
+       task->tss.reserve08     = 0;\r
+       task->tss.gs            = 0;\r
+       task->tss.reserve09     = 0;\r
+       task->tss.ldtr          = 0;\r
+       task->tss.reserve10     = 0;\r
+       task->tss.flags         = 0;\r
+       task->tss.iomap         = 0;\r
+\r
+       task->selector = System_SegmentDescriptor_Set(sizeof(IO_TaskStatusSegment) - 1, (int)&task->tss, AR_TSS32);\r
+\r
+       task->quantum = 2; /*0.02sec Default*/\r
+\r
+       task->cputime = 0;\r
+\r
+       task->state = initialized;\r
+\r
+       task->cons = 0;\r
+\r
+       for(i = 0; i < (TASK_DESCRIPTION_LENGTH - 1); i++){\r
+               if(description[i] == 0x00){\r
+                       break;\r
+               }\r
+               task->description[i] = description[i];\r
+       }\r
+       task->description[i] = 0x00;\r
+       return task;\r
+}\r
+\r
+void MultiTask_Task_Change_Quantum(UI_Task *task, uint quantum)\r
+{\r
+       if(1 <= quantum && quantum <= 25){      /*0.01-0.25sec*/\r
+               task->quantum = quantum;\r
+       }\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Run(UI_Task *task)\r
+{\r
+       uint eflags;\r
+\r
+       if(!(1 <= task->quantum && task->quantum <= 25)){\r
+               task->quantum = 2;\r
+       }\r
+       if(task->state == inuse){\r
+               return;\r
+       } else if(task->state == configured){\r
+               task->state = inuse;\r
+               return;\r
+       }\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       task->next = taskctrl->next;\r
+       taskctrl->next = task;\r
+       task->state = inuse;\r
+\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Sleep(UI_Task *task)\r
+{\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       task->state = configured;\r
+       if(taskctrl->now == task){\r
+               Timer_Cancel(taskctrl->ts);\r
+               MultiTask_TaskSwitch();\r
+       }\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Remove(UI_Task *task)\r
+{\r
+       UI_Task **next, *newnow;\r
+       uint eflags;\r
+       bool ts;\r
+\r
+       ts = false;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       if(taskctrl->now == task){\r
+               ts = true;\r
+       }\r
+\r
+       for(newnow = taskctrl->next; newnow->next != 0; newnow = newnow->next){\r
+\r
+       }\r
+\r
+       for(next = &taskctrl->next; (*next)->next != 0; next = &(*next)->next){\r
+               if((*next) == task){\r
+                       (*next) = task->next;\r
+                       task->next = 0;\r
+                       task->state = initialized;\r
+                       break;\r
+               }\r
+               newnow = (*next);\r
+       }\r
+       if(ts){\r
+               taskctrl->now = newnow;\r
+               MultiTask_TaskSwitch();\r
+       }\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+void MultiTask_Task_Arguments(UI_Task *task, int args, ...)\r
+{\r
+       int i;\r
+       va_list ap;\r
+\r
+       va_start(ap, args);\r
+       \r
+       task->tss.esp -= 4 * (args + 1);\r
+\r
+       for(i = 1; i < args + 1; i++){\r
+               *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);\r
+       }\r
+       va_end(ap);\r
+       return; \r
+}\r
+\r
+void MultiTask_TaskSwitch(void)\r
+{\r
+       UI_Task *old, *new;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       old = taskctrl->now;\r
+\r
+       for(new = taskctrl->now->next; ; new = new->next){\r
+               if(new == 0){\r
+                       new = taskctrl->next;\r
+               }\r
+               if(new->state == inuse){        /*configured = sleep*/\r
+                       taskctrl->now = new;\r
+                       break;\r
+               }\r
+       }\r
+       if(old == taskctrl->now){\r
+               taskctrl->now = old;\r
+               old = 0;\r
+       }\r
+       Timer_Set(taskctrl->ts, taskctrl->now->quantum, once);\r
+       Timer_Run(taskctrl->ts);\r
+       taskctrl->now->cputime += taskctrl->now->quantum;\r
+       if(old){\r
+               FarJMP(0, taskctrl->now->selector << 3);\r
+       }\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+UI_Task *MultiTask_Get_NowTask(void)\r
+{\r
+       return taskctrl->now;\r
+}\r
+\r
+void MultiTask_IdleTask(void)\r
+{\r
+       for(;;){\r
+               IO_HLT();\r
+       }\r
+}\r