OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / mtask.c
1 \r
2 #include "core.h"\r
3 \r
4 //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
5 //\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
6 \r
7 UI_TaskControl *Initialize_MultiTask_Control(IO_MemoryControl sysmemctrl)\r
8 {\r
9         UI_TaskControl *ctrl;\r
10         UI_Task *maintask;\r
11 \r
12         ctrl = Memory_Allocate(sysmemctrl, sizeof(UI_TaskControl));\r
13         ctrl->now = 0;\r
14         ctrl->sysmemctrl = sysmemctrl;\r
15 \r
16         maintask = MultiTask_Task_Initialize(ctrl, 0);\r
17 \r
18         Load_TR(maintask->selector << 3);\r
19 \r
20         ctrl->start = maintask;\r
21         ctrl->now = maintask;\r
22 \r
23         maintask->flags.linked = True;\r
24         maintask->flags.running = True;\r
25         maintask->flags.first_run = False;\r
26         FIFO32_Set_Task(maintask->fifo, maintask);\r
27 \r
28         return ctrl;\r
29 }\r
30 \r
31 UI_Task *MultiTask_Task_Initialize(UI_TaskControl *ctrl, uint tss_additional_size)\r
32 {\r
33         UI_Task *task;\r
34 \r
35         task = Memory_Allocate(ctrl->sysmemctrl, sizeof(UI_Task));\r
36         task->tss = Memory_Allocate(ctrl->sysmemctrl, sizeof(CPU_TaskStateSegment) + tss_additional_size);\r
37 \r
38         task->tss->reserve00            = 0;\r
39         task->tss->reserve01            = 0;\r
40         task->tss->reserve02            = 0;\r
41         task->tss->reserve03            = 0;\r
42         task->tss->reserve04            = 0;\r
43         task->tss->reserve05            = 0;\r
44         task->tss->reserve06            = 0;\r
45         task->tss->reserve07            = 0;\r
46         task->tss->reserve08            = 0;\r
47         task->tss->reserve09            = 0;\r
48         task->tss->reserve10            = 0;\r
49         task->tss->reserve11            = 0;\r
50 \r
51         task->tss->backlink             = 0;\r
52         task->tss->esp0                 = 0;\r
53         task->tss->ss0                  = 0;\r
54         task->tss->esp1                 = 0;\r
55         task->tss->ss1                  = 0;\r
56         task->tss->esp2                 = 0;\r
57         task->tss->ss2                  = 0;\r
58 \r
59         task->tss->cr3                  = 0;\r
60         task->tss->eip                  = 0;\r
61         task->tss->eflags.eflags        = 0x00000202;   //bit1=True, IF=True\r
62 \r
63         task->tss->eax                  = 0;\r
64         task->tss->ecx                  = 0;\r
65         task->tss->edx                  = 0;\r
66         task->tss->ebx                  = 0;\r
67         task->tss->esp                  = 0;\r
68         task->tss->ebp                  = 0;\r
69         task->tss->esi                  = 0;\r
70         task->tss->edi                  = 0;\r
71 \r
72         task->tss->es                   = 0;\r
73         task->tss->cs                   = 0;\r
74         task->tss->ss                   = 0;\r
75         task->tss->ds                   = 0;\r
76         task->tss->fs                   = 0;\r
77         task->tss->gs                   = 0;\r
78 \r
79         task->tss->ldtr                 = 0;\r
80         task->tss->flag_trap            = False;\r
81         task->tss->iomap_base           = 0x00004000;   //TSS\83\8a\83~\83b\83g\88È\8fã\82È\82ç\96³\8cø\r
82 \r
83         task->selector = System_SegmentDescriptor_Set(sizeof(CPU_TaskStateSegment) + tss_additional_size - 1, (uint)task->tss, AR_TSS32);\r
84 \r
85         task->next = 0;\r
86         task->count = 0;\r
87 \r
88         task->fifo = FIFO32_Initialize(ctrl->sysmemctrl, TASK_FIFOSIZE);\r
89 \r
90         task->flags.initialized = True;\r
91         task->flags.linked = False;\r
92         task->flags.first_run = True;\r
93 \r
94         return task;\r
95 }\r
96 \r
97 uint MultiTask_Internal_Task_SetLink(UI_TaskControl *ctrl, UI_Task *task)\r
98 {\r
99         UI_Task **last;\r
100         uint eflags;\r
101 \r
102         eflags = IO_Load_EFlags();\r
103         IO_CLI();\r
104 \r
105         for(last = &ctrl->start; *last != Null; last = &(*last)->next){\r
106                 if(*last == task){\r
107                         #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
108                                 debug("MultiTask_Internal_Task_SetLink:Task has already been linked(sel:0x%X).\n", task->selector);\r
109                         #endif\r
110                         return 1;\r
111                 }\r
112         }\r
113         task->next = Null;\r
114         *last = task;\r
115         task->flags.linked = True;\r
116 \r
117         IO_Store_EFlags(eflags);\r
118 \r
119         return 0;\r
120 }\r
121 \r
122 uint MultiTask_Internal_Task_ClearLink(UI_TaskControl *ctrl, UI_Task *task)\r
123 {\r
124         UI_Task **find;\r
125         uint eflags;\r
126 \r
127         eflags = IO_Load_EFlags();\r
128         IO_CLI();\r
129 \r
130         for(find = &ctrl->start; *find != task; find = &(*find)->next){\r
131                 if(*find == Null){\r
132                         #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
133                                 debug("MultiTask_Internal_Task_ClearLink:Task not found(sel:0x%X).\n", task->selector);\r
134                         #endif\r
135                         return 1;\r
136                 }\r
137         }\r
138         *find = task->next;\r
139         task->next = Null;\r
140         task->flags.linked = False;\r
141         task->flags.running = False;\r
142 \r
143         if(ctrl->now == task){\r
144                 MultiTask_TaskSwitch(ctrl);\r
145         }\r
146 \r
147         IO_Store_EFlags(eflags);\r
148 \r
149         return 0;\r
150 }\r
151 \r
152 void MultiTask_Task_Run(UI_TaskControl *ctrl, UI_Task *task)\r
153 {\r
154         #ifdef CHNOSPROJECT_DEBUG_CALLLINK\r
155                 debug("MultiTask_Task_Run:Called from[0x%08X].\n", *((uint *)(&ctrl - 1)));\r
156         #endif\r
157 \r
158         #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
159                 debug("MultiTask_Task_Run:Start Running Rq(sel:0x%X).\n", task->selector);\r
160         #endif\r
161 \r
162         if(task->flags.running){\r
163                 #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
164                         debug("MultiTask_Task_Run:Task has already been running(sel:0x%X).\n", task->selector);\r
165                 #endif\r
166                 return;\r
167         }\r
168 \r
169         if(!task->flags.linked){\r
170                 MultiTask_Internal_Task_SetLink(ctrl, task);\r
171         }\r
172 \r
173         task->flags.running = True;\r
174 \r
175         #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
176                 debug("MultiTask_Task_Run:Start Running(sel:0x%X).\n", task->selector);\r
177         #endif\r
178 \r
179         if(task->flags.first_run){\r
180                 #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
181                         debug("MultiTask_Task_Run:FIFO task autorun is enabled.\n");\r
182                 #endif\r
183                 FIFO32_Set_Task(task->fifo, task);\r
184                 task->flags.first_run = False;\r
185         }\r
186 \r
187         return;\r
188 }\r
189 \r
190 void MultiTask_TaskSwitch(UI_TaskControl *ctrl)\r
191 {\r
192         UI_Task *nexttask;\r
193         uint eflags;\r
194 \r
195         eflags = IO_Load_EFlags();\r
196         IO_CLI();\r
197 \r
198         for(nexttask = ctrl->now->next; ; nexttask = nexttask->next){\r
199                 if(nexttask == Null){   //\83\8a\83\93\83N\8fI\92[\82É\97\88\82½\82ç\90æ\93ª\82Ö\8aª\82«\96ß\82·\r
200                         nexttask = ctrl->start;\r
201                 }\r
202                 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
203                         return;\r
204                 }\r
205                 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
206                         ctrl->now = nexttask;\r
207                         ctrl->now->count++;\r
208                         FarJMP(0, ctrl->now->selector << 3);\r
209                         break;\r
210                 }\r
211         }\r
212 \r
213         IO_Store_EFlags(eflags);\r
214 \r
215         return;\r
216 }\r
217 \r
218 void MultiTask_Task_Sleep(UI_TaskControl *ctrl, UI_Task *task)\r
219 {\r
220         //CPL=0\89º\82ð\91z\92è\r
221 \r
222         uint eflags;\r
223 \r
224         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
225                 eflags = IO_Load_EFlags();\r
226                 IO_STIHLT();\r
227                 IO_Store_EFlags(eflags);\r
228                 return;\r
229         }\r
230 \r
231         task->flags.running = False;\r
232 \r
233         if(ctrl->now == task){\r
234                 MultiTask_TaskSwitch(ctrl);\r
235         }\r
236 \r
237         return;\r
238 }\r
239 \r
240 void MultiTask_Task_Kill(UI_TaskControl *ctrl, UI_Task *task)\r
241 {\r
242         //CPL=0\89º\82ð\91z\92è\r
243 \r
244         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
245                 #ifdef CHNOSPROJECT_DEBUG_MULTITASK\r
246                         debug("MultiTask_Task_Stop:Attempted to stop last task. Abort.\n");\r
247                 #endif\r
248                 INT_3();\r
249                 return;\r
250         }\r
251 \r
252         MultiTask_Internal_Task_ClearLink(ctrl, task);\r
253 \r
254         return;\r
255 }\r
256 /*\r
257 void MultiTask_Task_Free(UI_TaskControl *ctrl, UI_Task *task)\r
258 {\r
259         if(task->flags.linked){\r
260                 MultiTask_Task_Kill(ctrl, task);\r
261         }\r
262 \r
263 }\r
264 */\r
265 UI_Task *MultiTask_GetNowTask(UI_TaskControl *ctrl)\r
266 {\r
267         return ctrl->now;\r
268 }\r
269 \r
270 uint MultiTask_Push_Arguments(UI_Task *task, uint args, ...)\r
271 {\r
272         uint *vargs;\r
273         uint i;\r
274 \r
275         vargs = (uint *)(&args + 1);\r
276 \r
277         task->tss->esp -= 4 * (args + 1);\r
278 \r
279         for(i = 1; i < args + 1; i++){\r
280                 *((uint *)(task->tss->esp + (i * 4))) = vargs[i - 1];\r
281         }\r
282 \r
283         return 0;\r
284 }\r