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 #define read_csr(csr) \ 64 ({ \ 65 register unsigned long __v; \ 66 __asm__ __volatile__ ("csrr %0, %1" \ 67 : "=r" (__v) \ 68 : "i" (csr) \ 69 : "memory"); \ 70 __v; \ 71 }) 72 73 uint32_t VM_Version::get_current_vector_length() { 74 assert(_features & CPU_V, "should not call this"); 75 return (uint32_t)read_csr(CSR_VLENB); 76 } 77 78 void VM_Version::get_os_cpu_info() { 79 80 uint64_t auxv = getauxval(AT_HWCAP); 81 82 static_assert(CPU_I == HWCAP_ISA_I, "Flag CPU_I must follow Linux HWCAP"); 83 static_assert(CPU_M == HWCAP_ISA_M, "Flag CPU_M must follow Linux HWCAP"); 84 static_assert(CPU_A == HWCAP_ISA_A, "Flag CPU_A must follow Linux HWCAP"); 85 static_assert(CPU_F == HWCAP_ISA_F, "Flag CPU_F must follow Linux HWCAP"); 86 static_assert(CPU_D == HWCAP_ISA_D, "Flag CPU_D must follow Linux HWCAP"); 87 static_assert(CPU_C == HWCAP_ISA_C, "Flag CPU_C must follow Linux HWCAP"); 88 static_assert(CPU_V == HWCAP_ISA_V, "Flag CPU_V must follow Linux HWCAP"); 89 90 // RISC-V has four bit-manipulation ISA-extensions: Zba/Zbb/Zbc/Zbs. 91 // Availability for those extensions could not be queried from HWCAP. 92 // TODO: Add proper detection for those extensions. 93 _features = auxv & ( 94 HWCAP_ISA_I | 95 HWCAP_ISA_M | 96 HWCAP_ISA_A | 97 HWCAP_ISA_F | 98 HWCAP_ISA_D | 99 HWCAP_ISA_C | 100 HWCAP_ISA_V); 101 102 if (FILE *f = fopen("/proc/cpuinfo", "r")) { 103 char buf[512], *p; 104 while (fgets(buf, sizeof (buf), f) != NULL) { 105 if ((p = strchr(buf, ':')) != NULL) { 106 if (strncmp(buf, "uarch", sizeof "uarch" - 1) == 0) { 107 char* uarch = os::strdup(p + 2); 108 uarch[strcspn(uarch, "\n")] = '\0'; 109 _uarch = uarch; 110 break; 111 } 112 } 113 } 114 fclose(f); 115 } 116 }