Nucleus
Barry Files namespace f0dcd54 (3 years, 3 months ago)
/*
* This file is in control of initialising the tasking subsystem. It also
* implements the Task object.
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <nucleus/cpu.h>
#include <nucleus/task.h>
#include <nucleus/memory.h>
#include <nucleus/object.h>
#include <nucleus/vfs.h>
void init_scheduler(void);
void timer_handler(struct InterruptFrame *frame);
static void task_new(Object *);
/* Task object type */
ObjectType taskType = {
.name = "TASK",
.size = sizeof(Task),
.new = task_new,
};
Task *currentTask[MAX_CPUS];
pid_t nextTid = 1;
extern char stackTop[];
/* Create a new Task */
static void
task_new(Object *obj)
{
Task *task = (void *) obj;
task->tid = nextTid++;
task->tgid = task->tid;
task->priority = NORMAL;
task->state = READY;
}
/* Move the stack */
static void
move_stack(uintptr_t top, size_t size)
{
size_t offset;
uintptr_t oldStack, oldBase;
uintptr_t newStack, newBase;
top -= sizeof(uintptr_t);
asm volatile("mov %%esp, %0" : "=r" (oldStack));
asm volatile("mov %%ebp, %0" : "=r" (oldBase));
offset = top - (uintptr_t) stackTop;
newStack = oldStack + offset;
newBase = oldBase + offset;
memcpy((void *) newStack, (void *) oldStack, (size_t) stackTop - oldStack);
/* Update pointers on the stack */
uintptr_t i, tmp;
for (i = top; i > top - size; i -= sizeof(uintptr_t)) {
tmp = *(uintptr_t *) i;
if (tmp > oldStack && tmp < (uintptr_t) stackTop) {
tmp += offset;
*(uintptr_t *) i = tmp;
}
}
asm volatile("mov %0, %%esp" :: "r" (newStack));
asm volatile("mov %0, %%ebp" :: "r" (newBase));
}
/* Initialise tasking */
void
init_tasking(void)
{
move_stack(0xF0800000, 0x2000);
current = new(&taskType);
asm volatile("mov %%cr3, %0" : "=r" (current->pageDir));
current->state = RUNNING;
/* File System namespace */
current->fs = new(&fsType);
/* Files namespace */
current->files = new(&filesType);
init_scheduler();
register_interrupt(0, timer_handler);
}