Author: br
Date: Tue May 24 16:41:37 2016
New Revision: 300618
URL: https://svnweb.freebsd.org/changeset/base/300618

Log:
  Add initial DTrace support for RISC-V.
  
  Sponsored by: DARPA, AFRL
  Sponsored by: HEIF5

Added:
  head/cddl/contrib/opensolaris/lib/libdtrace/riscv/
  head/cddl/contrib/opensolaris/lib/libdtrace/riscv/dt_isadep.c   (contents, 
props changed)
  head/sys/cddl/contrib/opensolaris/uts/riscv/
  head/sys/cddl/contrib/opensolaris/uts/riscv/dtrace/
  head/sys/cddl/contrib/opensolaris/uts/riscv/dtrace/fasttrap_isa.c   
(contents, props changed)
  head/sys/cddl/contrib/opensolaris/uts/riscv/sys/
  head/sys/cddl/contrib/opensolaris/uts/riscv/sys/fasttrap_isa.h   (contents, 
props changed)
  head/sys/cddl/dev/dtrace/riscv/
  head/sys/cddl/dev/dtrace/riscv/dtrace_asm.S   (contents, props changed)
  head/sys/cddl/dev/dtrace/riscv/dtrace_isa.c   (contents, props changed)
  head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c   (contents, props changed)
  head/sys/cddl/dev/dtrace/riscv/regset.h   (contents, props changed)
  head/sys/cddl/dev/fbt/riscv/
  head/sys/cddl/dev/fbt/riscv/fbt_isa.c   (contents, props changed)
  head/sys/cddl/dev/fbt/riscv/fbt_isa.h   (contents, props changed)
Modified:
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
  head/cddl/lib/Makefile
  head/cddl/lib/libdtrace/Makefile
  head/cddl/usr.sbin/Makefile
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
  head/sys/cddl/dev/profile/profile.c
  head/sys/conf/files.riscv
  head/sys/riscv/include/frame.h
  head/sys/riscv/include/riscvreg.h
  head/sys/riscv/riscv/trap.c

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c        Tue May 
24 16:30:05 2016        (r300617)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c        Tue May 
24 16:41:37 2016        (r300618)
@@ -250,6 +250,9 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION_
                            dofr[j].dofr_offset + 4;
                        rel->r_info = ELF32_R_INFO(count + dep->de_global,
                            R_PPC_REL32);
+#elif defined(__riscv__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
 #elif defined(__sparc)
                        /*
                         * Add 4 bytes to hit the low half of this 64-bit
@@ -440,6 +443,8 @@ prepare_elf64(dtrace_hdl_t *dtp, const d
                            dofr[j].dofr_offset;
                        rel->r_info = ELF64_R_INFO(count + dep->de_global,
                            R_PPC64_REL64);
+#elif defined(__riscv__)
+/* XXX */
 #elif defined(__i386) || defined(__amd64)
                        rel->r_offset = s->dofs_offset +
                            dofr[j].dofr_offset;
@@ -935,7 +940,15 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, i
 
        return (0);
 }
-
+#elif defined(__riscv__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+    uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+       return (0);
+}
 #elif defined(__sparc)
 
 #define        DT_OP_RET               0x81c7e008

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c      Tue May 
24 16:30:05 2016        (r300617)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c      Tue May 
24 16:41:37 2016        (r300618)
@@ -310,7 +310,8 @@ pfprint_fp(dtrace_hdl_t *dtp, FILE *fp, 
        case sizeof (double):
                return (dt_printf(dtp, fp, format,
                    *((double *)addr) / n));
-#if !defined(__arm__) && !defined(__powerpc__) && !defined(__mips__)
+#if !defined(__arm__) && !defined(__powerpc__) && \
+    !defined(__mips__) && !defined(__riscv__)
        case sizeof (long double):
                return (dt_printf(dtp, fp, format,
                    *((long double *)addr) / ldn));

Added: head/cddl/contrib/opensolaris/lib/libdtrace/riscv/dt_isadep.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/riscv/dt_isadep.c       Tue May 
24 16:41:37 2016        (r300618)
@@ -0,0 +1,139 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ * Copyright 2014 Howard Su
+ * Copyright 2015 George V. Neville-Neil
+ * Copyright 2015 Ruslan Bukin <b...@bsdpad.com>
+ */
+
+#pragma ident  "%Z%%M% %I%     %E% SMI"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <dt_impl.h>
+#include <dt_pid.h>
+
+#if !defined(sun)
+#include <libproc_compat.h>
+#endif
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+
+       ftp->ftps_type = DTFTP_ENTRY;
+       ftp->ftps_pc = (uintptr_t)symp->st_value;
+       ftp->ftps_size = (size_t)symp->st_size;
+       ftp->ftps_noffs = 1;
+       ftp->ftps_offs[0] = 0;
+
+       if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+               dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+                   strerror(errno));
+               return (dt_set_errno(dtp, errno));
+       }
+
+       return (1);
+}
+
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+
+       dt_dprintf("%s: unimplemented\n", __func__);
+
+       return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+
+       if (!ALIGNED_POINTER(off, 4))
+               return (DT_PROC_ALIGN);
+
+       ftp->ftps_type = DTFTP_OFFSETS;
+       ftp->ftps_pc = (uintptr_t)symp->st_value;
+       ftp->ftps_size = (size_t)symp->st_size;
+       ftp->ftps_noffs = 1;
+       ftp->ftps_offs[0] = off;
+
+       if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+               dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+                   strerror(errno));
+               return (dt_set_errno(dtp, errno));
+       }
+
+       return (1);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+       ulong_t i;
+
+       ftp->ftps_type = DTFTP_OFFSETS;
+       ftp->ftps_pc = (uintptr_t)symp->st_value;
+       ftp->ftps_size = (size_t)symp->st_size;
+       ftp->ftps_noffs = 0;
+
+       /*
+        * If we're matching against everything, just iterate through each
+        * instruction in the function, otherwise look for matching offset
+        * names by constructing the string and comparing it against the
+        * pattern.
+        */
+       if (strcmp("*", pattern) == 0) {
+               for (i = 0; i < symp->st_size; i += 4) {
+                       ftp->ftps_offs[ftp->ftps_noffs++] = i;
+               }
+       } else {
+               char name[sizeof (i) * 2 + 1];
+
+               for (i = 0; i < symp->st_size; i += 4) {
+                       (void) sprintf(name, "%lx", i);
+                       if (gmatch(name, pattern))
+                               ftp->ftps_offs[ftp->ftps_noffs++] = i;
+               }
+       }
+
+       if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+               dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+                   strerror(errno));
+               return (dt_set_errno(dtp, errno));
+       }
+
+       return (ftp->ftps_noffs);
+}

Modified: head/cddl/lib/Makefile
==============================================================================
--- head/cddl/lib/Makefile      Tue May 24 16:30:05 2016        (r300617)
+++ head/cddl/lib/Makefile      Tue May 24 16:41:37 2016        (r300618)
@@ -26,7 +26,7 @@ _libzpool=    libzpool
 .endif
 .endif
 
-.if ${MACHINE_CPUARCH} != "sparc64" && ${MACHINE_CPUARCH} != "riscv"
+.if ${MACHINE_CPUARCH} != "sparc64"
 _drti=         drti
 _libdtrace=    libdtrace
 .endif

Modified: head/cddl/lib/libdtrace/Makefile
==============================================================================
--- head/cddl/lib/libdtrace/Makefile    Tue May 24 16:30:05 2016        
(r300617)
+++ head/cddl/lib/libdtrace/Makefile    Tue May 24 16:41:37 2016        
(r300618)
@@ -95,6 +95,10 @@ CFLAGS+=     -I${OPENSOLARIS_SYS_DISTDIR}/ut
 CFLAGS+=       -I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc
 .PATH:         
${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/powerpc
 .PATH:         ${.CURDIR}/../../../sys/cddl/dev/dtrace/powerpc
+.elif ${MACHINE_CPUARCH} == "riscv"
+CFLAGS+=       -I${OPENSOLARIS_SYS_DISTDIR}/uts/riscv
+.PATH:         ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/riscv
+.PATH:         ${.CURDIR}/../../../sys/cddl/dev/dtrace/riscv
 .elif ${MACHINE_CPUARCH} == "sparc64"
 CFLAGS+=       -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
 .PATH:         ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc

Modified: head/cddl/usr.sbin/Makefile
==============================================================================
--- head/cddl/usr.sbin/Makefile Tue May 24 16:30:05 2016        (r300617)
+++ head/cddl/usr.sbin/Makefile Tue May 24 16:41:37 2016        (r300618)
@@ -26,7 +26,8 @@ _lockstat=    lockstat
 _plockstat=    plockstat
 .endif
 
-.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
+    ${MACHINE_CPUARCH} == "riscv"
 _dtrace=       dtrace
 _lockstat=     lockstat
 .endif

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Tue May 
24 16:30:05 2016        (r300617)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Tue May 
24 16:41:37 2016        (r300618)
@@ -12026,7 +12026,7 @@ err:
 
        *factor = 1;
 #if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
-    defined(__mips__) || defined(__powerpc__)
+    defined(__mips__) || defined(__powerpc__) || defined(__riscv__)
        /*
         * FreeBSD isn't good at limiting the amount of memory we
         * ask to malloc, so let's place a limit here before trying

Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h   Tue May 24 
16:30:05 2016        (r300617)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h   Tue May 24 
16:41:37 2016        (r300618)
@@ -2495,6 +2495,16 @@ extern void dtrace_helpers_destroy(proc_
 
 #define        DTRACE_INVOP_SD         1
 #define        DTRACE_INVOP_LD         2
+
+#elif defined(__riscv__)
+
+#define        SD_RA_SP_MASK           0x1fff07f
+#define        SD_RA_SP                0x0113023
+
+#define        DTRACE_INVOP_SD         1
+#define        DTRACE_INVOP_RET        2
+#define        DTRACE_INVOP_NOP        3
+
 #endif
 
 #ifdef __cplusplus

Added: head/sys/cddl/contrib/opensolaris/uts/riscv/dtrace/fasttrap_isa.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/uts/riscv/dtrace/fasttrap_isa.c   Tue May 
24 16:41:37 2016        (r300618)
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ *     XXX: Placeholder for RISC-V fasttrap code
+ */

Added: head/sys/cddl/contrib/opensolaris/uts/riscv/sys/fasttrap_isa.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/cddl/contrib/opensolaris/uts/riscv/sys/fasttrap_isa.h      Tue May 
24 16:41:37 2016        (r300618)
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef        _FASTTRAP_ISA_H
+#define        _FASTTRAP_ISA_H
+
+#pragma ident  "%Z%%M% %I%     %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint32_t       fasttrap_instr_t;
+
+/* XXX: Place for RISC-V fasttrap headers */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FASTTRAP_ISA_H */

Added: head/sys/cddl/dev/dtrace/riscv/dtrace_asm.S
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/cddl/dev/dtrace/riscv/dtrace_asm.S Tue May 24 16:41:37 2016        
(r300618)
@@ -0,0 +1,176 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Portions Copyright 2016 Ruslan Bukin <b...@bsdpad.com>
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#define _ASM
+#define _LOCORE
+
+#include <sys/cpuvar_defs.h>
+#include <sys/dtrace.h>
+
+#include <machine/riscvreg.h>
+#include <machine/asm.h>
+
+#include "assym.s"
+
+/*
+void dtrace_membar_producer(void)
+*/
+ENTRY(dtrace_membar_producer)
+       RET
+END(dtrace_membar_producer)
+
+/*
+void dtrace_membar_consumer(void)
+*/
+ENTRY(dtrace_membar_consumer)
+       RET
+END(dtrace_membar_consumer)
+
+/*
+dtrace_icookie_t dtrace_interrupt_disable(void)
+*/
+ENTRY(dtrace_interrupt_disable)
+       csrci   sstatus, 1
+       RET
+END(dtrace_interrupt_disable)
+
+/*
+void dtrace_interrupt_enable(dtrace_icookie_t cookie)
+*/
+ENTRY(dtrace_interrupt_enable)
+       csrsi   sstatus, 1
+       RET
+END(dtrace_interrupt_enable)
+/*
+uint8_t
+dtrace_fuword8_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword8_nocheck)
+       lb      a0, 0(a0)
+       RET
+END(dtrace_fuword8_nocheck)
+
+/*
+uint16_t
+dtrace_fuword16_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword16_nocheck)
+       lh      a0, 0(a0)
+       RET
+END(dtrace_fuword16_nocheck)
+
+/*
+uint32_t
+dtrace_fuword32_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword32_nocheck)
+       lw      a0, 0(a0)
+       RET
+END(dtrace_fuword32_nocheck)
+
+/*
+uint64_t
+dtrace_fuword64_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword64_nocheck)
+       ld      a0, 0(a0)
+       RET
+END(dtrace_fuword64_nocheck)
+
+/*
+void
+dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size)
+*/
+ENTRY(dtrace_copy)
+       beqz    a2, 2f          /* If len == 0 then skip loop */
+1:
+       lb      a4, 0(a0)       /* Load from uaddr */
+       addi    a0, a0, 1
+       sb      a4, 0(a1)       /* Store in kaddr */
+       addi    a1, a1, 1
+       addi    a2, a2, -1      /* len-- */
+       bnez    a2, 1b
+2:
+       RET
+END(dtrace_copy)
+
+/*
+void
+dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+XXX: Check for flags?
+*/
+ENTRY(dtrace_copystr)
+       beqz    a2, 2f          /* If len == 0 then skip loop */
+       lb      a4, 0(a0)       /* Load from uaddr */
+       addi    a0, a0, 1
+       sb      a4, 0(a1)       /* Store in kaddr */
+       addi    a1, a1, 1
+       beqz    a4, 2f          /* If == 0 then break */
+       addi    a2, a2, -1      /* len-- */
+       bnez    a2, 1b
+2:
+       RET
+END(dtrace_copystr)
+
+/*
+uintptr_t
+dtrace_caller(int aframes)
+*/
+ENTRY(dtrace_caller)
+       li      a0, -1
+       RET
+END(dtrace_caller)
+
+/*
+uint32_t
+dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
+*/
+ENTRY(dtrace_cas32)
+1:     lr.w    a3, 0(a0)       /* Load target */
+       bne     a3, a1, 2f      /* *target != cmp ? return */
+       sc.w    a4, a2, 0(a0)   /* Store new to target */
+       bnez    a4, 1b          /* Try again if store not succeed */
+2:     mv      a0, a3          /* Return the value loaded from target */
+       RET
+END(dtrace_cas32)
+
+/*
+void *
+dtrace_casptr(volatile void *target, volatile void *cmp, volatile void *new)
+*/
+ENTRY(dtrace_casptr)
+1:     lr.d    a3, 0(a0)       /* Load target */
+       bne     a3, a1, 2f      /* *target != cmp ? return */
+       sc.d    a4, a2, 0(a0)   /* Store new to target */
+       bnez    a4, 1b          /* Try again if store not succeed */
+2:     mv      a0, a3          /* Return the value loaded from target */
+       RET
+END(dtrace_casptr)

Added: head/sys/cddl/dev/dtrace/riscv/dtrace_isa.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/cddl/dev/dtrace/riscv/dtrace_isa.c Tue May 24 16:41:37 2016        
(r300618)
@@ -0,0 +1,394 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Portions Copyright 2016 Ruslan Bukin <b...@bsdpad.com>
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/stack.h>
+#include <sys/pcpu.h>
+
+#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <machine/reg.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <machine/atomic.h>
+#include <machine/db_machdep.h>
+#include <machine/md_var.h>
+#include <machine/stack.h>
+#include <ddb/db_sym.h>
+#include <ddb/ddb.h>
+#include <sys/kdb.h>
+
+#include "regset.h"
+
+/*
+ * Wee need some reasonable default to prevent backtrace code
+ * from wandering too far
+ */
+#define        MAX_FUNCTION_SIZE 0x10000
+#define        MAX_PROLOGUE_SIZE 0x100
+#define        MAX_USTACK_DEPTH  2048
+
+uint8_t dtrace_fuword8_nocheck(void *);
+uint16_t dtrace_fuword16_nocheck(void *);
+uint32_t dtrace_fuword32_nocheck(void *);
+uint64_t dtrace_fuword64_nocheck(void *);
+
+void
+dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
+    uint32_t *intrpc)
+{
+       struct unwind_state state;
+       int scp_offset;
+       register_t sp;
+       int depth;
+
+       depth = 0;
+
+       if (intrpc != 0) {
+               pcstack[depth++] = (pc_t) intrpc;
+       }
+
+       aframes++;
+
+       __asm __volatile("mv %0, sp" : "=&r" (sp));
+
+       state.fp = (uint64_t)__builtin_frame_address(0);
+       state.sp = sp;
+       state.pc = (uint64_t)dtrace_getpcstack;
+
+       while (depth < pcstack_limit) {
+               if (unwind_frame(&state))
+                       break;
+
+               if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+                       break;
+
+               /*
+                * NB: Unlike some other architectures, we don't need to
+                * explicitly insert cpu_dtrace_caller as it appears in the
+                * normal kernel stack trace rather than a special trap frame.
+                */
+               if (aframes > 0) {
+                       aframes--;
+               } else {
+                       pcstack[depth++] = state.pc;
+               }
+
+       }
+
+       for (; depth < pcstack_limit; depth++) {
+               pcstack[depth] = 0;
+       }
+}
+
+static int
+dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
+    uintptr_t fp)
+{
+       volatile uint16_t *flags;
+       uintptr_t oldfp;
+       int ret;
+
+       ret = 0;
+       flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
+
+       ASSERT(pcstack == NULL || pcstack_limit > 0);
+
+       while (pc != 0) {
+               /*
+                * We limit the number of times we can go around this
+                * loop to account for a circular stack.
+                */
+               if (ret++ >= MAX_USTACK_DEPTH) {
+                       *flags |= CPU_DTRACE_BADSTACK;
+                       cpu_core[curcpu].cpuc_dtrace_illval = fp;
+                       break;
+               }
+
+               if (pcstack != NULL) {
+                       *pcstack++ = (uint64_t)pc;
+                       pcstack_limit--;
+                       if (pcstack_limit <= 0)
+                               break;
+               }
+
+               if (fp == 0)
+                       break;
+
+               pc = dtrace_fuword64((void *)(fp +
+                   offsetof(struct riscv_frame, f_retaddr)));
+               fp = dtrace_fuword64((void *)fp);
+
+               if (fp == oldfp) {
+                       *flags |= CPU_DTRACE_BADSTACK;
+                       cpu_core[curcpu].cpuc_dtrace_illval = fp;
+                       break;
+               }
+       }
+
+       return (ret);
+}
+
+void
+dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
+{
+       volatile uint16_t *flags;
+       struct trapframe *tf;
+       uintptr_t pc, sp, fp;
+       proc_t *p;
+       int n;
+
+       p = curproc;
+       flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
+
+       if (*flags & CPU_DTRACE_FAULT)
+               return;
+
+       if (pcstack_limit <= 0)
+               return;
+
+       /*
+        * If there's no user context we still need to zero the stack.
+        */
+       if (p == NULL || (tf = curthread->td_frame) == NULL)
+               goto zero;
+
+       *pcstack++ = (uint64_t)p->p_pid;
+       pcstack_limit--;
+
+       if (pcstack_limit <= 0)
+               return;
+
+       pc = tf->tf_sepc;
+       sp = tf->tf_sp;
+       fp = tf->tf_s[0];
+
+       if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
+               /*
+                * In an entry probe.  The frame pointer has not yet been
+                * pushed (that happens in the function prologue).  The
+                * best approach is to add the current pc as a missing top
+                * of stack and back the pc up to the caller, which is stored
+                * at the current stack pointer address since the call
+                * instruction puts it there right before the branch.
+                */
+
+               *pcstack++ = (uint64_t)pc;
+               pcstack_limit--;
+               if (pcstack_limit <= 0)
+                       return;
+
+               pc = tf->tf_ra;
+       }
+
+       n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp);
+       ASSERT(n >= 0);
+       ASSERT(n <= pcstack_limit);
+
+       pcstack += n;
+       pcstack_limit -= n;
+
+zero:
+       while (pcstack_limit-- > 0)
+               *pcstack++ = 0;
+}
+
+int
+dtrace_getustackdepth(void)
+{
+
+       printf("IMPLEMENT ME: %s\n", __func__);
+
+       return (0);
+}
+
+void
+dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
+{
+
+       printf("IMPLEMENT ME: %s\n", __func__);
+}
+
+/*ARGSUSED*/
+uint64_t
+dtrace_getarg(int arg, int aframes)
+{
+
+       printf("IMPLEMENT ME: %s\n", __func__);
+
+       return (0);
+}
+
+int
+dtrace_getstackdepth(int aframes)
+{
+       struct unwind_state state;
+       int scp_offset;
+       register_t sp;
+       int depth;
+       int done;
+
+       depth = 1;
+       done = 0;
+
+       __asm __volatile("mv %0, sp" : "=&r" (sp));
+
+       state.fp = (uint64_t)__builtin_frame_address(0);
+       state.sp = sp;
+       state.pc = (uint64_t)dtrace_getstackdepth;
+
+       do {
+               done = unwind_frame(&state);
+               if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+                       break;
+               depth++;
+       } while (!done);
+
+       if (depth < aframes)
+               return (0);
+       else
+               return (depth - aframes);
+}
+
+ulong_t
+dtrace_getreg(struct trapframe *rp, uint_t reg)
+{
+
+       printf("IMPLEMENT ME: %s\n", __func__);
+
+       return (0);
+}
+
+static int
+dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
+{
+
+       if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {
+               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+               cpu_core[curcpu].cpuc_dtrace_illval = uaddr;
+               return (0);
+       }
+
+       return (1);
+}
+
+void
+dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+       if (dtrace_copycheck(uaddr, kaddr, size))
+               dtrace_copy(uaddr, kaddr, size);
+}
+
+void
+dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+       if (dtrace_copycheck(uaddr, kaddr, size))
+               dtrace_copy(kaddr, uaddr, size);
+}
+
+void
+dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+       if (dtrace_copycheck(uaddr, kaddr, size))
+               dtrace_copystr(uaddr, kaddr, size, flags);
+}
+
+void
+dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+       if (dtrace_copycheck(uaddr, kaddr, size))
+               dtrace_copystr(kaddr, uaddr, size, flags);
+}
+
+uint8_t
+dtrace_fuword8(void *uaddr)
+{
+
+       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               return (0);
+       }
+
+       return (dtrace_fuword8_nocheck(uaddr));
+}
+
+uint16_t
+dtrace_fuword16(void *uaddr)
+{
+
+       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               return (0);
+       }
+
+       return (dtrace_fuword16_nocheck(uaddr));
+}
+
+uint32_t
+dtrace_fuword32(void *uaddr)
+{
+
+       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               return (0);
+       }
+
+       return (dtrace_fuword32_nocheck(uaddr));
+}
+
+uint64_t
+dtrace_fuword64(void *uaddr)
+{
+
+       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               return (0);
+       }
+
+       return (dtrace_fuword64_nocheck(uaddr));
+}

Added: head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/cddl/dev/dtrace/riscv/dtrace_subr.c        Tue May 24 16:41:37 
2016        (r300618)
@@ -0,0 +1,282 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Portions Copyright 2016 Ruslan Bukin <b...@bsdpad.com>
+ *
+ * $FreeBSD$
+ *
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kmem.h>
+#include <sys/smp.h>
+#include <sys/dtrace_impl.h>
+#include <sys/dtrace_bsd.h>
+#include <machine/vmparam.h>
+#include <machine/riscvreg.h>
+#include <machine/riscv_opcode.h>
+#include <machine/clock.h>
+#include <machine/frame.h>
+#include <machine/trap.h>
+#include <vm/pmap.h>
+
+extern dtrace_id_t     dtrace_probeid_error;
+extern int (*dtrace_invop_jump_addr)(struct trapframe *);
+extern void dtrace_getnanotime(struct timespec *tsp);
+
+int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t);
+void dtrace_invop_init(void);
+void dtrace_invop_uninit(void);
+
+typedef struct dtrace_invop_hdlr {
+       int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t);
+       struct dtrace_invop_hdlr *dtih_next;
+} dtrace_invop_hdlr_t;
+
+dtrace_invop_hdlr_t *dtrace_invop_hdlr;
+
+int
+dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax)
+{
+       dtrace_invop_hdlr_t *hdlr;
+       int rval;
+
+       for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
+               if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0)
+                       return (rval);
+
+       return (0);
+}
+
+
+void
+dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
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