1 /* 2 * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 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/register.hpp" 28 #include "runtime/os.hpp" 29 #include "runtime/os.inline.hpp" 30 #include "runtime/vm_version.hpp" 31 32 #include <asm/hwcap.h> 33 #include <sys/auxv.h> 34 35 #ifndef HWCAP_ISA_I 36 #define HWCAP_ISA_I (1 << ('I' - 'A')) 37 #endif 38 39 #ifndef HWCAP_ISA_M 40 #define HWCAP_ISA_M (1 << ('M' - 'A')) 41 #endif 42 43 #ifndef HWCAP_ISA_A 44 #define HWCAP_ISA_A (1 << ('A' - 'A')) 45 #endif 46 47 #ifndef HWCAP_ISA_F 48 #define HWCAP_ISA_F (1 << ('F' - 'A')) 49 #endif 50 51 #ifndef HWCAP_ISA_D 52 #define HWCAP_ISA_D (1 << ('D' - 'A')) 53 #endif 54 55 #ifndef HWCAP_ISA_C 56 #define HWCAP_ISA_C (1 << ('C' - 'A')) 57 #endif 58 59 #ifndef HWCAP_ISA_V 60 #define HWCAP_ISA_V (1 << ('V' - 'A')) 61 #endif 62 63 #ifndef HWCAP_ISA_B 64 #define HWCAP_ISA_B (1 << ('B' - 'A')) 65 #endif 66 67 #define read_csr(csr) \ 68 ({ \ 69 register unsigned long __v; \ 70 __asm__ __volatile__ ("csrr %0, %1" \ 71 : "=r" (__v) \ 72 : "i" (csr) \ 73 : "memory"); \ 74 __v; \ 75 }) 76 77 uint32_t VM_Version::get_current_vector_length() { 78 assert(_features & CPU_V, "should not call this"); 79 return (uint32_t)read_csr(CSR_VLENB); 80 } 81 82 void VM_Version::get_os_cpu_info() { 83 84 uint64_t auxv = getauxval(AT_HWCAP); 85 86 static_assert(CPU_I == HWCAP_ISA_I, "Flag CPU_I must follow Linux HWCAP"); 87 static_assert(CPU_M == HWCAP_ISA_M, "Flag CPU_M must follow Linux HWCAP"); 88 static_assert(CPU_A == HWCAP_ISA_A, "Flag CPU_A must follow Linux HWCAP"); 89 static_assert(CPU_F == HWCAP_ISA_F, "Flag CPU_F must follow Linux HWCAP"); 90 static_assert(CPU_D == HWCAP_ISA_D, "Flag CPU_D must follow Linux HWCAP"); 91 static_assert(CPU_C == HWCAP_ISA_C, "Flag CPU_C must follow Linux HWCAP"); 92 static_assert(CPU_V == HWCAP_ISA_V, "Flag CPU_V must follow Linux HWCAP"); 93 static_assert(CPU_B == HWCAP_ISA_B, "Flag CPU_B must follow Linux HWCAP"); 94 _features = auxv & ( 95 HWCAP_ISA_I | 96 HWCAP_ISA_M | 97 HWCAP_ISA_A | 98 HWCAP_ISA_F | 99 HWCAP_ISA_D | 100 HWCAP_ISA_C | 101 HWCAP_ISA_V | 102 HWCAP_ISA_B); 103 104 if (FILE *f = fopen("/proc/cpuinfo", "r")) { 105 char buf[512], *p; 106 while (fgets(buf, sizeof (buf), f) != NULL) { 107 if ((p = strchr(buf, ':')) != NULL) { 108 if (strncmp(buf, "uarch", sizeof "uarch" - 1) == 0) { 109 char* uarch = os::strdup(p + 2); 110 uarch[strcspn(uarch, "\n")] = '\0'; 111 _uarch = uarch; 112 break; 113 } 114 } 115 } 116 fclose(f); 117 } 118 }