Add support for 'C'-compressed ISA extension to DTrace FBT provider.
Approved by: re (kib) Sponsored by: DARPA, AFRL
This commit is contained in:
parent
545428e18d
commit
639c5f49ef
@ -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
|
||||
|
||||
|
@ -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, uintptr_t eax)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
|
||||
{
|
||||
@ -237,30 +236,59 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
|
||||
(uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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,8 +75,62 @@ 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
|
||||
@ -85,6 +141,8 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
|
||||
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 symindx,
|
||||
|
||||
/* 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 symindx,
|
||||
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 symindx,
|
||||
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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,116 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by the University of Cambridge
|
||||
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||
* UK Higher Education Innovation Fund (HEIF).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_RISCV_OPCODE_H_
|
||||
#define _MACHINE_RISCV_OPCODE_H_
|
||||
|
||||
/*
|
||||
* Define the instruction formats and opcode values for the
|
||||
* RISC-V instruction set.
|
||||
*/
|
||||
#include <machine/endian.h>
|
||||
|
||||
/*
|
||||
* Define the instruction formats.
|
||||
*/
|
||||
typedef union {
|
||||
unsigned word;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned funct7: 7;
|
||||
} RType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 6;
|
||||
unsigned funct7: 6;
|
||||
} R2Type;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned imm: 12;
|
||||
} IType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned imm0_4: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned imm5_11: 7;
|
||||
} SType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned imm11: 1;
|
||||
unsigned imm1_4: 4;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned imm5_10: 6;
|
||||
unsigned imm12: 1;
|
||||
} SBType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned imm12_31: 20;
|
||||
} UType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned imm12_19: 8;
|
||||
unsigned imm11: 1;
|
||||
unsigned imm1_10: 10;
|
||||
unsigned imm20: 1;
|
||||
} UJType;
|
||||
} InstFmt;
|
||||
|
||||
#define RISCV_OPCODE(r) (r & 0x7f)
|
||||
|
||||
#endif /* !_MACHINE_RISCV_OPCODE_H_ */
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user