/* * This file is in control of initialising the tasking subsystem. It also * implements the Task object. */ #include #include #include #include #include #include #include #include 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); }