correct ebreak implementation, gdbstub watcher
everything in gdb should work now :)
This commit is contained in:
		@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user