Add support for ddb(4).
Sponsored by: DARPA, AFRL Sponsored by: HEIF5
This commit is contained in:
parent
eef192d85c
commit
d52d6d7ca7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=296614
@ -29,7 +29,7 @@ S= ../../..
|
||||
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
|
||||
|
@ -23,6 +23,9 @@ 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
|
||||
@ -44,4 +47,5 @@ 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
|
||||
|
@ -79,10 +79,10 @@ options SMP
|
||||
# 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
|
||||
|
@ -267,10 +267,37 @@ 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;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -41,7 +41,51 @@
|
||||
#include <machine/frame.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
#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_ */
|
||||
|
116
sys/riscv/include/riscv_opcode.h
Normal file
116
sys/riscv/include/riscv_opcode.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by the University of Cambridge
|
||||
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||
* UK Higher Education Innovation Fund (HEIF).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_RISCV_OPCODE_H_
|
||||
#define _MACHINE_RISCV_OPCODE_H_
|
||||
|
||||
/*
|
||||
* Define the instruction formats and opcode values for the
|
||||
* RISC-V instruction set.
|
||||
*/
|
||||
#include <machine/endian.h>
|
||||
|
||||
/*
|
||||
* Define the instruction formats.
|
||||
*/
|
||||
typedef union {
|
||||
unsigned word;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned funct7: 7;
|
||||
} RType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 6;
|
||||
unsigned funct7: 6;
|
||||
} R2Type;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned imm: 12;
|
||||
} IType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned imm0_4: 5;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned imm5_11: 7;
|
||||
} SType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned imm11: 1;
|
||||
unsigned imm1_4: 4;
|
||||
unsigned funct3: 3;
|
||||
unsigned rs1: 5;
|
||||
unsigned rs2: 5;
|
||||
unsigned imm5_10: 6;
|
||||
unsigned imm12: 1;
|
||||
} SBType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned imm12_31: 20;
|
||||
} UType;
|
||||
|
||||
struct {
|
||||
unsigned opcode: 7;
|
||||
unsigned rd: 5;
|
||||
unsigned imm12_19: 8;
|
||||
unsigned imm11: 1;
|
||||
unsigned imm1_10: 10;
|
||||
unsigned imm20: 1;
|
||||
} UJType;
|
||||
} InstFmt;
|
||||
|
||||
#define RISCV_OPCODE(r) (r & 0x7f)
|
||||
|
||||
#endif /* !_MACHINE_RISCV_OPCODE_H_ */
|
@ -117,9 +117,10 @@
|
||||
#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))
|
||||
|
51
sys/riscv/include/stack.h
Normal file
51
sys/riscv/include/stack.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by the University of Cambridge
|
||||
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||
* UK Higher Education Innovation Fund (HEIF).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_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_ */
|
475
sys/riscv/riscv/db_disasm.c
Normal file
475
sys/riscv/riscv/db_disasm.c
Normal file
@ -0,0 +1,475 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by the University of Cambridge
|
||||
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||
* UK Higher Education Innovation Fund (HEIF).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <ddb/ddb.h>
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
#include <machine/riscvreg.h>
|
||||
#include <machine/riscv_opcode.h>
|
||||
|
||||
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);
|
||||
}
|
163
sys/riscv/riscv/db_interface.c
Normal file
163
sys/riscv/riscv/db_interface.c
Normal file
@ -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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
|
||||
#ifdef KDB
|
||||
#include <sys/kdb.h>
|
||||
#endif
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
#include <ddb/db_variables.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/stack.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
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);
|
||||
}
|
135
sys/riscv/riscv/db_trace.c
Normal file
135
sys/riscv/riscv/db_trace.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 The FreeBSD Foundation
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* 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 <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <ddb/ddb.h>
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
#include <machine/riscvreg.h>
|
||||
#include <machine/stack.h>
|
||||
|
||||
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);
|
||||
}
|
@ -42,11 +42,39 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/stack.h>
|
||||
|
||||
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
|
||||
@ -59,5 +87,14 @@ stack_save_td_running(struct stack *st, struct thread *td)
|
||||
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);
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysent.h>
|
||||
#ifdef KDB
|
||||
#include <sys/kdb.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -167,6 +170,13 @@ data_abort(struct trapframe *frame, int lower)
|
||||
int error;
|
||||
int sig;
|
||||
|
||||
#ifdef KDB
|
||||
if (kdb_active) {
|
||||
kdb_reenter();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
td = curthread;
|
||||
pcb = td->td_pcb;
|
||||
|
||||
@ -277,6 +287,7 @@ do_trap_supervisor(struct trapframe *frame)
|
||||
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);
|
||||
|
57
sys/riscv/riscv/unwind.c
Normal file
57
sys/riscv/riscv/unwind.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
|
||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by the University of Cambridge
|
||||
* Computer Laboratory as part of the CTSRD Project, with support from the
|
||||
* UK Higher Education Innovation Fund (HEIF).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <machine/stack.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user