From fc83627b14536d0b13b2dd751d09cecbea9db378 Mon Sep 17 00:00:00 2001 From: johannst Date: Tue, 29 Sep 2020 02:06:41 +0200 Subject: move thread init into arch/ --- lib/arch/x86_64/api.h | 6 ++++++ lib/arch/x86_64/asm.h | 4 ---- lib/arch/x86_64/init_stack.cc | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 lib/arch/x86_64/api.h delete mode 100644 lib/arch/x86_64/asm.h create mode 100644 lib/arch/x86_64/init_stack.cc (limited to 'lib/arch/x86_64') diff --git a/lib/arch/x86_64/api.h b/lib/arch/x86_64/api.h new file mode 100644 index 0000000..b2babc9 --- /dev/null +++ b/lib/arch/x86_64/api.h @@ -0,0 +1,6 @@ +/* Copyright (c) 2020 Johannes Stoelp */ + +#pragma once + +extern "C" void yield(const void* new_stack, void* const* old_stack); +void* init_stack(void* stack_ptr, void (*entry)(void*), void* ctx); diff --git a/lib/arch/x86_64/asm.h b/lib/arch/x86_64/asm.h deleted file mode 100644 index 962ff1b..0000000 --- a/lib/arch/x86_64/asm.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright (c) 2020 Johannes Stoelp */ - -extern "C" void thread_create(); -extern "C" void yield(const void* new_stack, void* const* old_stack); diff --git a/lib/arch/x86_64/init_stack.cc b/lib/arch/x86_64/init_stack.cc new file mode 100644 index 0000000..748fb56 --- /dev/null +++ b/lib/arch/x86_64/init_stack.cc @@ -0,0 +1,33 @@ +#include +#include // uintN_t + +extern "C" void thread_create(); + +void* init_stack(void* stack_ptr, void (*entry)(void*), void* ctx) { + static_assert(sizeof(uint64_t) == sizeof(std::uintptr_t), "Pointer must be 64bit!"); + + // Setup initial stack frame which will be popped when yielding + // first time into the thread. + // Basic idea is to yield into Thread::entry() function which will + // then call the user function. + + uint64_t* stack = static_cast(stack_ptr); + // Arguments for `thread_create`. + *(--stack) = reinterpret_cast(ctx); + *(--stack) = reinterpret_cast(entry); + + // Yield epilogue. + *(--stack) = reinterpret_cast(thread_create); // Return address + *(--stack) = static_cast(0); // rbp + + // Callee saved registers. + *(--stack) = static_cast(0); // rbx + *(--stack) = reinterpret_cast(static_cast(stack_ptr) - 4); // rbp + *(--stack) = static_cast(0); // r12 + *(--stack) = static_cast(0); // r13 + *(--stack) = static_cast(0); // r14 + *(--stack) = static_cast(0); // r15 + + assert((reinterpret_cast(stack) & 0xf) == 0); // 16byte aligned + return static_cast(stack); +} -- cgit v1.2.3