1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright 2015, Michael Ellerman, IBM Corp. 4 */ 5 6 #ifndef _SELFTESTS_POWERPC_TM_TM_H 7 #define _SELFTESTS_POWERPC_TM_TM_H 8 9 #include <asm/tm.h> 10 #include <asm/cputable.h> 11 #include <stdbool.h> 12 13 #include "utils.h" 14 15 static inline bool have_htm(void) 16 { 17 #ifdef PPC_FEATURE2_HTM 18 return have_hwcap2(PPC_FEATURE2_HTM); 19 #else 20 printf("PPC_FEATURE2_HTM not defined, can't check AT_HWCAP2\n"); 21 return false; 22 #endif 23 } 24 25 static inline bool have_htm_nosc(void) 26 { 27 #ifdef PPC_FEATURE2_HTM_NOSC 28 return have_hwcap2(PPC_FEATURE2_HTM_NOSC); 29 #else 30 printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n"); 31 return false; 32 #endif 33 } 34 35 static inline long failure_code(void) 36 { 37 return __builtin_get_texasru() >> 24; 38 } 39 40 static inline bool failure_is_persistent(void) 41 { 42 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT; 43 } 44 45 static inline bool failure_is_syscall(void) 46 { 47 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL; 48 } 49 50 static inline bool failure_is_unavailable(void) 51 { 52 return (failure_code() & TM_CAUSE_FAC_UNAV) == TM_CAUSE_FAC_UNAV; 53 } 54 55 static inline bool failure_is_reschedule(void) 56 { 57 if ((failure_code() & TM_CAUSE_RESCHED) == TM_CAUSE_RESCHED || 58 (failure_code() & TM_CAUSE_KVM_RESCHED) == TM_CAUSE_KVM_RESCHED || 59 (failure_code() & TM_CAUSE_KVM_FAC_UNAV) == TM_CAUSE_KVM_FAC_UNAV) 60 return true; 61 62 return false; 63 } 64 65 static inline bool failure_is_nesting(void) 66 { 67 return (__builtin_get_texasru() & 0x400000); 68 } 69 70 static inline int tcheck(void) 71 { 72 long cr; 73 asm volatile ("tcheck 0" : "=r"(cr) : : "cr0"); 74 return (cr >> 28) & 4; 75 } 76 77 static inline bool tcheck_doomed(void) 78 { 79 return tcheck() & 8; 80 } 81 82 static inline bool tcheck_active(void) 83 { 84 return tcheck() & 4; 85 } 86 87 static inline bool tcheck_suspended(void) 88 { 89 return tcheck() & 2; 90 } 91 92 static inline bool tcheck_transactional(void) 93 { 94 return tcheck() & 6; 95 } 96 97 #endif /* _SELFTESTS_POWERPC_TM_TM_H */ 98