From 980070b204bd35839f90ea0a237699032b1c5261 Mon Sep 17 00:00:00 2001 From: vhaudiquet Date: Sun, 8 Oct 2023 19:04:25 +0200 Subject: [PATCH] correct ebreak implementation, gdbstub watcher everything in gdb should work now :) --- src/cpu/rv32cpu.c | 10 +++++++++- src/gdbstub/gdbstub.c | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index a85dae9..a1ea41f 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -512,7 +512,10 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) fprintf(stderr, "ECALL: a7(sbi ext id) = %d, a6(sbi funct id) = %d\n", cpu->regs.a7, cpu->regs.a6); break; case IMM_EBREAK: - fprintf(stderr, "EBREAK\n"); + // EBREAK : on debug, give back hand to debugger ; without debug, end simulation + // In any way, we set back simulation ticks to 0 + cpu->sim_ticks_left = 1; + cpu->pc -= 4; break; default: fprintf(stderr, "FATAL: Unknown IMM for ECALL/EBREAK instruction while executing (IMM=0x%x)\n", instruction->immediate); @@ -650,6 +653,11 @@ void cpu_loop(rv32_cpu_t* cpu) { // Aquire CPU and memory mutex pthread_mutex_lock(&cpu0_mutex); + + // No simulation ticks left : wakeup people waiting on sim end + if(!cpu->sim_ticks_left) + pthread_cond_signal(&cpu0->sim_condition); + // Then, wait for simulation state to change until we get more ticks to simulate while(!cpu->sim_ticks_left) pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); diff --git a/src/gdbstub/gdbstub.c b/src/gdbstub/gdbstub.c index d556dd2..337eeac 100644 --- a/src/gdbstub/gdbstub.c +++ b/src/gdbstub/gdbstub.c @@ -25,10 +25,13 @@ typedef struct sockaddr sockaddr_t; socket_t gdbstub_server_socket; socket_t gdb_socket; pthread_t gdbstub_thread; +pthread_t gdbstub_watcher_thread; void gdbstub_thread_gdb(); +void gdbstub_cpu_watcher_thread(); static void gdbstub_handle_ctrlc(); + /* * Receive a packet from client gdb * Ignores the ACK on the way, and only returns the packet (not initial '$' symbol) @@ -161,6 +164,7 @@ void gdbstub_wait_for_connection() gdb_socket = c_socket; pthread_create(&gdbstub_thread, 0, (void*) gdbstub_thread_gdb, 0); + pthread_create(&gdbstub_watcher_thread, 0, (void*) gdbstub_cpu_watcher_thread, 0); } void gdbstub_thread_gdb() @@ -286,12 +290,14 @@ void gdbstub_thread_gdb() { // s : single-step - // TODO : Implement that correctly + // Send an ACK + send(gdb_socket, "+", 1, 0); - // Send back halt reason - // Halt Reason : Signal 05 (SIGTRAP) - char* resp = "S05"; - gdbstub_send_packet(resp, 3); + // Continue simulation, for 1 tick + pthread_mutex_lock(&cpu0_mutex); + cpu0->sim_ticks_left = 1; + pthread_mutex_unlock(&cpu0_mutex); + pthread_cond_signal(&cpu0->sim_condition); } else if(packet[0] == 'c') { @@ -310,6 +316,23 @@ void gdbstub_thread_gdb() } } +void gdbstub_cpu_watcher_thread() +{ + while(1) + { + pthread_mutex_lock(&cpu0_mutex); + pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); + if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0) + { + // Send back halt reason + // Halt Reason : Signal 05 (SIGTRAP) + char* resp = "S05"; + gdbstub_send_packet(resp, 3); + } + pthread_mutex_unlock(&cpu0_mutex); + } +} + /* * Handles the GDB CTRL+C (^C) command, that * should interrupt the simulation @@ -320,9 +343,4 @@ static void gdbstub_handle_ctrlc() pthread_mutex_lock(&cpu0_mutex); cpu0->sim_ticks_left = 0; pthread_mutex_unlock(&cpu0_mutex); - - // Send back halt signal to gdb - // Halt Reason : Signal 05 (SIGTRAP) - char* resp = "S05"; - gdbstub_send_packet(resp, 3); }