gdbstub on bp, unreachable, previous privilege S

master
vhaudiquet 11 months ago
parent b57739fe38
commit cf8a1de199
  1. 26
      src/cpu/exception.c
  2. 2
      src/cpu/exception.h
  3. 2
      src/cpu/interrupt.c
  4. 2
      src/cpu/rv32cpu.c

@ -1,8 +1,9 @@
#include "exception.h" #include "exception.h"
#include "vriscv.h"
#include <stdio.h> #include <stdio.h>
void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval) __attribute__((noreturn)) void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval)
{ {
// An exception can only be triggered by the CPU itself, // An exception can only be triggered by the CPU itself,
// so we know we already own the mutex // so we know we already own the mutex
@ -14,18 +15,28 @@ void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval)
// Exceptions cannot be disabled // Exceptions cannot be disabled
// Unset SIE (interrupt enable) bit
cpu->csr[CSR_SSTATUS] &= ~0b10U;
// Set xCAUSE : exception cause, with interrupt bit set to null // Set xCAUSE : exception cause, with interrupt bit set to null
cpu->csr[CSR_SCAUSE] = scause; cpu->csr[CSR_SCAUSE] = scause;
if(gdbstub && scause == SCAUSE_BREAKPOINT)
{
cpu->sim_ticks_left = 0;
// No simulation ticks left : wakeup people waiting on sim end
pthread_cond_signal(&cpu->sim_condition);
// Then, wait for simulation state to change until we get more ticks to simulate
while(!cpu->sim_ticks_left)
pthread_cond_wait(&cpu->sim_condition, &cpu->mutex);
}
// Save previous interrupt enable in xSTATUS.xPIE // Save previous interrupt enable in xSTATUS.xPIE
if(cpu->csr[CSR_SSTATUS] & 0b10U) if(cpu->csr[CSR_SSTATUS] & 0b10U)
cpu->csr[CSR_SSTATUS] |= 0x80; cpu->csr[CSR_SSTATUS] |= 0x80;
// Set previous privilege mode in xSTATUS.xPP // Set previous privilege mode in xSTATUS.xPP
// TODO // TODO : Allow user mode exceptions (by not setting this)
cpu->csr[CSR_SSTATUS] |= 0x100;
// Unset SIE (interrupt enable) bit
cpu->csr[CSR_SSTATUS] &= ~0b10U;
// Set privilege mode for exception handling, checking for delegation // Set privilege mode for exception handling, checking for delegation
// TODO // TODO
@ -44,6 +55,9 @@ void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval)
// Unlock cpu mutex, cpu_loop will lock it just after // Unlock cpu mutex, cpu_loop will lock it just after
pthread_mutex_unlock(&cpu->mutex); pthread_mutex_unlock(&cpu->mutex);
// cpu loop (attribute noreturn should erase previous stack) // TODO : Hard reset the stack pointer
// cpu loop
cpu_loop(cpu); cpu_loop(cpu);
__builtin_unreachable();
} }

@ -3,7 +3,7 @@
#include "rv32cpu.h" #include "rv32cpu.h"
void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval); __attribute__((noreturn)) void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval);
#define SCAUSE_INSTRUCTION_MISSALIGNED 0x0 #define SCAUSE_INSTRUCTION_MISSALIGNED 0x0
#define SCAUSE_INSTRUCTION_ACCESS_FAULT 0x1 #define SCAUSE_INSTRUCTION_ACCESS_FAULT 0x1

@ -42,6 +42,8 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause)
cpu->csr[CSR_SSTATUS] |= 0x80; cpu->csr[CSR_SSTATUS] |= 0x80;
// Set xSTATUS.xPP (Previous Privilege) bit // Set xSTATUS.xPP (Previous Privilege) bit
// TODO : Allow user mode interrupts (by not setting this)
cpu->csr[CSR_SSTATUS] |= 0x100;
// Unset xSTATUS.xIE (interrupt enable) bit // Unset xSTATUS.xIE (interrupt enable) bit
cpu->csr[CSR_SSTATUS] &= ~0b10U; cpu->csr[CSR_SSTATUS] &= ~0b10U;

@ -759,6 +759,8 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
// Let go of cpu mutex // Let go of cpu mutex
pthread_mutex_unlock(&cpu->mutex); pthread_mutex_unlock(&cpu->mutex);
} }
__builtin_unreachable();
} }
static void cpu_print_instruction(instruction_t* instruction) static void cpu_print_instruction(instruction_t* instruction)

Loading…
Cancel
Save