Multiple cleanups and improvements

- Cleanup exception trigger code
- Cleanup division to divide by 0
- Cleanup SRET code
- Cleanup CSR code
- Added interrupts
- Added TIMER interrupt
This commit is contained in:
2023-10-22 19:20:52 +02:00
parent a0935f0aad
commit 02114ea7d8
8 changed files with 193 additions and 56 deletions

View File

@@ -2,24 +2,48 @@
#include <stdio.h>
void exception_trigger(rv32_cpu_t* cpu, uint32_t scause)
void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval)
{
// An exception can only be triggered by the CPU itself,
// so we know we already own the mutex
// We are in the CPU thread itself, but we need
// the return of this function to be the beginning of
// the cpu loop
// To achieve that, we can just call cpu_loop (noreturn)
// at the end of this function
// An exception can only be triggered by the CPU itself,
// so we know we already own the mutex
// We are in the CPU thread itself, but we need
// the return of this function to be the beginning of
// the cpu loop
// To achieve that, we can just call cpu_loop (noreturn)
// at the end of this function
// Save execution context, so that 'mret/sret/..' can restore it
// Exceptions cannot be disabled
// Set xCAUSE : exception cause, with interrupt bit set to null
cpu->csr[CSR_SCAUSE] = scause;
// Save previous interrupt enable in xSTATUS.xPIE
if(cpu->csr[CSR_SSTATUS] & 0b10U)
cpu->csr[CSR_SSTATUS] |= 0x80;
// Set previous privilege mode in xSTATUS.xPP
// TODO
// Set PC to STVEC, and set SCAUSE
// TODO: If PC cannot be mmu_resolved, throw a 'double fault' ?
cpu->pc = cpu->csr[CSR_STVEC];
cpu->csr[CSR_SCAUSE] = scause;
// Unset SIE (interrupt enable) bit
cpu->csr[CSR_SSTATUS] &= ~0b10U;
pthread_mutex_unlock(&cpu0_mutex);
cpu_loop(cpu);
// Set privilege mode for exception handling, checking for delegation
// TODO
// Set xTVAL, exception-specific information related to xCAUSE
cpu->csr[CSR_STVAL] = tval;
// Set SEPC to instruction that caused exception
cpu->csr[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;
// Unlock cpu mutex, cpu_loop will lock it just after
pthread_mutex_unlock(&cpu0_mutex);
// cpu loop (attribute noreturn should erase previous stack)
cpu_loop(cpu);
}