Multithread gdbstub and execution, with cont/halt
This commit is contained in:
		| @@ -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); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user