1/* Copyright (C) 2017-2020 Free Software Foundation, Inc.
2
3   This file is part of GCC.
4
5   GCC is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3, or (at your option)
8   any later version.
9
10   GCC is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   Under Section 7 of GPL version 3, you are granted additional
16   permissions described in the GCC Runtime Library Exception, version
17   3.1, as published by the Free Software Foundation.
18
19   You should have received a copy of the GNU General Public License and
20   a copy of the GCC Runtime Library Exception along with this program;
21   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22   <http://www.gnu.org/licenses/>.  */
23
24#ifndef _SGXINTRIN_H_INCLUDED
25#define _SGXINTRIN_H_INCLUDED
26
27#ifndef __SGX__
28#pragma GCC push_options
29#pragma GCC target("sgx")
30#define __DISABLE_SGX__
31#endif /* __SGX__ */
32
33#define __encls_bc(leaf, b, c, retval)	    	 	\
34  __asm__ __volatile__ ("encls\n\t"		     	\
35	   : "=a" (retval)			     	\
36	   : "a" (leaf), "b" (b), "c" (c)		\
37	   : "cc")
38
39#define __encls_bcd(leaf, b, c, d, retval)	     	\
40  __asm__ __volatile__("encls\n\t"		     	\
41	   : "=a" (retval)			     	\
42	   : "a" (leaf), "b" (b), "c" (c), "d" (d)	\
43	   : "cc")
44
45#define __encls_c(leaf, c, retval)		     	\
46  __asm__ __volatile__("encls\n\t"		     	\
47	   : "=a" (retval)			     	\
48	   : "a" (leaf), "c" (c)			\
49	   : "cc")
50
51#define __encls_edbgrd(leaf, b, c, retval)	     	\
52  __asm__ __volatile__("encls\n\t"		     	\
53	   : "=a" (retval), "=b" (b)		     	\
54	   : "a" (leaf), "c" (c))
55
56#define __encls_generic(leaf, b, c, d, retval)   	\
57  __asm__ __volatile__("encls\n\t"		     	\
58	   : "=a" (retval), "=b" (b), "=c" (c), "=d" (d)\
59	   : "a" (leaf), "b" (b), "c" (c), "d" (d)	\
60	   : "cc")
61
62#define __enclu_bc(leaf, b, c, retval)			\
63  __asm__ __volatile__("enclu\n\t"			\
64	   : "=a" (retval)				\
65	   : "a" (leaf), "b" (b), "c" (c)		\
66	   : "cc")
67
68#define __enclu_bcd(leaf, b, c, d, retval)		\
69  __asm__ __volatile__("enclu\n\t"			\
70	   : "=a" (retval)				\
71	   : "a" (leaf), "b" (b), "c" (c), "d" (d)	\
72	   : "cc")
73
74#define __enclu_eenter(leaf, b, c, retval)		\
75  __asm__  __volatile__("enclu\n\t"			\
76	   : "=a" (retval), "=c" (c)			\
77	   : "a" (leaf), "b" (b), "c" (c)		\
78	   : "cc")
79
80#define __enclu_eexit(leaf, b, c, retval)		\
81  __asm__  __volatile__("enclu\n\t"			\
82	   : "=a" (retval), "=c" (c)			\
83	   : "a" (leaf), "b" (b)			\
84	   : "cc")
85
86#define __enclu_generic(leaf, b, c, d, retval)		\
87  __asm__ __volatile__("enclu\n\t"			\
88	   : "=a" (retval), "=b" (b), "=c" (c), "=d" (d)\
89	   : "a" (leaf), "b" (b), "c" (c), "d" (d)	\
90	   : "cc")
91
92#define __enclv_bc(leaf, b, c, retval)			\
93  __asm__ __volatile__("enclv\n\t"			\
94	   : "=a" (retval)				\
95	   : "a" (leaf), "b" (b), "c" (c)		\
96	   : "cc")
97
98#define __enclv_cd(leaf, c, d, retval)			\
99  __asm__ __volatile__("enclv\n\t"			\
100	   : "=a" (retval)				\
101	   : "a" (leaf), "c" (c), "d" (d)		\
102	   : "cc")
103
104#define __enclv_generic(leaf, b, c, d, retval)		\
105  __asm__ __volatile__("enclv\n\t"			\
106	   : "=a" (retval), "=b" (b), "=c" (b), "=d" (d)\
107	   : "a" (leaf), "b" (b), "c" (c), "d" (d)	\
108	   : "cc")
109
110extern __inline unsigned int
111__attribute__((__gnu_inline__, __always_inline__, __artificial__))
112_encls_u32 (const unsigned int __L, size_t __D[])
113{
114  enum __encls_type
115  {
116    __SGX_ECREATE = 0x00,
117    __SGX_EADD    = 0x01,
118    __SGX_EINIT   = 0x02,
119    __SGX_EREMOVE = 0x03,
120    __SGX_EDBGRD  = 0x04,
121    __SGX_EDBGWR  = 0x05,
122    __SGX_EEXTEND = 0x06,
123    __SGX_ELDB    = 0x07,
124    __SGX_ELDU    = 0x08,
125    __SGX_EBLOCK  = 0x09,
126    __SGX_EPA     = 0x0A,
127    __SGX_EWB     = 0x0B,
128    __SGX_ETRACK  = 0x0C,
129    __SGX_EAUG    = 0x0D,
130    __SGX_EMODPR  = 0x0E,
131    __SGX_EMODT   = 0x0F,
132    __SGX_ERDINFO = 0x10,
133    __SGX_ETRACKC = 0x11,
134    __SGX_ELDBC   = 0x12,
135    __SGX_ELDUC   = 0x13
136  };
137  enum __encls_type __T = (enum __encls_type)__L;
138  unsigned int __R = 0;
139  if (!__builtin_constant_p (__T))
140    __encls_generic (__L, __D[0], __D[1], __D[2], __R);
141  else switch (__T)
142    {
143    case __SGX_ECREATE:
144    case __SGX_EADD:
145    case __SGX_EDBGWR:
146    case __SGX_EEXTEND:
147    case __SGX_EPA:
148    case __SGX_EMODPR:
149    case __SGX_EMODT:
150    case __SGX_EAUG:
151    case __SGX_ERDINFO:
152      __encls_bc (__L, __D[0], __D[1], __R);
153      break;
154    case __SGX_EINIT:
155    case __SGX_ELDB:
156    case __SGX_ELDU:
157    case __SGX_EWB:
158    case __SGX_ELDBC:
159    case __SGX_ELDUC:
160      __encls_bcd (__L, __D[0], __D[1], __D[2], __R);
161      break;
162    case __SGX_EREMOVE:
163    case __SGX_EBLOCK:
164    case __SGX_ETRACK:
165    case __SGX_ETRACKC:
166      __encls_c (__L, __D[1], __R);
167      break;
168    case __SGX_EDBGRD:
169      __encls_edbgrd (__L, __D[0], __D[1], __R);
170      break;
171    default:
172      __encls_generic (__L, __D[0], __D[1], __D[2], __R);
173    }
174  return __R;
175}
176
177extern __inline unsigned int
178__attribute__((__gnu_inline__, __always_inline__, __artificial__))
179_enclu_u32 (const unsigned int __L, size_t __D[])
180{
181  enum __enclu_type
182  {
183    __SGX_EREPORT     = 0x00,
184    __SGX_EGETKEY     = 0x01,
185    __SGX_EENTER      = 0x02,
186    __SGX_ERESUME     = 0x03,
187    __SGX_EEXIT       = 0x04,
188    __SGX_EACCEPT     = 0x05,
189    __SGX_EMODPE      = 0x06,
190    __SGX_EACCEPTCOPY = 0x07
191  };
192  enum __enclu_type __T = (enum __enclu_type) __L;
193  unsigned int __R = 0;
194  if (!__builtin_constant_p (__T))
195    __enclu_generic (__L, __D[0], __D[1], __D[2], __R);
196  else switch (__T)
197    {
198    case __SGX_EREPORT:
199    case __SGX_EACCEPTCOPY:
200      __enclu_bcd (__L, __D[0], __D[1], __D[2], __R);
201      break;
202    case __SGX_EGETKEY:
203    case __SGX_ERESUME:
204    case __SGX_EACCEPT:
205    case __SGX_EMODPE:
206      __enclu_bc (__L, __D[0], __D[1], __R);
207      break;
208    case __SGX_EENTER:
209      __enclu_eenter (__L, __D[0], __D[1], __R);
210      break;
211    case __SGX_EEXIT:
212      __enclu_eexit (__L, __D[0], __D[1], __R);
213      break;
214    default:
215      __enclu_generic (__L, __D[0], __D[1], __D[2], __R);
216    }
217  return __R;
218}
219
220extern __inline unsigned int
221__attribute__((__gnu_inline__, __always_inline__, __artificial__))
222_enclv_u32 (const unsigned int __L, size_t __D[])
223{
224  enum __enclv_type
225  {
226    __SGX_EDECVIRTCHILD = 0x00,
227    __SGX_EINCVIRTCHILD = 0x01,
228    __SGX_ESETCONTEXT   = 0x02
229  };
230  unsigned int __R = 0;
231  if (!__builtin_constant_p (__L))
232    __enclv_generic (__L, __D[0], __D[1], __D[2], __R);
233  else switch (__L)
234    {
235    case __SGX_EDECVIRTCHILD:
236    case __SGX_EINCVIRTCHILD:
237      __enclv_bc (__L, __D[0], __D[1], __R);
238      break;
239    case __SGX_ESETCONTEXT:
240      __enclv_cd (__L, __D[1], __D[2], __R);
241      break;
242    default:
243      __enclv_generic (__L, __D[0], __D[1], __D[2], __R);
244    }
245  return __R;
246}
247
248#ifdef __DISABLE_SGX__
249#undef __DISABLE_SGX__
250#pragma GCC pop_options
251#endif /* __DISABLE_SGX__ */
252
253#endif /* _SGXINTRIN_H_INCLUDED */
254