Index: head/sys/conf/Makefile.riscv =================================================================== --- head/sys/conf/Makefile.riscv (revision 296613) +++ head/sys/conf/Makefile.riscv (revision 296614) @@ -1,49 +1,49 @@ # Makefile.riscv -- with config changes. # Copyright 1990 W. Jolitz # from: @(#)Makefile.i386 7.1 5/10/91 # from FreeBSD: src/sys/conf/Makefile.i386,v 1.255 2002/02/20 23:35:49 # $FreeBSD$ # # Makefile for FreeBSD # # RISCVTODO: copy pasted from aarch64, needs to be # constructed from a machine description: # config machineid # Most changes should be made in the machine description # /sys/riscv/conf/``machineid'' # after which you should do # config machineid # Generic makefile changes should be made in # /sys/conf/Makefile.riscv # after which config should be rerun for all machines. # # Which version of config(8) is required. %VERSREQ= 600012 .if !defined(S) S= ../../.. .endif .include "$S/conf/kern.pre.mk" INCLUDES+= -I$S/contrib/libfdt .if !empty(DDB_ENABLED) -CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer +CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls .endif %BEFORE_DEPEND %OBJS %FILES.c %FILES.s %FILES.m %CLEAN %RULES .include "$S/conf/kern.post.mk" Index: head/sys/conf/files.riscv =================================================================== --- head/sys/conf/files.riscv (revision 296613) +++ head/sys/conf/files.riscv (revision 296614) @@ -1,47 +1,51 @@ # $FreeBSD$ crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/ofw/ofw_cpu.c optional fdt kern/kern_clocksource.c standard kern/subr_dummy_vdso_tc.c standard libkern/bcmp.c standard libkern/ffs.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/memmove.c standard libkern/memset.c standard riscv/htif/htif.c standard riscv/htif/htif_block.c standard riscv/htif/htif_console.c standard riscv/riscv/autoconf.c standard riscv/riscv/bcopy.c standard riscv/riscv/bus_machdep.c standard riscv/riscv/busdma_machdep.c standard riscv/riscv/clock.c standard riscv/riscv/copyinout.S standard riscv/riscv/copystr.c standard riscv/riscv/cpufunc_asm.S standard +riscv/riscv/db_disasm.c optional ddb +riscv/riscv/db_interface.c optional ddb +riscv/riscv/db_trace.c optional ddb riscv/riscv/devmap.c standard riscv/riscv/dump_machdep.c standard riscv/riscv/elf_machdep.c standard riscv/riscv/intr_machdep.c standard riscv/riscv/in_cksum.c optional inet | inet6 riscv/riscv/identcpu.c standard riscv/riscv/locore.S standard no-obj riscv/riscv/machdep.c standard riscv/riscv/minidump_machdep.c standard riscv/riscv/mp_machdep.c optional smp riscv/riscv/mem.c standard riscv/riscv/nexus.c standard riscv/riscv/pmap.c standard riscv/riscv/stack_machdep.c optional ddb | stack riscv/riscv/support.S standard riscv/riscv/swtch.S standard riscv/riscv/sys_machdep.c standard riscv/riscv/trap.c standard riscv/riscv/timer.c standard riscv/riscv/uio_machdep.c standard riscv/riscv/uma_machdep.c standard +riscv/riscv/unwind.c optional ddb | kdtrace_hooks | stack riscv/riscv/vm_machdep.c standard Index: head/sys/riscv/conf/GENERIC =================================================================== --- head/sys/riscv/conf/GENERIC (revision 296613) +++ head/sys/riscv/conf/GENERIC (revision 296614) @@ -1,107 +1,107 @@ # # GENERIC -- Generic kernel configuration file for FreeBSD/RISC-V # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ cpu RISCV ident GENERIC makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols # makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support makeoptions NO_MODULES=1 # We don't yet support modules on RISC-V options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling options QUOTA # Enable disk quotas for UFS options MD_ROOT # MD is a potential root device options NFSCL # Network Filesystem Client options NFSD # Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_GPT # GUID Partition Tables. # options GEOM_RAID # Soft RAID functionality. options GEOM_LABEL # Provides labelization options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support # options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options KBD_INSTALL_CDEV # install a CDEV entry in /dev # options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing options CAPABILITY_MODE # Capsicum capability mode options CAPABILITIES # Capsicum capabilities options MAC # TrustedBSD MAC Framework # options KDTRACE_FRAME # Ensure frames are compiled in # options KDTRACE_HOOKS # Kernel DTrace hooks # options VFP # Floating-point support options RACCT # Resource accounting framework options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default options RCTL # Resource limits options SMP # Uncomment for memory disk # options MD_ROOT # options MD_ROOT_SIZE=8192 # 8MB ram disk # makeoptions MFS_IMAGE=/path/to/img # options ROOTDEVNAME=\"ufs:/dev/md0\" # Debugging support. Always need this: -# options KDB # Enable kernel debugger support. -# options KDB_TRACE # Print a stack trace for a panic. +options KDB # Enable kernel debugger support. +options KDB_TRACE # Print a stack trace for a panic. # For full debugger support use (turn off in stable branch): -# options DDB # Support DDB. +options DDB # Support DDB. # options GDB # Support remote GDB. options DEADLKRES # Enable the deadlock resolver options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS # options WITNESS # Enable checks to detect deadlocks and cycles # options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones options ROOTDEVNAME=\"ufs:/dev/htif_blk0\" # options EARLY_PRINTF # Pseudo devices. device loop # Network loopback device random # Entropy device device ether # Ethernet support device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling device firmware # firmware assist module options FDT Index: head/sys/riscv/htif/htif_console.c =================================================================== --- head/sys/riscv/htif/htif_console.c (revision 296613) +++ head/sys/riscv/htif/htif_console.c (revision 296614) @@ -1,369 +1,396 @@ /*- * Copyright (c) 2015-2016 Ruslan Bukin * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "htif.h" #include #include extern uint64_t console_intr; static tsw_outwakeup_t riscvtty_outwakeup; static struct ttydevsw riscv_ttydevsw = { .tsw_flags = TF_NOPREFIX, .tsw_outwakeup = riscvtty_outwakeup, }; static int polltime; static struct callout riscv_callout; static struct tty *tp = NULL; #if defined(KDB) static int alt_break_state; #endif static void riscv_timeout(void *); static cn_probe_t riscv_cnprobe; static cn_init_t riscv_cninit; static cn_term_t riscv_cnterm; static cn_getc_t riscv_cngetc; static cn_putc_t riscv_cnputc; static cn_grab_t riscv_cngrab; static cn_ungrab_t riscv_cnungrab; CONSOLE_DRIVER(riscv); #define MAX_BURST_LEN 1 #define QUEUE_SIZE 256 #define CONSOLE_DEFAULT_ID 1ul #define SPIN_IN_MACHINE_MODE 1 struct queue_entry { uint64_t data; uint64_t used; struct queue_entry *next; }; struct queue_entry cnqueue[QUEUE_SIZE]; struct queue_entry *entry_last; struct queue_entry *entry_served; static void htif_putc(int c) { uint64_t cmd; cmd = (HTIF_CMD_WRITE << HTIF_CMD_SHIFT); cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT); cmd |= c; #ifdef SPIN_IN_MACHINE_MODE machine_command(ECALL_HTIF_LOWPUTC, cmd); #else htif_command(cmd); #endif } static uint8_t htif_getc(void) { uint64_t cmd; uint8_t res; cmd = (HTIF_CMD_READ << HTIF_CMD_SHIFT); cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT); res = htif_command(cmd); return (res); } static void riscv_putc(int c) { uint64_t counter; uint64_t *cc; uint64_t val; val = 0; counter = 0; cc = (uint64_t*)&console_intr; *cc = 0; htif_putc(c); #ifndef SPIN_IN_MACHINE_MODE /* Wait for an interrupt */ __asm __volatile( "li %0, 1\n" /* counter = 1 */ "slli %0, %0, 12\n" /* counter <<= 12 */ "1:" "addi %0, %0, -1\n" /* counter -= 1 */ "beqz %0, 2f\n" /* counter == 0 ? finish */ "ld %1, 0(%2)\n" /* val = *cc */ "beqz %1, 1b\n" /* val == 0 ? repeat */ "2:" : "=&r"(counter), "=&r"(val) : "r"(cc) ); #endif } #ifdef EARLY_PRINTF early_putc_t *early_putc = riscv_putc; #endif static void cn_drvinit(void *unused) { if (riscv_consdev.cn_pri != CN_DEAD && riscv_consdev.cn_name[0] != '\0') { tp = tty_alloc(&riscv_ttydevsw, NULL); tty_init_console(tp, 0); tty_makedev(tp, NULL, "%s", "rcons"); polltime = 1; callout_init(&riscv_callout, 1); callout_reset(&riscv_callout, polltime, riscv_timeout, NULL); } } SYSINIT(cndev, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, cn_drvinit, NULL); static void riscvtty_outwakeup(struct tty *tp) { u_char buf[MAX_BURST_LEN]; int len; int i; for (;;) { len = ttydisc_getc(tp, buf, sizeof(buf)); if (len == 0) break; KASSERT(len == 1, ("tty error")); for (i = 0; i < len; i++) riscv_putc(buf[i]); } } static void riscv_timeout(void *v) { int c; tty_lock(tp); while ((c = riscv_cngetc(NULL)) != -1) ttydisc_rint(tp, c, 0); ttydisc_rint_done(tp); tty_unlock(tp); callout_reset(&riscv_callout, polltime, riscv_timeout, NULL); } static void riscv_cnprobe(struct consdev *cp) { cp->cn_pri = CN_NORMAL; } static void riscv_cninit(struct consdev *cp) { int i; strcpy(cp->cn_name, "rcons"); for (i = 0; i < QUEUE_SIZE; i++) { if (i == (QUEUE_SIZE - 1)) cnqueue[i].next = &cnqueue[0]; else cnqueue[i].next = &cnqueue[i+1]; cnqueue[i].data = 0; cnqueue[i].used = 0; } entry_last = &cnqueue[0]; entry_served = &cnqueue[0]; } static void riscv_cnterm(struct consdev *cp) { } static void riscv_cngrab(struct consdev *cp) { } static void riscv_cnungrab(struct consdev *cp) { } static int riscv_cngetc(struct consdev *cp) { +#if defined(KDB) + uint64_t devcmd; + uint64_t entry; + uint64_t devid; +#endif uint8_t data; int ch; - ch = htif_getc(); + htif_getc(); + +#if defined(KDB) + if (kdb_active) { + entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); + while (entry) { + devid = HTIF_DEV_ID(entry); + devcmd = HTIF_DEV_CMD(entry); + data = HTIF_DEV_DATA(entry); + + if (devid == CONSOLE_DEFAULT_ID && devcmd == 0) { + entry_last->data = data; + entry_last->used = 1; + entry_last = entry_last->next; + } else { + printf("Lost interrupt: devid %d\n", + devid); + } + + entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); + } + } +#endif if (entry_served->used == 1) { data = entry_served->data; entry_served->used = 0; entry_served = entry_served->next; ch = (data & 0xff); if (ch > 0 && ch < 0xff) { #if defined(KDB) kdb_alt_break(ch, &alt_break_state); #endif return (ch); } } return (-1); } static void riscv_cnputc(struct consdev *cp, int c) { riscv_putc(c); } /* * Bus interface. */ struct htif_console_softc { device_t dev; int running; int intr_chan; int cmd_done; int curtag; int index; }; static void htif_console_intr(void *arg, uint64_t entry) { struct htif_console_softc *sc; uint8_t devcmd; uint64_t data; sc = arg; devcmd = HTIF_DEV_CMD(entry); data = HTIF_DEV_DATA(entry); if (devcmd == 0) { entry_last->data = data; entry_last->used = 1; entry_last = entry_last->next; } } static int htif_console_probe(device_t dev) { return (0); } static int htif_console_attach(device_t dev) { struct htif_console_softc *sc; sc = device_get_softc(dev); sc->dev = dev; sc->index = htif_get_index(dev); if (sc->index < 0) return (EINVAL); htif_setup_intr(sc->index, htif_console_intr, sc); return (0); } static device_method_t htif_console_methods[] = { DEVMETHOD(device_probe, htif_console_probe), DEVMETHOD(device_attach, htif_console_attach), DEVMETHOD_END }; static driver_t htif_console_driver = { "htif_console", htif_console_methods, sizeof(struct htif_console_softc) }; static devclass_t htif_console_devclass; DRIVER_MODULE(htif_console, htif, htif_console_driver, htif_console_devclass, 0, 0); Index: head/sys/riscv/include/db_machdep.h =================================================================== --- head/sys/riscv/include/db_machdep.h (revision 296613) +++ head/sys/riscv/include/db_machdep.h (revision 296614) @@ -1,47 +1,91 @@ /*- - * Copyright (c) 2015 Ruslan Bukin + * Copyright (c) 2015-2016 Ruslan Bukin * 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_DB_MACHDEP_H_ #define _MACHINE_DB_MACHDEP_H_ #include #include #include +#define T_BREAKPOINT (EXCP_INSTR_BREAKPOINT) +#define T_WATCHPOINT (0) + typedef vm_offset_t db_addr_t; typedef long db_expr_t; + +#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_sepc) + +#define BKPT_INST (0x00100073) +#define BKPT_SIZE (INSN_SIZE) +#define BKPT_SET(inst) (BKPT_INST) + +#define BKPT_SKIP do { \ + kdb_frame->tf_sepc += BKPT_SIZE; \ +} while (0) + +#define db_clear_single_step kdb_cpu_clear_singlestep +#define db_set_single_step kdb_cpu_set_singlestep + +#define IS_BREAKPOINT_TRAP(type, code) (type == T_BREAKPOINT) +#define IS_WATCHPOINT_TRAP(type, code) (type == T_WATCHPOINT) + +#define inst_trap_return(ins) (ins == 0x10000073) /* eret */ +#define inst_return(ins) (ins == 0x00008067) /* ret */ +#define inst_call(ins) (((ins) & 0x7f) == 111 || \ + ((ins) & 0x7f) == 103) /* jal, jalr */ + +#define inst_load(ins) ({ \ + uint32_t tmp_instr = db_get_value(PC_REGS(), sizeof(uint32_t), FALSE); \ + is_load_instr(tmp_instr); \ +}) + +#define inst_store(ins) ({ \ + uint32_t tmp_instr = db_get_value(PC_REGS(), sizeof(uint32_t), FALSE); \ + is_store_instr(tmp_instr); \ +}) + +#define is_load_instr(ins) (((ins) & 0x7f) == 3) +#define is_store_instr(ins) (((ins) & 0x7f) == 35) + +#define next_instr_address(pc, bd) ((bd) ? (pc) : ((pc) + 4)) + +#define DB_SMALL_VALUE_MAX (0x7fffffff) +#define DB_SMALL_VALUE_MIN (-0x40001) + +#define DB_ELFSIZE 64 #endif /* !_MACHINE_DB_MACHDEP_H_ */ Index: head/sys/riscv/include/riscv_opcode.h =================================================================== --- head/sys/riscv/include/riscv_opcode.h (nonexistent) +++ head/sys/riscv/include/riscv_opcode.h (revision 296614) @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin + * 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 + +/* + * 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_ */ Property changes on: head/sys/riscv/include/riscv_opcode.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/riscv/include/riscvreg.h =================================================================== --- head/sys/riscv/include/riscvreg.h (revision 296613) +++ head/sys/riscv/include/riscvreg.h (revision 296614) @@ -1,164 +1,165 @@ /*- * Copyright (c) 2015-2016 Ruslan Bukin * 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_RISCVREG_H_ #define _MACHINE_RISCVREG_H_ /* Machine mode requests */ #define ECALL_MTIMECMP 0x01 #define ECALL_CLEAR_PENDING 0x02 #define ECALL_HTIF_CMD 0x03 #define ECALL_HTIF_GET_ENTRY 0x04 #define ECALL_MCPUID_GET 0x05 #define ECALL_MIMPID_GET 0x06 #define ECALL_SEND_IPI 0x07 #define ECALL_CLEAR_IPI 0x08 #define ECALL_HTIF_LOWPUTC 0x09 #define ECALL_MIE_SET 0x10 #define EXCP_SHIFT 0 #define EXCP_MASK (0xf << EXCP_SHIFT) #define EXCP_INSTR_ADDR_MISALIGNED 0 #define EXCP_INSTR_ACCESS_FAULT 1 #define EXCP_INSTR_ILLEGAL 2 #define EXCP_INSTR_BREAKPOINT 3 #define EXCP_LOAD_ADDR_MISALIGNED 4 #define EXCP_LOAD_ACCESS_FAULT 5 #define EXCP_STORE_ADDR_MISALIGNED 6 #define EXCP_STORE_ACCESS_FAULT 7 #define EXCP_UMODE_ENV_CALL 8 #define EXCP_SMODE_ENV_CALL 9 #define EXCP_HMODE_ENV_CALL 10 #define EXCP_MMODE_ENV_CALL 11 #define EXCP_INTR (1 << 31) #define EXCP_INTR_SOFTWARE 0 #define EXCP_INTR_TIMER 1 #define EXCP_INTR_HTIF 2 #define SSTATUS_IE (1 << 0) #define SSTATUS_PIE (1 << 3) #define SSTATUS_PS (1 << 4) #define MSTATUS_MPRV (1 << 16) #define MSTATUS_PRV_SHIFT 1 #define MSTATUS_PRV1_SHIFT 4 #define MSTATUS_PRV2_SHIFT 7 #define MSTATUS_PRV_MASK (0x3 << MSTATUS_PRV_SHIFT) #define MSTATUS_PRV_U 0 /* user */ #define MSTATUS_PRV_S 1 /* supervisor */ #define MSTATUS_PRV_H 2 /* hypervisor */ #define MSTATUS_PRV_M 3 /* machine */ #define MSTATUS_VM_SHIFT 17 #define MSTATUS_VM_MASK 0x1f #define MSTATUS_VM_MBARE 0 #define MSTATUS_VM_MBB 1 #define MSTATUS_VM_MBBID 2 #define MSTATUS_VM_SV32 8 #define MSTATUS_VM_SV39 9 #define MSTATUS_VM_SV48 10 #define MIE_SSIE (1 << 1) #define MIE_HSIE (1 << 2) #define MIE_MSIE (1 << 3) #define MIE_STIE (1 << 5) #define MIE_HTIE (1 << 6) #define MIE_MTIE (1 << 7) #define MIP_SSIP (1 << 1) #define MIP_HSIP (1 << 2) #define MIP_MSIP (1 << 3) #define MIP_STIP (1 << 5) #define MIP_HTIP (1 << 6) #define MIP_MTIP (1 << 7) #define SR_IE (1 << 0) #define SR_IE1 (1 << 3) #define SR_IE2 (1 << 6) #define SR_IE3 (1 << 9) #define SIE_SSIE (1 << 1) #define SIE_STIE (1 << 5) /* Note: sip register has no SIP_STIP bit in Spike simulator */ #define SIP_SSIP (1 << 1) #define SIP_STIP (1 << 5) -#define NCSRS 4096 -#define CSR_IPI 0x783 -#define XLEN 8 +#define NCSRS 4096 +#define CSR_IPI 0x783 +#define XLEN 8 +#define INSN_SIZE 4 #define CSR_ZIMM(val) \ (__builtin_constant_p(val) && ((u_long)(val) < 32)) #define csr_swap(csr, val) \ ({ if (CSR_ZIMM(val)) \ __asm __volatile("csrrwi %0, " #csr ", %1" \ : "=r" (val) : "i" (val)); \ else \ __asm __volatile("csrrw %0, " #csr ", %1" \ : "=r" (val) : "r" (val)); \ val; \ }) #define csr_write(csr, val) \ ({ if (CSR_ZIMM(val)) \ __asm __volatile("csrwi " #csr ", %0" :: "i" (val)); \ else \ __asm __volatile("csrw " #csr ", %0" :: "r" (val)); \ }) #define csr_set(csr, val) \ ({ if (CSR_ZIMM(val)) \ __asm __volatile("csrsi " #csr ", %0" :: "i" (val)); \ else \ __asm __volatile("csrs " #csr ", %0" :: "r" (val)); \ }) #define csr_clear(csr, val) \ ({ if (CSR_ZIMM(val)) \ __asm __volatile("csrci " #csr ", %0" :: "i" (val)); \ else \ __asm __volatile("csrc " #csr ", %0" :: "r" (val)); \ }) #define csr_read(csr) \ ({ u_long val; \ __asm __volatile("csrr %0, " #csr : "=r" (val)); \ val; \ }) #endif /* !_MACHINE_RISCVREG_H_ */ Index: head/sys/riscv/include/stack.h =================================================================== --- head/sys/riscv/include/stack.h (nonexistent) +++ head/sys/riscv/include/stack.h (revision 296614) @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin + * 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_STACK_H_ +#define _MACHINE_STACK_H_ + +#define INKERNEL(va) ((va) >= VM_MIN_KERNEL_ADDRESS && \ + (va) <= VM_MAX_KERNEL_ADDRESS) + +struct unwind_state { + uint64_t fp; + uint64_t sp; + uint64_t pc; +}; + +int unwind_frame(struct unwind_state *); + +#endif /* !_MACHINE_STACK_H_ */ Property changes on: head/sys/riscv/include/stack.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/riscv/riscv/db_disasm.c =================================================================== --- head/sys/riscv/riscv/db_disasm.c (nonexistent) +++ head/sys/riscv/riscv/db_disasm.c (revision 296614) @@ -0,0 +1,475 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +struct riscv_op { + char *name; + char *type; + char *fmt; + int opcode; + int funct3; + int funct7; /* Or imm, depending on type. */ +}; + +/* + * Keep sorted by opcode, funct3, funct7 so some instructions + * aliases will be supported (e.g. "mv" instruction alias) + * Use same print format as binutils do. + */ +static struct riscv_op riscv_opcodes[] = { + { "lb", "I", "d,o(s)", 3, 0, -1 }, + { "lh", "I", "d,o(s)", 3, 1, -1 }, + { "lw", "I", "d,o(s)", 3, 2, -1 }, + { "ld", "I", "d,o(s)", 3, 3, -1 }, + { "lbu", "I", "d,o(s)", 3, 4, -1 }, + { "lhu", "I", "d,o(s)", 3, 5, -1 }, + { "lwu", "I", "d,o(s)", 3, 6, -1 }, + { "ldu", "I", "d,o(s)", 3, 7, -1 }, + { "fence", "I", "", 15, 0, -1 }, + { "fence.i", "I", "", 15, 1, -1 }, + { "mv", "I", "d,s", 19, 0, 0 }, + { "addi", "I", "d,s,j", 19, 0, -1 }, + { "slli", "R2", "d,s,>", 19, 1, 0 }, + { "slti", "I", "d,s,j", 19, 2, -1 }, + { "sltiu", "I", "d,s,j", 19, 3, -1 }, + { "xori", "I", "d,s,j", 19, 4, -1 }, + { "srli", "R2", "d,s,>", 19, 5, 0 }, + { "srai", "R2", "d,s,>", 19, 5, 0b010000 }, + { "ori", "I", "d,s,j", 19, 6, -1 }, + { "andi", "I", "d,s,j", 19, 7, -1 }, + { "auipc", "U", "d,u", 23, -1, -1 }, + { "sext.w", "I", "d,s", 27, 0, 0 }, + { "addiw", "I", "d,s,j", 27, 0, -1 }, + { "slliw", "R", "d,s,<", 27, 1, 0 }, + { "srliw", "R", "d,s,<", 27, 5, 0 }, + { "sraiw", "R", "d,s,<", 27, 5, 0b0100000 }, + { "sb", "S", "t,q(s)", 35, 0, -1 }, + { "sh", "S", "t,q(s)", 35, 1, -1 }, + { "sw", "S", "t,q(s)", 35, 2, -1 }, + { "sd", "S", "t,q(s)", 35, 3, -1 }, + { "sbu", "S", "t,q(s)", 35, 4, -1 }, + { "shu", "S", "t,q(s)", 35, 5, -1 }, + { "swu", "S", "t,q(s)", 35, 6, -1 }, + { "sdu", "S", "t,q(s)", 35, 7, -1 }, + { "lr.w", "R", "d,t,0(s)", 47, 2, 0b0001000 }, + { "sc.w", "R", "d,t,0(s)", 47, 2, 0b0001100 }, + { "amoswap.w", "R", "d,t,0(s)", 47, 2, 0b0000100 }, + { "amoadd.w", "R", "d,t,0(s)", 47, 2, 0b0000000 }, + { "amoxor.w", "R", "d,t,0(s)", 47, 2, 0b0010000 }, + { "amoand.w", "R", "d,t,0(s)", 47, 2, 0b0110000 }, + { "amoor.w", "R", "d,t,0(s)", 47, 2, 0b0100000 }, + { "amomin.w", "R", "d,t,0(s)", 47, 2, 0b1000000 }, + { "amomax.w", "R", "d,t,0(s)", 47, 2, 0b1010000 }, + { "amominu.w", "R", "d,t,0(s)", 47, 2, 0b1100000 }, + { "amomaxu.w", "R", "d,t,0(s)", 47, 2, 0b1110000 }, + { "lr.w.aq", "R", "d,t,0(s)", 47, 2, 0b0001000 }, + { "sc.w.aq", "R", "d,t,0(s)", 47, 2, 0b0001100 }, + { "amoswap.w.aq","R", "d,t,0(s)", 47, 2, 0b0000110 }, + { "amoadd.w.aq","R", "d,t,0(s)", 47, 2, 0b0000010 }, + { "amoxor.w.aq","R", "d,t,0(s)", 47, 2, 0b0010010 }, + { "amoand.w.aq","R", "d,t,0(s)", 47, 2, 0b0110010 }, + { "amoor.w.aq", "R", "d,t,0(s)", 47, 2, 0b0100010 }, + { "amomin.w.aq","R", "d,t,0(s)", 47, 2, 0b1000010 }, + { "amomax.w.aq","R", "d,t,0(s)", 47, 2, 0b1010010 }, + { "amominu.w.aq","R", "d,t,0(s)", 47, 2, 0b1100010 }, + { "amomaxu.w.aq","R", "d,t,0(s)", 47, 2, 0b1110010 }, + { "amoswap.w.rl","R", "d,t,0(s)", 47, 2, 0b0000110 }, + { "amoadd.w.rl","R", "d,t,0(s)", 47, 2, 0b0000001 }, + { "amoxor.w.rl","R", "d,t,0(s)", 47, 2, 0b0010001 }, + { "amoand.w.rl","R", "d,t,0(s)", 47, 2, 0b0110001 }, + { "amoor.w.rl", "R", "d,t,0(s)", 47, 2, 0b0100001 }, + { "amomin.w.rl","R", "d,t,0(s)", 47, 2, 0b1000001 }, + { "amomax.w.rl","R", "d,t,0(s)", 47, 2, 0b1010001 }, + { "amominu.w.rl","R", "d,t,0(s)", 47, 2, 0b1100001 }, + { "amomaxu.w.rl","R", "d,t,0(s)", 47, 2, 0b1110001 }, + { "amoswap.d", "R", "d,t,0(s)", 47, 3, 0b0000100 }, + { "amoadd.d", "R", "d,t,0(s)", 47, 3, 0b0000000 }, + { "amoxor.d", "R", "d,t,0(s)", 47, 3, 0b0010000 }, + { "amoand.d", "R", "d,t,0(s)", 47, 3, 0b0110000 }, + { "amoor.d", "R", "d,t,0(s)", 47, 3, 0b0100000 }, + { "amomin.d", "R", "d,t,0(s)", 47, 3, 0b1000000 }, + { "amomax.d", "R", "d,t,0(s)", 47, 3, 0b1010000 }, + { "amominu.d", "R", "d,t,0(s)", 47, 3, 0b1100000 }, + { "amomaxu.d", "R", "d,t,0(s)", 47, 3, 0b1110000 }, + { "lr.d.aq", "R", "d,t,0(s)", 47, 3, 0b0001000 }, + { "sc.d.aq", "R", "d,t,0(s)", 47, 3, 0b0001100 }, + { "amoswap.d.aq","R", "d,t,0(s)", 47, 3, 0b0000110 }, + { "amoadd.d.aq","R", "d,t,0(s)", 47, 3, 0b0000010 }, + { "amoxor.d.aq","R", "d,t,0(s)", 47, 3, 0b0010010 }, + { "amoand.d.aq","R", "d,t,0(s)", 47, 3, 0b0110010 }, + { "amoor.d.aq", "R", "d,t,0(s)", 47, 3, 0b0100010 }, + { "amomin.d.aq","R", "d,t,0(s)", 47, 3, 0b1000010 }, + { "amomax.d.aq","R", "d,t,0(s)", 47, 3, 0b1010010 }, + { "amominu.d.aq","R", "d,t,0(s)", 47, 3, 0b1100010 }, + { "amomaxu.d.aq","R", "d,t,0(s)", 47, 3, 0b1110010 }, + { "amoswap.d.rl","R", "d,t,0(s)", 47, 3, 0b0000110 }, + { "amoadd.d.rl","R", "d,t,0(s)", 47, 3, 0b0000001 }, + { "amoxor.d.rl","R", "d,t,0(s)", 47, 3, 0b0010001 }, + { "amoand.d.rl","R", "d,t,0(s)", 47, 3, 0b0110001 }, + { "amoor.d.rl", "R", "d,t,0(s)", 47, 3, 0b0100001 }, + { "amomin.d.rl","R", "d,t,0(s)", 47, 3, 0b1000001 }, + { "amomax.d.rl","R", "d,t,0(s)", 47, 3, 0b1010001 }, + { "amominu.d.rl","R", "d,t,0(s)", 47, 3, 0b1100001 }, + { "amomaxu.d.rl","R", "d,t,0(s)", 47, 3, 0b1110001 }, + { "add", "R", "d,s,t", 51, 0, 0 }, + { "sub", "R", "d,s,t", 51, 0, 0b0100000 }, + { "mul", "R", "d,s,t", 51, 0, 0b0000001 }, + { "sll", "R", "d,s,t", 51, 1, 0 }, + { "slt", "R", "d,s,t", 51, 2, 0 }, + { "sltu", "R", "d,s,t", 51, 3, 0 }, + { "xor", "R", "d,s,t", 51, 4, 0 }, + { "srl", "R", "d,s,t", 51, 5, 0 }, + { "sra", "R", "d,s,t", 51, 5, 0b0100000 }, + { "or", "R", "d,s,t", 51, 6, 0 }, + { "and", "R", "d,s,t", 51, 7, 0 }, + { "lui", "U", "d,u", 55, -1, -1 }, + { "addw", "R", "d,s,t", 59, 0, 0 }, + { "subw", "R", "d,s,t", 59, 0, 0b0100000 }, + { "mulw", "R", "d,s,t", 59, 0, 1 }, + { "sllw", "R", "d,s,t", 59, 1, 0 }, + { "srlw", "R", "d,s,t", 59, 5, 0 }, + { "sraw", "R", "d,s,t", 59, 5, 0b0100000 }, + { "beq", "SB", "s,t,p", 99, 0, -1 }, + { "bne", "SB", "s,t,p", 99, 1, -1 }, + { "blt", "SB", "s,t,p", 99, 4, -1 }, + { "bge", "SB", "s,t,p", 99, 5, -1 }, + { "bltu", "SB", "s,t,p", 99, 6, -1 }, + { "bgeu", "SB", "s,t,p", 99, 7, -1 }, + { "jalr", "I", "d,s,j", 103, 0, -1 }, + { "jal", "UJ", "a", 111, -1, -1 }, + { "eret", "I", "", 115, 0, 0b000100000000 }, + { "sfence.vm", "I", "", 115, 0, 0b000100000001 }, + { "wfi", "I", "", 115, 0, 0b000100000010 }, + { "csrrw", "I", "d,E,s", 115, 1, -1}, + { "csrrs", "I", "d,E,s", 115, 2, -1}, + { "csrrc", "I", "d,E,s", 115, 3, -1}, + { "csrrwi", "I", "d,E,Z", 115, 5, -1}, + { "csrrsi", "I", "d,E,Z", 115, 6, -1}, + { "csrrci", "I", "d,E,Z", 115, 7, -1}, + { NULL, NULL, NULL, 0, 0, 0 } +}; + +struct csr_op { + char *name; + int imm; +}; + +static struct csr_op csr_name[] = { + { "fflags", 0x001 }, + { "frm", 0x002 }, + { "fcsr", 0x003 }, + { "cycle", 0xc00 }, + { "time", 0xc01 }, + { "instret", 0xc02 }, + { "stats", 0x0c0 }, + { "uarch0", 0xcc0 }, + { "uarch1", 0xcc1 }, + { "uarch2", 0xcc2 }, + { "uarch3", 0xcc3 }, + { "uarch4", 0xcc4 }, + { "uarch5", 0xcc5 }, + { "uarch6", 0xcc6 }, + { "uarch7", 0xcc7 }, + { "uarch8", 0xcc8 }, + { "uarch9", 0xcc9 }, + { "uarch10", 0xcca }, + { "uarch11", 0xccb }, + { "uarch12", 0xccc }, + { "uarch13", 0xccd }, + { "uarch14", 0xcce }, + { "uarch15", 0xccf }, + { "sstatus", 0x100 }, + { "stvec", 0x101 }, + { "sie", 0x104 }, + { "sscratch", 0x140 }, + { "sepc", 0x141 }, + { "sip", 0x144 }, + { "sptbr", 0x180 }, + { "sasid", 0x181 }, + { "cyclew", 0x900 }, + { "timew", 0x901 }, + { "instretw", 0x902 }, + { "stime", 0xd01 }, + { "scause", 0xd42 }, + { "sbadaddr", 0xd43 }, + { "stimew", 0xa01 }, + { "mstatus", 0x300 }, + { "mtvec", 0x301 }, + { "mtdeleg", 0x302 }, + { "mie", 0x304 }, + { "mtimecmp", 0x321 }, + { "mscratch", 0x340 }, + { "mepc", 0x341 }, + { "mcause", 0x342 }, + { "mbadaddr", 0x343 }, + { "mip", 0x344 }, + { "mtime", 0x701 }, + { "mcpuid", 0xf00 }, + { "mimpid", 0xf01 }, + { "mhartid", 0xf10 }, + { "mtohost", 0x780 }, + { "mfromhost", 0x781 }, + { "mreset", 0x782 }, + { "send_ipi", 0x783 }, + { "miobase", 0x784 }, + { "cycleh", 0xc80 }, + { "timeh", 0xc81 }, + { "instreth", 0xc82 }, + { "cyclehw", 0x980 }, + { "timehw", 0x981 }, + { "instrethw", 0x982 }, + { "stimeh", 0xd81 }, + { "stimehw", 0xa81 }, + { "mtimecmph", 0x361 }, + { "mtimeh", 0x741 }, + { NULL, 0 } +}; + +static char *reg_name[32] = { + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" +}; + +static int32_t +get_imm(InstFmt i, char *type, uint32_t *val) +{ + int imm; + + imm = 0; + + if (strcmp(type, "I") == 0) { + imm = i.IType.imm; + *val = imm; + if (imm & (1 << 11)) + imm |= (0xfffff << 12); /* sign extend */ + + } else if (strcmp(type, "S") == 0) { + imm = i.SType.imm0_4; + imm |= (i.SType.imm5_11 << 5); + *val = imm; + if (imm & (1 << 11)) + imm |= (0xfffff << 12); /* sign extend */ + + } else if (strcmp(type, "U") == 0) { + imm = i.UType.imm12_31; + *val = imm; + + } else if (strcmp(type, "UJ") == 0) { + imm = i.UJType.imm12_19 << 12; + imm |= i.UJType.imm11 << 11; + imm |= i.UJType.imm1_10 << 1; + imm |= i.UJType.imm20 << 20; + *val = imm; + if (imm & (1 << 20)) + imm |= (0xfff << 21); /* sign extend */ + + } else if (strcmp(type, "SB") == 0) { + imm = i.SBType.imm11 << 11; + imm |= i.SBType.imm1_4 << 1; + imm |= i.SBType.imm5_10 << 5; + imm |= i.SBType.imm12 << 12; + *val = imm; + if (imm & (1 << 12)) + imm |= (0xfffff << 12); /* sign extend */ + } + + return (imm); +} + +static int +oprint(struct riscv_op *op, vm_offset_t loc, int rd, + int rs1, int rs2, uint32_t val, vm_offset_t imm) +{ + char *p; + int i; + + p = op->fmt; + + db_printf("%s\t", op->name); + + while (*p) { + if (strncmp("d", p, 1) == 0) + db_printf("%s", reg_name[rd]); + + else if (strncmp("s", p, 1) == 0) + db_printf("%s", reg_name[rs1]); + + else if (strncmp("t", p, 1) == 0) + db_printf("%s", reg_name[rs2]); + + else if (strncmp(">", p, 1) == 0) + db_printf("0x%x", rs2); + + else if (strncmp("E", p, 1) == 0) { + for (i = 0; csr_name[i].name != NULL; i++) + if (csr_name[i].imm == val) + db_printf("%s", + csr_name[i].name); + } else if (strncmp("Z", p, 1) == 0) + db_printf("%d", rs1); + + else if (strncmp("<", p, 1) == 0) + db_printf("0x%x", rs2); + + else if (strncmp("j", p, 1) == 0) + db_printf("%d", imm); + + else if (strncmp("u", p, 1) == 0) + db_printf("0x%x", imm); + + else if (strncmp("a", p, 1) == 0) + db_printf("0x%016lx", imm); + + else if (strncmp("p", p, 1) == 0) + db_printf("0x%016lx", (loc + imm)); + + else if (strlen(p) >= 4) { + if (strncmp("o(s)", p, 4) == 0) + db_printf("%d(%s)", imm, reg_name[rs1]); + else if (strncmp("q(s)", p, 4) == 0) + db_printf("%d(%s)", imm, reg_name[rs1]); + else if (strncmp("0(s)", p, 4) == 0) + db_printf("(%s)", reg_name[rs1]); + } + + while (*p && strncmp(p, ",", 1) != 0) + p++; + + if (*p) { + db_printf(", "); + p++; + } + } + + + return (0); +} + +static int +match_type(InstFmt i, struct riscv_op *op, vm_offset_t loc) +{ + uint32_t val; + int found; + int imm; + + val = 0; + imm = get_imm(i, op->type, &val); + + if (strcmp(op->type, "U") == 0) { + oprint(op, loc, i.UType.rd, 0, 0, val, imm); + return (1); + } + if (strcmp(op->type, "UJ") == 0) { + oprint(op, loc, 0, 0, 0, val, (loc + imm)); + return (1); + } + if ((strcmp(op->type, "I") == 0) && \ + (op->funct3 == i.IType.funct3)) { + found = 0; + if (op->funct7 != -1) { + if (op->funct7 == i.IType.imm) + found = 1; + } else + found = 1; + + if (found) { + oprint(op, loc, i.IType.rd, + i.IType.rs1, 0, val, imm); + return (1); + } + } + if ((strcmp(op->type, "S") == 0) && \ + (op->funct3 == i.SType.funct3)) { + oprint(op, loc, 0, i.SType.rs1, i.SType.rs2, + val, imm); + return (1); + } + if ((strcmp(op->type, "SB") == 0) && \ + (op->funct3 == i.SBType.funct3)) { + oprint(op, loc, 0, i.SBType.rs1, i.SBType.rs2, + val, imm); + return (1); + } + if ((strcmp(op->type, "R2") == 0) && \ + (op->funct3 == i.R2Type.funct3) && \ + (op->funct7 == i.R2Type.funct7)) { + oprint(op, loc, i.R2Type.rd, i.R2Type.rs1, + i.R2Type.rs2, val, imm); + return (1); + } + if ((strcmp(op->type, "R") == 0) && \ + (op->funct3 == i.RType.funct3) && \ + (op->funct7 == i.RType.funct7)) { + oprint(op, loc, i.RType.rd, i.RType.rs1, + val, i.RType.rs2, imm); + return (1); + } + + return (0); +} + +vm_offset_t +db_disasm(vm_offset_t loc, bool altfmt) +{ + struct riscv_op *op; + InstFmt i; + int j; + + i.word = db_get_value(loc, INSN_SIZE, 0); + + /* First match opcode */ + for (j = 0; riscv_opcodes[j].name != NULL; j++) { + op = &riscv_opcodes[j]; + if (op->opcode == i.RType.opcode) { + if (match_type(i, op, loc)) + break; + } + } + + db_printf("\n"); + return(loc + INSN_SIZE); +} Property changes on: head/sys/riscv/riscv/db_disasm.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/riscv/riscv/db_interface.c =================================================================== --- head/sys/riscv/riscv/db_interface.c (nonexistent) +++ head/sys/riscv/riscv/db_interface.c (revision 296614) @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Semihalf under + * the sponsorship of the FreeBSD Foundation. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include + +#ifdef KDB +#include +#endif + +#include +#include + +#include +#include +#include +#include + +static int +db_frame(struct db_variable *vp, db_expr_t *valuep, int op) +{ + long *reg; + + if (kdb_frame == NULL) + return (0); + + reg = (long *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); + if (op == DB_VAR_GET) + *valuep = *reg; + else + *reg = *valuep; + return (1); +} + +#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) +struct db_variable db_regs[] = { + { "ra", DB_OFFSET(tf_ra), db_frame }, + { "sp", DB_OFFSET(tf_sp), db_frame }, + { "gp", DB_OFFSET(tf_gp), db_frame }, + { "tp", DB_OFFSET(tf_tp), db_frame }, + { "t0", DB_OFFSET(tf_t[0]), db_frame }, + { "t1", DB_OFFSET(tf_t[1]), db_frame }, + { "t2", DB_OFFSET(tf_t[2]), db_frame }, + { "t3", DB_OFFSET(tf_t[3]), db_frame }, + { "t4", DB_OFFSET(tf_t[4]), db_frame }, + { "t5", DB_OFFSET(tf_t[5]), db_frame }, + { "t6", DB_OFFSET(tf_t[6]), db_frame }, + { "s0", DB_OFFSET(tf_s[0]), db_frame }, + { "s1", DB_OFFSET(tf_s[1]), db_frame }, + { "s2", DB_OFFSET(tf_s[2]), db_frame }, + { "s3", DB_OFFSET(tf_s[3]), db_frame }, + { "s4", DB_OFFSET(tf_s[4]), db_frame }, + { "s5", DB_OFFSET(tf_s[5]), db_frame }, + { "s6", DB_OFFSET(tf_s[6]), db_frame }, + { "s7", DB_OFFSET(tf_s[7]), db_frame }, + { "s8", DB_OFFSET(tf_s[8]), db_frame }, + { "s9", DB_OFFSET(tf_s[9]), db_frame }, + { "s10", DB_OFFSET(tf_s[10]), db_frame }, + { "s11", DB_OFFSET(tf_s[11]), db_frame }, + { "a0", DB_OFFSET(tf_a[0]), db_frame }, + { "a1", DB_OFFSET(tf_a[1]), db_frame }, + { "a2", DB_OFFSET(tf_a[2]), db_frame }, + { "a3", DB_OFFSET(tf_a[3]), db_frame }, + { "a4", DB_OFFSET(tf_a[4]), db_frame }, + { "a5", DB_OFFSET(tf_a[5]), db_frame }, + { "a6", DB_OFFSET(tf_a[6]), db_frame }, + { "a7", DB_OFFSET(tf_a[7]), db_frame }, + { "sepc", DB_OFFSET(tf_sepc), db_frame }, + { "sstatus", DB_OFFSET(tf_sstatus), db_frame }, + { "sbadaddr", DB_OFFSET(tf_sbadaddr), db_frame }, + { "scause", DB_OFFSET(tf_scause), db_frame }, +}; + +struct db_variable *db_eregs = db_regs + nitems(db_regs); + +void +db_show_mdpcpu(struct pcpu *pc) +{ +} + +/* + * Read bytes from kernel address space for debugger. + */ +int +db_read_bytes(vm_offset_t addr, size_t size, char *data) +{ + jmp_buf jb; + void *prev_jb; + const char *src; + int ret; + + prev_jb = kdb_jmpbuf(jb); + ret = setjmp(jb); + + if (ret == 0) { + src = (const char *)addr; + while (size-- > 0) + *data++ = *src++; + } + (void)kdb_jmpbuf(prev_jb); + + return (ret); +} + +/* + * Write bytes to kernel address space for debugger. + */ +int +db_write_bytes(vm_offset_t addr, size_t size, char *data) +{ + jmp_buf jb; + void *prev_jb; + char *dst; + int ret; + + prev_jb = kdb_jmpbuf(jb); + ret = setjmp(jb); + if (ret == 0) { + dst = (char *)addr; + while (size-- > 0) + *dst++ = *data++; + + fence(); + + /* Clean D-cache and invalidate I-cache */ + cpu_dcache_wb_range(addr, (vm_size_t)size); + cpu_icache_sync_range(addr, (vm_size_t)size); + } + (void)kdb_jmpbuf(prev_jb); + + return (ret); +} Property changes on: head/sys/riscv/riscv/db_interface.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/riscv/riscv/db_trace.c =================================================================== --- head/sys/riscv/riscv/db_trace.c (nonexistent) +++ head/sys/riscv/riscv/db_trace.c (revision 296614) @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * Copyright (c) 2016 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by Semihalf under + * the sponsorship of the FreeBSD Foundation. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include + +#include +#include + +void +db_md_list_watchpoints() +{ + +} + +int +db_md_clr_watchpoint(db_expr_t addr, db_expr_t size) +{ + + return (0); +} + +int +db_md_set_watchpoint(db_expr_t addr, db_expr_t size) +{ + + return (0); +} + +static void +db_stack_trace_cmd(struct unwind_state *frame) +{ + const char *name; + db_expr_t offset; + db_expr_t value; + c_db_sym_t sym; + uint64_t pc; + + while (1) { + pc = frame->pc; + + if (unwind_frame(frame) < 0) + break; + + sym = db_search_symbol(pc, DB_STGY_ANY, &offset); + if (sym == C_DB_SYM_NULL) { + value = 0; + name = "(null)"; + } else + db_symbol_values(sym, &name, &value); + + db_printf("%s() at ", name); + db_printsym(frame->pc, DB_STGY_PROC); + db_printf("\n"); + + db_printf("\t pc = 0x%016lx ra = 0x%016lx\n", + pc, frame->pc); + db_printf("\t sp = 0x%016lx fp = 0x%016lx\n", + frame->sp, frame->fp); + db_printf("\n"); + } +} + +int +db_trace_thread(struct thread *thr, int count) +{ + struct unwind_state frame; + struct pcb *ctx; + + if (thr != curthread) { + ctx = kdb_thr_ctx(thr); + + frame.sp = (uint64_t)ctx->pcb_sp; + frame.fp = (uint64_t)ctx->pcb_s[0]; + frame.pc = (uint64_t)ctx->pcb_ra; + db_stack_trace_cmd(&frame); + } else + db_trace_self(); + return (0); +} + +void +db_trace_self(void) +{ + struct unwind_state frame; + uint64_t sp; + + __asm __volatile("mv %0, sp" : "=&r" (sp)); + + frame.sp = sp; + frame.fp = (uint64_t)__builtin_frame_address(0); + frame.pc = (uint64_t)db_trace_self; + db_stack_trace_cmd(&frame); +} Property changes on: head/sys/riscv/riscv/db_trace.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/riscv/riscv/stack_machdep.c =================================================================== --- head/sys/riscv/riscv/stack_machdep.c (revision 296613) +++ head/sys/riscv/riscv/stack_machdep.c (revision 296614) @@ -1,63 +1,100 @@ /*- * Copyright (c) 2016 Ruslan Bukin * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include +#include +static void +stack_capture(struct stack *st, struct unwind_state *frame) +{ + + stack_zero(st); + + while (1) { + unwind_frame(frame); + if (!INKERNEL((vm_offset_t)frame->fp) || + !INKERNEL((vm_offset_t)frame->pc)) + break; + if (stack_put(st, frame->pc) == -1) + break; + } +} + void stack_save_td(struct stack *st, struct thread *td) { + struct unwind_state frame; + if (TD_IS_SWAPPED(td)) + panic("stack_save_td: swapped"); + if (TD_IS_RUNNING(td)) + panic("stack_save_td: running"); + + frame.sp = td->td_pcb->pcb_sp; + frame.fp = td->td_pcb->pcb_s[0]; + frame.pc = td->td_pcb->pcb_ra; + + stack_capture(st, &frame); } int stack_save_td_running(struct stack *st, struct thread *td) { return (EOPNOTSUPP); } void stack_save(struct stack *st) { + struct unwind_state frame; + uint64_t sp; + __asm __volatile("mv %0, sp" : "=&r" (sp)); + + frame.sp = sp; + frame.fp = (uint64_t)__builtin_frame_address(0); + frame.pc = (uint64_t)stack_save; + + stack_capture(st, &frame); } Index: head/sys/riscv/riscv/trap.c =================================================================== --- head/sys/riscv/riscv/trap.c (revision 296613) +++ head/sys/riscv/riscv/trap.c (revision 296614) @@ -1,333 +1,344 @@ /*- * Copyright (c) 2015 Ruslan Bukin * 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include +#ifdef KDB +#include +#endif #include #include #include #include #include #include #include #include #include #include #include extern register_t fsu_intr_fault; /* Called from exception.S */ void do_trap_supervisor(struct trapframe *); void do_trap_user(struct trapframe *); static __inline void call_trapsignal(struct thread *td, int sig, int code, void *addr) { ksiginfo_t ksi; ksiginfo_init_trap(&ksi); ksi.ksi_signo = sig; ksi.ksi_code = code; ksi.ksi_addr = addr; trapsignal(td, &ksi); } int cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) { struct proc *p; register_t *ap; int nap; nap = 8; p = td->td_proc; ap = &td->td_frame->tf_a[0]; sa->code = td->td_frame->tf_t[0]; if (sa->code == SYS_syscall || sa->code == SYS___syscall) { sa->code = *ap++; nap--; } if (p->p_sysent->sv_mask) sa->code &= p->p_sysent->sv_mask; if (sa->code >= p->p_sysent->sv_size) sa->callp = &p->p_sysent->sv_table[0]; else sa->callp = &p->p_sysent->sv_table[sa->code]; sa->narg = sa->callp->sy_narg; memcpy(sa->args, ap, nap * sizeof(register_t)); if (sa->narg > nap) panic("TODO: Could we have more then 8 args?"); td->td_retval[0] = 0; td->td_retval[1] = 0; return (0); } #include "../../kern/subr_syscall.c" static void dump_regs(struct trapframe *frame) { int n; int i; n = (sizeof(frame->tf_t) / sizeof(frame->tf_t[0])); for (i = 0; i < n; i++) printf("t[%d] == 0x%016lx\n", i, frame->tf_t[i]); n = (sizeof(frame->tf_s) / sizeof(frame->tf_s[0])); for (i = 0; i < n; i++) printf("s[%d] == 0x%016lx\n", i, frame->tf_s[i]); n = (sizeof(frame->tf_a) / sizeof(frame->tf_a[0])); for (i = 0; i < n; i++) printf("a[%d] == 0x%016lx\n", i, frame->tf_a[i]); printf("sepc == 0x%016lx\n", frame->tf_sepc); printf("sstatus == 0x%016lx\n", frame->tf_sstatus); } static void svc_handler(struct trapframe *frame) { struct syscall_args sa; struct thread *td; int error; td = curthread; td->td_frame = frame; error = syscallenter(td, &sa); syscallret(td, error, &sa); } static void data_abort(struct trapframe *frame, int lower) { struct vm_map *map; uint64_t sbadaddr; struct thread *td; struct pcb *pcb; vm_prot_t ftype; vm_offset_t va; struct proc *p; int ucode; int error; int sig; +#ifdef KDB + if (kdb_active) { + kdb_reenter(); + return; + } +#endif + td = curthread; pcb = td->td_pcb; /* * Special case for fuswintr and suswintr. These can't sleep so * handle them early on in the trap handler. */ if (__predict_false(pcb->pcb_onfault == (vm_offset_t)&fsu_intr_fault)) { frame->tf_sepc = pcb->pcb_onfault; return; } sbadaddr = frame->tf_sbadaddr; p = td->td_proc; if (lower) map = &td->td_proc->p_vmspace->vm_map; else { /* The top bit tells us which range to use */ if ((sbadaddr >> 63) == 1) map = kernel_map; else map = &td->td_proc->p_vmspace->vm_map; } va = trunc_page(sbadaddr); if (frame->tf_scause == EXCP_STORE_ACCESS_FAULT) { ftype = (VM_PROT_READ | VM_PROT_WRITE); } else { ftype = (VM_PROT_READ); } if (map != kernel_map) { /* * Keep swapout from messing with us during this * critical time. */ PROC_LOCK(p); ++p->p_lock; PROC_UNLOCK(p); /* Fault in the user page: */ error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); PROC_LOCK(p); --p->p_lock; PROC_UNLOCK(p); } else { /* * Don't have to worry about process locking or stacks in the * kernel. */ error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); } if (error != KERN_SUCCESS) { if (lower) { sig = SIGSEGV; if (error == KERN_PROTECTION_FAILURE) ucode = SEGV_ACCERR; else ucode = SEGV_MAPERR; call_trapsignal(td, sig, ucode, (void *)sbadaddr); } else { if (td->td_intr_nesting_level == 0 && pcb->pcb_onfault != 0) { frame->tf_a[0] = error; frame->tf_sepc = pcb->pcb_onfault; return; } dump_regs(frame); panic("vm_fault failed: %lx, va 0x%016lx", frame->tf_sepc, sbadaddr); } } if (lower) userret(td, frame); } void do_trap_supervisor(struct trapframe *frame) { uint64_t exception; exception = (frame->tf_scause & EXCP_MASK); if (frame->tf_scause & EXCP_INTR) { /* Interrupt */ riscv_cpu_intr(frame); return; } CTR3(KTR_TRAP, "do_trap_supervisor: curthread: %p, sepc: %lx, frame: %p", curthread, frame->tf_sepc, frame); switch(exception) { case EXCP_LOAD_ACCESS_FAULT: case EXCP_STORE_ACCESS_FAULT: case EXCP_INSTR_ACCESS_FAULT: data_abort(frame, 0); break; case EXCP_INSTR_BREAKPOINT: #ifdef KDB kdb_trap(exception, 0, frame); #else dump_regs(frame); panic("No debugger in kernel.\n"); #endif + break; case EXCP_INSTR_ILLEGAL: dump_regs(frame); panic("Illegal instruction at %x\n", frame->tf_sepc); break; default: dump_regs(frame); panic("Unknown kernel exception %x badaddr %lx\n", exception, frame->tf_sbadaddr); } } void do_trap_user(struct trapframe *frame) { uint64_t exception; struct thread *td; td = curthread; td->td_frame = frame; exception = (frame->tf_scause & EXCP_MASK); if (frame->tf_scause & EXCP_INTR) { /* Interrupt */ riscv_cpu_intr(frame); return; } CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p", curthread, frame->tf_sepc, frame); switch(exception) { case EXCP_LOAD_ACCESS_FAULT: case EXCP_STORE_ACCESS_FAULT: case EXCP_INSTR_ACCESS_FAULT: data_abort(frame, 1); break; case EXCP_UMODE_ENV_CALL: frame->tf_sepc += 4; /* Next instruction */ svc_handler(frame); break; case EXCP_INSTR_ILLEGAL: call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc); userret(td, frame); break; case EXCP_INSTR_BREAKPOINT: call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_sepc); userret(td, frame); break; default: dump_regs(frame); panic("Unknown userland exception %x badaddr %lx\n", exception, frame->tf_sbadaddr); } } Index: head/sys/riscv/riscv/unwind.c =================================================================== --- head/sys/riscv/riscv/unwind.c (nonexistent) +++ head/sys/riscv/riscv/unwind.c (revision 296614) @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); +#include + +#include +#include + +int +unwind_frame(struct unwind_state *frame) +{ + uint64_t fp; + + fp = frame->fp; + + if (!INKERNEL(fp)) + return (-1); + + frame->sp = fp; + frame->fp = *(uint64_t *)(fp - 16); + frame->pc = *(uint64_t *)(fp - 8) - 4; + + return (0); +} Property changes on: head/sys/riscv/riscv/unwind.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property