aboutsummaryrefslogtreecommitdiff
path: root/lib/arch/arm/init_stack.cc
diff options
context:
space:
mode:
authorjohannst <johannes.stoelp@gmail.com>2021-02-26 23:19:03 +0100
committerjohannst <johannes.stoelp@gmail.com>2021-02-26 23:19:03 +0100
commit0d881bc974b74dff75c00a3cab5d535cbb2ace46 (patch)
tree35c5892c135d5623879b106e93df4cc235669a8d /lib/arch/arm/init_stack.cc
parent5fbee6be76c8751c282b45c54b8179ae525e00c1 (diff)
downloadmatcha-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.cc35
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);
+}