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