Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Sep 2018 14:34:10 +0000 (UTC)
From:      Ruslan Bukin <br@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r338444 - in head/sys: cddl/contrib/opensolaris/uts/common/sys cddl/dev/dtrace/riscv cddl/dev/fbt/riscv riscv/conf riscv/include
Message-ID:  <201809031434.w83EYAsJ082184@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br@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@freebsd.org
  * Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org
  * Portions Copyright 2013 Howard Su howardsu@freebsd.org
- * Portions Copyright 2016 Ruslan Bukin <br@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br@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))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201809031434.w83EYAsJ082184>