Re: [PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type
On Fri, Jun 10, 2022 at 1:20 PM wrote: > > From: Frank Chang > > Current RISC-V debug assumes that only type 2 trigger is supported. > To allow more types of triggers to be supported in the future > (e.g. type 6 trigger, which is similar to type 2 trigger with additional > functionality), we should determine the trigger type from tdata1.type. > > RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM. > > Signed-off-by: Frank Chang > --- > target/riscv/cpu.h | 2 +- > target/riscv/csr.c | 2 +- > target/riscv/debug.c | 183 - > target/riscv/debug.h | 15 ++-- > target/riscv/machine.c | 2 +- > 5 files changed, 137 insertions(+), 67 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 7d6397acdf..535123a989 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -289,7 +289,7 @@ struct CPUArchState { > > /* trigger module */ > target_ulong trigger_cur; > -type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM]; > +type2_trigger_t type2_trig[RV_MAX_TRIGGERS]; > > /* machine specific rdtime callback */ > uint64_t (*rdtime_fn)(void *); > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 6dbe9b541f..005ae31a01 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, > int csrno, > target_ulong *val) > { > /* return 0 in tdata1 to end the trigger enumeration */ > -if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) { > +if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) { > *val = 0; > return RISCV_EXCP_NONE; > } > diff --git a/target/riscv/debug.c b/target/riscv/debug.c > index fc6e13222f..abbcd38a17 100644 > --- a/target/riscv/debug.c > +++ b/target/riscv/debug.c > @@ -52,8 +52,15 @@ > /* tdata availability of a trigger */ > typedef bool tdata_avail[TDATA_NUM]; > > -static tdata_avail tdata_mapping[TRIGGER_NUM] = { > -[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false }, > +static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = { > +[TRIGGER_TYPE_NO_EXIST] = { false, false, false }, > +[TRIGGER_TYPE_AD_MATCH] = { true, true, true }, > +[TRIGGER_TYPE_INST_CNT] = { true, false, true }, > +[TRIGGER_TYPE_INT] = { true, true, true }, > +[TRIGGER_TYPE_EXCP] = { true, true, true }, > +[TRIGGER_TYPE_AD_MATCH6] = { true, true, true }, > +[TRIGGER_TYPE_EXT_SRC] = { true, false, false }, > +[TRIGGER_TYPE_UNAVAIL] = { true, true, true } > }; > > /* only breakpoint size 1/2/4/8 supported */ > @@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = { > [6 ... 15] = -1, > }; > > +static inline target_ulong extract_trigger_type(CPURISCVState *env, > +target_ulong tdata1) > +{ > +switch (riscv_cpu_mxl(env)) { > +case MXL_RV32: > +return extract32(tdata1, 28, 4); > +case MXL_RV64: > +return extract64(tdata1, 60, 4); I guess we should add a "case MXL_RV128" here so that it won't break rv128. See commit d1d8541217ce8a23e9e751cd868c7d618817134a > +default: > +g_assert_not_reached(); > +} > +} > + > +static inline target_ulong get_trigger_type(CPURISCVState *env, > +target_ulong trigger_index) > +{ > +target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol; > +return extract_trigger_type(env, tdata1); > +} > + > static inline target_ulong trigger_type(CPURISCVState *env, > trigger_type_t type) > { > @@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState > *env, > > bool tdata_available(CPURISCVState *env, int tdata_index) > { > +int trigger_type = get_trigger_type(env, env->trigger_cur); > + > if (unlikely(tdata_index >= TDATA_NUM)) { > return false; > } > > -if (unlikely(env->trigger_cur >= TRIGGER_NUM)) { > +if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) { > return false; > } > > -return tdata_mapping[env->trigger_cur][tdata_index]; > +return tdata_mapping[trigger_type][tdata_index]; > } > > target_ulong tselect_csr_read(CPURISCVState *env) > @@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, > target_ulong val, > qemu_log_mask(LOG_GUEST_ERROR, >"ignoring type write to tdata1 register\n"); > } > + > if (dmode != 0) { > qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); > } > @@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, > target_ulong index) > } > > static target_ulong type2_reg_read(CPURISCVState *env, > - target_ulong trigger_index, int > tdata_index) > + target_ulong index, int tdata_index) > {
Re: [PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type
On Fri, Jun 10, 2022 at 1:20 PM wrote: > > From: Frank Chang > > Current RISC-V debug assumes that only type 2 trigger is supported. > To allow more types of triggers to be supported in the future > (e.g. type 6 trigger, which is similar to type 2 trigger with additional > functionality), we should determine the trigger type from tdata1.type. > > RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM. > > Signed-off-by: Frank Chang > --- > target/riscv/cpu.h | 2 +- > target/riscv/csr.c | 2 +- > target/riscv/debug.c | 183 - > target/riscv/debug.h | 15 ++-- > target/riscv/machine.c | 2 +- > 5 files changed, 137 insertions(+), 67 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 7d6397acdf..535123a989 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -289,7 +289,7 @@ struct CPUArchState { > > /* trigger module */ > target_ulong trigger_cur; > -type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM]; > +type2_trigger_t type2_trig[RV_MAX_TRIGGERS]; > > /* machine specific rdtime callback */ > uint64_t (*rdtime_fn)(void *); > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 6dbe9b541f..005ae31a01 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, > int csrno, > target_ulong *val) > { > /* return 0 in tdata1 to end the trigger enumeration */ > -if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) { > +if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) { > *val = 0; > return RISCV_EXCP_NONE; > } > diff --git a/target/riscv/debug.c b/target/riscv/debug.c > index fc6e13222f..abbcd38a17 100644 > --- a/target/riscv/debug.c > +++ b/target/riscv/debug.c > @@ -52,8 +52,15 @@ > /* tdata availability of a trigger */ > typedef bool tdata_avail[TDATA_NUM]; > > -static tdata_avail tdata_mapping[TRIGGER_NUM] = { > -[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false }, > +static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = { > +[TRIGGER_TYPE_NO_EXIST] = { false, false, false }, > +[TRIGGER_TYPE_AD_MATCH] = { true, true, true }, > +[TRIGGER_TYPE_INST_CNT] = { true, false, true }, > +[TRIGGER_TYPE_INT] = { true, true, true }, > +[TRIGGER_TYPE_EXCP] = { true, true, true }, > +[TRIGGER_TYPE_AD_MATCH6] = { true, true, true }, > +[TRIGGER_TYPE_EXT_SRC] = { true, false, false }, > +[TRIGGER_TYPE_UNAVAIL] = { true, true, true } > }; > > /* only breakpoint size 1/2/4/8 supported */ > @@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = { > [6 ... 15] = -1, > }; > > +static inline target_ulong extract_trigger_type(CPURISCVState *env, > +target_ulong tdata1) > +{ > +switch (riscv_cpu_mxl(env)) { > +case MXL_RV32: > +return extract32(tdata1, 28, 4); > +case MXL_RV64: > +return extract64(tdata1, 60, 4); > +default: > +g_assert_not_reached(); > +} > +} > + > +static inline target_ulong get_trigger_type(CPURISCVState *env, > +target_ulong trigger_index) > +{ > +target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol; > +return extract_trigger_type(env, tdata1); > +} > + > static inline target_ulong trigger_type(CPURISCVState *env, > trigger_type_t type) > { > @@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState > *env, > > bool tdata_available(CPURISCVState *env, int tdata_index) > { > +int trigger_type = get_trigger_type(env, env->trigger_cur); > + > if (unlikely(tdata_index >= TDATA_NUM)) { > return false; > } > > -if (unlikely(env->trigger_cur >= TRIGGER_NUM)) { > +if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) { > return false; > } > > -return tdata_mapping[env->trigger_cur][tdata_index]; > +return tdata_mapping[trigger_type][tdata_index]; > } > > target_ulong tselect_csr_read(CPURISCVState *env) > @@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, > target_ulong val, > qemu_log_mask(LOG_GUEST_ERROR, >"ignoring type write to tdata1 register\n"); > } > + > if (dmode != 0) { > qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); > } > @@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, > target_ulong index) > } > > static target_ulong type2_reg_read(CPURISCVState *env, > - target_ulong trigger_index, int > tdata_index) > + target_ulong index, int tdata_index) > { > -uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; > target_ulong tdata; > > switch (tdata_index) { > @@
[PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type
From: Frank Chang Current RISC-V debug assumes that only type 2 trigger is supported. To allow more types of triggers to be supported in the future (e.g. type 6 trigger, which is similar to type 2 trigger with additional functionality), we should determine the trigger type from tdata1.type. RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM. Signed-off-by: Frank Chang --- target/riscv/cpu.h | 2 +- target/riscv/csr.c | 2 +- target/riscv/debug.c | 183 - target/riscv/debug.h | 15 ++-- target/riscv/machine.c | 2 +- 5 files changed, 137 insertions(+), 67 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 7d6397acdf..535123a989 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -289,7 +289,7 @@ struct CPUArchState { /* trigger module */ target_ulong trigger_cur; -type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM]; +type2_trigger_t type2_trig[RV_MAX_TRIGGERS]; /* machine specific rdtime callback */ uint64_t (*rdtime_fn)(void *); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 6dbe9b541f..005ae31a01 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, int csrno, target_ulong *val) { /* return 0 in tdata1 to end the trigger enumeration */ -if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) { +if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) { *val = 0; return RISCV_EXCP_NONE; } diff --git a/target/riscv/debug.c b/target/riscv/debug.c index fc6e13222f..abbcd38a17 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -52,8 +52,15 @@ /* tdata availability of a trigger */ typedef bool tdata_avail[TDATA_NUM]; -static tdata_avail tdata_mapping[TRIGGER_NUM] = { -[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false }, +static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = { +[TRIGGER_TYPE_NO_EXIST] = { false, false, false }, +[TRIGGER_TYPE_AD_MATCH] = { true, true, true }, +[TRIGGER_TYPE_INST_CNT] = { true, false, true }, +[TRIGGER_TYPE_INT] = { true, true, true }, +[TRIGGER_TYPE_EXCP] = { true, true, true }, +[TRIGGER_TYPE_AD_MATCH6] = { true, true, true }, +[TRIGGER_TYPE_EXT_SRC] = { true, false, false }, +[TRIGGER_TYPE_UNAVAIL] = { true, true, true } }; /* only breakpoint size 1/2/4/8 supported */ @@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = { [6 ... 15] = -1, }; +static inline target_ulong extract_trigger_type(CPURISCVState *env, +target_ulong tdata1) +{ +switch (riscv_cpu_mxl(env)) { +case MXL_RV32: +return extract32(tdata1, 28, 4); +case MXL_RV64: +return extract64(tdata1, 60, 4); +default: +g_assert_not_reached(); +} +} + +static inline target_ulong get_trigger_type(CPURISCVState *env, +target_ulong trigger_index) +{ +target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol; +return extract_trigger_type(env, tdata1); +} + static inline target_ulong trigger_type(CPURISCVState *env, trigger_type_t type) { @@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState *env, bool tdata_available(CPURISCVState *env, int tdata_index) { +int trigger_type = get_trigger_type(env, env->trigger_cur); + if (unlikely(tdata_index >= TDATA_NUM)) { return false; } -if (unlikely(env->trigger_cur >= TRIGGER_NUM)) { +if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) { return false; } -return tdata_mapping[env->trigger_cur][tdata_index]; +return tdata_mapping[trigger_type][tdata_index]; } target_ulong tselect_csr_read(CPURISCVState *env) @@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val, qemu_log_mask(LOG_GUEST_ERROR, "ignoring type write to tdata1 register\n"); } + if (dmode != 0) { qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); } @@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index) } static target_ulong type2_reg_read(CPURISCVState *env, - target_ulong trigger_index, int tdata_index) + target_ulong index, int tdata_index) { -uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; target_ulong tdata; switch (tdata_index) { @@ -280,10 +309,9 @@ static target_ulong type2_reg_read(CPURISCVState *env, return tdata; } -static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index, +static void type2_reg_write(CPURISCVState *env, target_ulong index, int tdata_index,