xref: /optee_os/core/arch/riscv/include/kernel/thread_private_arch.h (revision b9807372c2314a7a52993f6db52df545ca20ad3a)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright 2022-2023 NXP
4  */
5 
6 #ifndef __KERNEL_THREAD_PRIVATE_ARCH_H
7 #define __KERNEL_THREAD_PRIVATE_ARCH_H
8 
9 #ifndef __ASSEMBLER__
10 
11 #include <kernel/thread.h>
12 
13 #define STACK_TMP_OFFS		0
14 
15 #if defined(__clang__) && !defined(__OPTIMIZE_SIZE__)
16 #define STACK_TMP_SIZE		(4096 + STACK_TMP_OFFS + CFG_STACK_TMP_EXTRA)
17 #else
18 #define STACK_TMP_SIZE		(2048 + STACK_TMP_OFFS + CFG_STACK_TMP_EXTRA)
19 #endif
20 
21 #ifdef CFG_CORE_DEBUG_CHECK_STACKS
22 #define STACK_THREAD_SIZE	(10240 + CFG_STACK_THREAD_EXTRA)
23 #else
24 #define STACK_THREAD_SIZE	(8192 + CFG_STACK_THREAD_EXTRA)
25 #endif
26 
27 #define STACK_ABT_SIZE		4096
28 
29 #ifdef CFG_CORE_DEBUG_CHECK_STACKS
30 /*
31  * Extra space added to each stack in order to reliably detect and dump stack
32  * overflows. Should cover the maximum expected overflow size caused by any C
33  * function (say, 512 bytes; no function should have that much local variables),
34  * plus the maximum stack space needed by __cyg_profile_func_exit(): about 1 KB,
35  * a large part of which is used to print the call stack. Total: 1.5 KB.
36  */
37 #define STACK_CHECK_EXTRA	1536
38 #else
39 #define STACK_CHECK_EXTRA	0
40 #endif
41 
42 #define THREAD_RPC_NUM_ARGS     4
43 
44 #define	TRAP_MODE_KERNEL	0
45 #define	TRAP_MODE_USER		1
46 
47 struct thread_user_mode_rec {
48 	unsigned long ctx_regs_ptr;
49 	unsigned long exit_status0_ptr;
50 	unsigned long exit_status1_ptr;
51 	unsigned long pad;
52 	/*
53 	 * x[] is used to save registers for user/kernel context-switching
54 	 * 0: ra
55 	 * 1-2: s0-s1
56 	 * 3-12: s2-s11
57 	 */
58 	unsigned long x[13];
59 };
60 
61 extern long thread_user_kcode_offset;
62 
63 void thread_native_interrupt_handler(struct thread_ctx_regs *regs,
64 				     unsigned long cause);
65 void thread_foreign_interrupt_handler(struct thread_ctx_regs *regs);
66 
67 /*
68  * Initializes TVEC for current hart. Called by thread_init_per_cpu()
69  */
70 void thread_init_tvec(void);
71 void thread_trap_vect(void);
72 void thread_trap_vect_end(void);
73 
74 void thread_return_to_udomain(unsigned long arg0, unsigned long arg1,
75 			      unsigned long arg2, unsigned long arg3,
76 			      unsigned long arg4, unsigned long arg5);
77 
78 void __panic_at_abi_return(void);
79 
80 /* Helper function to prepare CSR status for exception return */
81 unsigned long xstatus_for_xret(uint8_t pie, uint8_t pp);
82 
83 /*
84  * Assembly function as the first function in a thread.  Handles a stdcall,
85  * a0-a3 holds the parameters. Hands over to __thread_std_abi_entry() when
86  * everything is set up and does some post processing once
87  * __thread_std_abi_entry() returns.
88  */
89 void thread_std_abi_entry(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3,
90 			  uint32_t a4, uint32_t a5);
91 uint32_t __thread_std_abi_entry(uint32_t a0, uint32_t a1, uint32_t a2,
92 				uint32_t a3, uint32_t a4, uint32_t a5);
93 /*
94  * Called from assembly only, vector_fast_abi_entry(). Handles a fast ABI
95  * by dispatching it to the registered fast ABI handler.
96  */
97 void thread_handle_fast_abi(struct thread_abi_args *args);
98 
99 /*
100  * Called from assembly only, vector_std_abi_entry(). Handles a std ABI by
101  * dispatching it to the registered std ABI handler.
102  */
103 uint32_t thread_handle_std_abi(uint32_t a0, uint32_t a1, uint32_t a2,
104 			       uint32_t a3, uint32_t a4, uint32_t a5,
105 			       uint32_t a6, uint32_t a7);
106 
107 /*
108  * Private functions made available for thread_rv.S
109  */
110 int thread_state_suspend(uint32_t flags, unsigned long status, vaddr_t pc);
111 void thread_resume(struct thread_ctx_regs *regs);
112 uint32_t __thread_enter_user_mode(struct thread_ctx_regs *regs,
113 				  uint32_t *exit_status0,
114 				  uint32_t *exit_status1);
115 void *thread_get_tmp_sp(void);
116 void thread_state_free(void);
117 struct thread_ctx_regs *thread_get_ctx_regs(void);
118 void thread_alloc_and_run(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3,
119 			  uint32_t a4, uint32_t a5);
120 void thread_resume_from_rpc(uint32_t thread_id, uint32_t a0, uint32_t a1,
121 			    uint32_t a2, uint32_t a3);
122 void thread_rpc_xstatus(uint32_t rv[THREAD_RPC_NUM_ARGS], unsigned long status);
123 void __thread_rpc(uint32_t rv[THREAD_RPC_NUM_ARGS]);
124 
thread_rpc(uint32_t rv[THREAD_RPC_NUM_ARGS])125 static inline void thread_rpc(uint32_t rv[THREAD_RPC_NUM_ARGS])
126 {
127 	__thread_rpc(rv);
128 }
129 
130 void thread_scall_handler(struct thread_scall_regs *regs);
131 
132 #endif /*__ASSEMBLER__*/
133 
134 /*
135  * Used in entry.S to allocate a temporary thread_core_local[0] for the boot CPU
136  * and the associated abort and temporary stacks.
137  */
138 #define THREAD_BOOT_INIT_TMP_ALLOC	(SMALL_PAGE_SIZE * 6)
139 
140 #endif /*__KERNEL_THREAD_PRIVATE_ARCH_H*/
141