From 771d82e9e536264824eaf828257293684e2a305d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 Sep 2024 11:46:47 -0400 Subject: [PATCH] gdb: Expose CHERI SCRs via the GDB stub This does not expose PCC and DDC in the new SCRs register group since those are already in the general purpose CHERI group. --- target/riscv/cpu.c | 5 +++ target/riscv/cpu.h | 3 ++ target/riscv/gdbstub.c | 73 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0eb49f00c9..6987fb16ea 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -999,6 +999,11 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) if (strcmp(xmlname, "riscv-csr.xml") == 0) { return cpu->dyn_csr_xml; } +#ifdef TARGET_CHERI + if (strcmp(xmlname, "riscv-scr.xml") == 0) { + return cpu->dyn_scr_xml; + } +#endif return NULL; } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 8fb3be1613..fc2db7c164 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -410,6 +410,9 @@ struct RISCVCPU { CPURISCVState env; char *dyn_csr_xml; +#ifdef TARGET_CHERI + char *dyn_scr_xml; +#endif /* Configuration Settings */ struct { diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index fd100980fd..924b1b9a97 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -228,6 +228,74 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg) return CSR_TABLE_SIZE; } +#if defined(TARGET_CHERI) +static struct SCR { + int index; + const char *name; + bool code; +} scrs[] = { + { .index = CheriSCR_UTCC, .name = "utcc", .code = true }, + { .index = CheriSCR_UTDC, .name = "utdc"}, + { .index = CheriSCR_UScratchC, .name = "uscratchc"}, + { .index = CheriSCR_UEPCC, .name = "uepcc", .code = true }, + + { .index = CheriSCR_STCC, .name = "stcc", .code = true }, + { .index = CheriSCR_STDC, .name = "stdc"}, + { .index = CheriSCR_SScratchC, .name = "sscratchc"}, + { .index = CheriSCR_SEPCC, .name = "sepcc", .code = true }, + + { .index = CheriSCR_MTCC, .name = "mtcc", .code = true }, + { .index = CheriSCR_MTDC, .name = "mtdc"}, + { .index = CheriSCR_MScratchC, .name = "mscratchc"}, + { .index = CheriSCR_MEPCC, .name = "mepcc", .code = true }, +}; + +static int riscv_gdb_get_scr(CPURISCVState *env, GByteArray *buf, int n) +{ + if (n < ARRAY_SIZE(scrs)) { + cap_register_t *scr = riscv_get_scr(env, scrs[n].index); + return gdb_get_capreg(buf, scr); + } + return 0; +} + +static int riscv_gdb_set_scr(CPURISCVState *env, uint8_t *mem_buf, int n) +{ + /* All CHERI registers are read-only currently. */ + if (n < ARRAY_SIZE(scrs)) { + return CHERI_CAP_SIZE + 1; + } + return 0; +} + +static int riscv_gen_dynamic_scr_xml(CPUState *cs, int base_reg) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + GString *s = g_string_new(NULL); + int bitsize = riscv_cpu_is_32bit(env) ? 64 : 128; + int i; + + g_string_printf(s, ""); + g_string_append_printf(s, ""); + g_string_append_printf(s, ""); + + for (i = 0; i < ARRAY_SIZE(scrs); i++) { + g_string_append_printf(s, "", base_reg + i); + } + + g_string_append_printf(s, ""); + + cpu->dyn_scr_xml = g_string_free(s, false); + return ARRAY_SIZE(scrs); +} +#endif + void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) { RISCVCPU *cpu = RISCV_CPU(cs); @@ -261,4 +329,9 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs), "riscv-csr.xml", 0); +#if defined(TARGET_CHERI) + gdb_register_coprocessor(cs, riscv_gdb_get_scr, riscv_gdb_set_scr, + riscv_gen_dynamic_scr_xml(cs, cs->gdb_num_regs), + "riscv-scr.xml", 0); +#endif }