1 /*
2 * Copyright (c) 2019-2020 Cobham Gaisler AB
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <ksched.h>
9
10 void z_thread_entry_wrapper(k_thread_entry_t thread,
11 void *arg1,
12 void *arg2,
13 void *arg3);
14
15 /*
16 * Frame used by _thread_entry_wrapper
17 *
18 * Allocate a 16 register window save area at bottom of the stack. This is
19 * required if we need to taken a trap (interrupt) in the thread entry wrapper.
20 */
21 struct init_stack_frame {
22 uint32_t window_save_area[16];
23 };
24
25 #if defined(CONFIG_FPU_SHARING)
26 #define USER_FP_MASK K_FP_REGS
27 #else
28 #define USER_FP_MASK 0
29 #endif
30
arch_new_thread(struct k_thread * thread,k_thread_stack_t * stack,char * stack_ptr,k_thread_entry_t entry,void * p1,void * p2,void * p3)31 void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
32 char *stack_ptr, k_thread_entry_t entry,
33 void *p1, void *p2, void *p3)
34 {
35 struct init_stack_frame *iframe;
36
37 /* Initial stack frame data, stored at base of the stack */
38 iframe = Z_STACK_PTR_TO_FRAME(struct init_stack_frame, stack_ptr);
39
40 thread->callee_saved.i0 = (uint32_t) entry;
41 thread->callee_saved.i1 = (uint32_t) p1;
42 thread->callee_saved.i2 = (uint32_t) p2;
43 thread->callee_saved.i3 = (uint32_t) p3;
44 thread->callee_saved.i6 = 0; /* frame pointer */
45 thread->callee_saved.o6 = (uint32_t) iframe; /* stack pointer */
46 thread->callee_saved.o7 = (uint32_t) z_thread_entry_wrapper - 8;
47 thread->callee_saved.psr = PSR_S | PSR_PS | PSR_ET;
48
49 if (IS_ENABLED(CONFIG_FPU_SHARING)) {
50 /* Selected threads can use the FPU */
51 if (thread->base.user_options & USER_FP_MASK) {
52 thread->callee_saved.psr |= PSR_EF;
53 }
54 } else if (IS_ENABLED(CONFIG_FPU)) {
55 /* Any thread can use the FPU */
56 thread->callee_saved.psr |= PSR_EF;
57 }
58
59 thread->switch_handle = thread;
60 }
61
z_arch_get_next_switch_handle(struct k_thread ** old_thread)62 void *z_arch_get_next_switch_handle(struct k_thread **old_thread)
63 {
64 *old_thread = _current;
65
66 return z_get_next_switch_handle(*old_thread);
67 }
68
69 #if defined(CONFIG_FPU_SHARING)
arch_float_disable(struct k_thread * thread)70 int arch_float_disable(struct k_thread *thread)
71 {
72 return -ENOTSUP;
73 }
74
arch_float_enable(struct k_thread * thread,unsigned int options)75 int arch_float_enable(struct k_thread *thread, unsigned int options)
76 {
77 return -ENOTSUP;
78 }
79 #endif /* CONFIG_FPU_SHARING */
80