Skip to content

Commit

Permalink
gdb: Expose CHERI SCRs via the GDB stub
Browse files Browse the repository at this point in the history
This does not expose PCC and DDC in the new SCRs register group since
those are already in the general purpose CHERI group.
  • Loading branch information
bsdjhb committed Sep 3, 2024
1 parent 6846c33 commit 92a33ac
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
5 changes: 5 additions & 0 deletions target/riscv/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
3 changes: 3 additions & 0 deletions target/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ struct RISCVCPU {
CPURISCVState env;

char *dyn_csr_xml;
#ifdef TARGET_CHERI
char *dyn_scr_xml;
#endif

/* Configuration Settings */
struct {
Expand Down
102 changes: 102 additions & 0 deletions target/riscv/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,103 @@ 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 inline cap_register_t *get_scr(CPUArchState *env, uint32_t index)
{
switch (index) {
case CheriSCR_PCC: return &env->PCC;
case CheriSCR_DDC: return &env->DDC;

case CheriSCR_UTCC: return &env->UTCC;
case CheriSCR_UTDC: return &env->UTDC;
case CheriSCR_UScratchC: return &env->UScratchC;
case CheriSCR_UEPCC: return &env->UEPCC;

case CheriSCR_STCC: return &env->STCC;
case CheriSCR_STDC: return &env->STDC;
case CheriSCR_SScratchC: return &env->SScratchC;
case CheriSCR_SEPCC: return &env->SEPCC;

case CheriSCR_MTCC: return &env->MTCC;
case CheriSCR_MTDC: return &env->MTDC;
case CheriSCR_MScratchC: return &env->MScratchC;
case CheriSCR_MEPCC: return &env->MEPCC;

case CheriSCR_BSTCC: return &env->VSTCC;
case CheriSCR_BSTDC: return &env->VSTDC;
case CheriSCR_BSScratchC: return &env->VSScratchC;
case CheriSCR_BSEPCC: return &env->VSEPCC;
default: assert(false);
}
}

static int riscv_gdb_get_scr(CPURISCVState *env, GByteArray *buf, int n)
{
if (n < ARRAY_SIZE(scrs)) {
cap_register_t *scr = 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, "<?xml version=\"1.0\"?>");
g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.scr\">");

for (i = 0; i < ARRAY_SIZE(scrs); i++) {
g_string_append_printf(s, "<reg name=\"%s\"", scrs[i].name);
g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
g_string_append_printf(s, " type=\"%s_capability\"",
scrs[i].code ? "code" : "data");
g_string_append_printf(s, " group=\"system\"");
g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
}

g_string_append_printf(s, "</feature>");

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);
Expand Down Expand Up @@ -261,4 +358,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
}

0 comments on commit 92a33ac

Please sign in to comment.