From c2a52f31a8191462d14df717093a6088781d1a2b Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Fri, 9 Jun 2023 09:06:37 +0300 Subject: [PATCH] target/riscv: cleanup trigger setup * Add a warning when eq trigger is setup and it's behavior is different from other triggers. * Make eq trigger's behavior consistent with other triggers in case of length == 1. * Fix a bug in setting chained triggers (LT, GT case). * Improve logging. Change-Id: Id1ed0d11971b8ed875afbb979e6c8a8b51dd3818 Signed-off-by: Evgeniy Naydanov --- src/target/riscv/riscv.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 94fbb6788f..160cf37dc4 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -655,9 +655,18 @@ struct trigger_request_info { riscv_reg_t tdata1_ignore_mask; }; +static void log_trigger_request_info(struct trigger_request_info trig_info) +{ + LOG_DEBUG("tdata1=%" PRIx64 ", tdata2=%" PRIx64 ", tdata1_ignore_mask=%" PRIx64, + trig_info.tdata1, trig_info.tdata2, trig_info.tdata1_ignore_mask); +}; + static int try_setup_single_match_trigger(struct target *target, struct trigger *trigger, struct trigger_request_info trig_info) { + LOG_TARGET_DEBUG(target, "trying to set up a match trigger"); + log_trigger_request_info(trig_info); + int trigger_type = get_field(trig_info.tdata1, CSR_MCONTROL_TYPE(riscv_xlen(target))); int ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -683,6 +692,9 @@ static int try_setup_chained_match_triggers(struct target *target, struct trigger *trigger, struct trigger_request_info t1, struct trigger_request_info t2) { + LOG_TARGET_DEBUG(target, "trying to set up a chain of match triggers"); + log_trigger_request_info(t1); + log_trigger_request_info(t2); int trigger_type = get_field(t1.tdata1, CSR_MCONTROL_TYPE(riscv_xlen(target))); int ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -717,8 +729,10 @@ static int try_setup_chained_match_triggers(struct target *target, struct match_triggers_tdata1_fields { riscv_reg_t common; struct { + /* Other values are available for this field, + * but currently only `any` is needed. + */ riscv_reg_t any; - riscv_reg_t s8bit; } size; struct { riscv_reg_t enable; @@ -752,10 +766,7 @@ static struct match_triggers_tdata1_fields fill_match_triggers_tdata1_fields_t2( .size = { .any = field_value(CSR_MCONTROL_SIZELO, CSR_MCONTROL_SIZELO_ANY & 3) | - field_value(CSR_MCONTROL_SIZEHI, (CSR_MCONTROL_SIZELO_ANY >> 2) & 3), - .s8bit = - field_value(CSR_MCONTROL_SIZELO, CSR_MCONTROL_SIZELO_8BIT & 3) | - field_value(CSR_MCONTROL_SIZEHI, (CSR_MCONTROL_SIZELO_8BIT >> 2) & 3) + field_value(CSR_MCONTROL_SIZEHI, (CSR_MCONTROL_SIZELO_ANY >> 2) & 3) }, .chain = { .enable = field_value(CSR_MCONTROL_CHAIN, CSR_MCONTROL_CHAIN_ENABLED), @@ -793,8 +804,7 @@ static struct match_triggers_tdata1_fields fill_match_triggers_tdata1_fields_t6( field_value(CSR_MCONTROL6_LOAD, trigger->is_read) | field_value(CSR_MCONTROL6_STORE, trigger->is_write), .size = { - .any = field_value(CSR_MCONTROL6_SIZE, CSR_MCONTROL6_SIZE_ANY), - .s8bit = field_value(CSR_MCONTROL6_SIZE, CSR_MCONTROL6_SIZE_8BIT) + .any = field_value(CSR_MCONTROL6_SIZE, CSR_MCONTROL6_SIZE_ANY) }, .chain = { .enable = field_value(CSR_MCONTROL6_CHAIN, CSR_MCONTROL6_CHAIN_ENABLED), @@ -852,13 +862,13 @@ static int maybe_add_trigger_t2_t6(struct target *target, struct trigger_request_info lt_1 = { .tdata1 = fields.common | fields.size.any | fields.chain.enable | fields.match.lt, - .tdata2 = trigger->address, + .tdata2 = trigger->address + trigger->length, .tdata1_ignore_mask = fields.tdata1_ignore_mask }; struct trigger_request_info ge_2 = { .tdata1 = fields.common | fields.size.any | fields.chain.disable | fields.match.ge, - .tdata2 = trigger->address + trigger->length, + .tdata2 = trigger->address, .tdata1_ignore_mask = fields.tdata1_ignore_mask }; ret = try_setup_chained_match_triggers(target, trigger, lt_1, ge_2); @@ -866,10 +876,12 @@ static int maybe_add_trigger_t2_t6(struct target *target, return ret; } LOG_TARGET_DEBUG(target, "trying to setup equality match trigger"); + if (trigger->length > 1) + LOG_TARGET_WARNING(target, "trigger will only match accesses at address 0x%" + TARGET_PRIxADDR, trigger->address); struct trigger_request_info eq = { - .tdata1 = fields.common | - (trigger->length == 1 ? fields.size.s8bit : fields.size.any) | - fields.chain.disable | fields.match.eq, + .tdata1 = fields.common | fields.size.any | fields.chain.disable | + fields.match.eq, .tdata2 = trigger->address, .tdata1_ignore_mask = fields.tdata1_ignore_mask };