// http://hosted.cjmovie.net/TutMultitask.htm // // #include "kernel.h" #include "lib/logger/log.h" // logger facilities #include "lib/int/stdint.h" #define FOOLOS_MODULE_NAME "task" int started; uint64_t task_system_clock; void task_test1() { uint32_t c; while(1) { c++; while(1)PutString("t1: %d", 00,500,0b1111100000000000, (c++)); } } void task_test2() { uint32_t c; while(1) { c++; while(1)PutString("t2: %d", 100,500,0b1111100000000000, (c++)); } } void task_test3() { uint32_t c; while(1) { c++; while(1)PutString("t3: %d",200,500,0b1111100000000000, (c++)); } } ////////////// // typedef struct{ //Simple structure for a thread unsigned int esp0; //Stack for kernel unsigned int esp3; //Stack for process } Thread; Thread Threads[3]; //Space for our simple threads. Just 2! volatile int CurrentTask; //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+4095; //This makes a pointer to the stack for us log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"new task : stack: 0x%08X ", stack); //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) { task_system_clock++; if(started!=0xabcde) return oldesp; if(CurrentTask!=-1)Threads[CurrentTask].esp0=oldesp; CurrentTask++; if(CurrentTask>2)CurrentTask=0; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"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); task_create(2,task_test3); started=0xabcde; CurrentTask=-1; }