Refactor CPU mutex code
This commit is contained in:
parent
02114ea7d8
commit
71f3fbc8b5
@ -42,7 +42,7 @@ void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval)
|
|||||||
cpu->pc = cpu->csr[CSR_STVEC] & 0xFFFFFFFC;
|
cpu->pc = cpu->csr[CSR_STVEC] & 0xFFFFFFFC;
|
||||||
|
|
||||||
// Unlock cpu mutex, cpu_loop will lock it just after
|
// Unlock cpu mutex, cpu_loop will lock it just after
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu->mutex);
|
||||||
|
|
||||||
// cpu loop (attribute noreturn should erase previous stack)
|
// cpu loop (attribute noreturn should erase previous stack)
|
||||||
cpu_loop(cpu);
|
cpu_loop(cpu);
|
||||||
|
@ -33,7 +33,7 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause)
|
|||||||
// but we know it is not in the middle of an instruction
|
// but we know it is not in the middle of an instruction
|
||||||
// (we got the mutex) ; this way we can just change
|
// (we got the mutex) ; this way we can just change
|
||||||
// registers to set interrupt handler execution
|
// registers to set interrupt handler execution
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu->mutex);
|
||||||
|
|
||||||
// Set xCAUSE with interrupt bit set
|
// Set xCAUSE with interrupt bit set
|
||||||
cpu->csr[CSR_SCAUSE] = 0x80000000 | scause;
|
cpu->csr[CSR_SCAUSE] = 0x80000000 | scause;
|
||||||
@ -67,7 +67,7 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interrupt_timer_thread()
|
void interrupt_timer_thread()
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
rv32_cpu_t* cpu0;
|
rv32_cpu_t* cpu0;
|
||||||
pthread_mutex_t cpu0_mutex;
|
|
||||||
|
|
||||||
typedef union RAW_INSTRUCTION
|
typedef union RAW_INSTRUCTION
|
||||||
{
|
{
|
||||||
@ -43,7 +42,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);
|
||||||
pthread_cond_init(&cpu0->sim_condition, 0);
|
pthread_cond_init(&cpu0->sim_condition, 0);
|
||||||
cpu0->regs.zero = 0;
|
cpu0->regs.zero = 0;
|
||||||
cpu0->privilege_mode = MACHINE;
|
cpu0->privilege_mode = MACHINE;
|
||||||
@ -716,14 +715,14 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
|
|||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
// Aquire CPU mutex
|
// Aquire CPU mutex
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu->mutex);
|
||||||
|
|
||||||
// No simulation ticks left : wakeup people waiting on sim end
|
// No simulation ticks left : wakeup people waiting on sim end
|
||||||
if(!cpu->sim_ticks_left)
|
if(!cpu->sim_ticks_left)
|
||||||
pthread_cond_signal(&cpu0->sim_condition);
|
pthread_cond_signal(&cpu->sim_condition);
|
||||||
// Then, wait for simulation state to change until we get more ticks to simulate
|
// Then, wait for simulation state to change until we get more ticks to simulate
|
||||||
while(!cpu->sim_ticks_left)
|
while(!cpu->sim_ticks_left)
|
||||||
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex);
|
pthread_cond_wait(&cpu->sim_condition, &cpu->mutex);
|
||||||
|
|
||||||
// Fetch
|
// Fetch
|
||||||
raw_instruction_t raw_instruction;
|
raw_instruction_t raw_instruction;
|
||||||
@ -758,7 +757,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
|
|||||||
cpu->sim_ticks_left--;
|
cpu->sim_ticks_left--;
|
||||||
|
|
||||||
// Let go of cpu mutex
|
// Let go of cpu mutex
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,13 +205,14 @@ typedef struct RV32_CPU
|
|||||||
ssize_t sim_ticks_left; // -1 : simulate forever
|
ssize_t sim_ticks_left; // -1 : simulate forever
|
||||||
size_t sim_ticks_done;
|
size_t sim_ticks_done;
|
||||||
pthread_cond_t sim_condition;
|
pthread_cond_t sim_condition;
|
||||||
|
|
||||||
|
pthread_mutex_t mutex;
|
||||||
} rv32_cpu_t;
|
} rv32_cpu_t;
|
||||||
|
|
||||||
uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr);
|
uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr);
|
||||||
void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value);
|
void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value);
|
||||||
|
|
||||||
extern rv32_cpu_t* cpu0;
|
extern rv32_cpu_t* cpu0;
|
||||||
extern pthread_mutex_t cpu0_mutex;
|
|
||||||
void cpu_init();
|
void cpu_init();
|
||||||
__attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu);
|
__attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu);
|
||||||
|
|
||||||
|
@ -203,7 +203,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++)
|
||||||
@ -217,7 +217,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;
|
||||||
@ -228,7 +228,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++)
|
||||||
@ -247,7 +247,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);
|
||||||
}
|
}
|
||||||
@ -296,9 +296,9 @@ void gdbstub_thread_gdb()
|
|||||||
send(gdb_socket, "+", 1, 0);
|
send(gdb_socket, "+", 1, 0);
|
||||||
|
|
||||||
// Continue simulation, for 1 tick
|
// Continue simulation, for 1 tick
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu0->mutex);
|
||||||
cpu0->sim_ticks_left = 1;
|
cpu0->sim_ticks_left = 1;
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu0->mutex);
|
||||||
pthread_cond_signal(&cpu0->sim_condition);
|
pthread_cond_signal(&cpu0->sim_condition);
|
||||||
}
|
}
|
||||||
else if(packet[0] == 'c')
|
else if(packet[0] == 'c')
|
||||||
@ -309,9 +309,9 @@ void gdbstub_thread_gdb()
|
|||||||
send(gdb_socket, "+", 1, 0);
|
send(gdb_socket, "+", 1, 0);
|
||||||
|
|
||||||
// Continue simulation
|
// Continue simulation
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu0->mutex);
|
||||||
cpu0->sim_ticks_left = -1;
|
cpu0->sim_ticks_left = -1;
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu0->mutex);
|
||||||
pthread_cond_signal(&cpu0->sim_condition);
|
pthread_cond_signal(&cpu0->sim_condition);
|
||||||
}
|
}
|
||||||
else gdbstub_send_unsupported();
|
else gdbstub_send_unsupported();
|
||||||
@ -322,8 +322,8 @@ void gdbstub_cpu_watcher_thread()
|
|||||||
{
|
{
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu0->mutex);
|
||||||
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex);
|
pthread_cond_wait(&cpu0->sim_condition, &cpu0->mutex);
|
||||||
if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0)
|
if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0)
|
||||||
{
|
{
|
||||||
// Send back halt reason
|
// Send back halt reason
|
||||||
@ -331,7 +331,7 @@ void gdbstub_cpu_watcher_thread()
|
|||||||
char* resp = "S05";
|
char* resp = "S05";
|
||||||
gdbstub_send_packet(resp, 3);
|
gdbstub_send_packet(resp, 3);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu0->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ void gdbstub_cpu_watcher_thread()
|
|||||||
static void gdbstub_handle_ctrlc()
|
static void gdbstub_handle_ctrlc()
|
||||||
{
|
{
|
||||||
// Halt the simulation
|
// Halt the simulation
|
||||||
pthread_mutex_lock(&cpu0_mutex);
|
pthread_mutex_lock(&cpu0->mutex);
|
||||||
cpu0->sim_ticks_left = 0;
|
cpu0->sim_ticks_left = 0;
|
||||||
pthread_mutex_unlock(&cpu0_mutex);
|
pthread_mutex_unlock(&cpu0->mutex);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user