1 /*
2  * Copyright (c) 2018 Linaro Limited.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief ARC specific syscall header
10  *
11  * This header contains the ARC specific syscall interface.  It is
12  * included by the syscall interface architecture-abstraction header
13  * (include/arch/syscall.h)
14  */
15 
16 #ifndef ZEPHYR_INCLUDE_ARCH_ARC_SYSCALL_H_
17 #define ZEPHYR_INCLUDE_ARCH_ARC_SYSCALL_H_
18 
19 #define _TRAP_S_CALL_RUNTIME_EXCEPT		2
20 #define _TRAP_S_CALL_SYSTEM_CALL		3
21 
22 #ifdef CONFIG_USERSPACE
23 #ifndef _ASMLANGUAGE
24 
25 #include <zephyr/types.h>
26 #include <stdbool.h>
27 
28 #ifdef CONFIG_ISA_ARCV2
29 #include <zephyr/arch/arc/v2/aux_regs.h>
30 #endif
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 /* Syscall invocation macros. arc-specific machine constraints used to ensure
36  * args land in the proper registers. Currently, they are all stub functions
37  * just for enabling CONFIG_USERSPACE on arc w/o errors.
38  */
39 
arch_syscall_invoke6(uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t arg6,uintptr_t call_id)40 static inline uintptr_t arch_syscall_invoke6(uintptr_t arg1, uintptr_t arg2,
41 					     uintptr_t arg3, uintptr_t arg4,
42 					     uintptr_t arg5, uintptr_t arg6,
43 					     uintptr_t call_id)
44 {
45 	register uint32_t ret __asm__("r0") = arg1;
46 	register uint32_t r1 __asm__("r1") = arg2;
47 	register uint32_t r2 __asm__("r2") = arg3;
48 	register uint32_t r3 __asm__("r3") = arg4;
49 	register uint32_t r4 __asm__("r4") = arg5;
50 	register uint32_t r5 __asm__("r5") = arg6;
51 	register uint32_t r6 __asm__("r6") = call_id;
52 
53 	compiler_barrier();
54 
55 	__asm__ volatile(
56 			 "trap_s %[trap_s_id]\n"
57 			 : "=r"(ret)
58 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
59 			   "r" (ret), "r" (r1), "r" (r2), "r" (r3),
60 			   "r" (r4), "r" (r5), "r" (r6));
61 
62 	return ret;
63 }
64 
arch_syscall_invoke5(uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t call_id)65 static inline uintptr_t arch_syscall_invoke5(uintptr_t arg1, uintptr_t arg2,
66 					     uintptr_t arg3, uintptr_t arg4,
67 					     uintptr_t arg5,
68 					     uintptr_t call_id)
69 {
70 	register uint32_t ret __asm__("r0") = arg1;
71 	register uint32_t r1 __asm__("r1") = arg2;
72 	register uint32_t r2 __asm__("r2") = arg3;
73 	register uint32_t r3 __asm__("r3") = arg4;
74 	register uint32_t r4 __asm__("r4") = arg5;
75 	register uint32_t r6 __asm__("r6") = call_id;
76 
77 	compiler_barrier();
78 
79 	__asm__ volatile(
80 			 "trap_s %[trap_s_id]\n"
81 			 : "=r"(ret)
82 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
83 			   "r" (ret), "r" (r1), "r" (r2), "r" (r3),
84 			   "r" (r4), "r" (r6));
85 
86 	return ret;
87 }
88 
arch_syscall_invoke4(uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t call_id)89 static inline uintptr_t arch_syscall_invoke4(uintptr_t arg1, uintptr_t arg2,
90 					     uintptr_t arg3, uintptr_t arg4,
91 					     uintptr_t call_id)
92 {
93 	register uint32_t ret __asm__("r0") = arg1;
94 	register uint32_t r1 __asm__("r1") = arg2;
95 	register uint32_t r2 __asm__("r2") = arg3;
96 	register uint32_t r3 __asm__("r3") = arg4;
97 	register uint32_t r6 __asm__("r6") = call_id;
98 
99 	compiler_barrier();
100 
101 	__asm__ volatile(
102 			 "trap_s %[trap_s_id]\n"
103 			 : "=r"(ret)
104 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
105 			   "r" (ret), "r" (r1), "r" (r2), "r" (r3),
106 			   "r" (r6));
107 
108 	return ret;
109 }
110 
arch_syscall_invoke3(uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t call_id)111 static inline uintptr_t arch_syscall_invoke3(uintptr_t arg1, uintptr_t arg2,
112 					     uintptr_t arg3,
113 					     uintptr_t call_id)
114 {
115 	register uint32_t ret __asm__("r0") = arg1;
116 	register uint32_t r1 __asm__("r1") = arg2;
117 	register uint32_t r2 __asm__("r2") = arg3;
118 	register uint32_t r6 __asm__("r6") = call_id;
119 
120 	compiler_barrier();
121 
122 	__asm__ volatile(
123 			 "trap_s %[trap_s_id]\n"
124 			 : "=r"(ret)
125 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
126 			   "r" (ret), "r" (r1), "r" (r2), "r" (r6));
127 
128 	return ret;
129 }
130 
arch_syscall_invoke2(uintptr_t arg1,uintptr_t arg2,uintptr_t call_id)131 static inline uintptr_t arch_syscall_invoke2(uintptr_t arg1, uintptr_t arg2,
132 					     uintptr_t call_id)
133 {
134 	register uint32_t ret __asm__("r0") = arg1;
135 	register uint32_t r1 __asm__("r1") = arg2;
136 	register uint32_t r6 __asm__("r6") = call_id;
137 
138 	compiler_barrier();
139 
140 	__asm__ volatile(
141 			 "trap_s %[trap_s_id]\n"
142 			 : "=r"(ret)
143 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
144 			   "r" (ret), "r" (r1), "r" (r6));
145 
146 	return ret;
147 }
148 
arch_syscall_invoke1(uintptr_t arg1,uintptr_t call_id)149 static inline uintptr_t arch_syscall_invoke1(uintptr_t arg1, uintptr_t call_id)
150 {
151 	register uint32_t ret __asm__("r0") = arg1;
152 	register uint32_t r6 __asm__("r6") = call_id;
153 
154 	compiler_barrier();
155 
156 	__asm__ volatile(
157 			 "trap_s %[trap_s_id]\n"
158 			 : "=r"(ret)
159 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
160 			   "r" (ret), "r" (r6));
161 
162 	return ret;
163 }
164 
arch_syscall_invoke0(uintptr_t call_id)165 static inline uintptr_t arch_syscall_invoke0(uintptr_t call_id)
166 {
167 	register uint32_t ret __asm__("r0");
168 	register uint32_t r6 __asm__("r6") = call_id;
169 
170 	compiler_barrier();
171 
172 	__asm__ volatile(
173 			 "trap_s %[trap_s_id]\n"
174 			 : "=r"(ret)
175 			 : [trap_s_id] "i" (_TRAP_S_CALL_SYSTEM_CALL),
176 			   "r" (ret), "r" (r6));
177 
178 	return ret;
179 }
180 
arch_is_user_context(void)181 static inline bool arch_is_user_context(void)
182 {
183 	uint32_t status;
184 
185 	compiler_barrier();
186 
187 	__asm__ volatile("lr %0, [%[status32]]\n"
188 			 : "=r"(status)
189 			 : [status32] "i" (_ARC_V2_STATUS32));
190 
191 	return !(status & _ARC_V2_STATUS32_US) ? true : false;
192 }
193 
194 #ifdef __cplusplus
195 }
196 #endif
197 
198 #endif /* _ASMLANGUAGE */
199 #endif /* CONFIG_USERSPACE */
200 #endif /* ZEPHYR_INCLUDE_ARCH_ARC_SYSCALL_H_ */
201