OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_009 / chnos / mtask.c
1 \r
2 #include "core.h"\r
3 \r
4 UI_TaskControl *taskctrl;\r
5 \r
6 void Initialise_MultiTask(void)\r
7 {\r
8         taskctrl = MemoryBlock_Allocate_System(sizeof(UI_TaskControl));\r
9         MemoryBlock_Write_Description(taskctrl, "SystemTaskCtrl");\r
10 \r
11         taskctrl->next = 0;\r
12 \r
13         taskctrl->main = MultiTask_Task_Get("SystemMainTask");\r
14         taskctrl->main->tss.ldtr = 0;\r
15         taskctrl->idle->tss.iomap = 0x4000;\r
16         taskctrl->main->tss.cr3 = (uint)ADR_Paging_Directory;\r
17         Load_TR(taskctrl->main->selector << 3);\r
18         taskctrl->now = taskctrl->main;\r
19 \r
20         taskctrl->idle = MultiTask_Task_Get("SystemIdleTask");\r
21         taskctrl->idle->tss.ldtr = 0;\r
22         taskctrl->idle->tss.iomap = 0x4000;\r
23         taskctrl->idle->tss.eip = (uint)&MultiTask_IdleTask;\r
24         taskctrl->idle->tss.eflags = 0x00000202;\r
25         taskctrl->idle->tss.esp = (uint)MemoryBlock_Allocate_System(64 * 1024) + 64 * 1024;\r
26         MemoryBlock_Write_Description((void *)(taskctrl->idle->tss.esp - 64 * 1024), "IdleTaskStack");\r
27         taskctrl->idle->tss.es = 1 * 8;\r
28         taskctrl->idle->tss.cs = 2 * 8;\r
29         taskctrl->idle->tss.ss = 1 * 8;\r
30         taskctrl->idle->tss.ds = 1 * 8;\r
31         taskctrl->idle->tss.fs = 1 * 8;\r
32         taskctrl->idle->tss.gs = 1 * 8;\r
33         taskctrl->idle->tss.cr3 = (uint)ADR_Paging_Directory;\r
34 \r
35         MultiTask_Task_Run(taskctrl->idle);\r
36         MultiTask_Task_Run(taskctrl->main);\r
37 \r
38         taskctrl->ts = Timer_Get(0, 0);\r
39         Timer_Set(taskctrl->ts, 2, once);\r
40         Timer_TaskSwitch_Set(taskctrl->ts);\r
41         Timer_Run(taskctrl->ts);\r
42 \r
43         return;\r
44 }\r
45 \r
46 UI_Task *MultiTask_Task_Get(const uchar *description)\r
47 {\r
48         uint i;\r
49         UI_Task *task;\r
50 \r
51         task = MemoryBlock_Allocate_System(sizeof(UI_Task));\r
52         MemoryBlock_Write_Description(task, "UI_Task");\r
53 \r
54         task->tss.backlink      = 0;\r
55         task->tss.reserve00     = 0;\r
56         task->tss.esp0          = 0;\r
57         task->tss.ss0           = 0;\r
58         task->tss.reserve01     = 0;\r
59         task->tss.esp1          = 0;\r
60         task->tss.ss1           = 0;\r
61         task->tss.reserve02     = 0;\r
62         task->tss.esp2          = 0;\r
63         task->tss.ss2           = 0;\r
64         task->tss.reserve03     = 0;\r
65         task->tss.cr3           = 0;\r
66         task->tss.eip           = 0;\r
67         task->tss.eflags        = 0;\r
68         task->tss.eax           = 0;\r
69         task->tss.ecx           = 0;\r
70         task->tss.edx           = 0;\r
71         task->tss.ebx           = 0;\r
72         task->tss.esp           = 0;\r
73         task->tss.ebp           = 0;\r
74         task->tss.esi           = 0;\r
75         task->tss.edi           = 0;\r
76         task->tss.es            = 0;\r
77         task->tss.reserve04     = 0;\r
78         task->tss.cs            = 0;\r
79         task->tss.reserve05     = 0;\r
80         task->tss.ss            = 0;\r
81         task->tss.reserve06     = 0;\r
82         task->tss.ds            = 0;\r
83         task->tss.reserve07     = 0;\r
84         task->tss.fs            = 0;\r
85         task->tss.reserve08     = 0;\r
86         task->tss.gs            = 0;\r
87         task->tss.reserve09     = 0;\r
88         task->tss.ldtr          = 0;\r
89         task->tss.reserve10     = 0;\r
90         task->tss.flags         = 0;\r
91         task->tss.iomap         = 0;\r
92 \r
93         task->selector = System_SegmentDescriptor_Set(sizeof(IO_TaskStatusSegment) - 1, (int)&task->tss, AR_TSS32);\r
94 \r
95         task->quantum = 2; /*0.02sec Default*/\r
96 \r
97         task->cputime = 0;\r
98 \r
99         task->state = initialized;\r
100 \r
101         task->cons = 0;\r
102 \r
103         for(i = 0; i < (TASK_DESCRIPTION_LENGTH - 1); i++){\r
104                 if(description[i] == 0x00){\r
105                         break;\r
106                 }\r
107                 task->description[i] = description[i];\r
108         }\r
109         task->description[i] = 0x00;\r
110         return task;\r
111 }\r
112 \r
113 void MultiTask_Task_Change_Quantum(UI_Task *task, uint quantum)\r
114 {\r
115         if(1 <= quantum && quantum <= 25){      /*0.01-0.25sec*/\r
116                 task->quantum = quantum;\r
117         }\r
118         return;\r
119 }\r
120 \r
121 void MultiTask_Task_Run(UI_Task *task)\r
122 {\r
123         uint eflags;\r
124 \r
125         if(!(1 <= task->quantum && task->quantum <= 25)){\r
126                 task->quantum = 2;\r
127         }\r
128         if(task->state == inuse){\r
129                 return;\r
130         } else if(task->state == configured){\r
131                 task->state = inuse;\r
132                 return;\r
133         }\r
134         eflags = IO_Load_EFlags();\r
135         IO_CLI();\r
136 \r
137         task->next = taskctrl->next;\r
138         taskctrl->next = task;\r
139         task->state = inuse;\r
140 \r
141         IO_Store_EFlags(eflags);\r
142         return;\r
143 }\r
144 \r
145 void MultiTask_Task_Sleep(UI_Task *task)\r
146 {\r
147         uint eflags;\r
148 \r
149         eflags = IO_Load_EFlags();\r
150         IO_CLI();\r
151 \r
152         task->state = configured;\r
153         if(taskctrl->now == task){\r
154                 Timer_Cancel(taskctrl->ts);\r
155                 MultiTask_TaskSwitch();\r
156         }\r
157 \r
158         IO_Store_EFlags(eflags);\r
159 \r
160         return;\r
161 }\r
162 \r
163 void MultiTask_Task_Remove(UI_Task *task)\r
164 {\r
165         UI_Task **next, *newnow;\r
166         uint eflags;\r
167         bool ts;\r
168 \r
169         ts = false;\r
170 \r
171         eflags = IO_Load_EFlags();\r
172         IO_CLI();\r
173 \r
174         if(taskctrl->now == task){\r
175                 ts = true;\r
176         }\r
177 \r
178         for(newnow = taskctrl->next; newnow->next != 0; newnow = newnow->next){\r
179 \r
180         }\r
181 \r
182         for(next = &taskctrl->next; (*next)->next != 0; next = &(*next)->next){\r
183                 if((*next) == task){\r
184                         (*next) = task->next;\r
185                         task->next = 0;\r
186                         task->state = initialized;\r
187                         break;\r
188                 }\r
189                 newnow = (*next);\r
190         }\r
191         if(ts){\r
192                 taskctrl->now = newnow;\r
193                 MultiTask_TaskSwitch();\r
194         }\r
195         IO_Store_EFlags(eflags);\r
196         return;\r
197 }\r
198 \r
199 void MultiTask_Task_Arguments(UI_Task *task, int args, ...)\r
200 {\r
201         int i;\r
202         va_list ap;\r
203 \r
204         va_start(ap, args);\r
205         \r
206         task->tss.esp -= 4 * (args + 1);\r
207 \r
208         for(i = 1; i < args + 1; i++){\r
209                 *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);\r
210         }\r
211         va_end(ap);\r
212         return; \r
213 }\r
214 \r
215 void MultiTask_TaskSwitch(void)\r
216 {\r
217         UI_Task *old, *new;\r
218         uint eflags;\r
219 \r
220         eflags = IO_Load_EFlags();\r
221         IO_CLI();\r
222 \r
223         old = taskctrl->now;\r
224 \r
225         for(new = taskctrl->now->next; ; new = new->next){\r
226                 if(new == 0){\r
227                         new = taskctrl->next;\r
228                 }\r
229                 if(new->state == inuse){        /*configured = sleep*/\r
230                         taskctrl->now = new;\r
231                         break;\r
232                 }\r
233         }\r
234         if(old == taskctrl->now){\r
235                 taskctrl->now = old;\r
236                 old = 0;\r
237         }\r
238         Timer_Set(taskctrl->ts, taskctrl->now->quantum, once);\r
239         Timer_Run(taskctrl->ts);\r
240         taskctrl->now->cputime += taskctrl->now->quantum;\r
241         if(old){\r
242                 FarJMP(0, taskctrl->now->selector << 3);\r
243         }\r
244         IO_Store_EFlags(eflags);\r
245         return;\r
246 }\r
247 \r
248 UI_Task *MultiTask_Get_NowTask(void)\r
249 {\r
250         return taskctrl->now;\r
251 }\r
252 \r
253 void MultiTask_IdleTask(void)\r
254 {\r
255         for(;;){\r
256                 IO_HLT();\r
257         }\r
258 }\r