Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
syscall.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 BayLibre, SAS
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
15
16#ifndef ZEPHYR_INCLUDE_ARCH_RISCV_SYSCALL_H_
17#define ZEPHYR_INCLUDE_ARCH_RISCV_SYSCALL_H_
18
19/*
20 * Privileged mode system calls
21 */
22#define RV_ECALL_RUNTIME_EXCEPT 0
23#define RV_ECALL_IRQ_OFFLOAD 1
24#define RV_ECALL_SCHEDULE 2
25
26#ifndef _ASMLANGUAGE
27
28#include <zephyr/types.h>
29#include <stdbool.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/*
37 * Syscall invocation macros. riscv-specific machine constraints used to ensure
38 * args land in the proper registers.
39 */
41 uintptr_t arg3, uintptr_t arg4,
42 uintptr_t arg5, uintptr_t arg6,
43 uintptr_t call_id)
44{
45 register unsigned long a0 __asm__ ("a0") = arg1;
46 register unsigned long a1 __asm__ ("a1") = arg2;
47 register unsigned long a2 __asm__ ("a2") = arg3;
48 register unsigned long a3 __asm__ ("a3") = arg4;
49 register unsigned long a4 __asm__ ("a4") = arg5;
50 register unsigned long a5 __asm__ ("a5") = arg6;
51 register unsigned long t0 __asm__ ("t0") = call_id;
52
53 __asm__ volatile ("ecall"
54 : "+r" (a0)
55 : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5),
56 "r" (t0)
57 : "memory");
58 return a0;
59}
60
62 uintptr_t arg3, uintptr_t arg4,
63 uintptr_t arg5,
64 uintptr_t call_id)
65{
66 register unsigned long a0 __asm__ ("a0") = arg1;
67 register unsigned long a1 __asm__ ("a1") = arg2;
68 register unsigned long a2 __asm__ ("a2") = arg3;
69 register unsigned long a3 __asm__ ("a3") = arg4;
70 register unsigned long a4 __asm__ ("a4") = arg5;
71 register unsigned long t0 __asm__ ("t0") = call_id;
72
73 __asm__ volatile ("ecall"
74 : "+r" (a0)
75 : "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (t0)
76 : "memory");
77 return a0;
78}
79
81 uintptr_t arg3, uintptr_t arg4,
82 uintptr_t call_id)
83{
84 register unsigned long a0 __asm__ ("a0") = arg1;
85 register unsigned long a1 __asm__ ("a1") = arg2;
86 register unsigned long a2 __asm__ ("a2") = arg3;
87 register unsigned long a3 __asm__ ("a3") = arg4;
88 register unsigned long t0 __asm__ ("t0") = call_id;
89
90 __asm__ volatile ("ecall"
91 : "+r" (a0)
92 : "r" (a1), "r" (a2), "r" (a3), "r" (t0)
93 : "memory");
94 return a0;
95}
96
98 uintptr_t arg3,
99 uintptr_t call_id)
100{
101 register unsigned long a0 __asm__ ("a0") = arg1;
102 register unsigned long a1 __asm__ ("a1") = arg2;
103 register unsigned long a2 __asm__ ("a2") = arg3;
104 register unsigned long t0 __asm__ ("t0") = call_id;
105
106 __asm__ volatile ("ecall"
107 : "+r" (a0)
108 : "r" (a1), "r" (a2), "r" (t0)
109 : "memory");
110 return a0;
111}
112
114 uintptr_t call_id)
115{
116 register unsigned long a0 __asm__ ("a0") = arg1;
117 register unsigned long a1 __asm__ ("a1") = arg2;
118 register unsigned long t0 __asm__ ("t0") = call_id;
119
120 __asm__ volatile ("ecall"
121 : "+r" (a0)
122 : "r" (a1), "r" (t0)
123 : "memory");
124 return a0;
125}
126
128{
129 register unsigned long a0 __asm__ ("a0") = arg1;
130 register unsigned long t0 __asm__ ("t0") = call_id;
131
132 __asm__ volatile ("ecall"
133 : "+r" (a0)
134 : "r" (t0)
135 : "memory");
136 return a0;
137}
138
140{
141 register unsigned long a0 __asm__ ("a0");
142 register unsigned long t0 __asm__ ("t0") = call_id;
143
144 __asm__ volatile ("ecall"
145 : "=r" (a0)
146 : "r" (t0)
147 : "memory");
148 return a0;
149}
150
151#ifdef CONFIG_USERSPACE
152static inline bool arch_is_user_context(void)
153{
154 /*
155 * Don't try accessing TLS variables if tp is not initialized.
156 *
157 * Note: this deliberately reads the thread pointer via
158 * __builtin_thread_pointer() rather than declaring a global register
159 * variable bound to "tp": clang miscompiles unrelated globals that
160 * happen to share the register's name (e.g. a global variable named
161 * "tp") when such a declaration is in scope, silently dropping their
162 * linkage, section attributes and initializers.
163 */
164 if (__builtin_thread_pointer() == NULL) {
165 return false;
166 }
167
168 /*
169 * Use an exported accessor (declared in arch/riscv/thread.h) rather
170 * than the thread-local directly, so loadable extensions, which cannot
171 * relocate a thread-local symbol, can call syscalls.
172 */
173 return z_riscv_thread_is_user_mode();
174}
175#endif
176
177#ifdef __cplusplus
178}
179#endif
180
181#endif /* _ASMLANGUAGE */
182#endif /* ZEPHYR_INCLUDE_ARCH_RISCV_SYSCALL_H_ */
static uintptr_t arch_syscall_invoke4(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t call_id)
Definition syscall.h:89
static uintptr_t arch_syscall_invoke2(uintptr_t arg1, uintptr_t arg2, uintptr_t call_id)
Definition syscall.h:131
static uintptr_t arch_syscall_invoke1(uintptr_t arg1, uintptr_t call_id)
Definition syscall.h:149
static uintptr_t arch_syscall_invoke0(uintptr_t call_id)
Definition syscall.h:165
static bool arch_is_user_context(void)
Definition syscall.h:181
static uintptr_t arch_syscall_invoke5(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t call_id)
Definition syscall.h:65
static uintptr_t arch_syscall_invoke3(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t call_id)
Definition syscall.h:111
static uintptr_t 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)
Definition syscall.h:40
Per-arch thread definition.
#define NULL
Definition iar_missing_defs.h:20
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105