From owner-svn-src-all@freebsd.org Mon Sep 3 14:34:11 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 72BAEFEBAA3; Mon, 3 Sep 2018 14:34:11 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2493F8712D; Mon, 3 Sep 2018 14:34:11 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1F80413C2; Mon, 3 Sep 2018 14:34:11 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w83EYBgl082188; Mon, 3 Sep 2018 14:34:11 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w83EYAsJ082184; Mon, 3 Sep 2018 14:34:10 GMT (envelope-from br@FreeBSD.org) Message-Id: <201809031434.w83EYAsJ082184@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Mon, 3 Sep 2018 14:34:10 +0000 (UTC) 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 X-SVN-Group: head X-SVN-Commit-Author: br X-SVN-Commit-Paths: in head/sys: cddl/contrib/opensolaris/uts/common/sys cddl/dev/dtrace/riscv cddl/dev/fbt/riscv riscv/conf riscv/include X-SVN-Commit-Revision: 338444 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Sep 2018 14:34:11 -0000 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 + * Portions Copyright 2016-2018 Ruslan Bukin * * $FreeBSD$ * @@ -42,8 +42,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include -#include #include #include #include @@ -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 + * Portions Copyright 2016-2018 Ruslan Bukin * * $FreeBSD$ */ @@ -37,10 +37,12 @@ #include #include +#include #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))