os/kernel/task.c

142 lines
2.4 KiB
C
Raw Normal View History

#include <kernel/task.h>
#include <kernel/heap.h>
struct Task* tasks;
size_t tasks_capacity;
size_t num_tasks;
size_t current_task = 0;
void setup_tasks()
{
tasks = malloc(sizeof(*tasks));
tasks_capacity = 1;
num_tasks = 1;
}
void add_task(struct Task task)
{
if (num_tasks == tasks_capacity) {
struct Task* temp = malloc(sizeof(*tasks) * tasks_capacity * 2);
for (size_t i = 0; i < num_tasks; i++) {
temp[i] = tasks[i];
}
tasks_capacity *= 2;
free(tasks);
tasks = temp;
}
tasks[num_tasks] = task;
num_tasks++;
}
size_t ss;
size_t esp;
size_t eflags;
size_t cs;
size_t eip;
void jump_kernel(size_t eax, size_t ebx, size_t ecx, size_t edx, size_t ebp, size_t esp);
void jump_user(size_t eax, size_t ebx, size_t ecx, size_t edx, size_t ebp);
static void save_state(
size_t eax,
size_t ebx,
size_t ecx,
size_t edx,
size_t esp,
size_t ebp,
size_t eip,
size_t cs,
size_t ds,
size_t eflags
) {
struct CPUState state = {
.eax = eax,
.ebx = ebx,
.ecx = ecx,
.edx = edx,
.esp = esp,
.ebp = ebp,
.eip = eip,
.cs = cs,
.ds = ds,
.eflags = eflags,
};
tasks[current_task].state = state;
current_task++;
current_task %= num_tasks;
}
void next_task() {
struct CPUState s = tasks[current_task].state;
ss = s.ds;
esp = s.esp;
eflags = s.eflags;
cs = s.cs;
eip = s.eip;
if ((cs & 3) == 0) {
jump_kernel(s.eax, s.ebx, s.ecx, s.edx, s.ebp, s.esp);
} else {
jump_user(s.eax, s.ebx, s.ecx, s.edx, s.ebp);
}
}
void _switch_task(
size_t eax,
size_t ebx,
size_t ecx,
size_t edx,
size_t ebp,
size_t esp_current,
size_t eip_passed,
size_t cs_passed,
size_t eflags_passed,
size_t esp_passed,
size_t ds_passed
)
{
if (num_tasks == 0) {
return;
};
size_t ds;
if ((cs & 3) == 0) {
ds = 0x10;
esp_current = esp_current + sizeof(size_t) * 3;
} else {
ds = ds_passed;
esp_current = esp_passed;
}
ss = ds_passed;
esp = esp_passed;
eflags = eflags_passed;
cs = cs_passed;
eip = eip_passed;
save_state(eax, ebx, ecx, edx, esp, ebp, eip_passed, cs_passed, ds, eflags_passed);
next_task();
}