< prev index next >

src/hotspot/cpu/aarch64/vm_version_aarch64.cpp

Print this page
rev 60630 : 8248659: AArch64: Extend CPU Feature detection
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban

@@ -24,48 +24,24 @@
  */
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
+#include "vm_version_aarch64.hpp"
 
 #include OS_HEADER_INLINE(os)
 
+#ifndef _WIN64
 #include <sys/auxv.h>
 #include <asm/hwcap.h>
-
-#ifndef HWCAP_AES
-#define HWCAP_AES   (1<<3)
-#endif
-
-#ifndef HWCAP_PMULL
-#define HWCAP_PMULL (1<<4)
-#endif
-
-#ifndef HWCAP_SHA1
-#define HWCAP_SHA1  (1<<5)
-#endif
-
-#ifndef HWCAP_SHA2
-#define HWCAP_SHA2  (1<<6)
-#endif
-
-#ifndef HWCAP_CRC32
-#define HWCAP_CRC32 (1<<7)
-#endif
-
-#ifndef HWCAP_ATOMICS
-#define HWCAP_ATOMICS (1<<8)
-#endif
-
-#ifndef HWCAP_SHA512
-#define HWCAP_SHA512 (1 << 21)
 #endif
 
 int VM_Version::_cpu;
 int VM_Version::_model;
 int VM_Version::_model2;

@@ -101,12 +77,14 @@
     __ enter();
 
     __ get_dczid_el0(rscratch1);
     __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset())));
 
+#ifndef _WIN64
     __ get_ctr_el0(rscratch1);
     __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::ctr_el0_offset())));
+#endif
 
     __ leave();
     __ ret(lr);
 
 #   undef __

@@ -163,17 +141,23 @@
        (SoftwarePrefetchHintDistance & 7)) {
     warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8");
     SoftwarePrefetchHintDistance &= ~7;
   }
 
-  uint64_t auxv = getauxval(AT_HWCAP);
+#ifndef _WIN64
+  _features = getauxval(AT_HWCAP);
+#else
+  if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))   _features |= CPU_CRC32;
+  if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))  _features |= CPU_AES | CPU_SHA1 | CPU_SHA2;
+  if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE))        _features |= CPU_ASIMD;
+  // No check for CPU_PMULL
+#endif // _WIN64
 
   char buf[512];
 
-  _features = auxv;
-
   int cpu_lines = 0;
+#ifndef _WIN64
   if (FILE *f = fopen("/proc/cpuinfo", "r")) {
     // need a large buffer as the flags line may include lots of text
     char buf[1024], *p;
     while (fgets(buf, sizeof (buf), f) != NULL) {
       if ((p = strchr(buf, ':')) != NULL) {

@@ -195,10 +179,32 @@
         }
       }
     }
     fclose(f);
   }
+#else
+  {
+    char* buf = ::getenv("PROCESSOR_IDENTIFIER");
+    if (buf && strstr(buf, "Ampere(TM)") != NULL) {
+      _cpu = CPU_AMCC;
+      cpu_lines++;
+    } else if (buf && strstr(buf, "Cavium Inc.") != NULL) {
+      _cpu = CPU_CAVIUM;
+      cpu_lines++;
+    } else {
+      log_info(os)("VM_Version: unknown CPU model");
+    }
+
+    if (_cpu) {
+      SYSTEM_INFO si;
+      GetSystemInfo(&si);
+      _model = si.wProcessorLevel;
+      _variant = si.wProcessorRevision / 0xFF;
+      _revision = si.wProcessorRevision & 0xFF;
+    }
+  }
+#endif // _WIN64
 
   if (os::supports_map_sync()) {
     // if dcpop is available publish data cache line flush size via
     // generic field, otherwise let if default to zero thereby
     // disabling writeback

@@ -282,25 +288,25 @@
   // undisclosed A53 cores which we could be swapped to at any stage
   if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _features |= CPU_A53MAC;
 
   sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
   if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2);
-  if (auxv & HWCAP_ASIMD) strcat(buf, ", simd");
-  if (auxv & HWCAP_CRC32) strcat(buf, ", crc");
-  if (auxv & HWCAP_AES)   strcat(buf, ", aes");
-  if (auxv & HWCAP_SHA1)  strcat(buf, ", sha1");
-  if (auxv & HWCAP_SHA2)  strcat(buf, ", sha256");
-  if (auxv & HWCAP_SHA512) strcat(buf, ", sha512");
-  if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse");
+  if (_features & CPU_ASIMD)    strcat(buf, ", simd");
+  if (_features & CPU_CRC32)    strcat(buf, ", crc");
+  if (_features & CPU_AES)      strcat(buf, ", aes");
+  if (_features & CPU_SHA1)     strcat(buf, ", sha1");
+  if (_features & CPU_SHA2)     strcat(buf, ", sha256");
+  if (_features & CPU_SHA512)   strcat(buf, ", sha512");
+  if (_features & CPU_LSE)      strcat(buf, ", lse");
 
   _features_string = os::strdup(buf);
 
   if (FLAG_IS_DEFAULT(UseCRC32)) {
-    UseCRC32 = (auxv & HWCAP_CRC32) != 0;
+    UseCRC32 = (_features & CPU_CRC32) != 0;
   }
 
-  if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) {
+  if (UseCRC32 && (_features & CPU_CRC32) == 0) {
     warning("UseCRC32 specified, but not supported on this CPU");
     FLAG_SET_DEFAULT(UseCRC32, false);
   }
 
   if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {

@@ -310,21 +316,21 @@
   if (UseVectorizedMismatchIntrinsic) {
     warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
     FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
   }
 
-  if (auxv & HWCAP_ATOMICS) {
+  if (_features & CPU_LSE) {
     if (FLAG_IS_DEFAULT(UseLSE))
       FLAG_SET_DEFAULT(UseLSE, true);
   } else {
     if (UseLSE) {
       warning("UseLSE specified, but not supported on this CPU");
       FLAG_SET_DEFAULT(UseLSE, false);
     }
   }
 
-  if (auxv & HWCAP_AES) {
+  if (_features & CPU_AES) {
     UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
     UseAESIntrinsics =
         UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
     if (UseAESIntrinsics && !UseAES) {
       warning("UseAESIntrinsics enabled, but UseAES not, enabling");

@@ -348,11 +354,11 @@
 
   if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
     UseCRC32Intrinsics = true;
   }
 
-  if (auxv & HWCAP_CRC32) {
+  if (_features & CPU_CRC32) {
     if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
       FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
     }
   } else if (UseCRC32CIntrinsics) {
     warning("CRC32C is not available on the CPU");

@@ -366,38 +372,38 @@
   if (UseMD5Intrinsics) {
     warning("MD5 intrinsics are not available on this CPU");
     FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
   }
 
-  if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) {
+  if (_features & (CPU_SHA1 | CPU_SHA2)) {
     if (FLAG_IS_DEFAULT(UseSHA)) {
       FLAG_SET_DEFAULT(UseSHA, true);
     }
   } else if (UseSHA) {
     warning("SHA instructions are not available on this CPU");
     FLAG_SET_DEFAULT(UseSHA, false);
   }
 
-  if (UseSHA && (auxv & HWCAP_SHA1)) {
+  if (UseSHA && (_features & CPU_SHA1)) {
     if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
       FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
     }
   } else if (UseSHA1Intrinsics) {
     warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
   }
 
-  if (UseSHA && (auxv & HWCAP_SHA2)) {
+  if (UseSHA && (_features & CPU_SHA2)) {
     if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
       FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
     }
   } else if (UseSHA256Intrinsics) {
     warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
   }
 
-  if (UseSHA && (auxv & HWCAP_SHA512)) {
+  if (UseSHA && (_features & CPU_SHA512)) {
     // Do not auto-enable UseSHA512Intrinsics until it has been fully tested on hardware
     // if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
       // FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
     // }
   } else if (UseSHA512Intrinsics) {

@@ -407,11 +413,11 @@
 
   if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
     FLAG_SET_DEFAULT(UseSHA, false);
   }
 
-  if (auxv & HWCAP_PMULL) {
+  if (_features & CPU_PMULL) {
     if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
       FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
     }
   } else if (UseGHASHIntrinsics) {
     warning("GHASH intrinsics are not available on this CPU");
< prev index next >