LCOV - code coverage report
Current view: top level - lib/eal/x86 - rte_cpuflags.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 17 27 63.0 %
Date: 2025-02-01 18:54:23 Functions: 2 3 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7 16 43.8 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2015 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "rte_cpuflags.h"
       6                 :            : 
       7                 :            : #include <stdio.h>
       8                 :            : #include <errno.h>
       9                 :            : #include <stdint.h>
      10                 :            : #include <string.h>
      11                 :            : #include <stdbool.h>
      12                 :            : 
      13                 :            : #include "rte_cpuid.h"
      14                 :            : #include "rte_atomic.h"
      15                 :            : 
      16                 :            : /**
      17                 :            :  * Struct to hold a processor feature entry
      18                 :            :  */
      19                 :            : struct feature_entry {
      20                 :            :         uint32_t leaf;                          /**< cpuid leaf */
      21                 :            :         uint32_t subleaf;                       /**< cpuid subleaf */
      22                 :            :         uint32_t reg;                           /**< cpuid register */
      23                 :            :         uint32_t bit;                           /**< cpuid register bit */
      24                 :            : #define CPU_FLAG_NAME_MAX_LEN 64
      25                 :            :         char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
      26                 :            :         bool has_value;
      27                 :            :         bool value;
      28                 :            : };
      29                 :            : 
      30                 :            : #define FEAT_DEF(name, leaf, subleaf, reg, bit) \
      31                 :            :         [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
      32                 :            : 
      33                 :            : struct feature_entry rte_cpu_feature_table[] = {
      34                 :            :         FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX,  0)
      35                 :            :         FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX,  1)
      36                 :            :         FEAT_DEF(DTES64, 0x00000001, 0, RTE_REG_ECX,  2)
      37                 :            :         FEAT_DEF(MONITOR, 0x00000001, 0, RTE_REG_ECX,  3)
      38                 :            :         FEAT_DEF(DS_CPL, 0x00000001, 0, RTE_REG_ECX,  4)
      39                 :            :         FEAT_DEF(VMX, 0x00000001, 0, RTE_REG_ECX,  5)
      40                 :            :         FEAT_DEF(SMX, 0x00000001, 0, RTE_REG_ECX,  6)
      41                 :            :         FEAT_DEF(EIST, 0x00000001, 0, RTE_REG_ECX,  7)
      42                 :            :         FEAT_DEF(TM2, 0x00000001, 0, RTE_REG_ECX,  8)
      43                 :            :         FEAT_DEF(SSSE3, 0x00000001, 0, RTE_REG_ECX,  9)
      44                 :            :         FEAT_DEF(CNXT_ID, 0x00000001, 0, RTE_REG_ECX, 10)
      45                 :            :         FEAT_DEF(FMA, 0x00000001, 0, RTE_REG_ECX, 12)
      46                 :            :         FEAT_DEF(CMPXCHG16B, 0x00000001, 0, RTE_REG_ECX, 13)
      47                 :            :         FEAT_DEF(XTPR, 0x00000001, 0, RTE_REG_ECX, 14)
      48                 :            :         FEAT_DEF(PDCM, 0x00000001, 0, RTE_REG_ECX, 15)
      49                 :            :         FEAT_DEF(PCID, 0x00000001, 0, RTE_REG_ECX, 17)
      50                 :            :         FEAT_DEF(DCA, 0x00000001, 0, RTE_REG_ECX, 18)
      51                 :            :         FEAT_DEF(SSE4_1, 0x00000001, 0, RTE_REG_ECX, 19)
      52                 :            :         FEAT_DEF(SSE4_2, 0x00000001, 0, RTE_REG_ECX, 20)
      53                 :            :         FEAT_DEF(X2APIC, 0x00000001, 0, RTE_REG_ECX, 21)
      54                 :            :         FEAT_DEF(MOVBE, 0x00000001, 0, RTE_REG_ECX, 22)
      55                 :            :         FEAT_DEF(POPCNT, 0x00000001, 0, RTE_REG_ECX, 23)
      56                 :            :         FEAT_DEF(TSC_DEADLINE, 0x00000001, 0, RTE_REG_ECX, 24)
      57                 :            :         FEAT_DEF(AES, 0x00000001, 0, RTE_REG_ECX, 25)
      58                 :            :         FEAT_DEF(XSAVE, 0x00000001, 0, RTE_REG_ECX, 26)
      59                 :            :         FEAT_DEF(OSXSAVE, 0x00000001, 0, RTE_REG_ECX, 27)
      60                 :            :         FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28)
      61                 :            :         FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29)
      62                 :            :         FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30)
      63                 :            :         FEAT_DEF(HYPERVISOR, 0x00000001, 0, RTE_REG_ECX, 31)
      64                 :            : 
      65                 :            :         FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX,  0)
      66                 :            :         FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX,  1)
      67                 :            :         FEAT_DEF(DE, 0x00000001, 0, RTE_REG_EDX,  2)
      68                 :            :         FEAT_DEF(PSE, 0x00000001, 0, RTE_REG_EDX,  3)
      69                 :            :         FEAT_DEF(TSC, 0x00000001, 0, RTE_REG_EDX,  4)
      70                 :            :         FEAT_DEF(MSR, 0x00000001, 0, RTE_REG_EDX,  5)
      71                 :            :         FEAT_DEF(PAE, 0x00000001, 0, RTE_REG_EDX,  6)
      72                 :            :         FEAT_DEF(MCE, 0x00000001, 0, RTE_REG_EDX,  7)
      73                 :            :         FEAT_DEF(CX8, 0x00000001, 0, RTE_REG_EDX,  8)
      74                 :            :         FEAT_DEF(APIC, 0x00000001, 0, RTE_REG_EDX,  9)
      75                 :            :         FEAT_DEF(SEP, 0x00000001, 0, RTE_REG_EDX, 11)
      76                 :            :         FEAT_DEF(MTRR, 0x00000001, 0, RTE_REG_EDX, 12)
      77                 :            :         FEAT_DEF(PGE, 0x00000001, 0, RTE_REG_EDX, 13)
      78                 :            :         FEAT_DEF(MCA, 0x00000001, 0, RTE_REG_EDX, 14)
      79                 :            :         FEAT_DEF(CMOV, 0x00000001, 0, RTE_REG_EDX, 15)
      80                 :            :         FEAT_DEF(PAT, 0x00000001, 0, RTE_REG_EDX, 16)
      81                 :            :         FEAT_DEF(PSE36, 0x00000001, 0, RTE_REG_EDX, 17)
      82                 :            :         FEAT_DEF(PSN, 0x00000001, 0, RTE_REG_EDX, 18)
      83                 :            :         FEAT_DEF(CLFSH, 0x00000001, 0, RTE_REG_EDX, 19)
      84                 :            :         FEAT_DEF(DS, 0x00000001, 0, RTE_REG_EDX, 21)
      85                 :            :         FEAT_DEF(ACPI, 0x00000001, 0, RTE_REG_EDX, 22)
      86                 :            :         FEAT_DEF(MMX, 0x00000001, 0, RTE_REG_EDX, 23)
      87                 :            :         FEAT_DEF(FXSR, 0x00000001, 0, RTE_REG_EDX, 24)
      88                 :            :         FEAT_DEF(SSE, 0x00000001, 0, RTE_REG_EDX, 25)
      89                 :            :         FEAT_DEF(SSE2, 0x00000001, 0, RTE_REG_EDX, 26)
      90                 :            :         FEAT_DEF(SS, 0x00000001, 0, RTE_REG_EDX, 27)
      91                 :            :         FEAT_DEF(HTT, 0x00000001, 0, RTE_REG_EDX, 28)
      92                 :            :         FEAT_DEF(TM, 0x00000001, 0, RTE_REG_EDX, 29)
      93                 :            :         FEAT_DEF(PBE, 0x00000001, 0, RTE_REG_EDX, 31)
      94                 :            : 
      95                 :            :         FEAT_DEF(DIGTEMP, 0x00000006, 0, RTE_REG_EAX,  0)
      96                 :            :         FEAT_DEF(TRBOBST, 0x00000006, 0, RTE_REG_EAX,  1)
      97                 :            :         FEAT_DEF(ARAT, 0x00000006, 0, RTE_REG_EAX,  2)
      98                 :            :         FEAT_DEF(PLN, 0x00000006, 0, RTE_REG_EAX,  4)
      99                 :            :         FEAT_DEF(ECMD, 0x00000006, 0, RTE_REG_EAX,  5)
     100                 :            :         FEAT_DEF(PTM, 0x00000006, 0, RTE_REG_EAX,  6)
     101                 :            : 
     102                 :            :         FEAT_DEF(MPERF_APERF_MSR, 0x00000006, 0, RTE_REG_ECX,  0)
     103                 :            :         FEAT_DEF(ACNT2, 0x00000006, 0, RTE_REG_ECX,  1)
     104                 :            :         FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX,  3)
     105                 :            : 
     106                 :            :         FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX,  0)
     107                 :            :         FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX,  3)
     108                 :            :         FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX,  4)
     109                 :            :         FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX,  5)
     110                 :            :         FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX,  7)
     111                 :            :         FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX,  8)
     112                 :            :         FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX,  9)
     113                 :            :         FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10)
     114                 :            :         FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11)
     115                 :            :         FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16)
     116                 :            :         FEAT_DEF(AVX512DQ, 0x00000007, 0, RTE_REG_EBX, 17)
     117                 :            :         FEAT_DEF(RDSEED, 0x00000007, 0, RTE_REG_EBX, 18)
     118                 :            :         FEAT_DEF(AVX512IFMA, 0x00000007, 0, RTE_REG_EBX, 21)
     119                 :            :         FEAT_DEF(AVX512CD, 0x00000007, 0, RTE_REG_EBX, 28)
     120                 :            :         FEAT_DEF(AVX512BW, 0x00000007, 0, RTE_REG_EBX, 30)
     121                 :            :         FEAT_DEF(AVX512VL, 0x00000007, 0, RTE_REG_EBX, 31)
     122                 :            : 
     123                 :            :         FEAT_DEF(AVX512VBMI, 0x00000007, 0, RTE_REG_ECX,  1)
     124                 :            :         FEAT_DEF(WAITPKG, 0x00000007, 0, RTE_REG_ECX,  5)
     125                 :            :         FEAT_DEF(AVX512VBMI2, 0x00000007, 0, RTE_REG_ECX,  6)
     126                 :            :         FEAT_DEF(GFNI, 0x00000007, 0, RTE_REG_ECX,  8)
     127                 :            :         FEAT_DEF(VAES, 0x00000007, 0, RTE_REG_ECX,  9)
     128                 :            :         FEAT_DEF(VPCLMULQDQ, 0x00000007, 0, RTE_REG_ECX, 10)
     129                 :            :         FEAT_DEF(AVX512VNNI, 0x00000007, 0, RTE_REG_ECX, 11)
     130                 :            :         FEAT_DEF(AVX512BITALG, 0x00000007, 0, RTE_REG_ECX, 12)
     131                 :            :         FEAT_DEF(AVX512VPOPCNTDQ, 0x00000007, 0, RTE_REG_ECX, 14)
     132                 :            :         FEAT_DEF(CLDEMOTE, 0x00000007, 0, RTE_REG_ECX, 25)
     133                 :            :         FEAT_DEF(MOVDIRI, 0x00000007, 0, RTE_REG_ECX, 27)
     134                 :            :         FEAT_DEF(MOVDIR64B, 0x00000007, 0, RTE_REG_ECX, 28)
     135                 :            : 
     136                 :            :         FEAT_DEF(AVX512VP2INTERSECT, 0x00000007, 0, RTE_REG_EDX,  8)
     137                 :            : 
     138                 :            :         FEAT_DEF(LAHF_SAHF, 0x80000001, 0, RTE_REG_ECX,  0)
     139                 :            :         FEAT_DEF(LZCNT, 0x80000001, 0, RTE_REG_ECX,  4)
     140                 :            :         FEAT_DEF(MONITORX, 0x80000001, 0, RTE_REG_ECX,  29)
     141                 :            : 
     142                 :            :         FEAT_DEF(SYSCALL, 0x80000001, 0, RTE_REG_EDX, 11)
     143                 :            :         FEAT_DEF(XD, 0x80000001, 0, RTE_REG_EDX, 20)
     144                 :            :         FEAT_DEF(1GB_PG, 0x80000001, 0, RTE_REG_EDX, 26)
     145                 :            :         FEAT_DEF(RDTSCP, 0x80000001, 0, RTE_REG_EDX, 27)
     146                 :            :         FEAT_DEF(EM64T, 0x80000001, 0, RTE_REG_EDX, 29)
     147                 :            : 
     148                 :            :         FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX,  8)
     149                 :            : };
     150                 :            : 
     151                 :            : int
     152                 :     251626 : rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
     153                 :            : {
     154                 :            :         struct feature_entry *feat;
     155                 :            :         cpuid_registers_t regs;
     156                 :            :         unsigned int maxleaf;
     157                 :            : 
     158         [ +  - ]:     251626 :         if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
     159                 :            :                 /* Flag does not match anything in the feature tables */
     160                 :            :                 return -ENOENT;
     161                 :            : 
     162                 :            :         feat = &rte_cpu_feature_table[feature];
     163         [ +  + ]:     251626 :         if (feat->has_value)
     164                 :     245861 :                 return feat->value;
     165                 :            : 
     166         [ +  - ]:       5765 :         if (!feat->leaf)
     167                 :            :                 /* This entry in the table wasn't filled out! */
     168                 :            :                 return -EFAULT;
     169                 :            : 
     170                 :       5765 :         maxleaf = __get_cpuid_max(feat->leaf & 0x80000000, NULL);
     171                 :            : 
     172         [ -  + ]:       5765 :         if (maxleaf < feat->leaf) {
     173                 :          0 :                 feat->value = 0;
     174                 :          0 :                 goto out;
     175                 :            :         }
     176                 :            : 
     177                 :            : #ifdef RTE_TOOLCHAIN_MSVC
     178                 :            :         __cpuidex(regs, feat->leaf, feat->subleaf);
     179                 :            : #else
     180                 :       5765 :         __cpuid_count(feat->leaf, feat->subleaf,
     181                 :            :                          regs[RTE_REG_EAX], regs[RTE_REG_EBX],
     182                 :            :                          regs[RTE_REG_ECX], regs[RTE_REG_EDX]);
     183                 :            : #endif
     184                 :            : 
     185                 :            :         /* check if the feature is enabled */
     186                 :       5765 :         feat->value = (regs[feat->reg] >> feat->bit) & 1;
     187                 :       5765 : out:
     188                 :       5765 :         rte_compiler_barrier();
     189                 :       5765 :         feat->has_value = true;
     190                 :       5765 :         return feat->value;
     191                 :            : }
     192                 :            : 
     193                 :            : const char *
     194                 :          0 : rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
     195                 :            : {
     196         [ #  # ]:          0 :         if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
     197                 :            :                 return NULL;
     198                 :          0 :         return rte_cpu_feature_table[feature].name;
     199                 :            : }
     200                 :            : 
     201                 :            : void
     202                 :        252 : rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
     203                 :            : {
     204                 :            :         memset(intrinsics, 0, sizeof(*intrinsics));
     205                 :            : 
     206         [ -  + ]:        252 :         if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_WAITPKG)) {
     207                 :          0 :                 intrinsics->power_monitor = 1;
     208                 :          0 :                 intrinsics->power_pause = 1;
     209         [ #  # ]:          0 :                 if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_RTM))
     210                 :          0 :                         intrinsics->power_monitor_multi = 1;
     211         [ -  + ]:        252 :         } else if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_MONITORX)) {
     212                 :          0 :                 intrinsics->power_monitor = 1;
     213                 :            :         }
     214                 :        252 : }

Generated by: LCOV version 1.14