1  /* Copyright (C) 2017-2023 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  
     110  extern __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  
     177  extern __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  
     220  extern __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 */