Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright 2015, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #ifndef _SELFTESTS_POWERPC_TM_TM_H
0007 #define _SELFTESTS_POWERPC_TM_TM_H
0008 
0009 #include <stdbool.h>
0010 #include <asm/tm.h>
0011 
0012 #include "utils.h"
0013 #include "reg.h"
0014 
0015 #define TM_RETRIES 100
0016 
0017 static inline bool have_htm(void)
0018 {
0019 #ifdef PPC_FEATURE2_HTM
0020     return have_hwcap2(PPC_FEATURE2_HTM);
0021 #else
0022     printf("PPC_FEATURE2_HTM not defined, can't check AT_HWCAP2\n");
0023     return false;
0024 #endif
0025 }
0026 
0027 static inline bool have_htm_nosc(void)
0028 {
0029 #ifdef PPC_FEATURE2_HTM_NOSC
0030     return have_hwcap2(PPC_FEATURE2_HTM_NOSC);
0031 #else
0032     printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n");
0033     return false;
0034 #endif
0035 }
0036 
0037 /*
0038  * Transactional Memory was removed in ISA 3.1. A synthetic TM implementation
0039  * is provided on P10 for threads running in P8/P9 compatibility  mode. The
0040  * synthetic implementation immediately fails after tbegin. This failure sets
0041  * Bit 7 (Failure Persistent) and Bit 15 (Implementation-specific).
0042  */
0043 static inline bool htm_is_synthetic(void)
0044 {
0045     int i;
0046 
0047     /*
0048      * Per the ISA, the Failure Persistent bit may be incorrect. Try a few
0049      * times in case we got an Implementation-specific failure on a non ISA
0050      * v3.1 system. On these systems the Implementation-specific failure
0051      * should not be persistent.
0052      */
0053     for (i = 0; i < TM_RETRIES; i++) {
0054         asm volatile(
0055         "tbegin.;"
0056         "beq 1f;"
0057         "tend.;"
0058         "1:"
0059         :
0060         :
0061         : "memory");
0062 
0063         if ((__builtin_get_texasr() & (TEXASR_FP | TEXASR_IC)) !=
0064             (TEXASR_FP | TEXASR_IC))
0065             break;
0066     }
0067     return i == TM_RETRIES;
0068 }
0069 
0070 static inline long failure_code(void)
0071 {
0072     return __builtin_get_texasru() >> 24;
0073 }
0074 
0075 static inline bool failure_is_persistent(void)
0076 {
0077     return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
0078 }
0079 
0080 static inline bool failure_is_syscall(void)
0081 {
0082     return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
0083 }
0084 
0085 static inline bool failure_is_unavailable(void)
0086 {
0087     return (failure_code() & TM_CAUSE_FAC_UNAV) == TM_CAUSE_FAC_UNAV;
0088 }
0089 
0090 static inline bool failure_is_reschedule(void)
0091 {
0092     if ((failure_code() & TM_CAUSE_RESCHED) == TM_CAUSE_RESCHED ||
0093         (failure_code() & TM_CAUSE_KVM_RESCHED) == TM_CAUSE_KVM_RESCHED ||
0094         (failure_code() & TM_CAUSE_KVM_FAC_UNAV) == TM_CAUSE_KVM_FAC_UNAV)
0095         return true;
0096 
0097     return false;
0098 }
0099 
0100 static inline bool failure_is_nesting(void)
0101 {
0102     return (__builtin_get_texasru() & 0x400000);
0103 }
0104 
0105 static inline int tcheck(void)
0106 {
0107     long cr;
0108     asm volatile ("tcheck 0" : "=r"(cr) : : "cr0");
0109     return (cr >> 28) & 4;
0110 }
0111 
0112 static inline bool tcheck_doomed(void)
0113 {
0114     return tcheck() & 8;
0115 }
0116 
0117 static inline bool tcheck_active(void)
0118 {
0119     return tcheck() & 4;
0120 }
0121 
0122 static inline bool tcheck_suspended(void)
0123 {
0124     return tcheck() & 2;
0125 }
0126 
0127 static inline bool tcheck_transactional(void)
0128 {
0129     return tcheck() & 6;
0130 }
0131 
0132 #endif /* _SELFTESTS_POWERPC_TM_TM_H */