#include "panic.h" #include "task.h" #include "paging.h" #include "log.h" struct tss { struct tss *prev; uint32_t esp0; uint32_t ss0; uint32_t esp1; uint32_t ss1; uint32_t esp2; uint32_t ss2; uint32_t cr3; uint32_t eip; uint32_t eflags; uint32_t eax; uint32_t ecx; uint32_t edx; uint32_t ebx; uint32_t esp; uint32_t ebp; uint32_t esi; uint32_t edi; uint32_t es; uint32_t cs; uint32_t ss; uint32_t ds; uint32_t fs; uint32_t gs; uint32_t ldt; uint16_t trap; uint16_t iomp; } __attribute__ ((packed)); #define TSS ((struct tss *)0x00004f98) #define MAX_TASKS 64 static struct task_state tasks[MAX_TASKS]; struct task_state *active_task; void init_tasks() { active_task = tasks; for (uint8_t i = 0; i < MAX_TASKS; ++i) tasks[i].page_directory = 0; TSS->ss0 = 0x18; TSS->esp0 = 0x00040000; //TSS->cs = 0x13; //TSS->ds = 0x1b; //TSS->ss = 0x1b; TSS->iomp = sizeof(struct tss); asm volatile ( "mov $0x08, %%ax\n" "ltr %%ax" : : : "ax"); } uint32_t new_task(struct task_state state) { for (uint8_t n = 0; n < MAX_TASKS; ++n) if (!tasks[n].page_directory) { tasks[n] = state; return n + 1; } PANIC("Maximum number of tasks reached."); } void advance_active_task() { do if (++active_task == tasks + MAX_TASKS) active_task = tasks; while (!active_task->page_directory || active_task->wait_mode); } void make_sure_tasks() { for (uint8_t n = 0; n < MAX_TASKS; ++n) if (tasks[n].page_directory) while (1) { for (uint8_t n = 0; n < MAX_TASKS; ++n) if (tasks[n].page_directory && !tasks[n].wait_mode) return; asm ("hlt"); } set_log_mode(LOG_SYSTEM); logsz("No tasks, halting."); while (1) asm ("hlt"); } void delete_task(struct task_state *state) { switch_to_kernel_cr3(); free_task_pd(state->page_directory); switch_to_task_cr3(); state->page_directory = 0; uint32_t handle = state - tasks + 1; for (uint8_t n = 0; n < MAX_TASKS; ++n) if (tasks[n].page_directory && (tasks[n].wait_mode == PROCESS_END) && (tasks[n].wait_arg == handle)) tasks[n].wait_mode = NONE; }