1 /* 2 * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, 2020, Red Hat Inc. 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 #ifndef CPU_AARCH64_VM_VERSION_AARCH64_HPP 27 #define CPU_AARCH64_VM_VERSION_AARCH64_HPP 28 29 #include "spin_wait_aarch64.hpp" 30 #include "runtime/abstract_vm_version.hpp" 31 #include "utilities/sizes.hpp" 32 33 class VM_Version : public Abstract_VM_Version { 34 friend class JVMCIVMStructs; 35 36 protected: 37 static int _cpu; 38 static int _model; 39 static int _model2; 40 static int _variant; 41 static int _revision; 42 static int _stepping; 43 44 static int _zva_length; 45 static int _dcache_line_size; 46 static int _icache_line_size; 47 static int _initial_sve_vector_length; 48 49 static SpinWait _spin_wait; 50 51 // Read additional info using OS-specific interfaces 52 static void get_os_cpu_info(); 53 54 // Sets the SVE length and returns a new actual value or negative on error. 55 // If the len is larger than the system largest supported SVE vector length, 56 // the function sets the largest supported value. 57 static int set_and_get_current_sve_vector_length(int len); 58 static int get_current_sve_vector_length(); 59 60 public: 61 // Initialization 62 static void initialize(); 63 static void check_virtualizations(); 64 65 static void print_platform_virtualization_info(outputStream*); 66 67 // Asserts 68 static void assert_is_initialized() { 69 } 70 71 static bool expensive_load(int ld_size, int scale) { 72 if (cpu_family() == CPU_ARM) { 73 // Half-word load with index shift by 1 (aka scale is 2) has 74 // extra cycle latency, e.g. ldrsh w0, [x1,w2,sxtw #1]. 75 if (ld_size == 2 && scale == 2) { 76 return true; 77 } 78 } 79 return false; 80 } 81 82 // The CPU implementer codes can be found in 83 // ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile 84 // https://developer.arm.com/docs/ddi0487/latest 85 // Arm can assign codes that are not published in the manual. 86 // Apple's code is defined in 87 // https://github.com/apple/darwin-xnu/blob/33eb983/osfmk/arm/cpuid.h#L62 88 enum Family { 89 CPU_AMPERE = 0xC0, 90 CPU_ARM = 'A', 91 CPU_BROADCOM = 'B', 92 CPU_CAVIUM = 'C', 93 CPU_DEC = 'D', 94 CPU_HISILICON = 'H', 95 CPU_INFINEON = 'I', 96 CPU_MOTOROLA = 'M', 97 CPU_NVIDIA = 'N', 98 CPU_AMCC = 'P', 99 CPU_QUALCOM = 'Q', 100 CPU_MARVELL = 'V', 101 CPU_INTEL = 'i', 102 CPU_APPLE = 'a', 103 }; 104 105 enum Ampere_CPU_Model { 106 CPU_MODEL_EMAG = 0x0, /* CPU implementer is CPU_AMCC */ 107 CPU_MODEL_ALTRA = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ 108 CPU_MODEL_ALTRAMAX = 0xd0c, /* CPU implementer is CPU_ARM, Neoverse N1 */ 109 CPU_MODEL_AMPERE_1 = 0xac3, /* CPU implementer is CPU_AMPERE */ 110 CPU_MODEL_AMPERE_1A = 0xac4 /* CPU implementer is CPU_AMPERE */ 111 }; 112 113 enum Feature_Flag { 114 #define CPU_FEATURE_FLAGS(decl) \ 115 decl(FP, "fp", 0) \ 116 decl(ASIMD, "simd", 1) \ 117 decl(EVTSTRM, "evtstrm", 2) \ 118 decl(AES, "aes", 3) \ 119 decl(PMULL, "pmull", 4) \ 120 decl(SHA1, "sha1", 5) \ 121 decl(SHA2, "sha256", 6) \ 122 decl(CRC32, "crc", 7) \ 123 decl(LSE, "lse", 8) \ 124 decl(DCPOP, "dcpop", 16) \ 125 decl(SHA3, "sha3", 17) \ 126 decl(SHA512, "sha512", 21) \ 127 decl(SVE, "sve", 22) \ 128 /* flags above must follow Linux HWCAP */ \ 129 decl(SVE2, "sve2", 28) \ 130 decl(STXR_PREFETCH, "stxr_prefetch", 29) \ 131 decl(A53MAC, "a53mac", 30) 132 133 #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit), 134 CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG) 135 #undef DECLARE_CPU_FEATURE_FLAG 136 }; 137 138 static int cpu_family() { return _cpu; } 139 static int cpu_model() { return _model; } 140 static int cpu_model2() { return _model2; } 141 static int cpu_variant() { return _variant; } 142 static int cpu_revision() { return _revision; } 143 144 static bool is_zva_enabled() { return 0 <= _zva_length; } 145 static int zva_length() { 146 assert(is_zva_enabled(), "ZVA not available"); 147 return _zva_length; 148 } 149 150 static int icache_line_size() { return _icache_line_size; } 151 static int dcache_line_size() { return _dcache_line_size; } 152 static int get_initial_sve_vector_length() { return _initial_sve_vector_length; }; 153 154 static bool supports_fast_class_init_checks() { return true; } 155 constexpr static bool supports_stack_watermark_barrier() { return true; } 156 constexpr static bool supports_recursive_lightweight_locking() { return true; } 157 158 static void get_compatible_board(char *buf, int buflen); 159 160 static const SpinWait& spin_wait_desc() { return _spin_wait; } 161 162 static bool supports_on_spin_wait() { return _spin_wait.inst() != SpinWait::NONE; } 163 164 #ifdef __APPLE__ 165 // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64) 166 static bool is_cpu_emulated(); 167 #endif 168 }; 169 170 #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP