Define CSR STATUS bits, std functions on exception

This commit is contained in:
2023-10-24 00:19:10 +02:00
parent cf8a1de199
commit 2d33e50074
3 changed files with 49 additions and 12 deletions

View File

@@ -16,10 +16,10 @@ __attribute__((noreturn)) void exception_trigger(rv32_cpu_t* cpu, uint32_t scaus
// Exceptions cannot be disabled
// Unset SIE (interrupt enable) bit
cpu->csr[CSR_SSTATUS] &= ~0b10U;
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) & (~STATUS_SIE));
// Set xCAUSE : exception cause, with interrupt bit set to null
cpu->csr[CSR_SCAUSE] = scause;
csr_write(cpu, CSR_SCAUSE, scause);
if(gdbstub && scause == SCAUSE_BREAKPOINT)
{
cpu->sim_ticks_left = 0;
@@ -31,26 +31,28 @@ __attribute__((noreturn)) void exception_trigger(rv32_cpu_t* cpu, uint32_t scaus
}
// Save previous interrupt enable in xSTATUS.xPIE
if(cpu->csr[CSR_SSTATUS] & 0b10U)
cpu->csr[CSR_SSTATUS] |= 0x80;
if(csr_read(cpu, CSR_SSTATUS) & STATUS_SIE)
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) | STATUS_SPIE);
else
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) & (~STATUS_SPIE));
// Set previous privilege mode in xSTATUS.xPP
// TODO : Allow user mode exceptions (by not setting this)
cpu->csr[CSR_SSTATUS] |= 0x100;
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) | STATUS_SPP);
// Set privilege mode for exception handling, checking for delegation
// TODO
// Set xTVAL, exception-specific information related to xCAUSE
cpu->csr[CSR_STVAL] = tval;
csr_write(cpu, CSR_STVAL, tval);
// Set SEPC to instruction that caused exception
cpu->csr[CSR_SEPC] = cpu->pc;
csr_write(cpu, CSR_SEPC, cpu->pc);
// Set PC to xTVEC : exception handling code
// xTVEC: [Base(30bits) Mode(2 bits)], address 4-byte aligned in base
// Exceptions are not vectored (we can safely ignore mode)
cpu->pc = cpu->csr[CSR_STVEC] & 0xFFFFFFFC;
cpu->pc = csr_read(cpu, CSR_STVEC) & 0xFFFFFFFC;
// Unlock cpu mutex, cpu_loop will lock it just after
pthread_mutex_unlock(&cpu->mutex);