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 <b...@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <b...@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 j...@freebsd.org
  * Portions Copyright 2013 Justin Hibbits jhibb...@freebsd.org
  * Portions Copyright 2013 Howard Su howar...@freebsd.org
- * Portions Copyright 2016 Ruslan Bukin <b...@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <b...@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))
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to