1 /*
2  * Copyright (C) 2016 Kernkonzept GmbH.
3  * Author(s): Sarah Hoffmann <sarah.hoffmann@kernkonzept.com>
4  *
5  * This file is distributed under the terms of the GNU General Public
6  * License, version 2.  Please see the COPYING-GPL-2 file for details.
7  */
8 #pragma once
9 
10 #include <l4/sys/compiler.h>
11 
12 #if _MIPS_SZPTR == 32
13 #define L4UTIL_THREAD_START_LOAD_FUNC_ADDR(func) "la $t9," func "\n"
14 #else
15 #define L4UTIL_THREAD_START_LOAD_FUNC_ADDR(func) "dla $t9," func "\n"
16 #endif
17 
18 #if _MIPS_SIM == _ABIO32
19 #define L4UTIL_THREAD_START_SETUP_GP  ".cpload $25;"
20 #else
21 #define L4UTIL_THREAD_START_SETUP_GP \
22 " bal 10f \n" \
23 "  nop    \n" \
24 "10:      \n" \
25 " .cpsetup $31, $25, 10b \n"
26 #endif
27 
28 
29 #define __L4UTIL_THREAD_FUNC(name) \
30 EXTERN_C_BEGIN \
31 static void  __attribute__((used)) name##_worker_function(void); \
32 asm ( \
33   ".type " #name ", function \n" \
34   ".global " #name " \n" \
35   #name ": \n .set push; .set noreorder;" \
36   L4UTIL_THREAD_START_SETUP_GP \
37   L4UTIL_THREAD_START_LOAD_FUNC_ADDR(#name "_worker_function") \
38   "  jal $t9 \n" \
39   "   nop    \n"\
40   ".set pop" \
41 ); \
42 EXTERN_C_END \
43 static L4_NORETURN void name##_worker_function(void)
44 
45 #define L4UTIL_THREAD_FUNC(name) __L4UTIL_THREAD_FUNC(name)
46 
47 #define __L4UTIL_THREAD_STATIC_FUNC(name) \
48 EXTERN_C_BEGIN \
49 void __attribute__((visibility("internal"))) name(void); \
50 static void __attribute__((used)) name ##_worker_function(void); \
51 asm ( \
52   ".type " #name ", function \n" \
53   #name ": \n .set push; .set noreorder;" \
54   L4UTIL_THREAD_START_SETUP_GP \
55   L4UTIL_THREAD_START_LOAD_FUNC_ADDR(#name "_worker_function") \
56   "  jal $t9 \n" \
57   "   nop    \n"\
58   ".set pop" \
59 ); \
60 EXTERN_C_END \
61 static L4_NORETURN void name##_worker_function(void)
62 
63 #define L4UTIL_THREAD_STATIC_FUNC(name) __L4UTIL_THREAD_STATIC_FUNC(name)
64 
65 
66 #include_next <l4/util/thread.h>
67