Tiberiu Chibici
17342b6665
==================================================== Mainly changed: Tasking + Implemented multitasking + Switching works ? TODO: Fix other not working tasking routines
108 lines
2.2 KiB
C
108 lines
2.2 KiB
C
/*
|
|
* tasking-multi.c
|
|
*
|
|
* Created on: Sep 8, 2011
|
|
* Author: Tiberiu
|
|
*/
|
|
|
|
#include <tasking.h>
|
|
#include <memory-add.h>
|
|
#include <stdio.h>
|
|
|
|
Task* TaskList;
|
|
Task* CurrentTask;
|
|
uint32 NextPid = 1;
|
|
|
|
void TaskSwitch (_RegsStack32* regs)
|
|
{
|
|
MagicBreakpoint();
|
|
|
|
if (!TaskList) return;
|
|
|
|
uint32 eip = TaskReadEip();
|
|
if (eip == 0xABCDEF) return;
|
|
|
|
// Save context
|
|
asm volatile ("mov %%esp, %0" : "=r"(CurrentTask->Esp));
|
|
asm volatile ("mov %%ebp, %0" : "=r"(CurrentTask->Ebp));
|
|
CurrentTask->Eip = eip;
|
|
|
|
// Next task
|
|
CurrentTask = (!CurrentTask->Next) ? TaskList : CurrentTask->Next ;
|
|
|
|
// Switch context
|
|
PagingSwitchDirectory(CurrentTask->Pd);
|
|
|
|
// Prepare for jump
|
|
asm volatile (""
|
|
"mov %0, %%ebp; "
|
|
"mov %1, %%esp; "
|
|
"mov %2, %%ecx; "
|
|
"mov $0xABCDEF, %%eax; "
|
|
"jmp *%%ecx; "
|
|
: : "r"(CurrentTask->Ebp), "r"(CurrentTask->Esp), "r"(CurrentTask->Eip)
|
|
: "eax", "ecx");
|
|
}
|
|
|
|
// Fallback for new tasks
|
|
void TaskEnd ()
|
|
{
|
|
// Find parent of current task
|
|
if (CurrentTask->Pid == TaskList->Pid) TaskList = TaskList->Next;
|
|
|
|
else {
|
|
Task* t = TaskList;
|
|
while (t->Next && t->Next->Pid != CurrentTask->Pid) t = t->Next;
|
|
|
|
t->Next = CurrentTask->Next;
|
|
}
|
|
|
|
// Free allocated space
|
|
kfree((void*)CurrentTask->StackLowerBase);
|
|
kfree(CurrentTask);
|
|
|
|
// Wait for next task
|
|
for (;;) ;
|
|
}
|
|
|
|
void TaskCreate (void (*func)())
|
|
{
|
|
// Create a new task
|
|
Task* t = kmalloc(sizeof(Task));
|
|
|
|
// Set up data
|
|
t->StackLowerBase = (uint32) kmalloc(0x1000); // Allocate some space for new stack
|
|
t->StackUpperBase = t->StackLowerBase + 0x1000;
|
|
t->Next = NULL;
|
|
t->Pd = KernelDirectory;
|
|
t->Pid = NextPid++;
|
|
|
|
// Set up stack
|
|
/*memset(&t->Regs, 0, sizeof(_RegsStack32));
|
|
t->Regs.ebp = t->StackUpperBase;
|
|
t->Regs.esp = (t->StackUpperBase - 0x4 - sizeof(_RegsStack32));
|
|
t->Regs.useresp = t->StackUpperBase - 0x4;
|
|
t->Regs.eip = (uint32) func;
|
|
*(uint32 *) (t->Regs.esp) = (uint32) TaskEnd; // Fallback function
|
|
t->Initialized = 0;
|
|
|
|
// Read eflags
|
|
asm volatile ("pushf; pop %0" : "=r"(t->Regs.eflags));*/
|
|
|
|
// Add the task to the list
|
|
Task* last = TaskList;
|
|
while (last && last->Next) last = last->Next;
|
|
if (last) last->Next = t;
|
|
}
|
|
|
|
void TaskInitialize()
|
|
{
|
|
Task* t = kmalloc(sizeof(Task));
|
|
|
|
t->Pid = NextPid++;
|
|
t->Pd = KernelDirectory;
|
|
t->Next = NULL;
|
|
|
|
TaskList = CurrentTask = t;
|
|
}
|