Make CPU and memory thread-safe
This commit is contained in:
		@@ -9,7 +9,7 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rv32_cpu_t* cpu0;
 | 
					rv32_cpu_t* cpu0;
 | 
				
			||||||
pthread_mutex_t* cpu0_mutex;
 | 
					pthread_mutex_t cpu0_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef union RAW_INSTRUCTION
 | 
					typedef union RAW_INSTRUCTION
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -41,7 +41,7 @@ static void cpu_print_instruction(instruction_t* instruction);
 | 
				
			|||||||
void cpu_init()
 | 
					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);
 | 
				
			||||||
	cpu0->regs.zero = 0;
 | 
						cpu0->regs.zero = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -647,8 +647,9 @@ void cpu_loop(rv32_cpu_t* cpu)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	while(1)
 | 
						while(1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Aquire CPU mutex
 | 
							// Aquire CPU and memory mutex
 | 
				
			||||||
		pthread_mutex_lock(cpu0_mutex);
 | 
							pthread_mutex_lock(&cpu0_mutex);
 | 
				
			||||||
 | 
							pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Fetch
 | 
							// Fetch
 | 
				
			||||||
		raw_instruction_t raw_instruction;
 | 
							raw_instruction_t raw_instruction;
 | 
				
			||||||
@@ -674,8 +675,9 @@ void cpu_loop(rv32_cpu_t* cpu)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		cpu->pc += 4;
 | 
							cpu->pc += 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Let go of cpu mutex
 | 
							// Let go of cpu and memory mutex
 | 
				
			||||||
		pthread_mutex_unlock(cpu0_mutex);
 | 
							pthread_mutex_unlock(&cpu0_mutex);
 | 
				
			||||||
 | 
							pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -189,7 +189,7 @@ typedef struct RV32_CPU
 | 
				
			|||||||
} rv32_cpu_t;
 | 
					} rv32_cpu_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern rv32_cpu_t* cpu0;
 | 
					extern rv32_cpu_t* cpu0;
 | 
				
			||||||
extern pthread_mutex_t* cpu0_mutex;
 | 
					extern pthread_mutex_t cpu0_mutex;
 | 
				
			||||||
void cpu_init();
 | 
					void cpu_init();
 | 
				
			||||||
void cpu_loop(rv32_cpu_t* cpu);
 | 
					void cpu_loop(rv32_cpu_t* cpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,7 +184,7 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
			char resp[32 * 8 + 8 + 1] = {0};
 | 
								char resp[32 * 8 + 8 + 1] = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Obtain CPU0 mutex
 | 
								// Obtain CPU0 mutex
 | 
				
			||||||
			pthread_mutex_lock(cpu0_mutex);
 | 
								pthread_mutex_lock(&cpu0_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// All general purpose registers in host byte order as chars
 | 
								// All general purpose registers in host byte order as chars
 | 
				
			||||||
			for(size_t i = 0; i < 32; i++)
 | 
								for(size_t i = 0; i < 32; i++)
 | 
				
			||||||
@@ -198,7 +198,7 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
			snprintf(resp + 32 * 8, 9, "%08x", pc);
 | 
								snprintf(resp + 32 * 8, 9, "%08x", pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Let go of CPU0 mutex
 | 
								// Let go of CPU0 mutex
 | 
				
			||||||
			pthread_mutex_unlock(cpu0_mutex);
 | 
								pthread_mutex_unlock(&cpu0_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Final packet size, send packet
 | 
								// Final packet size, send packet
 | 
				
			||||||
			size_t size = 32 * 8 + 8;
 | 
								size_t size = 32 * 8 + 8;
 | 
				
			||||||
@@ -209,7 +209,7 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
			// G : write all registers -> read and set all registers
 | 
								// G : write all registers -> read and set all registers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Obtain CPU0 mutex
 | 
								// Obtain CPU0 mutex
 | 
				
			||||||
			pthread_mutex_lock(cpu0_mutex);
 | 
								pthread_mutex_lock(&cpu0_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// All general purpose registers in host byte order as chars
 | 
								// All general purpose registers in host byte order as chars
 | 
				
			||||||
			for(size_t i = 1; i < 32; i++)
 | 
								for(size_t i = 1; i < 32; i++)
 | 
				
			||||||
@@ -228,7 +228,7 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
			cpu0->pc = pc;
 | 
								cpu0->pc = pc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Let go of CPU0 Mutex
 | 
								// Let go of CPU0 Mutex
 | 
				
			||||||
			pthread_mutex_unlock(cpu0_mutex);
 | 
								pthread_mutex_unlock(&cpu0_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			gdbstub_send_packet("OK", 2);
 | 
								gdbstub_send_packet("OK", 2);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -239,6 +239,9 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
			uint32_t length;
 | 
								uint32_t length;
 | 
				
			||||||
			sscanf(packet + 1, "%x,%x", &address, &length);
 | 
								sscanf(packet + 1, "%x,%x", &address, &length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Aquire memory mutex
 | 
				
			||||||
 | 
								pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			char data[length * 2 + 1];
 | 
								char data[length * 2 + 1];
 | 
				
			||||||
			for(size_t i = 0; i < length; i++)
 | 
								for(size_t i = 0; i < length; i++)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -246,6 +249,9 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
				snprintf(data + i * 2, 3, "%02x", value);
 | 
									snprintf(data + i * 2, 3, "%02x", value);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Let go of memory mutex
 | 
				
			||||||
 | 
								pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			gdbstub_send_packet(data, length * 2);
 | 
								gdbstub_send_packet(data, length * 2);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if(packet[0] == 'M')
 | 
							else if(packet[0] == 'M')
 | 
				
			||||||
@@ -260,6 +266,9 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
				data_start++;
 | 
									data_start++;
 | 
				
			||||||
			data_start++;
 | 
								data_start++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Aquire memory mutex
 | 
				
			||||||
 | 
								pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for(size_t i = 0; i < length; i++)
 | 
								for(size_t i = 0; i < length; i++)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				uint32_t value;
 | 
									uint32_t value;
 | 
				
			||||||
@@ -267,6 +276,9 @@ void gdbstub_thread_gdb()
 | 
				
			|||||||
				memory[mmu_translate(address + i)] = value;
 | 
									memory[mmu_translate(address + i)] = value;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Let go of memory mutex
 | 
				
			||||||
 | 
								pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			gdbstub_send_packet("OK", 2);
 | 
								gdbstub_send_packet("OK", 2);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if(packet[0] == 's')
 | 
							else if(packet[0] == 's')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,10 @@
 | 
				
			|||||||
#include "vriscv.h"
 | 
					#include "vriscv.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint8_t* memory;
 | 
					uint8_t* memory;
 | 
				
			||||||
 | 
					pthread_mutex_t memory_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void mem_init()
 | 
					void mem_init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    memory = malloc(memory_size);
 | 
					    memory = malloc(memory_size);
 | 
				
			||||||
 | 
					    pthread_mutex_init(&memory_mutex, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,10 @@
 | 
				
			|||||||
#define MEMORY_H
 | 
					#define MEMORY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern uint8_t* memory;
 | 
					extern uint8_t* memory;
 | 
				
			||||||
 | 
					extern pthread_mutex_t memory_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void mem_init();
 | 
					void mem_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user