1 /*
2 * Copyright (c) 1997, 2023, 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
157 static void get_compatible_board(char *buf, int buflen);
158
159 static const SpinWait& spin_wait_desc() { return _spin_wait; }
160
161 static bool supports_on_spin_wait() { return _spin_wait.inst() != SpinWait::NONE; }
162
163 #ifdef __APPLE__
164 // Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64)
165 static bool is_cpu_emulated();
166 #endif
167 };
168
169 #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
--- EOF ---