Skip to content

Commit

Permalink
8309258: RISC-V: Add riscv_hwprobe syscall
Browse files Browse the repository at this point in the history
Reviewed-by: fjiang, stuefe, fyang, luhenry
  • Loading branch information
robehn committed Jun 20, 2023
1 parent 4a9cc8a commit 31b6fd7
Show file tree
Hide file tree
Showing 5 changed files with 529 additions and 109 deletions.
48 changes: 27 additions & 21 deletions src/hotspot/cpu/riscv/vm_version_riscv.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2023, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,24 +31,35 @@
#include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"

const char* VM_Version::_uarch = "";
const char* VM_Version::_vm_mode = "";
#include <ctype.h>

uint32_t VM_Version::_initial_vector_length = 0;

#define DEF_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
VM_Version::NAME##RVFeatureValue VM_Version::NAME(PRETTY, BIT, FSTRING);
RV_FEATURE_FLAGS(DEF_RV_FEATURE)

#define ADD_RV_FEATURE_IN_LIST(NAME, PRETTY, BIT, FSTRING, FLAGF) \
&VM_Version::NAME,
VM_Version::RVFeatureValue* VM_Version::_feature_list[] = {
RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST)
nullptr};

void VM_Version::initialize() {
_supports_cx8 = true;
_supports_atomic_getset4 = true;
_supports_atomic_getadd4 = true;
_supports_atomic_getset8 = true;
_supports_atomic_getadd8 = true;

get_os_cpu_info();
setup_cpu_available_features();

// check if satp.mode is supported, currently supports up to SV48(RV64)
if (get_satp_mode() > VM_SV48) {
if (satp_mode.value() > VM_SV48 || satp_mode.value() < VM_MBARE) {
vm_exit_during_initialization(
err_msg("Unsupported satp mode: %s. Only satp modes up to sv48 are supported for now.",
_vm_mode));
err_msg(
"Unsupported satp mode: SV%d. Only satp modes up to sv48 are supported for now.",
(int)satp_mode.value()));
}

// https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva20-profiles
Expand Down Expand Up @@ -165,16 +177,16 @@ void VM_Version::initialize() {
}

if (UseRVV) {
if (!(_features & CPU_V)) {
if (!ext_V.enabled()) {
warning("RVV is not supported on this CPU");
FLAG_SET_DEFAULT(UseRVV, false);
} else {
// read vector length from vector CSR vlenb
_initial_vector_length = get_current_vector_length();
_initial_vector_length = cpu_vector_length();
}
}

if (UseRVC && !(_features & CPU_C)) {
if (UseRVC && !ext_C.enabled()) {
warning("RVC is not supported on this CPU");
FLAG_SET_DEFAULT(UseRVC, false);

Expand All @@ -185,7 +197,11 @@ void VM_Version::initialize() {
}

if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
if (unaligned_access.value() != MISALIGNED_FAST) {
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
} else {
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, false);
}
}

if (UseZbb) {
Expand All @@ -208,16 +224,6 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseBlockZeroing, false);
}

char buf[512];
buf[0] = '\0';
if (_uarch != nullptr && strcmp(_uarch, "") != 0) snprintf(buf, sizeof(buf), "%s,", _uarch);
strcat(buf, "rv64");
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, name);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED

_features_string = os::strdup(buf);

#ifdef COMPILER2
c2_initialize();
#endif // COMPILER2
Expand Down Expand Up @@ -333,6 +339,6 @@ void VM_Version::initialize_cpu_information(void) {
_no_of_threads = _no_of_cores;
_no_of_sockets = _no_of_cores;
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "RISCV64");
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", _features_string);
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", features_string());
_initialized = true;
}
194 changes: 158 additions & 36 deletions src/hotspot/cpu/riscv/vm_version_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2023, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,55 +31,176 @@
#include "runtime/abstract_vm_version.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals_extension.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/sizes.hpp"

class RiscvHwprobe;

class VM_Version : public Abstract_VM_Version {
#ifdef COMPILER2
private:
static void c2_initialize();
#endif // COMPILER2
friend RiscvHwprobe;
private:
class RVFeatureValue {
const char* const _pretty;
const bool _feature_string;
const uint64_t _feature_bit;
bool _enabled;
int64_t _value;
public:
RVFeatureValue(const char* pretty, int bit_num, bool fstring) :
_pretty(pretty), _feature_string(fstring), _feature_bit(nth_bit(bit_num)),
_enabled(false), _value(-1) {
}
void enable_feature(int64_t value = 0) {
_enabled = true;
_value = value;
}
const char* const pretty() { return _pretty; }
const uint64_t feature_bit() { return _feature_bit; }
const bool feature_string() { return _feature_string; }
bool enabled() { return _enabled; }
int64_t value() { return _value; }
virtual void update_flag() = 0;
};

// VM modes (satp.mode) privileged ISA 1.10
enum VM_MODE {
VM_MBARE = 0,
VM_SV39 = 8,
VM_SV48 = 9,
VM_SV57 = 10,
VM_SV64 = 11
};
#define UPDATE_DEFAULT(flag) \
void update_flag() { \
assert(enabled(), "Must be."); \
if (FLAG_IS_DEFAULT(flag)) { \
FLAG_SET_DEFAULT(flag, true); \
} \
} \

#define NO_UPDATE_DEFAULT \
void update_flag() {} \

// Frozen standard extensions
// I RV64I
// M Integer Multiplication and Division
// A Atomic Instructions
// F Single-Precision Floating-Point
// D Single-Precision Floating-Point
// (G = M + A + F + D)
// Q Quad-Precision Floating-Point
// C Compressed Instructions
// H Hypervisor
//
// Others, open and non-standard
// V Vector
//
// Cache Management Operations
// Zicbom Cache Block Management Operations
// Zicboz Cache Block Zero Operations
// Zicbop Cache Block Prefetch Operations
//
// Bit-manipulation
// Zba Address generation instructions
// Zbb Basic bit-manipulation
// Zbc Carry-less multiplication
// Zbs Single-bit instructions
//
// Zicsr Control and Status Register (CSR) Instructions
// Zifencei Instruction-Fetch Fence
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
// Zihintpause Pause instruction HINT
//
// Other features and settings
// mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2..
// marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch.
// mimpid A unique encoding of the version of the processor implementation.
// unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast)
// satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64

#define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord

// declaration name , extension name, bit pos ,in str, mapped flag)
#define RV_FEATURE_FLAGS(decl) \
decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \
decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \
decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \
decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \

#define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
struct NAME##RVFeatureValue : public RVFeatureValue { \
NAME##RVFeatureValue(const char* pretty, int bit, bool fstring) : \
RVFeatureValue(pretty, bit, fstring) {} \
FLAGF; \
}; \
static NAME##RVFeatureValue NAME; \

RV_FEATURE_FLAGS(DECLARE_RV_FEATURE)
#undef DECLARE_RV_FEATURE

// VM modes (satp.mode) privileged ISA 1.10
enum VM_MODE : int {
VM_NOTSET = -1,
VM_MBARE = 0,
VM_SV39 = 39,
VM_SV48 = 48,
VM_SV57 = 57,
VM_SV64 = 64
};

static VM_MODE parse_satp_mode(const char* vm_mode);

// Values from riscv_hwprobe()
enum UNALIGNED_ACCESS : int {
MISALIGNED_UNKNOWN = 0,
MISALIGNED_EMULATED = 1,
MISALIGNED_SLOW = 2,
MISALIGNED_FAST = 3,
MISALIGNED_UNSUPPORTED = 4
};

protected:
static const char* _uarch;
static const char* _vm_mode;
// Null terminated list
static RVFeatureValue* _feature_list[];

// Enables features in _feature_list
static void setup_cpu_available_features();
// Helper for specific queries
static void os_aux_features();
static char* os_uarch_additional_features();
static void vendor_features();
// Vendors specific features
static void rivos_features();

// Determine vector length iff ext_V/UseRVV
static uint32_t cpu_vector_length();
static uint32_t _initial_vector_length;
static void get_os_cpu_info();
static uint32_t get_current_vector_length();
static VM_MODE get_satp_mode();

public:
#ifdef COMPILER2
static void c2_initialize();
#endif // COMPILER2

public:
// Initialization
static void initialize();
static void initialize_cpu_information();

constexpr static bool supports_stack_watermark_barrier() { return true; }

static bool supports_on_spin_wait() { return UseZihintpause; }

enum Feature_Flag {
#define CPU_FEATURE_FLAGS(decl) \
decl(I, "i", 8) \
decl(M, "m", 12) \
decl(A, "a", 0) \
decl(F, "f", 5) \
decl(D, "d", 3) \
decl(C, "c", 2) \
decl(V, "v", 21)

#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
#undef DECLARE_CPU_FEATURE_FLAG
};

static void initialize_cpu_information(void);
};

#endif // CPU_RISCV_VM_VERSION_RISCV_HPP
Loading

1 comment on commit 31b6fd7

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.