From f3c39b00ca73f19b3e9685b06afd7107f338ffa2 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 5 May 2016 14:53:56 -0700 Subject: [PATCH] Make sure to fence.i after setting/clearing a swbp This doesn't change anything since Debug ROM already executes a fence.i, but it will be more correct if that is no longer necessary. --- riscv/gdbserver.cc | 18 +++++++++++++----- riscv/gdbserver.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/riscv/gdbserver.cc b/riscv/gdbserver.cc index 43e0adb..fbe0027 100644 --- a/riscv/gdbserver.cc +++ b/riscv/gdbserver.cc @@ -86,6 +86,11 @@ static uint32_t csrw(unsigned int source, unsigned int csr) { return (csr << 20) | (source << 15) | MATCH_CSRRW; } +static uint32_t fence_i() +{ + return MATCH_FENCE_I; +} + static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) { return (bits(offset, 11, 5) << 25) | @@ -337,7 +342,13 @@ class continue_op_t : public operation_t case 0: gs.write_debug_ram(0, ld(S0, 0, (uint16_t) DEBUG_RAM_START+16)); gs.write_debug_ram(1, csrw(S0, DPC_ADDRESS)); - gs.write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2)))); + if (gs.fence_i_required) { + gs.write_debug_ram(2, fence_i()); + gs.write_debug_ram(3, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*3)))); + gs.fence_i_required = false; + } else { + gs.write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2)))); + } gs.write_debug_ram(4, gs.saved_dpc); gs.write_debug_ram(5, gs.saved_dpc >> 32); gs.set_interrupt(0); @@ -1389,9 +1400,9 @@ void gdbserver_t::handle_breakpoint(const std::vector &packet) return send_packet("E53"); } + fence_i_required = true; add_operation(new collect_translation_info_op_t(*this, bp.address, bp.size)); if (insert) { - // TODO: this only works on little-endian hosts. unsigned char* swbp = new unsigned char[4]; if (bp.size == 2) { swbp[0] = C_EBREAK & 0xff; @@ -1419,9 +1430,6 @@ void gdbserver_t::handle_breakpoint(const std::vector &packet) delete found_bp; } - // TODO mmu->flush_icache(); - // TODO sim->debug_mmu->flush_icache(); - return send_packet("OK"); } diff --git a/riscv/gdbserver.h b/riscv/gdbserver.h index 2ab2ffe..6211146 100644 --- a/riscv/gdbserver.h +++ b/riscv/gdbserver.h @@ -142,6 +142,7 @@ public: reg_t dcsr; reg_t sptbr; bool sptbr_valid; + bool fence_i_required; std::map pte_cache; -- 2.30.2