vm_version_aarch64.cpp revision 11658:8a5735c11a84
1154899Srik/*
2154899Srik * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3154899Srik * Copyright (c) 2015, Red Hat Inc. All rights reserved.
4154899Srik * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5154899Srik *
6154899Srik * This code is free software; you can redistribute it and/or modify it
7154899Srik * under the terms of the GNU General Public License version 2 only, as
8154899Srik * published by the Free Software Foundation.
9154899Srik *
10154899Srik * This code is distributed in the hope that it will be useful, but WITHOUT
11154899Srik * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12154899Srik * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13154899Srik * version 2 for more details (a copy is included in the LICENSE file that
14154899Srik * accompanied this code).
15154899Srik *
16154899Srik * You should have received a copy of the GNU General Public License version
17154899Srik * 2 along with this work; if not, write to the Free Software Foundation,
18154899Srik * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19154899Srik *
20154899Srik * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21154899Srik * or visit www.oracle.com if you need additional information or have any
22154899Srik * questions.
23154899Srik *
24154899Srik */
25154899Srik
26154899Srik#include "precompiled.hpp"
27154899Srik#include "asm/macroAssembler.hpp"
28154899Srik#include "asm/macroAssembler.inline.hpp"
29154899Srik#include "memory/resourceArea.hpp"
30154899Srik#include "runtime/java.hpp"
31154899Srik#include "runtime/stubCodeGenerator.hpp"
32154899Srik#include "utilities/macros.hpp"
33154899Srik#include "vm_version_aarch64.hpp"
34154899Srik
35154899Srik#include OS_HEADER_INLINE(os)
36154899Srik
37154899Srik#ifndef BUILTIN_SIM
38154899Srik#include <sys/auxv.h>
39154899Srik#include <asm/hwcap.h>
40154899Srik#else
41154899Srik#define getauxval(hwcap) 0
42154899Srik#endif
43154899Srik
44154899Srik#ifndef HWCAP_AES
45154899Srik#define HWCAP_AES   (1<<3)
46154899Srik#endif
47154899Srik
48154899Srik#ifndef HWCAP_PMULL
49154899Srik#define HWCAP_PMULL (1<<4)
50154899Srik#endif
51154899Srik
52154899Srik#ifndef HWCAP_SHA1
53154899Srik#define HWCAP_SHA1  (1<<5)
54154899Srik#endif
55154899Srik
56154899Srik#ifndef HWCAP_SHA2
57154899Srik#define HWCAP_SHA2  (1<<6)
58154899Srik#endif
59154899Srik
60154899Srik#ifndef HWCAP_CRC32
61154899Srik#define HWCAP_CRC32 (1<<7)
62154899Srik#endif
63154899Srik
64154899Srik#ifndef HWCAP_ATOMICS
65154899Srik#define HWCAP_ATOMICS (1<<8)
66154899Srik#endif
67154899Srik
68154899Srikint VM_Version::_cpu;
69154899Srikint VM_Version::_model;
70154899Srikint VM_Version::_model2;
71154899Srikint VM_Version::_variant;
72154899Srikint VM_Version::_revision;
73154899Srikint VM_Version::_stepping;
74154899SrikVM_Version::PsrInfo VM_Version::_psr_info   = { 0, };
75180132Srik
76154899Srikstatic BufferBlob* stub_blob;
77154899Srikstatic const int stub_size = 550;
78154899Srik
79154899Srikextern "C" {
80154899Srik  typedef void (*getPsrInfo_stub_t)(void*);
81154899Srik}
82154899Srikstatic getPsrInfo_stub_t getPsrInfo_stub = NULL;
83154899Srik
84154899Srik
85154899Srikclass VM_Version_StubGenerator: public StubCodeGenerator {
86154899Srik public:
87154899Srik
88154899Srik  VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
89154899Srik
90154899Srik  address generate_getPsrInfo() {
91154899Srik    StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub");
92154899Srik#   define __ _masm->
93154899Srik    address start = __ pc();
94154899Srik
95154899Srik#ifdef BUILTIN_SIM
96154899Srik    __ c_stub_prolog(1, 0, MacroAssembler::ret_type_void);
97154899Srik#endif
98154899Srik
99154899Srik    // void getPsrInfo(VM_Version::PsrInfo* psr_info);
100154899Srik
101154899Srik    address entry = __ pc();
102154899Srik
103154899Srik    __ enter();
104154899Srik
105154899Srik    __ get_dczid_el0(rscratch1);
106154899Srik    __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset())));
107154899Srik
108154899Srik    __ get_ctr_el0(rscratch1);
109154899Srik    __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::ctr_el0_offset())));
110154899Srik
111154899Srik    __ leave();
112154899Srik    __ ret(lr);
113154899Srik
114154899Srik#   undef __
115154899Srik
116154899Srik    return start;
117154899Srik  }
118154899Srik};
119154899Srik
120154899Srik
121154899Srikvoid VM_Version::get_processor_features() {
122154899Srik  _supports_cx8 = true;
123154899Srik  _supports_atomic_getset4 = true;
124154899Srik  _supports_atomic_getadd4 = true;
125154899Srik  _supports_atomic_getset8 = true;
126154899Srik  _supports_atomic_getadd8 = true;
127154899Srik
128154899Srik  getPsrInfo_stub(&_psr_info);
129154899Srik
130154899Srik  int dcache_line = VM_Version::dcache_line_size();
131154899Srik
132154899Srik  if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
133154899Srik    FLAG_SET_DEFAULT(AllocatePrefetchDistance, 3*dcache_line);
134154899Srik  if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
135154899Srik    FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line);
136154899Srik  if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes))
137154899Srik    FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line);
138154899Srik  if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
139154899Srik    FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line);
140154899Srik
141154899Srik  if (PrefetchCopyIntervalInBytes != -1 &&
142154899Srik       ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
143154899Srik    warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
144154899Srik    PrefetchCopyIntervalInBytes &= ~7;
145154899Srik    if (PrefetchCopyIntervalInBytes >= 32768)
146154899Srik      PrefetchCopyIntervalInBytes = 32760;
147154899Srik  }
148154899Srik
149154899Srik  unsigned long auxv = getauxval(AT_HWCAP);
150154899Srik
151154899Srik  char buf[512];
152154899Srik
153154899Srik  _features = auxv;
154154899Srik
155154899Srik  int cpu_lines = 0;
156154899Srik  if (FILE *f = fopen("/proc/cpuinfo", "r")) {
157154899Srik    char buf[128], *p;
158154899Srik    while (fgets(buf, sizeof (buf), f) != NULL) {
159154899Srik      if (p = strchr(buf, ':')) {
160154899Srik        long v = strtol(p+1, NULL, 0);
161154899Srik        if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
162154899Srik          _cpu = v;
163154899Srik          cpu_lines++;
164154899Srik        } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
165154899Srik          _variant = v;
166154899Srik        } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
167154899Srik          if (_model != v)  _model2 = _model;
168154899Srik          _model = v;
169154899Srik        } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
170154899Srik          _revision = v;
171154899Srik        }
172154899Srik      }
173154899Srik    }
174154899Srik    fclose(f);
175154899Srik  }
176154899Srik
177154899Srik  // Enable vendor specific features
178154899Srik  if (_cpu == CPU_CAVIUM && _variant == 0) _features |= CPU_DMB_ATOMICS;
179154899Srik  if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _features |= CPU_A53MAC;
180154899Srik  if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH;
181154899Srik  // If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07)
182154899Srik  // we assume the worst and assume we could be on a big little system and have
183154899Srik  // undisclosed A53 cores which we could be swapped to at any stage
184154899Srik  if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _features |= CPU_A53MAC;
185154899Srik
186154899Srik  sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
187154899Srik  if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2);
188154899Srik  if (auxv & HWCAP_ASIMD) strcat(buf, ", simd");
189154899Srik  if (auxv & HWCAP_CRC32) strcat(buf, ", crc");
190154899Srik  if (auxv & HWCAP_AES)   strcat(buf, ", aes");
191154899Srik  if (auxv & HWCAP_SHA1)  strcat(buf, ", sha1");
192154899Srik  if (auxv & HWCAP_SHA2)  strcat(buf, ", sha256");
193154899Srik  if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse");
194154899Srik
195154899Srik  _features_string = os::strdup(buf);
196154899Srik
197154899Srik  if (FLAG_IS_DEFAULT(UseCRC32)) {
198154899Srik    UseCRC32 = (auxv & HWCAP_CRC32) != 0;
199154899Srik  }
200154899Srik  if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) {
201154899Srik    warning("UseCRC32 specified, but not supported on this CPU");
202154899Srik  }
203
204  if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
205    FLAG_SET_DEFAULT(UseAdler32Intrinsics, true);
206  }
207
208  if (UseVectorizedMismatchIntrinsic) {
209    warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
210    FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
211  }
212
213  if (auxv & HWCAP_ATOMICS) {
214    if (FLAG_IS_DEFAULT(UseLSE))
215      FLAG_SET_DEFAULT(UseLSE, true);
216  } else {
217    if (UseLSE) {
218      warning("UseLSE specified, but not supported on this CPU");
219    }
220  }
221
222  if (auxv & HWCAP_AES) {
223    UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
224    UseAESIntrinsics =
225        UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
226    if (UseAESIntrinsics && !UseAES) {
227      warning("UseAESIntrinsics enabled, but UseAES not, enabling");
228      UseAES = true;
229    }
230  } else {
231    if (UseAES) {
232      warning("UseAES specified, but not supported on this CPU");
233    }
234    if (UseAESIntrinsics) {
235      warning("UseAESIntrinsics specified, but not supported on this CPU");
236    }
237  }
238
239  if (UseAESCTRIntrinsics) {
240    warning("AES/CTR intrinsics are not available on this CPU");
241    FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
242  }
243
244  if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
245    UseCRC32Intrinsics = true;
246  }
247
248  if (auxv & HWCAP_CRC32) {
249    if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
250      FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
251    }
252  } else if (UseCRC32CIntrinsics) {
253    warning("CRC32C is not available on the CPU");
254    FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
255  }
256
257  if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) {
258    if (FLAG_IS_DEFAULT(UseSHA)) {
259      FLAG_SET_DEFAULT(UseSHA, true);
260    }
261  } else if (UseSHA) {
262    warning("SHA instructions are not available on this CPU");
263    FLAG_SET_DEFAULT(UseSHA, false);
264  }
265
266  if (UseSHA && (auxv & HWCAP_SHA1)) {
267    if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
268      FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
269    }
270  } else if (UseSHA1Intrinsics) {
271    warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
272    FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
273  }
274
275  if (UseSHA && (auxv & HWCAP_SHA2)) {
276    if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
277      FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
278    }
279  } else if (UseSHA256Intrinsics) {
280    warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
281    FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
282  }
283
284  if (UseSHA512Intrinsics) {
285    warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
286    FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
287  }
288
289  if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
290    FLAG_SET_DEFAULT(UseSHA, false);
291  }
292
293  if (auxv & HWCAP_PMULL) {
294    if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
295      FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
296    }
297  } else if (UseGHASHIntrinsics) {
298    warning("GHASH intrinsics are not available on this CPU");
299    FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
300  }
301
302  if (is_zva_enabled()) {
303    if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
304      FLAG_SET_DEFAULT(UseBlockZeroing, true);
305    }
306    if (FLAG_IS_DEFAULT(BlockZeroingLowLimit)) {
307      FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * VM_Version::zva_length());
308    }
309  } else if (UseBlockZeroing) {
310    warning("DC ZVA is not available on this CPU");
311    FLAG_SET_DEFAULT(UseBlockZeroing, false);
312  }
313
314  // This machine allows unaligned memory accesses
315  if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
316    FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
317  }
318
319  if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
320    UseMultiplyToLenIntrinsic = true;
321  }
322
323  if (FLAG_IS_DEFAULT(UseBarriersForVolatile)) {
324    UseBarriersForVolatile = (_features & CPU_DMB_ATOMICS) != 0;
325  }
326
327  if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
328    UsePopCountInstruction = true;
329  }
330
331  if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
332    UseMontgomeryMultiplyIntrinsic = true;
333  }
334  if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
335    UseMontgomerySquareIntrinsic = true;
336  }
337
338#ifdef COMPILER2
339  if (FLAG_IS_DEFAULT(OptoScheduling)) {
340    OptoScheduling = true;
341  }
342#endif
343}
344
345void VM_Version::initialize() {
346  ResourceMark rm;
347
348  stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size);
349  if (stub_blob == NULL) {
350    vm_exit_during_initialization("Unable to allocate getPsrInfo_stub");
351  }
352
353  CodeBuffer c(stub_blob);
354  VM_Version_StubGenerator g(&c);
355  getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t,
356                                   g.generate_getPsrInfo());
357
358  get_processor_features();
359}
360