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