summaryrefslogtreecommitdiffstats
path: root/arch/riscv/kernel
diff options
context:
space:
mode:
authorVincent Chen <vincent.chen@sifive.com>2020-04-16 10:38:07 +0800
committerPalmer Dabbelt <palmerdabbelt@google.com>2020-05-18 11:38:11 -0700
commitd96575709cc7056f34fdd5cdc16bcffe5bdb573d (patch)
tree73935f4d016aa0de26ce4276e2715ae84bd5c731 /arch/riscv/kernel
parentfe89bd2be8667d4d876329dd534dd59158e33b1f (diff)
riscv: Use the XML target descriptions to report 3 system registers
The $status, $badaddr, and $cause registers belong to the thread context, so KGDB can obtain their contents from pt_regs in each trap. However, the sequential number of these registers in the gdb register list is far from the general-purpose registers. If riscv port uses the existing method to report these three registers, many trivial registers with sequence numbers in the middle of them will also be packaged to the reply packets. To solve this problem, the riscv port wants to introduce the GDB target description mechanism to customize the reported register list. By the list, the KGDB can ignore the intermediate registers and just reports the general-purpose registers and these three system registers. Signed-off-by: Vincent Chen <vincent.chen@sifive.com> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r--arch/riscv/kernel/kgdb.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
index 6bdc0908a5b8..eb1afab47679 100644
--- a/arch/riscv/kernel/kgdb.c
+++ b/arch/riscv/kernel/kgdb.c
@@ -10,6 +10,7 @@
#include <linux/irqflags.h>
#include <linux/string.h>
#include <asm/cacheflush.h>
+#include <asm/gdb_xml.h>
enum {
NOT_KGDB_BREAK = 0,
@@ -51,6 +52,9 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{DBG_REG_T5, GDB_SIZEOF_REG, offsetof(struct pt_regs, t5)},
{DBG_REG_T6, GDB_SIZEOF_REG, offsetof(struct pt_regs, t6)},
{DBG_REG_EPC, GDB_SIZEOF_REG, offsetof(struct pt_regs, epc)},
+ {DBG_REG_STATUS, GDB_SIZEOF_REG, offsetof(struct pt_regs, status)},
+ {DBG_REG_BADADDR, GDB_SIZEOF_REG, offsetof(struct pt_regs, badaddr)},
+ {DBG_REG_CAUSE, GDB_SIZEOF_REG, offsetof(struct pt_regs, cause)},
};
char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
@@ -103,6 +107,17 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
regs->epc = pc;
}
+void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
+ char *remcom_out_buffer)
+{
+ if (!strncmp(remcom_in_buffer, gdb_xfer_read_target,
+ sizeof(gdb_xfer_read_target)))
+ strcpy(remcom_out_buffer, riscv_gdb_stub_target_desc);
+ else if (!strncmp(remcom_in_buffer, gdb_xfer_read_cpuxml,
+ sizeof(gdb_xfer_read_cpuxml)))
+ strcpy(remcom_out_buffer, riscv_gdb_stub_cpuxml);
+}
+
static inline void kgdb_arch_update_addr(struct pt_regs *regs,
char *remcom_in_buffer)
{