Multithread gdbstub and execution, with cont/halt

master
vhaudiquet 1 year ago
parent a10f56446a
commit f52699a8bf
  1. 9
      src/cpu/rv32cpu.c
  2. 7
      src/cpu/rv32cpu.h
  3. 12
      src/gdbstub/gdbstub.c
  4. 1
      src/main.c

@ -42,6 +42,7 @@ void cpu_init()
{ {
cpu0 = calloc(1, sizeof(rv32_cpu_t)); cpu0 = calloc(1, sizeof(rv32_cpu_t));
pthread_mutex_init(&cpu0_mutex, 0); pthread_mutex_init(&cpu0_mutex, 0);
pthread_cond_init(&cpu0->sim_condition, 0);
cpu0->regs.zero = 0; cpu0->regs.zero = 0;
} }
@ -651,6 +652,9 @@ void cpu_loop(rv32_cpu_t* cpu)
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0_mutex);
pthread_mutex_lock(&memory_mutex); pthread_mutex_lock(&memory_mutex);
while(!cpu->sim_ticks_left)
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex);
// Fetch // Fetch
raw_instruction_t raw_instruction; raw_instruction_t raw_instruction;
if(cpu->pc > memory_size - 4) if(cpu->pc > memory_size - 4)
@ -675,6 +679,11 @@ void cpu_loop(rv32_cpu_t* cpu)
cpu->pc += 4; cpu->pc += 4;
// Update simulation data
cpu->sim_ticks_done++;
if(cpu->sim_ticks_left != (-1))
cpu->sim_ticks_left--;
// Let go of cpu and memory mutex // Let go of cpu and memory mutex
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0_mutex);
pthread_mutex_unlock(&memory_mutex); pthread_mutex_unlock(&memory_mutex);

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h>
/* /*
* This is a structure encoding for the registers of * This is a structure encoding for the registers of
@ -184,8 +185,14 @@ typedef struct RV32_CPU_REGS
typedef struct RV32_CPU typedef struct RV32_CPU
{ {
// CPU values
rv32_cpu_regs_t regs; rv32_cpu_regs_t regs;
uint32_t pc; uint32_t pc;
// Simulation data
ssize_t sim_ticks_left; // -1 : simulate forever
size_t sim_ticks_done;
pthread_cond_t sim_condition;
} rv32_cpu_t; } rv32_cpu_t;
extern rv32_cpu_t* cpu0; extern rv32_cpu_t* cpu0;

@ -24,6 +24,7 @@ typedef struct sockaddr sockaddr_t;
socket_t gdbstub_server_socket; socket_t gdbstub_server_socket;
socket_t gdb_socket; socket_t gdb_socket;
pthread_t gdbstub_thread;
void gdbstub_thread_gdb(); void gdbstub_thread_gdb();
static void gdbstub_handle_ctrlc(); static void gdbstub_handle_ctrlc();
@ -159,7 +160,7 @@ void gdbstub_wait_for_connection()
gdb_socket = c_socket; gdb_socket = c_socket;
gdbstub_thread_gdb(); pthread_create(&gdbstub_thread, 0, (void*) gdbstub_thread_gdb, 0);
} }
void gdbstub_thread_gdb() void gdbstub_thread_gdb()
@ -285,6 +286,8 @@ void gdbstub_thread_gdb()
{ {
// s : single-step // s : single-step
// TODO : Implement that correctly
// Send back halt reason // Send back halt reason
// Halt Reason : Signal 05 (SIGTRAP) // Halt Reason : Signal 05 (SIGTRAP)
char* resp = "S05"; char* resp = "S05";
@ -298,6 +301,10 @@ void gdbstub_thread_gdb()
send(gdb_socket, "+", 1, 0); send(gdb_socket, "+", 1, 0);
// Continue simulation // Continue simulation
pthread_mutex_lock(&cpu0_mutex);
cpu0->sim_ticks_left = -1;
pthread_mutex_unlock(&cpu0_mutex);
pthread_cond_signal(&cpu0->sim_condition);
} }
else gdbstub_send_unsupported(); else gdbstub_send_unsupported();
} }
@ -310,6 +317,9 @@ void gdbstub_thread_gdb()
static void gdbstub_handle_ctrlc() static void gdbstub_handle_ctrlc()
{ {
// Halt the simulation // Halt the simulation
pthread_mutex_lock(&cpu0_mutex);
cpu0->sim_ticks_left = 0;
pthread_mutex_unlock(&cpu0_mutex);
// Send back halt signal to gdb // Send back halt signal to gdb
// Halt Reason : Signal 05 (SIGTRAP) // Halt Reason : Signal 05 (SIGTRAP)

@ -28,6 +28,7 @@ int main(int argc, char** argv)
} }
// CPU simulation : create cpu0 thread // CPU simulation : create cpu0 thread
if(!gdbstub) cpu0->sim_ticks_left = -1; // Simulate forever
pthread_t cpu0_thread; pthread_t cpu0_thread;
pthread_create(&cpu0_thread, 0, (void*) cpu_loop, cpu0); pthread_create(&cpu0_thread, 0, (void*) cpu_loop, cpu0);

Loading…
Cancel
Save