From 5766efe0c3d02ae13256617bee7f39d76ed2fe41 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 25 Jan 2017 11:35:57 -0800 Subject: [PATCH 1/3] riscv: Globally disable interrupts when running algorithms. --- src/target/riscv/riscv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index e7ca09924..0987e6693 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2696,6 +2696,18 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, } } + + // Disable Interrupts before attempting to run the algorithm. + // Is it possible/desirable to do this in the calling code instead? + uint64_t current_mstatus; + + register_get(&target->reg_cache->reg_list[REG_MSTATUS]); + current_mstatus = info->mstatus_actual; + current_mstatus = current_mstatus & ~((uint64_t) 0x8); + register_set((&target->reg_cache->reg_list[REG_MSTATUS]), (uint8_t*) ¤t_mstatus); + info->mstatus_actual = current_mstatus; + + /// Run algorithm LOG_DEBUG("resume at 0x%x", entry_point); if (riscv_resume(target, 0, entry_point, 0, 0) != ERROR_OK) { From d5892f0ee5a30a1d6787d5e1a4114a976d9ce205 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 25 Jan 2017 15:23:10 -0800 Subject: [PATCH 2/3] riscv: Use proper UINT packing and unpacking routines for disabling interrupts before running algorithms. --- src/target/riscv/riscv.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 0987e6693..11183ae7d 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2698,15 +2698,16 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, // Disable Interrupts before attempting to run the algorithm. - // Is it possible/desirable to do this in the calling code instead? uint64_t current_mstatus; + uint8_t mstatus_bytes[8]; + LOG_DEBUG("Disabling Interrupts"); register_get(&target->reg_cache->reg_list[REG_MSTATUS]); - current_mstatus = info->mstatus_actual; - current_mstatus = current_mstatus & ~((uint64_t) 0x8); - register_set((&target->reg_cache->reg_list[REG_MSTATUS]), (uint8_t*) ¤t_mstatus); - info->mstatus_actual = current_mstatus; + current_mstatus = buf_get_u64(target->reg_cache->reg_list[REG_MSTATUS].value, 0, info->xlen); + buf_set_u64(mstatus_bytes, 0, info->xlen, (current_mstatus & (~((uint64_t)MSTATUS_MIE))) ); + register_set(&target->reg_cache->reg_list[REG_MSTATUS], mstatus_bytes); + info->mstatus_actual = current_mstatus & ~MSTATUS_MIE; /// Run algorithm LOG_DEBUG("resume at 0x%x", entry_point); @@ -2741,6 +2742,12 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, return ERROR_FAIL; } + // Restore Interrupts + LOG_DEBUG("Restoring Interrupts"); + buf_set_u64(mstatus_bytes, 0, info->xlen, current_mstatus); + register_set(&target->reg_cache->reg_list[REG_MSTATUS], mstatus_bytes); + info->mstatus_actual = current_mstatus; + /// Restore registers uint8_t buf[8]; buf_set_u64(buf, 0, info->xlen, saved_pc); From 5d82a395f13c70f44398d7a9cc44564806441a6e Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 25 Jan 2017 21:51:02 -0800 Subject: [PATCH 3/3] riscv: disable interrupts for all priviledge levels --- src/target/riscv/riscv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 11183ae7d..fb48ca608 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2704,10 +2704,10 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, LOG_DEBUG("Disabling Interrupts"); register_get(&target->reg_cache->reg_list[REG_MSTATUS]); current_mstatus = buf_get_u64(target->reg_cache->reg_list[REG_MSTATUS].value, 0, info->xlen); - buf_set_u64(mstatus_bytes, 0, info->xlen, (current_mstatus & (~((uint64_t)MSTATUS_MIE))) ); + uint64_t ie_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE; + buf_set_u64(mstatus_bytes, 0, info->xlen, set_field(current_mstatus, ie_mask, 0)); register_set(&target->reg_cache->reg_list[REG_MSTATUS], mstatus_bytes); - info->mstatus_actual = current_mstatus & ~MSTATUS_MIE; /// Run algorithm LOG_DEBUG("resume at 0x%x", entry_point); @@ -2746,7 +2746,6 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, LOG_DEBUG("Restoring Interrupts"); buf_set_u64(mstatus_bytes, 0, info->xlen, current_mstatus); register_set(&target->reg_cache->reg_list[REG_MSTATUS], mstatus_bytes); - info->mstatus_actual = current_mstatus; /// Restore registers uint8_t buf[8];