jdk

Форк
0
/
vm_version_linux_aarch64.cpp 
222 строки · 6.7 Кб
1
/*
2
 * Copyright (c) 2006, 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
#include "precompiled.hpp"
27
#include "runtime/os.hpp"
28
#include "runtime/os.inline.hpp"
29
#include "runtime/vm_version.hpp"
30

31
#include <asm/hwcap.h>
32
#include <sys/auxv.h>
33
#include <sys/prctl.h>
34

35
#ifndef HWCAP_AES
36
#define HWCAP_AES   (1<<3)
37
#endif
38

39
#ifndef HWCAP_PMULL
40
#define HWCAP_PMULL (1<<4)
41
#endif
42

43
#ifndef HWCAP_SHA1
44
#define HWCAP_SHA1  (1<<5)
45
#endif
46

47
#ifndef HWCAP_SHA2
48
#define HWCAP_SHA2  (1<<6)
49
#endif
50

51
#ifndef HWCAP_CRC32
52
#define HWCAP_CRC32 (1<<7)
53
#endif
54

55
#ifndef HWCAP_ATOMICS
56
#define HWCAP_ATOMICS (1<<8)
57
#endif
58

59
#ifndef HWCAP_DCPOP
60
#define HWCAP_DCPOP (1<<16)
61
#endif
62

63
#ifndef HWCAP_SHA3
64
#define HWCAP_SHA3 (1 << 17)
65
#endif
66

67
#ifndef HWCAP_SHA512
68
#define HWCAP_SHA512 (1 << 21)
69
#endif
70

71
#ifndef HWCAP_SVE
72
#define HWCAP_SVE (1 << 22)
73
#endif
74

75
#ifndef HWCAP_PACA
76
#define HWCAP_PACA (1 << 30)
77
#endif
78

79
#ifndef HWCAP2_SVE2
80
#define HWCAP2_SVE2 (1 << 1)
81
#endif
82

83
#ifndef HWCAP2_SVEBITPERM
84
#define HWCAP2_SVEBITPERM (1 << 4)
85
#endif
86

87
#ifndef PR_SVE_GET_VL
88
// For old toolchains which do not have SVE related macros defined.
89
#define PR_SVE_SET_VL   50
90
#define PR_SVE_GET_VL   51
91
#endif
92

93
int VM_Version::get_current_sve_vector_length() {
94
  assert(VM_Version::supports_sve(), "should not call this");
95
  return prctl(PR_SVE_GET_VL);
96
}
97

98
int VM_Version::set_and_get_current_sve_vector_length(int length) {
99
  assert(VM_Version::supports_sve(), "should not call this");
100
  int new_length = prctl(PR_SVE_SET_VL, length);
101
  return new_length;
102
}
103

104
void VM_Version::get_os_cpu_info() {
105

106
  uint64_t auxv = getauxval(AT_HWCAP);
107
  uint64_t auxv2 = getauxval(AT_HWCAP2);
108

109
  static_assert(CPU_FP      == HWCAP_FP,      "Flag CPU_FP must follow Linux HWCAP");
110
  static_assert(CPU_ASIMD   == HWCAP_ASIMD,   "Flag CPU_ASIMD must follow Linux HWCAP");
111
  static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
112
  static_assert(CPU_AES     == HWCAP_AES,     "Flag CPU_AES must follow Linux HWCAP");
113
  static_assert(CPU_PMULL   == HWCAP_PMULL,   "Flag CPU_PMULL must follow Linux HWCAP");
114
  static_assert(CPU_SHA1    == HWCAP_SHA1,    "Flag CPU_SHA1 must follow Linux HWCAP");
115
  static_assert(CPU_SHA2    == HWCAP_SHA2,    "Flag CPU_SHA2 must follow Linux HWCAP");
116
  static_assert(CPU_CRC32   == HWCAP_CRC32,   "Flag CPU_CRC32 must follow Linux HWCAP");
117
  static_assert(CPU_LSE     == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
118
  static_assert(CPU_DCPOP   == HWCAP_DCPOP,   "Flag CPU_DCPOP must follow Linux HWCAP");
119
  static_assert(CPU_SHA3    == HWCAP_SHA3,    "Flag CPU_SHA3 must follow Linux HWCAP");
120
  static_assert(CPU_SHA512  == HWCAP_SHA512,  "Flag CPU_SHA512 must follow Linux HWCAP");
121
  static_assert(CPU_SVE     == HWCAP_SVE,     "Flag CPU_SVE must follow Linux HWCAP");
122
  static_assert(CPU_PACA    == HWCAP_PACA,    "Flag CPU_PACA must follow Linux HWCAP");
123
  _features = auxv & (
124
      HWCAP_FP      |
125
      HWCAP_ASIMD   |
126
      HWCAP_EVTSTRM |
127
      HWCAP_AES     |
128
      HWCAP_PMULL   |
129
      HWCAP_SHA1    |
130
      HWCAP_SHA2    |
131
      HWCAP_CRC32   |
132
      HWCAP_ATOMICS |
133
      HWCAP_DCPOP   |
134
      HWCAP_SHA3    |
135
      HWCAP_SHA512  |
136
      HWCAP_SVE     |
137
      HWCAP_PACA);
138

139
  if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
140
  if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
141

142
  uint64_t ctr_el0;
143
  uint64_t dczid_el0;
144
  __asm__ (
145
    "mrs %0, CTR_EL0\n"
146
    "mrs %1, DCZID_EL0\n"
147
    : "=r"(ctr_el0), "=r"(dczid_el0)
148
  );
149

150
  _icache_line_size = (1 << (ctr_el0 & 0x0f)) * 4;
151
  _dcache_line_size = (1 << ((ctr_el0 >> 16) & 0x0f)) * 4;
152

153
  if (!(dczid_el0 & 0x10)) {
154
    _zva_length = 4 << (dczid_el0 & 0xf);
155
  }
156

157
  if (FILE *f = os::fopen("/proc/cpuinfo", "r")) {
158
    // need a large buffer as the flags line may include lots of text
159
    char buf[1024], *p;
160
    while (fgets(buf, sizeof (buf), f) != nullptr) {
161
      if ((p = strchr(buf, ':')) != nullptr) {
162
        long v = strtol(p+1, nullptr, 0);
163
        if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
164
          _cpu = v;
165
        } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
166
          _variant = v;
167
        } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
168
          if (_model != v)  _model2 = _model;
169
          _model = v;
170
        } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
171
          _revision = v;
172
        } else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
173
          if (strstr(p+1, "dcpop")) {
174
            guarantee(_features & CPU_DCPOP, "dcpop availability should be consistent");
175
          }
176
        }
177
      }
178
    }
179
    fclose(f);
180
  }
181
}
182

183
static bool read_fully(const char *fname, char *buf, size_t buflen) {
184
  assert(buf != nullptr, "invalid argument");
185
  assert(buflen >= 1, "invalid argument");
186
  int fd = os::open(fname, O_RDONLY, 0);
187
  if (fd != -1) {
188
    ssize_t read_sz = ::read(fd, buf, buflen);
189
    ::close(fd);
190

191
    // Skip if the contents is just "\n" because some machine only sets
192
    // '\n' to the board name.
193
    // (e.g. esys/devices/virtual/dmi/id/board_name)
194
    if (read_sz > 0 && !(read_sz == 1 && *buf == '\n')) {
195
      // Replace '\0' to ' '
196
      for (char *ch = buf; ch < buf + read_sz - 1; ch++) {
197
        if (*ch == '\0') {
198
          *ch = ' ';
199
        }
200
      }
201
      buf[read_sz - 1] = '\0';
202
      return true;
203
    }
204
  }
205
  *buf = '\0';
206
  return false;
207
}
208

209
void VM_Version::get_compatible_board(char *buf, int buflen) {
210
  const char *board_name_file_list[] = {
211
    "/proc/device-tree/compatible",
212
    "/sys/devices/virtual/dmi/id/board_name",
213
    "/sys/devices/virtual/dmi/id/product_name",
214
    nullptr
215
  };
216

217
  for (const char **fname = board_name_file_list; *fname != nullptr; fname++) {
218
    if (read_fully(*fname, buf, buflen)) {
219
      return;
220
    }
221
  }
222
}
223

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.