96 #define PR_SVE_SET_VL 50
97 #define PR_SVE_GET_VL 51
98 #endif
99
100 int VM_Version::get_current_sve_vector_length() {
101 assert(VM_Version::supports_sve(), "should not call this");
102 return prctl(PR_SVE_GET_VL);
103 }
104
105 int VM_Version::set_and_get_current_sve_vector_length(int length) {
106 assert(VM_Version::supports_sve(), "should not call this");
107 int new_length = prctl(PR_SVE_SET_VL, length);
108 return new_length;
109 }
110
111 void VM_Version::get_os_cpu_info() {
112
113 uint64_t auxv = getauxval(AT_HWCAP);
114 uint64_t auxv2 = getauxval(AT_HWCAP2);
115
116 static_assert(CPU_FP == HWCAP_FP, "Flag CPU_FP must follow Linux HWCAP");
117 static_assert(CPU_ASIMD == HWCAP_ASIMD, "Flag CPU_ASIMD must follow Linux HWCAP");
118 static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
119 static_assert(CPU_AES == HWCAP_AES, "Flag CPU_AES must follow Linux HWCAP");
120 static_assert(CPU_PMULL == HWCAP_PMULL, "Flag CPU_PMULL must follow Linux HWCAP");
121 static_assert(CPU_SHA1 == HWCAP_SHA1, "Flag CPU_SHA1 must follow Linux HWCAP");
122 static_assert(CPU_SHA2 == HWCAP_SHA2, "Flag CPU_SHA2 must follow Linux HWCAP");
123 static_assert(CPU_CRC32 == HWCAP_CRC32, "Flag CPU_CRC32 must follow Linux HWCAP");
124 static_assert(CPU_LSE == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
125 static_assert(CPU_DCPOP == HWCAP_DCPOP, "Flag CPU_DCPOP must follow Linux HWCAP");
126 static_assert(CPU_SHA3 == HWCAP_SHA3, "Flag CPU_SHA3 must follow Linux HWCAP");
127 static_assert(CPU_SHA512 == HWCAP_SHA512, "Flag CPU_SHA512 must follow Linux HWCAP");
128 static_assert(CPU_SVE == HWCAP_SVE, "Flag CPU_SVE must follow Linux HWCAP");
129 static_assert(CPU_PACA == HWCAP_PACA, "Flag CPU_PACA must follow Linux HWCAP");
130 static_assert(CPU_FPHP == HWCAP_FPHP, "Flag CPU_FPHP must follow Linux HWCAP");
131 static_assert(CPU_ASIMDHP == HWCAP_ASIMDHP, "Flag CPU_ASIMDHP must follow Linux HWCAP");
132 _features = auxv & (
133 HWCAP_FP |
134 HWCAP_ASIMD |
135 HWCAP_EVTSTRM |
136 HWCAP_AES |
137 HWCAP_PMULL |
138 HWCAP_SHA1 |
139 HWCAP_SHA2 |
140 HWCAP_CRC32 |
141 HWCAP_ATOMICS |
142 HWCAP_DCPOP |
143 HWCAP_SHA3 |
144 HWCAP_SHA512 |
145 HWCAP_SVE |
146 HWCAP_PACA |
147 HWCAP_FPHP |
148 HWCAP_ASIMDHP);
149
150 if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
151 if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
152
153 uint64_t ctr_el0;
154 uint64_t dczid_el0;
155 __asm__ (
156 "mrs %0, CTR_EL0\n"
157 "mrs %1, DCZID_EL0\n"
158 : "=r"(ctr_el0), "=r"(dczid_el0)
159 );
160
161 _icache_line_size = (1 << (ctr_el0 & 0x0f)) * 4;
162 _dcache_line_size = (1 << ((ctr_el0 >> 16) & 0x0f)) * 4;
163
164 if (!(dczid_el0 & 0x10)) {
165 _zva_length = 4 << (dczid_el0 & 0xf);
166 }
167
168 if (FILE *f = os::fopen("/proc/cpuinfo", "r")) {
169 // need a large buffer as the flags line may include lots of text
170 char buf[1024], *p;
171 while (fgets(buf, sizeof (buf), f) != nullptr) {
172 if ((p = strchr(buf, ':')) != nullptr) {
173 long v = strtol(p+1, nullptr, 0);
174 if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
175 _cpu = v;
176 } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
177 _variant = v;
178 } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
179 if (_model != v) _model2 = _model;
180 _model = v;
181 } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
182 _revision = v;
183 } else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
184 if (strstr(p+1, "dcpop")) {
185 guarantee(_features & CPU_DCPOP, "dcpop availability should be consistent");
186 }
187 }
188 }
189 }
190 fclose(f);
191 }
192 }
193
194 static bool read_fully(const char *fname, char *buf, size_t buflen) {
195 assert(buf != nullptr, "invalid argument");
196 assert(buflen >= 1, "invalid argument");
197 int fd = os::open(fname, O_RDONLY, 0);
198 if (fd != -1) {
199 PRAGMA_DIAG_PUSH
200 PRAGMA_NONNULL_IGNORED
201 // Suppress false positive gcc warning, which may be an example of
202 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87489
203 // The warning also hasn't been seen with vanilla gcc release, so may also
204 // involve some distro-specific gcc patch.
205 ssize_t read_sz = ::read(fd, buf, buflen);
|
96 #define PR_SVE_SET_VL 50
97 #define PR_SVE_GET_VL 51
98 #endif
99
100 int VM_Version::get_current_sve_vector_length() {
101 assert(VM_Version::supports_sve(), "should not call this");
102 return prctl(PR_SVE_GET_VL);
103 }
104
105 int VM_Version::set_and_get_current_sve_vector_length(int length) {
106 assert(VM_Version::supports_sve(), "should not call this");
107 int new_length = prctl(PR_SVE_SET_VL, length);
108 return new_length;
109 }
110
111 void VM_Version::get_os_cpu_info() {
112
113 uint64_t auxv = getauxval(AT_HWCAP);
114 uint64_t auxv2 = getauxval(AT_HWCAP2);
115
116 static_assert(BIT_MASK(CPU_FP) == HWCAP_FP, "Flag CPU_FP must follow Linux HWCAP");
117 static_assert(BIT_MASK(CPU_ASIMD) == HWCAP_ASIMD, "Flag CPU_ASIMD must follow Linux HWCAP");
118 static_assert(BIT_MASK(CPU_EVTSTRM) == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
119 static_assert(BIT_MASK(CPU_AES) == HWCAP_AES, "Flag CPU_AES must follow Linux HWCAP");
120 static_assert(BIT_MASK(CPU_PMULL) == HWCAP_PMULL, "Flag CPU_PMULL must follow Linux HWCAP");
121 static_assert(BIT_MASK(CPU_SHA1) == HWCAP_SHA1, "Flag CPU_SHA1 must follow Linux HWCAP");
122 static_assert(BIT_MASK(CPU_SHA2) == HWCAP_SHA2, "Flag CPU_SHA2 must follow Linux HWCAP");
123 static_assert(BIT_MASK(CPU_CRC32) == HWCAP_CRC32, "Flag CPU_CRC32 must follow Linux HWCAP");
124 static_assert(BIT_MASK(CPU_LSE) == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
125 static_assert(BIT_MASK(CPU_DCPOP) == HWCAP_DCPOP, "Flag CPU_DCPOP must follow Linux HWCAP");
126 static_assert(BIT_MASK(CPU_SHA3) == HWCAP_SHA3, "Flag CPU_SHA3 must follow Linux HWCAP");
127 static_assert(BIT_MASK(CPU_SHA512) == HWCAP_SHA512, "Flag CPU_SHA512 must follow Linux HWCAP");
128 static_assert(BIT_MASK(CPU_SVE) == HWCAP_SVE, "Flag CPU_SVE must follow Linux HWCAP");
129 static_assert(BIT_MASK(CPU_PACA) == HWCAP_PACA, "Flag CPU_PACA must follow Linux HWCAP");
130 static_assert(BIT_MASK(CPU_FPHP) == HWCAP_FPHP, "Flag CPU_FPHP must follow Linux HWCAP");
131 static_assert(BIT_MASK(CPU_ASIMDHP) == HWCAP_ASIMDHP, "Flag CPU_ASIMDHP must follow Linux HWCAP");
132 _features = auxv & (
133 HWCAP_FP |
134 HWCAP_ASIMD |
135 HWCAP_EVTSTRM |
136 HWCAP_AES |
137 HWCAP_PMULL |
138 HWCAP_SHA1 |
139 HWCAP_SHA2 |
140 HWCAP_CRC32 |
141 HWCAP_ATOMICS |
142 HWCAP_DCPOP |
143 HWCAP_SHA3 |
144 HWCAP_SHA512 |
145 HWCAP_SVE |
146 HWCAP_PACA |
147 HWCAP_FPHP |
148 HWCAP_ASIMDHP);
149
150 if (auxv2 & HWCAP2_SVE2) set_feature(CPU_SVE2);
151 if (auxv2 & HWCAP2_SVEBITPERM) set_feature(CPU_SVEBITPERM);
152
153 uint64_t ctr_el0;
154 uint64_t dczid_el0;
155 __asm__ (
156 "mrs %0, CTR_EL0\n"
157 "mrs %1, DCZID_EL0\n"
158 : "=r"(ctr_el0), "=r"(dczid_el0)
159 );
160
161 _icache_line_size = (1 << (ctr_el0 & 0x0f)) * 4;
162 _dcache_line_size = (1 << ((ctr_el0 >> 16) & 0x0f)) * 4;
163
164 if (!(dczid_el0 & 0x10)) {
165 _zva_length = 4 << (dczid_el0 & 0xf);
166 }
167
168 if (FILE *f = os::fopen("/proc/cpuinfo", "r")) {
169 // need a large buffer as the flags line may include lots of text
170 char buf[1024], *p;
171 while (fgets(buf, sizeof (buf), f) != nullptr) {
172 if ((p = strchr(buf, ':')) != nullptr) {
173 long v = strtol(p+1, nullptr, 0);
174 if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
175 _cpu = v;
176 } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
177 _variant = v;
178 } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
179 if (_model != v) _model2 = _model;
180 _model = v;
181 } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
182 _revision = v;
183 } else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
184 if (strstr(p+1, "dcpop")) {
185 guarantee(supports_feature(CPU_DCPOP), "dcpop availability should be consistent");
186 }
187 }
188 }
189 }
190 fclose(f);
191 }
192 }
193
194 static bool read_fully(const char *fname, char *buf, size_t buflen) {
195 assert(buf != nullptr, "invalid argument");
196 assert(buflen >= 1, "invalid argument");
197 int fd = os::open(fname, O_RDONLY, 0);
198 if (fd != -1) {
199 PRAGMA_DIAG_PUSH
200 PRAGMA_NONNULL_IGNORED
201 // Suppress false positive gcc warning, which may be an example of
202 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87489
203 // The warning also hasn't been seen with vanilla gcc release, so may also
204 // involve some distro-specific gcc patch.
205 ssize_t read_sz = ::read(fd, buf, buflen);
|