summaryrefslogtreecommitdiff
path: root/kc/core/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'kc/core/cpu')
-rw-r--r--kc/core/cpu/arch_thread.c81
-rw-r--r--kc/core/cpu/arch_thread.h12
-rw-r--r--kc/core/cpu/cpu.c4
-rw-r--r--kc/core/cpu/cpu_task.S54
-rw-r--r--kc/core/cpu/cpu_thread.S57
-rw-r--r--kc/core/cpu/exceptions.h4
6 files changed, 154 insertions, 58 deletions
diff --git a/kc/core/cpu/arch_thread.c b/kc/core/cpu/arch_thread.c
new file mode 100644
index 0000000..c0d707a
--- /dev/null
+++ b/kc/core/cpu/arch_thread.c
@@ -0,0 +1,81 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdnoreturn.h>
+
+#include <libc/stdio.h>
+
+#include "task.h"
+
+struct arch_register_context
+{
+ uint64_t
+ r15,
+ r14,
+ r13,
+ r12,
+ r11,
+ r10,
+ r9,
+ r8,
+ rsi,
+ rdi,
+ rdx,
+ rcx,
+ rbx,
+ rax,
+ rbp,
+ rsp;
+};
+
+extern uint64_t *get_tss_rsp0(void);
+
+struct arch_thread_context
+{
+ struct arch_register_context register_context;
+ void *return_address;
+};
+
+extern void arch_swap_thread_stack(
+ void * volatile *outgoing_stack,
+ void *incoming_stack);
+
+extern void arch_begin_thread(
+ void *(func)(void *),
+ void *params);
+
+void arch_create_thread(
+ struct kc_thread *thread,
+ void *(*func)(void *),
+ void *params)
+{
+ uintptr_t stack_pointer = (uintptr_t)thread->kernel_stack_pointer;
+ struct arch_thread_context *context = (struct arch_thread_context *)
+ (stack_pointer -= sizeof(*context));
+ thread->kernel_stack_pointer = (void *)stack_pointer;
+
+ context->return_address = (void *)arch_begin_thread;
+ context->register_context.rdi = (uint64_t)func;
+ context->register_context.rsi = (uint64_t)params;
+ context->register_context.rdx = (uint64_t)thread;
+ context->register_context.rsp = (uint64_t)&context->return_address;
+}
+
+void arch_swap_thread(
+ struct kc_thread *outgoing,
+ struct kc_thread *incoming)
+{
+ arch_swap_thread_stack(&outgoing->kernel_stack_pointer, incoming->kernel_stack_pointer);
+}
+
+void *arch_idle_loop(void *)
+{
+ for (;;) __asm__ ("hlt");
+ return nullptr;
+}
+
+noreturn void arch_terminate_thread(union kc_thread_result result, struct kc_thread *)
+{
+ kct_terminate(result);
+ for (;;) __asm__ ("hlt");
+}
+
diff --git a/kc/core/cpu/arch_thread.h b/kc/core/cpu/arch_thread.h
new file mode 100644
index 0000000..2b8d0fb
--- /dev/null
+++ b/kc/core/cpu/arch_thread.h
@@ -0,0 +1,12 @@
+#pragma once
+
+void * arch_idle_loop(void *);
+
+void arch_create_thread(
+ struct kc_thread *thread,
+ void *(kc_thread_func)(void *),
+ void *params);
+
+void arch_swap_thread(
+ struct kc_thread *outgoing,
+ struct kc_thread *incoming);
diff --git a/kc/core/cpu/cpu.c b/kc/core/cpu/cpu.c
index da55d38..226c9cf 100644
--- a/kc/core/cpu/cpu.c
+++ b/kc/core/cpu/cpu.c
@@ -10,7 +10,7 @@
#include <stddef.h>
#include <stdint.h>
-#include <lib/kstdio.h>
+#include <libc/stdio.h>
#define GDT_ENTRIES 16
#define IDT_ENTRIES 256
@@ -53,7 +53,7 @@ uint64_t *get_tss_rsp0(void)
static void syscall_entry(void)
{
- kprintf("system call\n");
+ printf("system call\n");
halt();
}
diff --git a/kc/core/cpu/cpu_task.S b/kc/core/cpu/cpu_task.S
deleted file mode 100644
index a411028..0000000
--- a/kc/core/cpu/cpu_task.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/* thread switching routines for x86_64
-* adapted from:
-* https://wiki.osdev.org/Brendan%27s_Multi-tasking_Tutorial
-*
-*
-*/
-
-.hidden cpu_set_thread
-.global cpu_set_thread
-.type cpu_set_thread, @function
-cpu_set_thread:
- /* x86_64 SysV ABI
- * must save the following registers to the stack:
- * rbx, rsp, rbp, r12, r13, r14, r15
- * the following are the parameters for switching tasks
- * rdi: pointer to control block of thread being switched to
- * rsi: pointer to control block of the current thread
- * rdx: pointer to this cpu's task state segment rsp0 field
- */
- // test for attempt to switch to same thread
- cmp %rdi,%rsi
- je .Lnothing
- // test for a NULL origin thread
- test %rsi,%rsi
- // skip saving the state for a NULL origin thread
- jz .Lnull_thread
- push %rbx
- push %r12
- push %r13
- push %r14
- push %r15
- push %rbp
- /* the current task will be in rsi */
- mov %rsp, 0(%rsi) // save the stack pointer for the current task
-.Lnull_thread:
- mov 0(%rdi),%rsp // new stack is the next's task's stack
- mov 8(%rdi),%rbx // top of the next task's kernel stack
- mov %rbx,0(%rdx) // save the esp0 to the tss
- mov 16(%rdi),%rax // page map for the next task
- mov %cr3, %rcx // in case we need to change the page map
- cmp %rax,%rcx
- je .Lfinish
- mov %rax,%cr3 // if the page maps are not the same, reload
-.Lfinish:
- pop %rbp // get all the registers off the new task's stack
- pop %r15
- pop %r14
- pop %r13
- pop %r12
- pop %rbx
-.Lnothing: // do nothing if the threads are the same
- ret // leave into the new task
-.size cpu_set_thread, . - cpu_set_thread
-
diff --git a/kc/core/cpu/cpu_thread.S b/kc/core/cpu/cpu_thread.S
new file mode 100644
index 0000000..c4d04e1
--- /dev/null
+++ b/kc/core/cpu/cpu_thread.S
@@ -0,0 +1,57 @@
+.section .text
+
+.extern arch_terminate_thread
+
+.global arch_begin_thread
+arch_begin_thread:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ pushq %rdx
+ pushq %rbp
+ movq %rsp, %rbp
+ andq $-16, %rsp
+ callq *%rax
+ movq %rax, %rdi
+ movq 8(%rbp), %rsi
+ callq arch_terminate_thread
+
+.global arch_swap_thread_stack
+arch_swap_thread_stack:
+ pushq %rsp
+ pushq %rbp
+ pushq %rax
+ pushq %rbx
+ pushq %rcx
+ pushq %rdx
+ pushq %rdi
+ pushq %rsi
+ pushq %r8
+ pushq %r9
+ pushq %r10
+ pushq %r11
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp, (%rdi)
+ .Lenter_thread:
+ movq %rsi, %rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %r11
+ popq %r10
+ popq %r9
+ popq %r8
+ popq %rsi
+ popq %rdi
+ popq %rdx
+ popq %rcx
+ popq %rbx
+ popq %rax
+ popq %rbp
+ popq %rsp
+ retq
+
+
diff --git a/kc/core/cpu/exceptions.h b/kc/core/cpu/exceptions.h
index 7babb65..14a2088 100644
--- a/kc/core/cpu/exceptions.h
+++ b/kc/core/cpu/exceptions.h
@@ -21,7 +21,7 @@
#ifndef __ASSEMBLER__
-#include <lib/kstdio.h>
+#include <libc/stdio.h>
struct isr_context_param_regs
{
@@ -53,7 +53,7 @@ struct isr_context
static inline void print_exception_context(struct isr_context *context)
{
- kprintf(
+ printf(
"exception %#hhx:%x context:\n"
"interrupt entry state:\n"
"rip: %#hx:%p rflags: %#0.16lx\n"