1/*===------------------ uintrintrin.h - UINTR intrinsics -------------------=== 2 * 3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 * See https://llvm.org/LICENSE.txt for license information. 5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 * 7 *===-----------------------------------------------------------------------=== 8 */ 9 10#ifndef __X86GPRINTRIN_H 11#error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead." 12#endif 13 14#ifndef __UINTRINTRIN_H 15#define __UINTRINTRIN_H 16 17/* Define the default attributes for the functions in this file */ 18#define __DEFAULT_FN_ATTRS \ 19 __attribute__((__always_inline__, __nodebug__, __target__("uintr"))) 20 21#ifdef __x86_64__ 22 23struct __uintr_frame 24{ 25 unsigned long long rip; 26 unsigned long long rflags; 27 unsigned long long rsp; 28}; 29 30/// Clears the user interrupt flag (UIF). Its effect takes place immediately: a 31/// user interrupt cannot be delivered on the instruction boundary following 32/// CLUI. Can be executed only if CR4.UINT = 1, the logical processor is in 33/// 64-bit mode, and software is not executing inside an enclave; otherwise, 34/// each causes an invalid-opcode exception. Causes a transactional abort if 35/// executed inside a transactional region; the abort loads EAX as it would 36/// had it been due to an execution of CLI. 37/// 38/// \headerfile <x86gprintrin.h> 39/// 40/// This intrinsic corresponds to the <c> CLUI </c> instruction. 41/// 42/// \code{.operation} 43/// UIF := 0 44/// \endcode 45static __inline__ void __DEFAULT_FN_ATTRS 46_clui (void) 47{ 48 __builtin_ia32_clui(); 49} 50 51/// Sets the user interrupt flag (UIF). Its effect takes place immediately; a 52/// user interrupt may be delivered on the instruction boundary following 53/// STUI. Can be executed only if CR4.UINT = 1, the logical processor is in 54/// 64-bit mode, and software is not executing inside an enclave; otherwise, 55/// each causes an invalid-opcode exception. Causes a transactional abort if 56/// executed inside a transactional region; the abort loads EAX as it would 57/// had it been due to an execution of STI. 58/// 59/// \headerfile <x86gprintrin.h> 60/// 61/// This intrinsic corresponds to the <c> STUI </c> instruction. 62/// 63/// \code{.operation} 64/// UIF := 1 65/// \endcode 66static __inline__ void __DEFAULT_FN_ATTRS 67_stui (void) 68{ 69 __builtin_ia32_stui(); 70} 71 72/// Get the current value of the user interrupt flag (UIF). Can be executed 73/// regardless of CPL and inside a transactional region. Can be executed only 74/// if CR4.UINT = 1, the logical processor is in 64-bit mode, and software is 75/// not executing inside an enclave; otherwise, it causes an invalid-opcode 76/// exception. 77/// 78/// \headerfile <x86gprintrin.h> 79/// 80/// This intrinsic corresponds to the <c> TESTUI </c> instruction. 81/// 82/// \returns The current value of the user interrupt flag (UIF). 83/// 84/// \code{.operation} 85/// CF := UIF 86/// ZF := 0 87/// AF := 0 88/// OF := 0 89/// PF := 0 90/// SF := 0 91/// dst := CF 92/// \endcode 93static __inline__ unsigned char __DEFAULT_FN_ATTRS 94_testui (void) 95{ 96 return __builtin_ia32_testui(); 97} 98 99/// Send interprocessor user interrupt. Can be executed only if 100/// CR4.UINT = IA32_UINT_TT[0] = 1, the logical processor is in 64-bit mode, 101/// and software is not executing inside an enclave; otherwise, it causes an 102/// invalid-opcode exception. May be executed at any privilege level, all of 103/// its memory accesses are performed with supervisor privilege. 104/// 105/// \headerfile <x86gprintrin.h> 106/// 107/// This intrinsic corresponds to the <c> SENDUIPI </c> instruction 108/// 109/// \param __a 110/// Index of user-interrupt target table entry in user-interrupt target 111/// table. 112/// 113/// \code{.operation} 114/// IF __a > UITTSZ 115/// GP (0) 116/// FI 117/// tempUITTE := MEM[UITTADDR + (a<<4)] 118/// // tempUITTE must be valid, and can't have any reserved bit set 119/// IF (tempUITTE.V == 0 OR tempUITTE[7:1] != 0) 120/// GP (0) 121/// FI 122/// tempUPID := MEM[tempUITTE.UPIDADDR] // under lock 123/// // tempUPID can't have any reserved bit set 124/// IF (tempUPID[15:2] != 0 OR tempUPID[31:24] != 0) 125/// GP (0) // release lock 126/// FI 127/// tempUPID.PIR[tempUITTE.UV] := 1; 128/// IF (tempUPID.SN == 0 AND tempUPID.ON == 0) 129/// tempUPID.ON := 1 130/// sendNotify := 1 131/// ELSE 132/// sendNotify := 0 133/// FI 134/// MEM[tempUITTE.UPIDADDR] := tempUPID // release lock 135/// IF sendNotify == 1 136/// IF IA32_APIC_BASE[10] == 1 // local APIC is in x2APIC mode 137/// // send ordinary IPI with vector tempUPID.NV to 32-bit physical APIC 138/// // ID tempUPID.NDST 139/// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST) 140/// ELSE 141/// // send ordinary IPI with vector tempUPID.NV to 8-bit physical APIC 142/// // ID tempUPID.NDST[15:8] 143/// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST[15:8]) 144/// FI 145/// FI 146/// \endcode 147static __inline__ void __DEFAULT_FN_ATTRS 148_senduipi (unsigned long long __a) 149{ 150 __builtin_ia32_senduipi(__a); 151} 152 153#endif /* __x86_64__ */ 154 155#undef __DEFAULT_FN_ATTRS 156 157#endif /* __UINTRINTRIN_H */ 158