From: Tim Newsome Date: Wed, 9 Mar 2016 18:31:51 +0000 (-0800) Subject: Implement binary memory write. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;ds=sidebyside;h=38b8c095df4555b618bd269e3a53817c91dc893d;p=riscv-isa-sim.git Implement binary memory write. Also set the simulation running again when gdb disconnects. --- diff --git a/riscv/gdbserver.cc b/riscv/gdbserver.cc index a3663c9..d188f92 100644 --- a/riscv/gdbserver.cc +++ b/riscv/gdbserver.cc @@ -145,6 +145,7 @@ void gdbserver_t::accept() int oldopts = fcntl(client_fd, F_GETFL, 0); fcntl(client_fd, F_SETFL, oldopts | O_NONBLOCK); expect_ack = false; + extended_mode = false; // gdb wants the core to be halted when it attaches. processor_t *p = sim->get_core(0); @@ -170,11 +171,12 @@ void gdbserver_t::read() } else if (bytes == 0) { // The remote disconnected. client_fd = 0; + processor_t *p = sim->get_core(0); + p->set_halted(false); recv_buf.reset(); send_buf.reset(); } else { recv_buf.data_added(bytes); - printf("Read %d bytes.\n", bytes); } } @@ -251,7 +253,6 @@ void gdbserver_t::process_requests() uint8_t b = recv_buf[i]; if (packet.empty() && expect_ack && b == '+') { - fprintf(stderr, "Received ack\n"); recv_buf.consume(1); break; } @@ -287,8 +288,6 @@ void gdbserver_t::process_requests() // There's a partial packet in the buffer. Wait until we get more data to // process it. if (packet.size()) { - fprintf(stderr, "Partial packet: "); - print_packet(packet); break; } } @@ -299,7 +298,7 @@ void gdbserver_t::handle_halt_reason(const std::vector &packet) send_packet("S00"); } -void gdbserver_t::handle_read_general_registers(const std::vector &packet) +void gdbserver_t::handle_general_registers_read(const std::vector &packet) { // Register order that gdb expects is: // "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", @@ -345,7 +344,7 @@ uint64_t consume_hex_number(std::vector::const_iterator &iter, return value; } -void gdbserver_t::handle_read_register(const std::vector &packet) +void gdbserver_t::handle_register_read(const std::vector &packet) { // p n @@ -380,17 +379,15 @@ void gdbserver_t::handle_read_register(const std::vector &packet) expect_ack = true; } -void gdbserver_t::handle_read_memory(const std::vector &packet) +void gdbserver_t::handle_memory_read(const std::vector &packet) { // m addr,length std::vector::const_iterator iter = packet.begin() + 2; reg_t address = consume_hex_number(iter, packet.end()); - printf("address=%lx %c\n", address, *iter); if (*iter != ',') return send_packet("E16"); // EINVAL iter++; reg_t length = consume_hex_number(iter, packet.end()); - printf("length=%lx %c\n", length, *iter); if (*iter != '#') return send_packet("E16"); // EINVAL @@ -407,6 +404,64 @@ void gdbserver_t::handle_read_memory(const std::vector &packet) send_running_checksum(); } +void gdbserver_t::handle_memory_binary_write(const std::vector &packet) +{ + // X addr,length:XX... + std::vector::const_iterator iter = packet.begin() + 2; + reg_t address = consume_hex_number(iter, packet.end()); + if (*iter != ',') + return send_packet("E16"); // EINVAL + iter++; + reg_t length = consume_hex_number(iter, packet.end()); + if (*iter != ':') + return send_packet("E16"); // EINVAL + iter++; + + processor_t *p = sim->get_core(0); + mmu_t* mmu = sim->debug_mmu; + for (unsigned int i = 0; i < length; i++) { + if (iter == packet.end()) { + return send_packet("E16"); // EINVAL + } + mmu->store_uint8(address + i, *iter); + iter++; + } + if (*iter != '#') + return send_packet("E4b"); // EOVERFLOW + + send_packet("OK"); +} + +void gdbserver_t::handle_continue(const std::vector &packet) +{ + // c [addr] + processor_t *p = sim->get_core(0); + if (packet[2] != '#') { + std::vector::const_iterator iter = packet.begin() + 2; + p->state.pc = consume_hex_number(iter, packet.end()); + if (*iter != '#') + return send_packet("E16"); // EINVAL + } + + p->set_halted(false); +} + +void gdbserver_t::handle_kill(const std::vector &packet) +{ + // k + // The exact effect of this packet is not specified. + // Looks like OpenOCD disconnects? + // TODO +} + +void gdbserver_t::handle_extended(const std::vector &packet) +{ + // Enable extended mode. In extended mode, the remote server is made + // persistent. The ‘R’ packet is used to restart the program being debugged. + send_packet("OK"); + extended_mode = true; +} + void gdbserver_t::handle_packet(const std::vector &packet) { if (compute_checksum(packet) != extract_checksum(packet)) { @@ -422,19 +477,29 @@ void gdbserver_t::handle_packet(const std::vector &packet) send("+"); switch (packet[1]) { + case '!': + return handle_extended(packet); case '?': return handle_halt_reason(packet); case 'g': - return handle_read_general_registers(packet); + return handle_general_registers_read(packet); + case 'k': + return handle_kill(packet); case 'm': - return handle_read_memory(packet); + return handle_memory_read(packet); +// case 'M': +// return handle_memory_write(packet); + case 'X': + return handle_memory_binary_write(packet); case 'p': - return handle_read_register(packet); + return handle_register_read(packet); case 'c': return handle_continue(packet); } // Not supported. + fprintf(stderr, "** Unsupported packet: "); + print_packet(packet); send_packet(""); } @@ -445,20 +510,6 @@ void gdbserver_t::handle_interrupt() send_packet("S02"); // Pretend program received SIGINT. } -void gdbserver_t::handle_continue(const std::vector &packet) -{ - // c [addr] - processor_t *p = sim->get_core(0); - if (packet[2] != '#') { - std::vector::const_iterator iter = packet.begin() + 2; - p->state.pc = consume_hex_number(iter, packet.end()); - if (*iter != '#') - return send_packet("E16"); // EINVAL - } - - p->set_halted(false); -} - void gdbserver_t::handle() { if (client_fd > 0) { @@ -484,7 +535,7 @@ void gdbserver_t::send(uint64_t value) { char buffer[3]; for (unsigned int i = 0; i < 8; i++) { - sprintf(buffer, "%02x", value & 0xff); + sprintf(buffer, "%02x", (int) (value & 0xff)); send(buffer); value >>= 8; } @@ -494,7 +545,7 @@ void gdbserver_t::send(uint32_t value) { char buffer[3]; for (unsigned int i = 0; i < 4; i++) { - sprintf(buffer, "%02x", value & 0xff); + sprintf(buffer, "%02x", (int) (value & 0xff)); send(buffer); value >>= 8; } diff --git a/riscv/gdbserver.h b/riscv/gdbserver.h index 8add2ad..4b34aef 100644 --- a/riscv/gdbserver.h +++ b/riscv/gdbserver.h @@ -56,10 +56,13 @@ public: void handle_interrupt(); void handle_halt_reason(const std::vector &packet); - void handle_read_general_registers(const std::vector &packet); - void handle_read_memory(const std::vector &packet); - void handle_read_register(const std::vector &packet); + void handle_general_registers_read(const std::vector &packet); + void handle_memory_read(const std::vector &packet); + void handle_memory_binary_write(const std::vector &packet); + void handle_register_read(const std::vector &packet); void handle_continue(const std::vector &packet); + void handle_kill(const std::vector &packet); + void handle_extended(const std::vector &packet); private: sim_t *sim; @@ -69,6 +72,7 @@ private: circular_buffer_t send_buf; bool expect_ack; + bool extended_mode; // Read pending data from the client. void read();