From 2c6374feedeb95b9b0a0e186030ee05726acfee1 Mon Sep 17 00:00:00 2001
From: Claudio Fontana <claudio.fontana@huawei.com>
Date: Wed, 7 May 2014 17:50:20 +0200
Subject: [PATCH] aarch64: arch-switch: implement switch to first

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
---
 arch/aarch64/arch-switch.hh       | 39 +++++++++++++++++++++++++------
 arch/aarch64/arch-thread-state.hh |  4 +++-
 arch/aarch64/entry.S              |  6 -----
 3 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/arch/aarch64/arch-switch.hh b/arch/aarch64/arch-switch.hh
index 763534f83..590508d89 100644
--- a/arch/aarch64/arch-switch.hh
+++ b/arch/aarch64/arch-switch.hh
@@ -12,12 +12,10 @@
 
 #include <osv/barrier.hh>
 #include <string.h>
+#include "arch-setup.hh"
 
 extern "C" {
-void thread_main(void);
 void thread_main_c(sched::thread* t);
-void stack_trampoline(sched::thread* t, void (*func)(sched::thread*),
-                      void** stacktop);
 }
 
 namespace sched {
@@ -29,7 +27,24 @@ void thread::switch_to()
 
 void thread::switch_to_first()
 {
-    abort();
+    barrier();
+    arch_setup_tls(_tcb);
+    barrier();
+
+    s_current = this;
+    current_cpu = _detached_state->_cpu;
+    remote_thread_local_var(percpu_base) = _detached_state->_cpu->percpu_base;
+
+    asm volatile("\n"
+                 "ldp x29, x0, %0  \n"
+                 "ldp x2, x1, %1   \n"
+                 "mov sp, x2       \n"
+                 "blr x1           \n"
+                 :
+                 : "Ump"(this->_state.fp), "Ump"(this->_state.sp)
+                 : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
+                   "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+                   "x16", "x17", "x18", "x30", "memory");
 }
 
 void thread::init_stack()
@@ -43,9 +58,10 @@ void thread::init_stack()
         stack.deleter = stack.default_deleter;
     }
     void** stacktop = reinterpret_cast<void**>(stack.begin + stack.size);
-    _state.fp = this;
-    _state.pc = reinterpret_cast<void*>(thread_main);
+    _state.fp = 0;
+    _state.thread = this;
     _state.sp = stacktop;
+    _state.pc = reinterpret_cast<void*>(thread_main_c);
 }
 
 void thread::setup_tcb()
@@ -66,7 +82,16 @@ void thread::free_tcb()
 
 void thread_main_c(thread* t)
 {
-    abort();
+    debug_early_u64("thread_main_c: thread* t=", (u64)t);
+
+    arch::irq_enable();
+
+#ifdef CONF_preempt
+    preempt_enable();
+#endif
+
+    t->main();
+    t->complete();
 }
 
 }
diff --git a/arch/aarch64/arch-thread-state.hh b/arch/aarch64/arch-thread-state.hh
index bc592b6fb..af4244723 100644
--- a/arch/aarch64/arch-thread-state.hh
+++ b/arch/aarch64/arch-thread-state.hh
@@ -9,8 +9,10 @@
 #define ARCH_THREAD_STATE_HH_
 
 struct thread_state {
-    void* sp;
     void* fp;
+    void* thread;
+
+    void* sp;
     void* pc;
 };
 
diff --git a/arch/aarch64/entry.S b/arch/aarch64/entry.S
index 35e942988..e39a7678c 100644
--- a/arch/aarch64/entry.S
+++ b/arch/aarch64/entry.S
@@ -137,12 +137,6 @@ entry_fiq:
 entry_serror:
         b       entry_invalid
 
-.global thread_main
-thread_main:
-        .type thread_main, @function
-	mov x0, x29
-	bl thread_main_c
-
 .global call_signal_handler_thunk
 call_signal_handler_thunk:
         .type call_signal_handler_thunk, @function
-- 
GitLab