2 * Copyright 2003-2010, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler <axeld@pinc-software.de>
7 * Ingo Weinhold <bonefish@cs.tu-berlin.de>
8 * François Revol <revol@free.fr>
10 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
11 * Distributed under the terms of the NewOS License.
16 #include <arch_thread.h>
19 #include <arch/thread.h>
20 #include <boot/stage2.h>
24 #include <vm/vm_types.h>
25 #include <vm/VMAddressSpace.h>
27 #include <arch/vm_translation_map.h>
31 //#define TRACE_ARCH_THREAD
32 #ifdef TRACE_ARCH_THREAD
33 # define TRACE(x) dprintf x
38 // Valid initial arch_thread state. We just memcpy() it when initializing
39 // a new thread structure.
40 static struct arch_thread sInitialState
;
42 Thread
*gCurrentThread
;
46 arm_push_iframe(struct iframe_stack
*stack
, struct iframe
*frame
)
48 ASSERT(stack
->index
< IFRAME_TRACE_DEPTH
);
49 stack
->frames
[stack
->index
++] = frame
;
54 arm_pop_iframe(struct iframe_stack
*stack
)
56 ASSERT(stack
->index
> 0);
63 arch_thread_init(struct kernel_args
*args
)
65 // Initialize the static initial arch_thread state (sInitialState).
66 // Currently nothing to do, i.e. zero initialized is just fine.
73 arch_team_init_team_struct(Team
*team
, bool kernel
)
75 // Nothing to do. The structure is empty.
81 arch_thread_init_thread_struct(Thread
*thread
)
83 // set up an initial state (stack & fpu)
84 memcpy(&thread
->arch_info
, &sInitialState
, sizeof(struct arch_thread
));
91 arch_thread_init_kthread_stack(Thread
* thread
, void* _stack
, void* _stackTop
,
92 void (*function
)(void*), const void* data
)
94 addr_t
* stackTop
= (addr_t
*)_stackTop
;
96 TRACE(("arch_thread_init_kthread_stack(%s): stack top %p, function %p, data: "
97 "%p\n", thread
->name
, stackTop
, function
, data
));
99 // push the function address -- that's the return address used after the
100 // context switch (lr/r14 register)
101 *--stackTop
= (addr_t
)function
;
103 // simulate storing registers r1-r12
104 for (int i
= 1; i
<= 12; i
++)
107 // push the function argument as r0
108 *--stackTop
= (addr_t
)data
;
110 // save the stack position
111 thread
->arch_info
.sp
= stackTop
;
116 arch_thread_init_tls(Thread
*thread
)
118 uint32 tls
[TLS_USER_THREAD_SLOT
+ 1];
120 thread
->user_local_storage
= thread
->user_stack_base
121 + thread
->user_stack_size
;
123 // initialize default TLS fields
124 memset(tls
, 0, sizeof(tls
));
125 tls
[TLS_BASE_ADDRESS_SLOT
] = thread
->user_local_storage
;
126 tls
[TLS_THREAD_ID_SLOT
] = thread
->id
;
127 tls
[TLS_USER_THREAD_SLOT
] = (addr_t
)thread
->user_thread
;
129 return user_memcpy((void *)thread
->user_local_storage
, tls
, sizeof(tls
));
132 extern "C" void arm_context_switch(void *from
, void *to
);
135 arch_thread_context_switch(Thread
*from
, Thread
*to
)
137 TRACE(("arch_thread_context_switch: %p(%s/%p) -> %p(%s/%p)\n",
138 from
, from
->name
, from
->arch_info
.sp
, to
, to
->name
, to
->arch_info
.sp
));
139 arm_context_switch(&from
->arch_info
, &to
->arch_info
);
140 TRACE(("arch_thread_context_switch %p %p\n", to
, from
));
145 arch_thread_dump_info(void *info
)
147 struct arch_thread
*at
= (struct arch_thread
*)info
;
149 dprintf("\tsp: %p\n", at
->sp
);
154 arch_thread_enter_userspace(Thread
*thread
, addr_t entry
,
155 void *arg1
, void *arg2
)
157 panic("arch_thread_enter_uspace(): not yet implemented\n");
163 arch_on_signal_stack(Thread
*thread
)
170 arch_setup_signal_frame(Thread
*thread
, struct sigaction
*sa
,
171 struct signal_frame_data
*signalFrameData
)
178 arch_restore_signal_frame(struct signal_frame_data
* signalFrameData
)
185 arch_check_syscall_restart(Thread
*thread
)
190 /** Saves everything needed to restore the frame in the child fork in the
191 * arch_fork_arg structure to be passed to arch_restore_fork_frame().
192 * Also makes sure to return the right value.
195 arch_store_fork_frame(struct arch_fork_arg
*arg
)
200 /** Restores the frame from a forked team as specified by the provided
201 * arch_fork_arg structure.
202 * Needs to be called from within the child team, ie. instead of
203 * arch_thread_enter_uspace() as thread "starter".
204 * This function does not return to the caller, but will enter userland
205 * in the child team at the same position where the parent team left of.
208 arch_restore_fork_frame(struct arch_fork_arg
*arg
)