diff options
author | johannst <johannes.stoelp@gmail.com> | 2021-02-26 23:19:03 +0100 |
---|---|---|
committer | johannst <johannes.stoelp@gmail.com> | 2021-02-26 23:19:03 +0100 |
commit | 0d881bc974b74dff75c00a3cab5d535cbb2ace46 (patch) | |
tree | 35c5892c135d5623879b106e93df4cc235669a8d /lib/arch/arm/init_stack.cc | |
parent | 5fbee6be76c8751c282b45c54b8179ae525e00c1 (diff) | |
download | matcha-threads-0d881bc974b74dff75c00a3cab5d535cbb2ace46.tar.gz matcha-threads-0d881bc974b74dff75c00a3cab5d535cbb2ace46.zip |
added implementation for armv7a
Diffstat (limited to 'lib/arch/arm/init_stack.cc')
-rw-r--r-- | lib/arch/arm/init_stack.cc | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/arch/arm/init_stack.cc b/lib/arch/arm/init_stack.cc new file mode 100644 index 0000000..422be64 --- /dev/null +++ b/lib/arch/arm/init_stack.cc @@ -0,0 +1,35 @@ +#include <cassert> +#include <cstdint> // uintN_t + +extern "C" void thread_create(); + +void* init_stack(void* stack_ptr, void (*entry)(void*), const void* ctx) { + static_assert(sizeof(uint32_t) == sizeof(std::uintptr_t), "Pointer must be 32bit!"); + + // 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. + + uint32_t* stack = static_cast<uint32_t*>(stack_ptr); + // Arguments for `thread_create`. + *(--stack) = reinterpret_cast<uint32_t>(ctx); + *(--stack) = reinterpret_cast<uint32_t>(entry); + + // Yield epilogue. + *(--stack) = reinterpret_cast<uint32_t>(thread_create); // r15 (PC) + *(--stack) = static_cast<uint32_t>(0); // r11 (FP) + + // Callee saved registers. + *(--stack) = static_cast<uint32_t>(0); // r11 + *(--stack) = static_cast<uint32_t>(0); // r10 + *(--stack) = static_cast<uint32_t>(0); // r9 + *(--stack) = static_cast<uint32_t>(0); // r8 + *(--stack) = static_cast<uint32_t>(0); // r7 + *(--stack) = static_cast<uint32_t>(0); // r6 + *(--stack) = static_cast<uint32_t>(0); // r5 + *(--stack) = static_cast<uint32_t>(0); // r4 + + assert((reinterpret_cast<std::uintptr_t>(stack) & 0x7) == 0); // 8byte aligned + return static_cast<void*>(stack); +} |