Добавлено переключение потоков

This commit is contained in:
Aren Elchinyan 2024-01-20 19:04:26 +03:00
parent 9527feb839
commit 99b04b5481
7 changed files with 106 additions and 91 deletions

View File

@ -15,15 +15,16 @@
#define STACK_SIZE 8192 // 1MB
typedef struct task {
uint64_t id; // Идентификатор задачи
uint64_t priority; // Приоритет задачи
void *entry_point; // Точка входа в задачу
uint64_t status; // Состояние задачи
void *stack; // Указатель на стек
void *rsp; // Указатель на RSP
uint64_t stack_size; // Размер стека задачи
struct task *next; // Следующий поток
struct task *last; // Предыдущий поток
uint64_t rax, rbx, rcx, rdx;
uint64_t rsi, rdi, rsp, rbp;
uint64_t cr3;
uint64_t id;
uint64_t ret;
void *stack;
struct task *last;
struct task *next;
} __attribute__((packed)) task_t;
struct frame {

View File

@ -13,6 +13,8 @@
#include <stdarg.h>
#include <stdint.h>
#define UNUSED(x) (void)(x)
#define abs(x) ((x) < 0 ? -(x) : (x))
#define assert(check) \

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 1
#define VERSION_BUILD 945
#define VERSION_BUILD 968

View File

@ -33,20 +33,24 @@ static void encode_idt_entry(uint8_t vector, void *handler, uint8_t flags) {
static void exception_handler(struct frame state) {
LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]);
LOG(" RAX=%x RBX=%x\n"
" RCX=%x RDX=%x\n"
" RSI=%x RDI=%x\n"
" RBP=%x RSP=%x\n"
" R08=%x R09=%x\n"
" R10=%x R11=%x\n"
" R12=%x R13=%x\n"
" R14=%x R15=%x\n"
" RIP=%x RFLAGS=%x\n"
" CS=%x SS=%x\n"
" ERR=%x INT=%u",
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));
LOG("\tRAX=%x RBX=%x\n"
"\tRCX=%x RDX=%x\n"
"\tRSI=%x RDI=%x\n"
"\tRBP=%x RSP=%x\n"
"\tR08=%x R09=%x\n"
"\tR10=%x R11=%x\n"
"\tR12=%x R13=%x\n"
"\tR14=%x R15=%x\n"
"\tRIP=%x RFLAGS=%x\n"
"\tCS=%x SS=%x\n"
"\tERR=%x INT=%u\n",
state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rbp, state.rsp, state.r8, state.r9,
state.r10, state.r11, state.r12, state.r13, state.r14, state.r15, state.rip, state.rflags, state.cs, state.ss,
state.err, state.int_number);
LOG("\tCR3=%x\n", cr3);
asm volatile("cli; hlt");
}

View File

@ -10,123 +10,100 @@
#include <log.h>
#include <mem.h>
#if 0
static volatile uint64_t next_thread_id = 0;
static task_t *last_task = NULL;
static task_t *kernel_task = NULL;
task_t *current_task = NULL;
extern uint64_t full_init;
void task_switch_asm(task_t *, task_t *);
void task_switch(struct frame *state) {
// Смена потоков
UNUSED(state);
LOG("Смена потоков\n");
asm volatile("cli");
asm volatile("pushf");
task_t *prev_task = current_task;
task_t *next = current_task->next;
task_t *last = current_task;
if (current_task->next == NULL) { current_task = kernel_task; }
current_task = next;
LOG("Смена потоков %u -> ", current_task->id);
asm volatile("mov %%rsp, %0" : "=a"(current_task->rsp));
current_task = current_task->next;
if (current_task == NULL) {
// LOG("current_task == NULL\n");
// LOG("current_task = kernel_task\n");
current_task = kernel_task;
}
LOG("%u\n", current_task->id);
asm volatile("mov %0, %%rsp" ::"a"(current_task->rsp));
asm volatile("popf");
LOG("Смена потоков 2\n");
task_switch_asm(last, next);
asm volatile("sti");
}
task_t *task_new_thread(void (*func)(void *), void *arg) {
uint64_t eflags;
void *stack = NULL;
uint64_t task_new_thread(void (*func)(void *), void *arg) {
asm volatile("cli");
LOG("Выделение потока\n");
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));
asm volatile("pushf");
asm volatile("pop %0" : "=r"(eflags));
uint64_t *stack = mem_alloc(STACK_SIZE);
task_t *new_task = mem_alloc(sizeof(task_t));
tool_memset(stack, 0, STACK_SIZE);
tool_memset(new_task, 0, sizeof(task_t));
new_task->id = next_thread_id++;
new_task->stack_size = STACK_SIZE;
new_task->entry_point = func;
uint64_t *stack_top = (uint64_t *)((uint64_t)stack + STACK_SIZE);
new_task->priority = 1;
*(--stack_top) = (uint64_t)arg;
*(--stack_top) = (uint64_t)func;
stack = mem_alloc(STACK_SIZE);
new_task->rsp = (uint64_t)new_task->stack + STACK_SIZE - sizeof(uint64_t) * 2;
new_task->stack = stack;
new_task->rsp = (uintptr_t)stack + STACK_SIZE - 16;
new_task->cr3 = cr3;
new_task->id = next_thread_id++;
uintptr_t *rsp = (uintptr_t *)stack;
*(--rsp) = (uintptr_t)func; // Добавляем entry_point на стек
*(--rsp) = eflags | (1 << 9); // Сохраняем флаги на стеке
// Добавляем new_task в цепочку
if (last_task != NULL) { last_task->next = new_task; }
new_task->last = last_task;
new_task->next = NULL;
last_task = new_task;
if (kernel_task == NULL) {
LOG("Ядро ID: %u\n", new_task->id);
kernel_task = new_task;
current_task = new_task;
}
if (current_task != new_task) {
LOG("Прошлый ID: %u\n", current_task->id);
current_task->next = new_task;
}
new_task->last = current_task;
new_task->next = current_task->next;
current_task->next->last = new_task;
current_task->next = new_task;
LOG("Создан новый поток с ID: %u\n", new_task->id);
asm volatile("sti"); // Включаем прерывания
return new_task;
if (full_init) {
asm volatile("sti"); // Включаем прерывания
}
return new_task->id;
}
#endif
void notask_switch( ) {
asm volatile("nop");
void dummy(uint64_t n) {
for (;;) {
asm volatile("hlt");
}
}
void task_init( ) {
LOG("Потоки не инициализированы\n");
idt_set_int(32, notask_switch);
asm volatile("cli");
idt_set_int(32, task_switch);
#if 0
return;
uint64_t rsp;
uint64_t cr3;
asm volatile("mov %%rsp, %0" : "=r"(rsp));
asm volatile("mov %%cr3, %0" : "=r"(cr3));
asm volatile("cli");
kernel_task = mem_alloc(sizeof(task_t));
tool_memset(kernel_task, 0, sizeof(task_t));
kernel_task->id = next_thread_id++;
kernel_task->stack_size = STACK_SIZE;
kernel_task->cr3 = cr3;
kernel_task->rsp = rsp;
current_task = kernel_task;
current_task->last = current_task;
current_task->next = current_task;
last_task = kernel_task;
task_new_thread(dummy, 2 + 2);
LOG("Потоки инициализированы\n");
#endif
}

27
kernel/cpu/task_switch.s Normal file
View File

@ -0,0 +1,27 @@
.global task_switch_asm
task_switch_asm:
pushfq
movq %rax, (%rdi)
movq %rbx, 8(%rdi)
movq %rcx, 16(%rdi)
movq %rdx, 24(%rdi)
movq %rsi, 32(%rdi)
movq %rdi, 40(%rdi)
movq %rsp, 48(%rdi)
movq %rbp, 56(%rdi)
movq %cr3, %rax
movq %rax, 64(%rdi)
movq 64(%rsi), %rax
movq %rax, %cr3
movq 56(%rsi), %rbp
movq 48(%rsi), %rsp
movq 40(%rsi), %rdi
movq 24(%rsi), %rdx
movq 16(%rsi), %rcx
movq 8(%rsi), %rbx
movq (%rsi), %rax
movq 32(%rsi), %rsi
popfq
retq

View File

@ -15,6 +15,8 @@
#include <tool.h>
#include <version.h>
uint64_t full_init = 0;
// Точка входа
void _start( ) {
asm volatile("cli");
@ -37,6 +39,8 @@ void _start( ) {
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
full_init = 1;
asm volatile("sti");
for (;;) { asm volatile("hlt"); }