From 0b0ae3586c50c110dad12cc04c029106e5f2eeb5 Mon Sep 17 00:00:00 2001 From: Oxore Date: Sun, 25 Sep 2022 21:13:36 +0300 Subject: Break execution on bus fault, support GDB NoAck mode --- emulator.cpp | 77 ++++++++++++++---------------------------------------------- 1 file changed, 18 insertions(+), 59 deletions(-) (limited to 'emulator.cpp') diff --git a/emulator.cpp b/emulator.cpp index 945a104..ceb4217 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -32,6 +32,7 @@ static constexpr struct timespec kOneMillisecond{0, 1000000}; char msg_buf[MESSAGE_BUFFER_SIZE]; M68KDebuggingControl g_m68k_debug{}; +bool g_no_ack_mode{}; static int set_socket_reuseaddr(const int socket_fd) { @@ -113,7 +114,14 @@ static std::string CreateResponse( case PacketType::kNone: break; case PacketType::kQuerySupported: - break; + return "PacketSize=400000" // PacketSize number is in HEX + // These commented-out options are from OpenOCD + // TODO ";qXfer:memory-map:read+" + // TODO ";qXfer:features:read+" + // TODO ";qXfer:threads:read+" + ";QStartNoAckMode+" // It makes GDB shit fast! + ";vContSupported+" // We support "vCont?" packet + ; case PacketType::kQueryHaltReason: return "S05"; // TODO real reason case PacketType::kQueryC: @@ -145,6 +153,9 @@ static std::string CreateResponse( } } break; + case PacketType::kQStartNoAckMode: + g_no_ack_mode = true; + return "OK"; case PacketType::kSetThreadForCont: return "OK"; case PacketType::kSetThreadForOps: @@ -287,63 +298,11 @@ int m68k_instr_callback(const int pc) return 0; } -static inline bool ranges_overlap( - const uint32_t a_start, - const uint32_t a_len, - const uint32_t b_start, - const uint32_t b_len) -{ - return (a_start < b_start + b_len && b_start < a_start + a_len); -} - -// XXX Maybe better move it to bus.cpp? -void m68k_read_callback(const uint32_t address, const uint32_t size) -{ - const auto access_it = std::find_if( - access_bkpts.begin(), - access_bkpts.end(), - [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); }); - if (access_it != access_bkpts.end()) { - g_m68k_debug.SetRunning(false); - g_m68k_debug.RaiseBreakpoint(); - m68k_end_timeslice(); - printf("Access watchpoint @ 0x%08x\n", address); - } - const auto it = std::find_if( - read_bkpts.begin(), - read_bkpts.end(), - [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); }); - if (it != read_bkpts.end()) { - g_m68k_debug.SetRunning(false); - g_m68k_debug.RaiseBreakpoint(); - m68k_end_timeslice(); - printf("Read watchpoint @ 0x%08x\n", address); - } -} - -// XXX Maybe better move it to bus.cpp? -void m68k_write_callback(const uint32_t address, const uint32_t size) +void m68k_breakpoint_callback(void) { - const auto access_it = std::find_if( - access_bkpts.begin(), - access_bkpts.end(), - [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); }); - if (access_it != access_bkpts.end()) { - g_m68k_debug.SetRunning(false); - g_m68k_debug.RaiseBreakpoint(); - m68k_end_timeslice(); - printf("Access watchpoint @ 0x%08x\n", address); - } - const auto it = std::find_if( - write_bkpts.begin(), - write_bkpts.end(), - [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); }); - if (it != write_bkpts.end()) { - g_m68k_debug.SetRunning(false); - g_m68k_debug.RaiseBreakpoint(); - m68k_end_timeslice(); - printf("Write watchpoint @ 0x%08x\n", address); - } + g_m68k_debug.SetRunning(false); + g_m68k_debug.RaiseBreakpoint(); + m68k_end_timeslice(); } void ParseAndReact( @@ -363,7 +322,7 @@ void ParseAndReact( " Packet type: \"%s\"\n", GDBRemote::Packet::PacketTypeToString(packet.type)); } - if (res->ack.length() > 0) { + if (res->ack.length() > 0 && !g_no_ack_mode) { printf("-> \"%s\"\n", res->ack.c_str()); if (send(conn_fd, &res->ack[0], res->ack.length(), 0) == -1) perror("Send failed (ack/nak)"); @@ -428,7 +387,7 @@ int emulator(M68KDebuggingControl& m68k_debug) break; } if (m68k_debug.IsRunning()) { - m68k_execute(1000); + m68k_execute(10000); } if (m68k_debug.HasBreakpoint()) { m68k_debug.ResetPendingBreakpoint(); -- cgit v1.2.3