Signed-off-by: LIU Zhiwei <zhiwei_...@c-sky.com> --- risu_reginfo_riscv64.c | 134 +++++++++++++++++++++++++++++++++++++++++ risu_riscv64.c | 47 +++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 risu_reginfo_riscv64.c create mode 100644 risu_riscv64.c
diff --git a/risu_reginfo_riscv64.c b/risu_reginfo_riscv64.c new file mode 100644 index 0000000..cfa9889 --- /dev/null +++ b/risu_reginfo_riscv64.c @@ -0,0 +1,134 @@ +/****************************************************************************** + * Copyright (c) 2020 PingTouGe Semiconductor + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIU Zhiwei (PingTouGe) - initial implementation + * based on Peter Maydell's risu_arm.c + *****************************************************************************/ + +#include <stdio.h> +#include <ucontext.h> +#include <string.h> +#include <signal.h> /* for FPSIMD_MAGIC */ +#include <stdlib.h> +#include <stddef.h> +#include <stdbool.h> +#include <inttypes.h> +#include <assert.h> +#include <sys/prctl.h> + +#include "risu.h" +#include "risu_reginfo_riscv64.h" + +const struct option * const arch_long_opts; +const char * const arch_extra_help; + +void process_arch_opt(int opt, const char *arg) +{ + abort(); +} + +const int reginfo_size(void) +{ + return sizeof(struct reginfo); +} + +/* reginfo_init: initialize with a ucontext */ +void reginfo_init(struct reginfo *ri, ucontext_t *uc) +{ + int i; + union __riscv_mc_fp_state *fp; + /* necessary to be able to compare with memcmp later */ + memset(ri, 0, sizeof(*ri)); + + for (i = 0; i < 32; i++) { + ri->regs[i] = uc->uc_mcontext.__gregs[i]; + } + + ri->sp = 0xdeadbeefdeadbeef; + ri->regs[2] = 0xdeadbeefdeadbeef; + ri->regs[3] = 0xdeadbeefdeadbeef; + ri->regs[4] = 0xdeadbeefdeadbeef; + ri->pc = uc->uc_mcontext.__gregs[0] - image_start_address; + ri->faulting_insn = *((uint32_t *) uc->uc_mcontext.__gregs[0]); + fp = &uc->uc_mcontext.__fpregs; + ri->fcsr = fp->__d.__fcsr; + + for (i = 0; i < 32; i++) { + ri->fregs[i] = fp->__d.__f[i]; + } +} + +/* reginfo_is_eq: compare the reginfo structs, returns nonzero if equal */ +int reginfo_is_eq(struct reginfo *r1, struct reginfo *r2) +{ + return memcmp(r1, r2, reginfo_size()) == 0; +} + +/* reginfo_dump: print state to a stream, returns nonzero on success */ +int reginfo_dump(struct reginfo *ri, FILE * f) +{ + int i; + fprintf(f, " faulting insn %08x\n", ri->faulting_insn); + + for (i = 1; i < 32; i++) { + fprintf(f, " X%-2d : %016" PRIx64 "\n", i, ri->regs[i]); + } + + fprintf(f, " sp : %016" PRIx64 "\n", ri->sp); + fprintf(f, " pc : %016" PRIx64 "\n", ri->pc); + fprintf(f, " fcsr : %08x\n", ri->fcsr); + + for (i = 0; i < 32; i++) { + fprintf(f, " F%-2d : %016" PRIx64 "\n", i, ri->fregs[i]); + } + + return !ferror(f); +} + +/* reginfo_dump_mismatch: print mismatch details to a stream, ret nonzero=ok */ +int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE * f) +{ + int i; + fprintf(f, "mismatch detail (master : apprentice):\n"); + if (m->faulting_insn != a->faulting_insn) { + fprintf(f, " faulting insn mismatch %08x vs %08x\n", + m->faulting_insn, a->faulting_insn); + } + for (i = 1; i < 32; i++) { + if (m->regs[i] != a->regs[i]) { + fprintf(f, " X%-2d : %016" PRIx64 " vs %016" PRIx64 "\n", + i, m->regs[i], a->regs[i]); + } + } + + if (m->sp != a->sp) { + fprintf(f, " sp : %016" PRIx64 " vs %016" PRIx64 "\n", + m->sp, a->sp); + } + + if (m->pc != a->pc) { + fprintf(f, " pc : %016" PRIx64 " vs %016" PRIx64 "\n", + m->pc, a->pc); + } + + if (m->fcsr != a->fcsr) { + fprintf(f, " fcsr : %08x vs %08x\n", m->fcsr, a->fcsr); + } + + for (i = 0; i < 32; i++) { + if (m->fregs[i] != a->fregs[i]) { + fprintf(f, " F%-2d : " + "%016" PRIx64 " vs " + "%016" PRIx64 "\n", i, + (uint64_t) m->fregs[i], + (uint64_t) a->fregs[i]); + } + } + + return !ferror(f); +} diff --git a/risu_riscv64.c b/risu_riscv64.c new file mode 100644 index 0000000..f742a40 --- /dev/null +++ b/risu_riscv64.c @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright (c) 2020 PingTouGe Semiconductor + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * LIU Zhiwei(Linaro) - initial implementation + * based on Peter Maydell's risu_arm.c + *****************************************************************************/ + +#include "risu.h" + +void advance_pc(void *vuc) +{ + ucontext_t *uc = vuc; + uc->uc_mcontext.__gregs[0] += 4; +} + +void set_ucontext_paramreg(void *vuc, uint64_t value) +{ + ucontext_t *uc = vuc; + uc->uc_mcontext.__gregs[10] = value; +} + +uint64_t get_reginfo_paramreg(struct reginfo *ri) +{ + return ri->regs[10]; +} + +int get_risuop(struct reginfo *ri) +{ + /* Return the risuop we have been asked to do + * (or -1 if this was a SIGILL for a non-risuop insn) + */ + uint32_t insn = ri->faulting_insn; + uint32_t op = (insn & 0xf00) >> 8; + uint32_t key = insn & ~0xf00; + uint32_t risukey = 0x0000006b; + return (key != risukey) ? -1 : op; +} + +uintptr_t get_pc(struct reginfo *ri) +{ + return ri->pc; +} -- 2.23.0