aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cddl/dev/dtrace/riscv/dtrace_subr.c')
-rw-r--r--sys/cddl/dev/dtrace/riscv/dtrace_subr.c51
1 files changed, 23 insertions, 28 deletions
diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
index c1ac339b3a26..3a6aacd86fcd 100644
--- a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
@@ -21,26 +21,22 @@
*
* Portions Copyright 2016-2018 Ruslan Bukin <br@bsdpad.com>
*
- * $FreeBSD$
- *
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/kmem.h>
+#include <sys/proc.h>
#include <sys/smp.h>
#include <sys/dtrace_impl.h>
#include <sys/dtrace_bsd.h>
+#include <cddl/dev/dtrace/dtrace_cddl.h>
#include <machine/vmparam.h>
#include <machine/encoding.h>
#include <machine/riscvreg.h>
@@ -68,14 +64,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
int
dtrace_invop(uintptr_t addr, struct trapframe *frame)
{
+ struct thread *td;
dtrace_invop_hdlr_t *hdlr;
int rval;
+ rval = 0;
+ td = curthread;
+ td->t_dtrace_trapframe = frame;
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
if ((rval = hdlr->dtih_func(addr, frame, 0)) != 0)
- return (rval);
-
- return (0);
+ break;
+ td->t_dtrace_trapframe = NULL;
+ return (rval);
}
void
@@ -162,7 +162,7 @@ dtrace_sync(void)
* Returns nanoseconds since boot.
*/
uint64_t
-dtrace_gethrtime()
+dtrace_gethrtime(void)
{
struct timespec curtime;
@@ -194,9 +194,7 @@ dtrace_trap(struct trapframe *frame, u_int type)
* flag is cleared and finally re-scheduling is enabled.
*
* Check if DTrace has enabled 'no-fault' mode:
- *
*/
-
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
/*
* There are only a couple of trap types that are expected.
@@ -206,15 +204,19 @@ dtrace_trap(struct trapframe *frame, u_int type)
case SCAUSE_LOAD_ACCESS_FAULT:
case SCAUSE_STORE_ACCESS_FAULT:
case SCAUSE_INST_ACCESS_FAULT:
+ case SCAUSE_INST_PAGE_FAULT:
+ case SCAUSE_LOAD_PAGE_FAULT:
+ case SCAUSE_STORE_PAGE_FAULT:
/* Flag a bad address. */
cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
- cpu_core[curcpu].cpuc_dtrace_illval = 0;
+ cpu_core[curcpu].cpuc_dtrace_illval = frame->tf_stval;
/*
* Offset the instruction pointer to the instruction
* following the one causing the fault.
*/
- frame->tf_sepc += 4;
+ frame->tf_sepc +=
+ dtrace_instr_size((uint8_t *)frame->tf_sepc);
return (1);
default:
@@ -238,16 +240,6 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
}
static int
-match_opcode(uint32_t insn, int match, int mask)
-{
-
- if (((insn ^ match) & mask) == 0)
- return (1);
-
- return (0);
-}
-
-static int
dtrace_invop_start(struct trapframe *frame)
{
register_t *sp;
@@ -259,7 +251,7 @@ dtrace_invop_start(struct trapframe *frame)
if (invop == 0)
return (-1);
- if (match_opcode(invop, (MATCH_SD | RS2_RA | RS1_SP),
+ if (dtrace_match_opcode(invop, (MATCH_SD | RS2_RA | RS1_SP),
(MASK_SD | RS2_MASK | RS1_MASK))) {
/* Non-compressed store of ra to sp */
imm = (invop >> 7) & 0x1f;
@@ -270,14 +262,14 @@ dtrace_invop_start(struct trapframe *frame)
return (0);
}
- if (match_opcode(invop, (MATCH_JALR | (X_RA << RS1_SHIFT)),
+ if (dtrace_match_opcode(invop, (MATCH_JALR | (X_RA << RS1_SHIFT)),
(MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) {
/* Non-compressed ret */
frame->tf_sepc = frame->tf_ra;
return (0);
}
- if (match_opcode(invop, (MATCH_C_SDSP | RS2_C_RA),
+ if (dtrace_match_opcode(invop, (MATCH_C_SDSP | RS2_C_RA),
(MASK_C_SDSP | RS2_C_MASK))) {
/* 'C'-compressed store of ra to sp */
uimm = ((invop >> 10) & 0x7) << 3;
@@ -288,13 +280,16 @@ dtrace_invop_start(struct trapframe *frame)
return (0);
}
- if (match_opcode(invop, (MATCH_C_JR | (X_RA << RD_SHIFT)),
+ if (dtrace_match_opcode(invop, (MATCH_C_JR | (X_RA << RD_SHIFT)),
(MASK_C_JR | RD_MASK))) {
/* 'C'-compressed ret */
frame->tf_sepc = frame->tf_ra;
return (0);
}
+ if (dtrace_match_opcode(invop, MATCH_C_NOP, MASK_C_NOP))
+ return (0);
+
#ifdef INVARIANTS
panic("Instruction %x doesn't match any opcode.", invop);
#endif