Skip to content

Commit

Permalink
AArch64: Add processor feature detection to port library
Browse files Browse the repository at this point in the history
Add processor feature detection using auxiliary vector as ppc/z does.

Signed-off-by: Akira Saitoh <saiaki@jp.ibm.com>
  • Loading branch information
Akira Saitoh committed Apr 19, 2021
1 parent 2ccbf5e commit 92ff179
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 2 deletions.
56 changes: 56 additions & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,62 @@ typedef struct OMRProcessorDesc {
#define OMR_FEATURE_X86_AVX512BW 96 + 30 /* AVX512 Byte and Word */
#define OMR_FEATURE_X86_AVX512VL 96 + 31 /* AVX512 Vector Length */

/* AArch64 Linux features
* See https://www.kernel.org/doc/html/latest/arm64/elf_hwcaps.html.
*/
#define OMR_FEATURE_ARM64_FP 0 /* Floating Point without FP16 */
#define OMR_FEATURE_ARM64_ASIMD 1 /* Advanced SIMD without FP16 */
#define OMR_FEATURE_ARM64_EVTSTRM 2 /* Event Stream */
#define OMR_FEATURE_ARM64_AES 3 /* FEAT_AES */
#define OMR_FEATURE_ARM64_PMULL 4 /* FEAT_PMULL */
#define OMR_FEATURE_ARM64_SHA1 5 /* FEAT_SHA1 */
#define OMR_FEATURE_ARM64_SHA256 6 /* FEAT_SHA256 */
#define OMR_FEATURE_ARM64_CRC32 7 /* FEAT_CRC32 */
#define OMR_FEATURE_ARM64_LSE 8 /* FEAT_LSE */
#define OMR_FEATURE_ARM64_FP16 9 /* FEAT_FP16 */
#define OMR_FEATURE_ARM64_ASIMDHP 10 /* Advanced SIMD with FP16 */
#define OMR_FEATURE_ARM64_CPUID 11 /* CPU ID/feature register */
#define OMR_FEATURE_ARM64_RDM 12 /* FEAT_RDM */
#define OMR_FEATURE_ARM64_JSCVT 13 /* FEAT_JSCVT */
#define OMR_FEATURE_ARM64_FCMA 14 /* FEAT_FCMA */
#define OMR_FEATURE_ARM64_LRCPC 15 /* FEAT_LRCPC */
#define OMR_FEATURE_ARM64_DPB 16 /* FEAT_DPB */
#define OMR_FEATURE_ARM64_SHA3 17 /* FEAT_SHA3 */
#define OMR_FEATURE_ARM64_SM3 18 /* FEAT_SM3 */
#define OMR_FEATURE_ARM64_SM4 19 /* FEAT_SM4 */
#define OMR_FEATURE_ARM64_DOTPROD 20 /* FEAT_DotProd */
#define OMR_FEATURE_ARM64_SHA512 21 /* FEAT_SHA512 */
#define OMR_FEATURE_ARM64_SVE 22 /* FEAT_SVE */
#define OMR_FEATURE_ARM64_FHM 23 /* FEAT_FHM */
#define OMR_FEATURE_ARM64_DIT 24 /* FEAT_DIT */
#define OMR_FEATURE_ARM64_LSE2 25 /* FEAT_LSE2 */
#define OMR_FEATURE_ARM64_LRCPC2 26 /* FEAT_LRCPC2 */
#define OMR_FEATURE_ARM64_FLAGM 27 /* FEAT_FlagM */
#define OMR_FEATURE_ARM64_SSBS 28 /* FEAT_SSBS */
#define OMR_FEATURE_ARM64_SB 29 /* FEAT_SB */
#define OMR_FEATURE_ARM64_PAUTH 30 /* FEAT_PAuth */
#define OMR_FEATURE_ARM64_PACG 31 /* PACGA instruction */

#define OMR_FEATURE_ARM64_DPB2 32 /* FEAT_DPB2 */
#define OMR_FEATURE_ARM64_SVE2 33 /* FEAT_SVE2 */
#define OMR_FEATURE_ARM64_SVE_AES 34 /* FEAT_SVE_AES */
#define OMR_FEATURE_ARM64_SVE_PMULL128 35 /* FEAT_SVE_PMULL128 */
#define OMR_FEATURE_ARM64_SVE_BITPERM 36 /* FEAT_SVE_BitPerm */
#define OMR_FEATURE_ARM64_SVE_SHA3 37 /* FEAT_SVE_SHA3 */
#define OMR_FEATURE_ARM64_SVE_SM4 38 /* FEAT_SVE_SM4 */
#define OMR_FEATURE_ARM64_FLAGM2 39 /* FEAT_FlagM2 */
#define OMR_FEATURE_ARM64_FRINTTS 40 /* FEAT_FRINTTS */
#define OMR_FEATURE_ARM64_SVE_I8MM 41 /* FEAT_I8MM */
#define OMR_FEATURE_ARM64_F32MM 42 /* FEAT_F32MM */
#define OMR_FEATURE_ARM64_F64MM 43 /* FEAT_F64MM */
#define OMR_FEATURE_ARM64_SVE_BF16 44 /* FEAT_BF16 */
#define OMR_FEATURE_ARM64_I8MM 45 /* FEAT_I8MM */
#define OMR_FEATURE_ARM64_BF16 46 /* FEAT_BF16 */
#define OMR_FEATURE_ARM64_DGH 47 /* FEAT_DGH */
#define OMR_FEATURE_ARM64_RNG 48 /* FEAT_RNG */
#define OMR_FEATURE_ARM64_BTI 49 /* FEAT_BTI */
#define OMR_FEATURE_ARM64_MTE2 50 /* FEAT_MTE2 */

struct OMRControlFileStatus;
struct OMRPortShSemParameters;

Expand Down
4 changes: 4 additions & 0 deletions port/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ elseif(OMR_ARCH_S390)
if(OMR_OS_LINUX)
list(APPEND OBJECTS auxv.c)
endif()
elseif(OMR_ARCH_AARCH64)
if(OMR_OS_LINUX)
list(APPEND OBJECTS auxv.c)
endif()
endif()

if(OMR_OPT_CUDA)
Expand Down
5 changes: 5 additions & 0 deletions port/port_objects.mk
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ ifeq (s390,$(OMR_HOST_ARCH))
OBJECTS += auxv
endif
endif
ifeq (aarch64,$(OMR_HOST_ARCH))
ifeq (linux,$(OMR_HOST_OS))
OBJECTS += auxv
endif
endif
ifeq (1,$(OMR_OPT_CUDA))
OBJECTS += omrcuda
endif
Expand Down
159 changes: 157 additions & 2 deletions port/unix/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@
#include "omrsimap.h"
#endif /* defined(J9ZOS390) */

#if defined(LINUXPPC) || (defined(S390) && defined(LINUX) && !defined(J9ZTPF))
#if defined(LINUXPPC) || (defined(S390) && defined(LINUX) && !defined(J9ZTPF)) || (defined(AARCH64) && defined(LINUX))
#include "auxv.h"
#include <strings.h>
#endif /* defined(LINUXPPC) || (defined(S390) && defined(LINUX) && !defined(J9ZTPF)) */
#endif /* defined(LINUXPPC) || (defined(S390) && defined(LINUX) && !defined(J9ZTPF)) || (defined(AARCH64) && defined(LINUX)) */

#if (defined(S390))
#include "omrportpriv.h"
Expand Down Expand Up @@ -265,6 +265,11 @@ const char * omrsysinfo_get_s390_processor_feature_name(uint32_t feature);
static intptr_t omrsysinfo_get_riscv_description(struct OMRPortLibrary *portLibrary, OMRProcessorDesc *desc);
#endif

#if defined(AARCH64) && defined(LINUX)
static const char *omrsysinfo_get_aarch64_processor_feature_name(uint32_t feature);
static intptr_t omrsysinfo_get_linux_aarch64_description(struct OMRPortLibrary *portLibrary, OMRProcessorDesc *desc);
#endif /* defined(AARCH64) && defined(LINUX) */

static const char getgroupsErrorMsgPrefix[] = "getgroups : ";

typedef struct EnvListItem {
Expand Down Expand Up @@ -632,6 +637,8 @@ omrsysinfo_get_processor_description(struct OMRPortLibrary *portLibrary, OMRProc
rc = omrsysinfo_get_s390_description(portLibrary, desc);
#elif defined(RISCV)
rc = omrsysinfo_get_riscv_description(portLibrary, desc);
#elif (defined(AARCH64) && defined(LINUX))
rc = omrsysinfo_get_linux_aarch64_description(portLibrary, desc);
#endif
}

Expand Down Expand Up @@ -704,6 +711,8 @@ omrsysinfo_get_processor_feature_name(struct OMRPortLibrary *portLibrary, uint32
rc = omrsysinfo_get_s390_processor_feature_name(feature);
#elif (defined(AIXPPC) || defined(LINUXPPC))
rc = omrsysinfo_get_ppc_processor_feature_name(feature);
#elif (defined(AARCH64) && defined(LINUX))
rc = omrsysinfo_get_aarch64_processor_feature_name(feature);
#endif
Trc_PRT_sysinfo_get_processor_feature_name_Exit(rc);
return rc;
Expand Down Expand Up @@ -1683,6 +1692,152 @@ omrsysinfo_get_riscv_description(struct OMRPortLibrary *portLibrary, OMRProcesso
}
#endif /* defined(RISCV) */

#if defined(AARCH64) && defined(LINUX)
static const char *
omrsysinfo_get_aarch64_processor_feature_name(uint32_t feature)
{
switch (feature) {
case OMR_FEATURE_ARM64_FP:
return "fp";
case OMR_FEATURE_ARM64_ASIMD:
return "asimd";
case OMR_FEATURE_ARM64_EVTSTRM:
return "evtstrm";
case OMR_FEATURE_ARM64_AES:
return "aes";
case OMR_FEATURE_ARM64_PMULL:
return "pmull";
case OMR_FEATURE_ARM64_SHA1:
return "sha1";
case OMR_FEATURE_ARM64_SHA256:
return "sha2";
case OMR_FEATURE_ARM64_CRC32:
return "crc32";
case OMR_FEATURE_ARM64_LSE:
return "atomics";
case OMR_FEATURE_ARM64_FP16:
return "fphp";
case OMR_FEATURE_ARM64_ASIMDHP:
return "asimdhp";
case OMR_FEATURE_ARM64_CPUID:
return "cpuid";
case OMR_FEATURE_ARM64_RDM:
return "asimdrdm";
case OMR_FEATURE_ARM64_JSCVT:
return "jscvt";
case OMR_FEATURE_ARM64_FCMA:
return "fcma";
case OMR_FEATURE_ARM64_LRCPC:
return "lrcpc";
case OMR_FEATURE_ARM64_DPB:
return "dcpop";
case OMR_FEATURE_ARM64_SHA3:
return "sha3";
case OMR_FEATURE_ARM64_SM3:
return "sm3";
case OMR_FEATURE_ARM64_SM4:
return "sm4";
case OMR_FEATURE_ARM64_DOTPROD:
return "asimddp"; /* Advanced SIMD Dot Product */
case OMR_FEATURE_ARM64_SHA512:
return "sha512";
case OMR_FEATURE_ARM64_SVE:
return "sve";
case OMR_FEATURE_ARM64_FHM:
return "asimdfhm";
case OMR_FEATURE_ARM64_DIT:
return "dit";
case OMR_FEATURE_ARM64_LSE2:
return "uscat"; /* unaligned single copy atomicity */
case OMR_FEATURE_ARM64_LRCPC2:
return "ilrcpc"; /* immediate variants of LRCPC */
case OMR_FEATURE_ARM64_FLAGM:
return "flagm";
case OMR_FEATURE_ARM64_SSBS:
return "ssbs";
case OMR_FEATURE_ARM64_SB:
return "sb";
case OMR_FEATURE_ARM64_PAUTH:
return "paca"; /* pointer authentication code to the address */
case OMR_FEATURE_ARM64_PACG:
return "pacg"; /* pointer authentication code generic */
case OMR_FEATURE_ARM64_DPB2:
return "dcpodp"; /* data cache point of deep persistence */
case OMR_FEATURE_ARM64_SVE2:
return "sve2";
case OMR_FEATURE_ARM64_SVE_AES:
return "sveaes";
case OMR_FEATURE_ARM64_SVE_PMULL128:
return "svepmull";
case OMR_FEATURE_ARM64_SVE_BITPERM:
return "svebitperm";
case OMR_FEATURE_ARM64_SVE_SHA3:
return "svesha3";
case OMR_FEATURE_ARM64_SVE_SM4:
return "svesm4";
case OMR_FEATURE_ARM64_FLAGM2:
return "flagm2";
case OMR_FEATURE_ARM64_FRINTTS:
return "frint";
case OMR_FEATURE_ARM64_SVE_I8MM:
return "svei8mm";
case OMR_FEATURE_ARM64_F32MM:
return "svef32mm";
case OMR_FEATURE_ARM64_F64MM:
return "svef64mm";
case OMR_FEATURE_ARM64_SVE_BF16:
return "svebf16";
case OMR_FEATURE_ARM64_I8MM:
return "i8mm";
case OMR_FEATURE_ARM64_BF16:
return "bf16";
case OMR_FEATURE_ARM64_DGH:
return "dgh";
case OMR_FEATURE_ARM64_RNG:
return "rng";
case OMR_FEATURE_ARM64_BTI:
return "bti";
case OMR_FEATURE_ARM64_MTE2:
return "mte";
default:
return "null";
}
return "null";
}

/**
* @internal
* Populates OMRProcessorDesc *desc on Linux ARM64
*
* @param[in] desc pointer to the struct that will contain the CPU type and features.
*
* @return 0 on success, -1 on failure
*/
static intptr_t
omrsysinfo_get_linux_aarch64_description(struct OMRPortLibrary *portLibrary, OMRProcessorDesc *desc)
{
/* initialize auxv prior to querying the auxv */
if (prefetch_auxv() != 0) {
desc->processor = OMR_PROCESSOR_ARM64_V8_A;
desc->physicalProcessor = OMR_PROCESSOR_ARM64_V8_A;
desc->features[0] = 0;
desc->features[1] = 0;
return -1;
}

desc->processor = OMR_PROCESSOR_ARM64_V8_A;
desc->physicalProcessor = desc->processor;
/* Linux ARM64 features:
* Can't error check these calls as both 0 & -1 are valid
* bit fields that could be returned by this query.
*/
desc->features[0] = query_auxv(AT_HWCAP);
desc->features[1] = query_auxv(AT_HWCAP2);

return 0;
}
#endif /* defined(AARCH64) && defined(LINUX) */

intptr_t
omrsysinfo_get_env(struct OMRPortLibrary *portLibrary, const char *envVar, char *infoString, uintptr_t bufSize)
{
Expand Down

0 comments on commit 92ff179

Please sign in to comment.