summaryrefslogtreecommitdiff
path: root/kernel/task.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-08-30 18:32:21 +0200
committerMichal Idziorek <m.i@gmx.at>2014-08-30 18:32:21 +0200
commit837255c8ff040f84699d3c2efd329fc04dbafbdf (patch)
tree69e7f907818c289e615c216c242f055acf45d55c /kernel/task.c
parente733ac719f0bec2bd8f749dbca4de8ad524aaddb (diff)
Added multitasking support for two tasks ;)
Diffstat (limited to 'kernel/task.c')
-rw-r--r--kernel/task.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/kernel/task.c b/kernel/task.c
new file mode 100644
index 0000000..fb71640
--- /dev/null
+++ b/kernel/task.c
@@ -0,0 +1,128 @@
+// http://hosted.cjmovie.net/TutMultitask.htm
+//
+//
+#include "kernel.h"
+#include "../lib/logger/log.h" // logger facilities
+#define FOOLOS_MODULE_NAME "task"
+
+void task_test1()
+{
+ uint8_t c1;
+
+ while(1)
+ {
+ c1++;
+ asm("cli");
+
+ PutString("task1: %03d", 0,560,0xffffff, c1);
+
+ asm("sti");
+ }
+
+}
+
+void task_test2()
+{
+ uint8_t c2;
+
+ while(1)
+ {
+ c2++;
+ asm("cli");
+ PutString("task2: %03d", 0,580,0xffffff, c2);
+
+ asm("sti");
+ }
+
+}
+
+//////////////
+//
+typedef struct{ //Simple structure for a thread
+ unsigned int esp0; //Stack for kernel
+ unsigned int esp3; //Stack for process
+} Thread;
+
+
+Thread Threads[2]; //Space for our simple threads. Just 2!
+int CurrentTask = -1; //The thread currenlty running (-1 == none)
+
+
+void task_create(int pid,void(*thread)())
+{
+ unsigned int *stack;
+
+ Threads[pid].esp0 = pmmngr_alloc_block();
+ stack = (unsigned int*)Threads[pid].esp0+4000; //This makes a pointer to the stack for us
+
+ //First, this stuff is pushed by the processor
+ *--stack = 0x0202; //This is EFLAGS
+ *--stack = 0x08; //This is CS, our code segment
+ *--stack = (uint32_t)thread; //This is EIP
+
+ //Next, the stuff pushed by 'pusha'
+ *--stack = 0; //EDI
+ *--stack = 0; //ESI
+ *--stack = 0; //EBP
+ *--stack = 0; //Just an offset, no value
+ *--stack = 0; //EBX
+ *--stack = 0; //EDX
+ *--stack = 0; //ECX
+ *--stack = 0; //EAX
+
+ //Now these are the data segments pushed by the IRQ handler
+
+ /*
+ *--stack = 0x10; //DS
+ *--stack = 0x10; //ES
+ *--stack = 0x10; //FS
+ *--stack = 0x10; //GS
+ */
+
+
+ Threads[pid].esp0 = (uint32_t)stack; //Update the stack pointer
+
+
+};
+
+uint32_t task_switch_next(uint32_t oldesp)
+{
+
+
+
+ if(CurrentTask != -1){ //Were we even running a task?
+ Threads[CurrentTask].esp0 =oldesp; //Save the new esp for the thread
+
+ //Now switch what task we're on
+ if(CurrentTask == 0)CurrentTask = 1;
+ else CurrentTask = 0;
+ } else{
+ CurrentTask = 0; //We just started multi-tasking, start with task 0
+ }
+
+ uint32_t esp=0;
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"oldesp: 0x%08X saved / next task: %d (esp: 0x%08X) ",oldesp, CurrentTask,Threads[CurrentTask].esp0);
+
+ return Threads[CurrentTask].esp0; //Return new stack pointer to ASM
+}
+
+void stack_trace(uint32_t *stack,int size)
+{
+ for(int i=size;i>=0;i--)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stack: 0x%08X -> 0x%08X", stack, *stack);
+ stack++;
+
+
+ }
+}
+
+void task_init()
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init multitasking.");
+ task_create(0,task_test1);
+ task_create(1,task_test2);
+}
+
+
+