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>
This commit is contained in:
Vincent Chen
2020-04-16 10:38:07 +08:00
committed by Palmer Dabbelt
parent fe89bd2be8
commit d96575709c
4 changed files with 140 additions and 1 deletions

View File

@@ -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)
{