1 /*
  2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "precompiled.hpp"
 27 #include "asm/macroAssembler.hpp"
 28 #include "asm/macroAssembler.inline.hpp"
 29 #include "memory/resourceArea.hpp"
 30 #include "runtime/java.hpp"
 31 #include "runtime/os.hpp"
 32 #include "runtime/stubCodeGenerator.hpp"
 33 #include "runtime/vm_version.hpp"
 34 #include "utilities/formatBuffer.hpp"
 35 #include "utilities/macros.hpp"
 36 
 37 #include OS_HEADER_INLINE(os)
 38 
 39 #include <sys/auxv.h>
 40 #include <asm/hwcap.h>
 41 
 42 #ifndef COMPAT_HWCAP_ISA_I
 43 #define COMPAT_HWCAP_ISA_I  (1 << ('I' - 'A'))
 44 #endif
 45 
 46 #ifndef COMPAT_HWCAP_ISA_M
 47 #define COMPAT_HWCAP_ISA_M  (1 << ('M' - 'A'))
 48 #endif
 49 
 50 #ifndef COMPAT_HWCAP_ISA_A
 51 #define COMPAT_HWCAP_ISA_A  (1 << ('A' - 'A'))
 52 #endif
 53 
 54 #ifndef COMPAT_HWCAP_ISA_F
 55 #define COMPAT_HWCAP_ISA_F  (1 << ('F' - 'A'))
 56 #endif
 57 
 58 #ifndef COMPAT_HWCAP_ISA_D
 59 #define COMPAT_HWCAP_ISA_D  (1 << ('D' - 'A'))
 60 #endif
 61 
 62 #ifndef COMPAT_HWCAP_ISA_C
 63 #define COMPAT_HWCAP_ISA_C  (1 << ('C' - 'A'))
 64 #endif
 65 
 66 #ifndef COMPAT_HWCAP_ISA_V
 67 #define COMPAT_HWCAP_ISA_V  (1 << ('V' - 'A'))
 68 #endif
 69 
 70 #ifndef COMPAT_HWCAP_ISA_B
 71 #define COMPAT_HWCAP_ISA_B  (1 << ('B' - 'A'))
 72 #endif
 73 
 74 int VM_Version::_initial_vector_length = 0;
 75 address VM_Version::_checkvext_fault_pc = NULL;
 76 address VM_Version::_checkvext_continuation_pc = NULL;
 77 
 78 static BufferBlob* stub_blob;
 79 static const int stub_size = 550;
 80 
 81 extern "C" {
 82   typedef int (*getPsrInfo_stub_t)();
 83 }
 84 static getPsrInfo_stub_t getPsrInfo_stub = NULL;
 85 
 86 
 87 class VM_Version_StubGenerator: public StubCodeGenerator {
 88  public:
 89 
 90   VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
 91   ~VM_Version_StubGenerator() {}
 92 
 93   address generate_getPsrInfo(address* fault_pc, address* continuation_pc) {
 94     StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub");
 95 #   define __ _masm->
 96     address start = __ pc();
 97 
 98     __ enter();
 99 
100     __ mv(x10, zr);
101     // read vlenb from CSR_VLENB, may sigill
102     *fault_pc = __ pc();
103     __ csrr(x10, CSR_VLENB);
104 
105     *continuation_pc = __ pc();
106     __ leave();
107     __ ret();
108 
109 #   undef __
110 
111     return start;
112   }
113 };
114 
115 void VM_Version::get_processor_features() {
116   if (FLAG_IS_DEFAULT(UseFMA)) {
117     FLAG_SET_DEFAULT(UseFMA, true);
118   }
119   if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
120     FLAG_SET_DEFAULT(AllocatePrefetchDistance, 0);
121   }
122 
123   if (UseAES || UseAESIntrinsics) {
124     if (UseAES && !FLAG_IS_DEFAULT(UseAES)) {
125       warning("AES instructions are not available on this CPU");
126       FLAG_SET_DEFAULT(UseAES, false);
127     }
128     if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
129       warning("AES intrinsics are not available on this CPU");
130       FLAG_SET_DEFAULT(UseAESIntrinsics, false);
131     }
132   }
133 
134   if (UseAESCTRIntrinsics) {
135     warning("AES/CTR intrinsics are not available on this CPU");
136     FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
137   }
138 
139   if (UseSHA) {
140     warning("SHA instructions are not available on this CPU");
141     FLAG_SET_DEFAULT(UseSHA, false);
142   }
143 
144   if (UseSHA1Intrinsics) {
145     warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
146     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
147   }
148 
149   if (UseSHA256Intrinsics) {
150     warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
151     FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
152   }
153 
154   if (UseSHA512Intrinsics) {
155     warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
156     FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
157   }
158 
159   if (UseSHA3Intrinsics) {
160     warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
161     FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
162   }
163 
164   if (UsePopCountInstruction) {
165     warning("Pop count instructions are not available on this CPU.");
166     FLAG_SET_DEFAULT(UsePopCountInstruction, false);
167   }
168 
169   if (UseCRC32Intrinsics) {
170     warning("CRC32 intrinsics are not available on this CPU.");
171     FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
172   }
173 
174   if (UseCRC32CIntrinsics) {
175     warning("CRC32C intrinsics are not available on this CPU.");
176     FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
177   }
178 
179   if (UseMD5Intrinsics) {
180     warning("MD5 intrinsics are not available on this CPU.");
181     FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
182   }
183 
184   if (!FLAG_IS_DEFAULT(UseVExt) && UseVExt) {
185     // try to read vector register VLENB, if success, rvv is supported
186     // otherwise, csrr will trigger sigill
187     ResourceMark rm;
188 
189     stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size);
190     if (stub_blob == NULL) {
191       vm_exit_during_initialization("Unable to allocate getPsrInfo_stub");
192     }
193 
194     CodeBuffer c(stub_blob);
195     VM_Version_StubGenerator g(&c);
196     getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t,
197                                      g.generate_getPsrInfo(&VM_Version::_checkvext_fault_pc, &VM_Version::_checkvext_continuation_pc));
198     _initial_vector_length = getPsrInfo_stub();
199   }
200 
201   if (!_initial_vector_length) {
202     if (UseVExt) {
203       warning("RVV is not supported on this CPU");
204       FLAG_SET_DEFAULT(UseVExt, false);
205     }
206   } else if (FLAG_IS_DEFAULT(UseVExt)) {
207     UseVExt = true;
208   }
209 
210 #ifdef COMPILER2
211   get_c2_processor_features();
212 #endif // COMPILER2
213 }
214 
215 #ifdef COMPILER2
216 void VM_Version::get_c2_processor_features() {
217   // lack of cmove in riscv64
218   if (UseCMoveUnconditionally) {
219     FLAG_SET_DEFAULT(UseCMoveUnconditionally, false);
220   }
221   if (ConditionalMoveLimit > 0) {
222     FLAG_SET_DEFAULT(ConditionalMoveLimit, 0);
223   }
224 
225   if (!UseVExt) {
226     FLAG_SET_DEFAULT(SpecialEncodeISOArray, false);
227   }
228 
229   if (!UseVExt && MaxVectorSize) {
230     FLAG_SET_DEFAULT(MaxVectorSize, 0);
231   }
232 
233   if (UseVExt) {
234     if (FLAG_IS_DEFAULT(MaxVectorSize)) {
235       MaxVectorSize = _initial_vector_length;
236     } else if (MaxVectorSize < 16) {
237       warning("RVV does not support vector length less than 16 bytes. Disabling RVV.");
238       UseVExt = false;
239     } else if (is_power_of_2(MaxVectorSize)) {
240       if (MaxVectorSize > _initial_vector_length) {
241         warning("Current system only supports max RVV vector length %d. Set MaxVectorSize to %d",
242                 _initial_vector_length, _initial_vector_length);
243       }
244       MaxVectorSize = _initial_vector_length;
245     } else {
246       vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize));
247     }
248   }
249 
250   // disable prefetch
251   if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
252     FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
253   }
254 }
255 #endif // COMPILER2
256 
257 void VM_Version::initialize() {
258   get_processor_features();
259   UNSUPPORTED_OPTION(CriticalJNINatives);
260 }