svn commit: r338444 - in head/sys: cddl/contrib/opensolaris/uts/common/sys cddl/dev/dtrace/riscv cddl/dev/fbt/riscv riscv/conf riscv/include
Ruslan Bukin
br at FreeBSD.org
Mon Sep 3 14:34:11 UTC 2018
Author: br
Date: Mon Sep 3 14:34:09 2018
New Revision: 338444
URL: https://svnweb.freebsd.org/changeset/base/338444
Log:
Add support for 'C'-compressed ISA extension to DTrace FBT provider.
Approved by: re (kib)
Sponsored by: DARPA, AFRL
Deleted:
head/sys/riscv/include/riscv_opcode.h
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
head/sys/cddl/dev/fbt/riscv/fbt_isa.c
head/sys/riscv/conf/GENERIC
head/sys/riscv/include/riscvreg.h
Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Mon Sep 3 14:26:43 2018 (r338443)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Mon Sep 3 14:34:09 2018 (r338444)
@@ -2496,12 +2496,11 @@ extern void dtrace_helpers_destroy(proc_t *);
#elif defined(__riscv)
-#define SD_RA_SP_MASK 0x01fff07f
-#define SD_RA_SP 0x00113023
-
#define DTRACE_INVOP_SD 1
-#define DTRACE_INVOP_RET 2
-#define DTRACE_INVOP_NOP 3
+#define DTRACE_INVOP_C_SDSP 2
+#define DTRACE_INVOP_RET 3
+#define DTRACE_INVOP_C_RET 4
+#define DTRACE_INVOP_NOP 5
#endif
Modified: head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c Mon Sep 3 14:26:43 2018 (r338443)
+++ head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c Mon Sep 3 14:34:09 2018 (r338444)
@@ -19,7 +19,7 @@
*
* CDDL HEADER END
*
- * Portions Copyright 2016 Ruslan Bukin <br at bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br at bsdpad.com>
*
* $FreeBSD$
*
@@ -42,8 +42,8 @@ __FBSDID("$FreeBSD$");
#include <sys/dtrace_impl.h>
#include <sys/dtrace_bsd.h>
#include <machine/vmparam.h>
+#include <machine/encoding.h>
#include <machine/riscvreg.h>
-#include <machine/riscv_opcode.h>
#include <machine/clock.h>
#include <machine/frame.h>
#include <machine/trap.h>
@@ -77,7 +77,6 @@ dtrace_invop(uintptr_t addr, struct trapframe *frame,
return (0);
}
-
void
dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
{
@@ -238,29 +237,58 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_
}
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)
{
- int data, invop, reg, update_sp;
- register_t arg1, arg2;
register_t *sp;
+ uint32_t uimm;
uint32_t imm;
- InstFmt i;
- int offs;
- int tmp;
+ int invop;
invop = dtrace_invop(frame->tf_sepc, frame, frame->tf_sepc);
- if (invop == RISCV_INSN_RET) {
+ if (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;
+ imm |= ((invop >> 25) & 0x7f) << 5;
+ sp = (register_t *)((uint8_t *)frame->tf_sp + imm);
+ *sp = frame->tf_ra;
+ frame->tf_sepc += INSN_SIZE;
+ return (0);
+ }
+
+ if (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 ((invop & SD_RA_SP_MASK) == SD_RA_SP) {
- i.word = invop;
- imm = i.SType.imm0_4 | (i.SType.imm5_11 << 5);
- sp = (register_t *)((uint8_t *)frame->tf_sp + imm);
+ if (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;
+ uimm |= ((invop >> 7) & 0x7) << 6;
+ sp = (register_t *)((uint8_t *)frame->tf_sp + uimm);
*sp = frame->tf_ra;
- frame->tf_sepc += INSN_SIZE;
+ frame->tf_sepc += INSN_C_SIZE;
+ return (0);
+ }
+
+ if (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);
}
Modified: head/sys/cddl/dev/fbt/riscv/fbt_isa.c
==============================================================================
--- head/sys/cddl/dev/fbt/riscv/fbt_isa.c Mon Sep 3 14:26:43 2018 (r338443)
+++ head/sys/cddl/dev/fbt/riscv/fbt_isa.c Mon Sep 3 14:34:09 2018 (r338444)
@@ -21,7 +21,7 @@
* Portions Copyright 2006-2008 John Birrell jb at freebsd.org
* Portions Copyright 2013 Justin Hibbits jhibbits at freebsd.org
* Portions Copyright 2013 Howard Su howardsu at freebsd.org
- * Portions Copyright 2016 Ruslan Bukin <br at bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br at bsdpad.com>
*
* $FreeBSD$
*/
@@ -37,10 +37,12 @@
#include <sys/dtrace.h>
#include <machine/riscvreg.h>
+#include <machine/encoding.h>
#include "fbt.h"
-#define FBT_PATCHVAL (RISCV_INSN_BREAK)
+#define FBT_C_PATCHVAL MATCH_C_EBREAK
+#define FBT_PATCHVAL MATCH_EBREAK
#define FBT_ENTRY "entry"
#define FBT_RETURN "return"
@@ -73,10 +75,64 @@ void
fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
{
- *fbt->fbtp_patchpoint = val;
- cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+ switch(fbt->fbtp_patchval) {
+ case FBT_C_PATCHVAL:
+ *(uint16_t *)fbt->fbtp_patchpoint = (uint16_t)val;
+ cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 2);
+ break;
+ case FBT_PATCHVAL:
+ *fbt->fbtp_patchpoint = val;
+ cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+ break;
+ };
}
+static int
+match_opcode(uint32_t insn, int match, int mask)
+{
+
+ if (((insn ^ match) & mask) == 0)
+ return (1);
+
+ return (0);
+}
+
+static int
+check_c_ret(uint32_t **instr)
+{
+ uint16_t *instr1;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ instr1 = (uint16_t *)(*instr) + i;
+ if (match_opcode(*instr1, (MATCH_C_JR | (X_RA << RD_SHIFT)),
+ (MASK_C_JR | RD_MASK))) {
+ *instr = (uint32_t *)instr1;
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+check_c_sdsp(uint32_t **instr)
+{
+ uint16_t *instr1;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ instr1 = (uint16_t *)(*instr) + i;
+ if (match_opcode(*instr1, (MATCH_C_SDSP | RS2_C_RA),
+ (MASK_C_SDSP | RS2_C_MASK))) {
+ *instr = (uint32_t *)instr1;
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
int
fbt_provide_module_function(linker_file_t lf, int symindx,
linker_symval_t *symval, void *opaque)
@@ -85,6 +141,8 @@ fbt_provide_module_function(linker_file_t lf, int symi
uint32_t *instr, *limit;
const char *name;
char *modname;
+ int patchval;
+ int rval;
modname = opaque;
name = symval->name;
@@ -98,8 +156,20 @@ fbt_provide_module_function(linker_file_t lf, int symi
/* Look for sd operation */
for (; instr < limit; instr++) {
- if ((*instr & SD_RA_SP_MASK) == SD_RA_SP)
+ /* Look for a non-compressed store of ra to sp */
+ if (match_opcode(*instr, (MATCH_SD | RS2_RA | RS1_SP),
+ (MASK_SD | RS2_MASK | RS1_MASK))) {
+ rval = DTRACE_INVOP_SD;
+ patchval = FBT_PATCHVAL;
break;
+ }
+
+ /* Look for a 'C'-compressed store of ra to sp. */
+ if (check_c_sdsp(&instr)) {
+ rval = DTRACE_INVOP_C_SDSP;
+ patchval = FBT_C_PATCHVAL;
+ break;
+ }
}
if (instr >= limit)
@@ -113,8 +183,8 @@ fbt_provide_module_function(linker_file_t lf, int symi
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
fbt->fbtp_savedval = *instr;
- fbt->fbtp_patchval = FBT_PATCHVAL;
- fbt->fbtp_rval = DTRACE_INVOP_SD;
+ fbt->fbtp_patchval = patchval;
+ fbt->fbtp_rval = rval;
fbt->fbtp_symindx = symindx;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
@@ -125,8 +195,20 @@ fbt_provide_module_function(linker_file_t lf, int symi
retfbt = NULL;
again:
for (; instr < limit; instr++) {
- if (*instr == RISCV_INSN_RET)
+ /* Look for non-compressed return */
+ if (match_opcode(*instr, (MATCH_JALR | (X_RA << RS1_SHIFT)),
+ (MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) {
+ rval = DTRACE_INVOP_RET;
+ patchval = FBT_PATCHVAL;
break;
+ }
+
+ /* Look for 'C'-compressed return */
+ if (check_c_ret(&instr)) {
+ rval = DTRACE_INVOP_C_RET;
+ patchval = FBT_C_PATCHVAL;
+ break;
+ }
}
if (instr >= limit)
@@ -150,9 +232,9 @@ again:
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
fbt->fbtp_symindx = symindx;
- fbt->fbtp_rval = DTRACE_INVOP_RET;
+ fbt->fbtp_rval = rval;
fbt->fbtp_savedval = *instr;
- fbt->fbtp_patchval = FBT_PATCHVAL;
+ fbt->fbtp_patchval = patchval;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
Modified: head/sys/riscv/conf/GENERIC
==============================================================================
--- head/sys/riscv/conf/GENERIC Mon Sep 3 14:26:43 2018 (r338443)
+++ head/sys/riscv/conf/GENERIC Mon Sep 3 14:34:09 2018 (r338444)
@@ -88,6 +88,15 @@ device vtnet # VirtIO Ethernet device
device virtio_blk # VirtIO Block device
device virtio_mmio # VirtIO MMIO bus
+# DTrace support
+# device dtrace
+# device dtrace_profile
+# device dtrace_sdt
+# device dtrace_fbt
+# device dtrace_systrace
+# device dtrace_prototype
+# device dtraceall
+
# Serial (COM) ports
device uart # Generic UART driver
device uart_ns8250 # ns8250-type UART driver
Modified: head/sys/riscv/include/riscvreg.h
==============================================================================
--- head/sys/riscv/include/riscvreg.h Mon Sep 3 14:26:43 2018 (r338443)
+++ head/sys/riscv/include/riscvreg.h Mon Sep 3 14:34:09 2018 (r338444)
@@ -157,10 +157,31 @@
#define XLEN 8
#define INSN_SIZE 4
+#define INSN_C_SIZE 2
-#define RISCV_INSN_NOP 0x00000013
-#define RISCV_INSN_BREAK 0x00100073
-#define RISCV_INSN_RET 0x00008067
+#define X_RA 1
+#define X_SP 2
+#define X_GP 3
+#define X_TP 4
+#define X_T0 5
+#define X_T1 6
+#define X_T2 7
+#define X_T3 28
+
+#define RD_SHIFT 7
+#define RD_MASK (0x1f << RD_SHIFT)
+#define RS1_SHIFT 15
+#define RS1_MASK (0x1f << RS1_SHIFT)
+#define RS1_SP (X_SP << RS1_SHIFT)
+#define RS2_SHIFT 20
+#define RS2_MASK (0x1f << RS2_SHIFT)
+#define RS2_RA (X_RA << RS2_SHIFT)
+#define IMM_SHIFT 20
+#define IMM_MASK (0xfff << IMM_SHIFT)
+
+#define RS2_C_SHIFT 2
+#define RS2_C_MASK (0x1f << RS2_C_SHIFT)
+#define RS2_C_RA (X_RA << RS2_C_SHIFT)
#define CSR_ZIMM(val) \
(__builtin_constant_p(val) && ((u_long)(val) < 32))
More information about the svn-src-all
mailing list