diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp index a00659f37cb42..407db154177a5 100644 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp @@ -56,8 +56,9 @@ // put OS-includes here # include -# include # include +# include +# include # include # include # include @@ -340,6 +341,26 @@ static const char* reg_abi_names[] = { "x28(t3)", "x29(t4)","x30(t5)", "x31(t6)" }; + +// If compiling on kernel without V support the struct: +// "struct __riscv_v_ext_state" is not defined. +// As below code below requires this layout we just define it here, +// instead of trying to include it, even if available. +struct redefine_riscv_v_ext_state { + unsigned long vstart; + unsigned long vl; + unsigned long vtype; + unsigned long vcsr; + unsigned long vlenb; + void *datap; +}; + +// This magic number is not in any user-space header. +// No other choice but to define it. +#ifndef RISCV_V_MAGIC +#define RISCV_V_MAGIC 0x53465457 +#endif + void os::print_context(outputStream *st, const void *context) { if (context == nullptr) return; @@ -350,6 +371,64 @@ void os::print_context(outputStream *st, const void *context) { st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]); } st->cr(); + + const struct __riscv_mc_d_ext_state * const f_ext_state = &(uc->uc_mcontext.__fpregs.__d); + st->print_cr("Floating point state:"); + st->print_cr("fcsr=" UINT32_FORMAT, f_ext_state->__fcsr); + st->print_cr("Floating point registers:"); + for (int r = 0; r < 32; r++) { + st->print_cr("f%d=" INTPTR_FORMAT " | %g", r, (intptr_t)f_ext_state->__f[r], (double)f_ext_state->__f[r]); + } + st->cr(); + + // vector state + struct __riscv_extra_ext_header *ext; + struct redefine_riscv_v_ext_state *v_ext_state; + + // Find the vector context + ext = (struct __riscv_extra_ext_header *)(&uc->uc_mcontext.__fpregs); + if (ext->hdr.magic != RISCV_V_MAGIC) { + st->print_cr("Vector state: not found"); + return; + } + + // size = sizeof(struct __riscv_ctx_hdr) + sizeof(struct __sc_riscv_v_state) + riscv_v_vsize; + uint32_t ext_size = ext->hdr.size; + + if (ext_size < (sizeof(struct __riscv_ctx_hdr) + sizeof(*v_ext_state))) { + st->print_cr("Vector state: not found, invalid size"); + return; + } + + ext_size -= (sizeof(struct __riscv_ctx_hdr) + sizeof(*v_ext_state)); + + v_ext_state = (struct redefine_riscv_v_ext_state *)((char *)(ext) + sizeof(*ext)); + + st->print_cr("Vector state:"); + st->print_cr("vstart=" INTPTR_FORMAT, v_ext_state->vstart); + st->print_cr("vl=" INTPTR_FORMAT, v_ext_state->vl); + st->print_cr("vtype=" INTPTR_FORMAT, v_ext_state->vtype); + st->print_cr("vcsr=" INTPTR_FORMAT, v_ext_state->vcsr); + st->print_cr("vlenb=" INTPTR_FORMAT, v_ext_state->vlenb); + st->print_cr("Vector registers:"); + + uint64_t vr_size = v_ext_state->vlenb; + + if (ext_size < (32 * vr_size)) { + st->print_cr("Vector registers: not found, invalid size"); + return; + } + // datap format is undocumented, but is generated by kernel function riscv_v_vstate_save(). + uint8_t *regp = (uint8_t *)v_ext_state->datap; + for (int r = 0; r < 32; r++) { + st->print("v%d=0x", r); + for (int i = vr_size; i > 0; i--) { + st->print("%02" PRIx8, regp[i-1]); + } + st->print_cr(""); + regp += vr_size; + } + st->cr(); } void os::print_register_info(outputStream *st, const void *context, int& continuation) {