1 /* $NetBSD: db_machdep.h,v 1.8 2023/06/12 19:04:14 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matt Thomas of 3am Software Foundry. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _RISCV_DB_MACHDEP_H_ 33 #define _RISCV_DB_MACHDEP_H_ 34 35 #include <riscv/locore.h> /* T_BREAK */ 36 #include <riscv/frame.h> 37 38 #define DB_ELF_SYMBOLS 39 40 typedef vaddr_t db_addr_t; /* address - unsigned */ 41 #define DDB_EXPR_FMT "l" /* expression is long */ 42 typedef long db_expr_t; /* expression - signed */ 43 44 typedef struct trapframe db_regs_t; 45 46 extern const uint32_t cpu_Debugger_insn[]; 47 extern const uint32_t cpu_Debugger_ret[]; 48 extern db_regs_t ddb_regs; 49 #define DDB_REGS (&ddb_regs) 50 51 #define PC_REGS(tf) ((tf)->tf_pc) 52 53 #define PC_ADVANCE(tf) do { \ 54 if (db_get_value((tf)->tf_pc, sizeof(uint32_t), false) == BKPT_INST) \ 55 (tf)->tf_pc += BKPT_SIZE; \ 56 } while(0) 57 58 /* Similar to PC_ADVANCE(), except only advance on cpu_Debugger()'s bpt */ 59 #define PC_BREAK_ADVANCE(tf) do { \ 60 if ((tf)->tf_pc == (register_t)cpu_Debugger_insn) \ 61 (tf)->tf_pc = (register_t)cpu_Debugger_ret; \ 62 } while(0) 63 64 #define BKPT_ADDR(addr) (addr) /* breakpoint address */ 65 #define BKPT_INST 0x00100073 66 #define BKPT_SIZE (sizeof(uint32_t)) /* size of bkpt inst */ 67 #define BKPT_SET(inst, addr) (BKPT_INST) 68 69 /* 70 * XXX with the C extension there's also a 16-bit-wide breakpoint 71 * instruction, the idea being that you use it when inserting a 72 * breakpoint into a stream of 16-bit instructions, but it looks like 73 * MI ddb can't cope with having two sizes :-( 74 */ 75 #if 0 76 #define BKPT_INST_2 0x9002 77 #define BKPT_SIZE_2 (sizeof(uint16_t)) 78 #endif 79 80 #define IS_BREAKPOINT_TRAP(type, code) ((type) == CAUSE_BREAKPOINT) 81 #define IS_WATCHPOINT_TRAP(type, code) (0) 82 83 /* 84 * Interface to disassembly 85 */ 86 db_addr_t db_disasm_insn(uint32_t, db_addr_t, bool); 87 88 89 /* 90 * Entrypoints to DDB for kernel, keyboard drivers, init hook 91 */ 92 void kdb_kbd_trap(db_regs_t *); 93 int kdb_trap(int, db_regs_t *); 94 95 static inline void 96 db_set_ddb_regs(int type, struct trapframe *tf) 97 { 98 *curcpu()->ci_ddb_regs = *tf; 99 } 100 101 102 /* 103 * Constants for KGDB. 104 */ 105 typedef register_t kgdb_reg_t; 106 #define KGDB_NUMREGS 90 107 #define KGDB_BUFLEN 1024 108 109 /* 110 * RISCV cpus have no hardware single-step. 111 */ 112 #define SOFTWARE_SSTEP 113 114 #define inst_trap_return(ins) ((ins)&0) 115 116 bool inst_branch(uint32_t inst); 117 bool inst_call(uint32_t inst); 118 bool inst_return(uint32_t inst); 119 bool inst_load(uint32_t inst); 120 bool inst_store(uint32_t inst); 121 bool inst_unconditional_flow_transfer(uint32_t inst); 122 db_addr_t branch_taken(uint32_t inst, db_addr_t pc, db_regs_t *regs); 123 db_addr_t next_instr_address(db_addr_t pc, bool bd); 124 125 bool ddb_running_on_this_cpu_p(void); 126 bool ddb_running_on_any_cpu_p(void); 127 void db_resume_others(void); 128 129 #if 0 130 /* 131 * We have machine-dependent commands. 132 */ 133 #define DB_MACHINE_COMMANDS 134 #endif 135 136 void dump_trapframe(const struct trapframe *, void (*)(const char *, ...) __printflike(1, 2)); 137 138 #endif /* _RISCV_DB_MACHDEP_H_ */ 139