1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _CM4F_SYSCALL_DO_H_
18 #define _CM4F_SYSCALL_DO_H_
19 
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #ifdef _OS_BUILD_
26     #error "Syscalls should not be called from OS code"
27 #endif
28 
29 
30 #include <stdint.h>
31 #include <stdarg.h>
32 
33 #if defined(__ICCARM__)
34 
35 #pragma swi_number=0
36 __swi uintptr_t cpuSyscallDo(uint32_t syscallNo, uint32_t vl);
37 
38 #elif defined(__GNUC__)
39 
40 #define cpuSyscallDo(syscallNo, vaListPtr)                     \
41     ({                                                         \
42         register uint32_t _r0 asm("r0") = syscallNo;           \
43         register uint32_t _r1 asm("r1") = (uint32_t)vaListPtr; \
44         asm volatile (                                         \
45             "swi 0      \n"                                    \
46             :"=r"(_r0), "=r"(_r1)                              \
47             :"0"(_r0), "1"(_r1)                                \
48             :"memory"                                          \
49         );                                                     \
50         _r0;                                                   \
51     })
52 
53 /* these are specific to arm-eabi-32-le-gcc ONLY. YMMV otherwise */
54 
55 #define cpuSyscallDo0P(syscallNo)                    \
56     ({                                               \
57         register uint32_t _r0 asm("r0") = syscallNo; \
58         asm volatile (                               \
59             "swi 0      \n"                          \
60             :"=r"(_r0)                               \
61             :"0"(_r0)                                \
62             :"memory"                                \
63         );                                           \
64         _r0;                                         \
65     })
66 
67 
68 #define cpuSyscallDo1P(syscallNo, p1)                  \
69     ({                                                 \
70         register uint32_t _r0 asm("r0") = syscallNo;   \
71         register uint32_t _r1 asm("r1") = (uint32_t)p1;\
72         asm volatile (                                 \
73             "swi 1      \n"                            \
74             :"=r"(_r0), "=r"(_r1)                      \
75             :"0"(_r0), "1"(_r1)                        \
76             :"memory"                                  \
77         );                                             \
78         _r0;                                           \
79     })
80 
81 
82 
83 #define cpuSyscallDo2P(syscallNo, p1, p2)              \
84     ({                                                 \
85         register uint32_t _r0 asm("r0") = syscallNo;   \
86         register uint32_t _r1 asm("r1") = (uint32_t)p1;\
87         register uint32_t _r2 asm("r2") = (uint32_t)p2;\
88         asm volatile (                                 \
89             "swi 1      \n"                            \
90             :"=r"(_r0), "=r"(_r1), "=r"(_r2)           \
91             :"0"(_r0), "1"(_r1), "2"(_r2)              \
92             :"memory"                                  \
93         );                                             \
94         _r0;                                           \
95     })
96 
97 #define cpuSyscallDo3P(syscallNo, p1, p2, p3)          \
98     ({                                                 \
99         register uint32_t _r0 asm("r0") = syscallNo;   \
100         register uint32_t _r1 asm("r1") = (uint32_t)p1;\
101         register uint32_t _r2 asm("r2") = (uint32_t)p2;\
102         register uint32_t _r3 asm("r3") = (uint32_t)p3;\
103         asm volatile (                                 \
104             "swi 1      \n"                            \
105             :"=r"(_r0), "=r"(_r1), "=r"(_r2), "=r"(_r3)\
106             :"0"(_r0), "1"(_r1), "2"(_r2), "3"(_r3)    \
107             :"memory"                                  \
108         );                                             \
109         _r0;                                           \
110     })
111 
112 #define cpuSyscallDo4P(syscallNo, p1, p2, p3, p4)                   \
113     ({                                                              \
114         register uint32_t _r0 asm("r0") = syscallNo;                \
115         register uint32_t _r1 asm("r1") = (uint32_t)p1;             \
116         register uint32_t _r2 asm("r2") = (uint32_t)p2;             \
117         register uint32_t _r3 asm("r3") = (uint32_t)p3;             \
118         register uint32_t _r12 asm("r12") = (uint32_t)p4;           \
119         asm volatile (                                              \
120             "swi 1      \n"                                         \
121             :"=r"(_r0), "=r"(_r1), "=r"(_r2), "=r"(_r3), "=r"(_r12) \
122             :"0"(_r0), "1"(_r1), "2"(_r2), "3"(_r3), "4"(_r12)      \
123             :"memory"                                               \
124         );                                                          \
125         _r0;                                                        \
126     })
127 
128 #endif
129 
130 
131 #ifdef __cplusplus
132 }
133 #endif
134 
135 #endif
136 
137