Define CSR STATUS bits, std functions on exception
This commit is contained in:
parent
cf8a1de199
commit
2d33e50074
@ -61,4 +61,40 @@
|
||||
/* Machine Memory Protection */
|
||||
#define CSR_PMPCFG0 0x3A0
|
||||
|
||||
// CSR STATUS
|
||||
// SIE: Supervisor Interrupt Enable
|
||||
#define STATUS_SIE 0x2
|
||||
// MIE: Machine Interrupt Enable
|
||||
#define STATUS_MIE 0x8
|
||||
// SPIE: Supervisor Previous Interrupt Enable
|
||||
#define STATUS_SPIE 0x20
|
||||
// MPIE: Machine Previous Interrupt Enable
|
||||
#define STATUS_MPIE 0x80
|
||||
// UBE : User Big Endian (always 0 for us, we are little endian)
|
||||
#define STATUS_UBE 0x40
|
||||
// SPP : Supervisor Previous Privilege
|
||||
#define STATUS_SPP 0x100
|
||||
// VS (2bits) : for extensions
|
||||
#define STATUS_VS 0x600
|
||||
// MPP (2bits) : Machine Previous Privilege
|
||||
#define STATUS_MPP 0x1800
|
||||
// FS (2bits) : for extensions
|
||||
#define STATUS_FS 0x6000
|
||||
// XS (2bits) : for extensions
|
||||
#define STATUS_XS 0x18000
|
||||
// MPRV : Modify PRiVilege
|
||||
#define STATUS_MPRV 0x20000
|
||||
// SUM : permit Supervisor User Memory access
|
||||
#define STATUS_SUM 0x40000
|
||||
// MXR : Make eXecutable Readable
|
||||
#define STATUS_MXR 0x80000
|
||||
// TVM : Trap Virtual Memory (virtualization support)
|
||||
#define STATUS_TVM 0x100000
|
||||
// TW : Timeout Wait (virtualization support)
|
||||
#define STATUS_TW 0x200000
|
||||
// TSR : Trap SRET (virtualization support)
|
||||
#define STATUS_TSR 0x400000
|
||||
// SD : for extensions
|
||||
#define STATUS_SD 0x80000000
|
||||
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
@ -529,15 +529,14 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
case IMM_SRET:
|
||||
// SRET: Return from supervisor interrupt
|
||||
// Restore Interrupt Enable from Previous Interrupt Enable
|
||||
uint32_t sstatus = csr_read(cpu, CSR_SSTATUS);
|
||||
if(sstatus & 0x80)
|
||||
csr_write(cpu, CSR_SSTATUS, sstatus | 0b10);
|
||||
if(csr_read(cpu, CSR_SSTATUS) & STATUS_SPIE)
|
||||
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) | STATUS_SIE);
|
||||
|
||||
// Restore privilege mode from Previous Privilege
|
||||
// TODO
|
||||
|
||||
// Set Previous Interrupt Enable to 1
|
||||
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) | 0x80);
|
||||
csr_write(cpu, CSR_SSTATUS, csr_read(cpu, CSR_SSTATUS) | STATUS_SPIE);
|
||||
|
||||
// Set Previous Privilege to 0
|
||||
// TODO
|
||||
|
Loading…
Reference in New Issue
Block a user