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_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 }