Implement counteren (1.10+ spec)
This commit is contained in:
parent
570720fdd8
commit
b01490b5f3
|
@ -215,6 +215,7 @@ object Riscv{
|
|||
def MINSTRET = 0xB02 // MRW Machine instructions-retired counter.
|
||||
def MCYCLEH = 0xB80 // MRW Upper 32 bits of mcycle, RV32I only.
|
||||
def MINSTRETH = 0xB82 // MRW Upper 32 bits of minstret, RV32I only.
|
||||
val MCOUNTEREN = 0x306
|
||||
|
||||
val SSTATUS = 0x100
|
||||
val SIE = 0x104
|
||||
|
|
|
@ -1058,6 +1058,28 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
|||
utimeAccess(CSR.UTIMEH, utime(63 downto 32))
|
||||
}
|
||||
|
||||
class Xcounteren(csrId : Int) extends Area{
|
||||
val IR,TM,CY = RegInit(True) //For backward compatibility
|
||||
if(ucycleAccess != CsrAccess.NONE) rw(csrId, 0 -> CY)
|
||||
if(utimeAccess != CsrAccess.NONE) rw(csrId, 1 -> TM)
|
||||
if(uinstretAccess != CsrAccess.NONE) rw(csrId, 2 -> IR)
|
||||
}
|
||||
def xcounterChecks(access : CsrAccess, csrId : Int, enable : Xcounteren => Bool) = {
|
||||
if(access != CsrAccess.NONE) during(csrId){
|
||||
if(userGen) when(privilege < 3 && !enable(mcounteren)){ forceFailCsr() }
|
||||
if(supervisorGen) when(privilege < 1 && !enable(scounteren)){ forceFailCsr() }
|
||||
}
|
||||
}
|
||||
|
||||
val mcounteren = userGen generate new Xcounteren(CSR.MCOUNTEREN)
|
||||
val scounteren = supervisorGen generate new Xcounteren(CSR.SCOUNTEREN)
|
||||
xcounterChecks(ucycleAccess , CSR.UCYCLE , _.CY)
|
||||
xcounterChecks(ucycleAccess , CSR.UCYCLEH , _.CY)
|
||||
xcounterChecks(utimeAccess , CSR.UTIME , _.TM)
|
||||
xcounterChecks(utimeAccess , CSR.UTIMEH , _.TM)
|
||||
xcounterChecks(uinstretAccess, CSR.UINSTRET , _.IR)
|
||||
xcounterChecks(uinstretAccess, CSR.UINSTRETH, _.IR)
|
||||
|
||||
pipeline(MPP) := mstatus.MPP
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
.globl _star
|
||||
#define TEST_ID x28
|
||||
|
||||
#include "privileged.h"
|
||||
|
||||
|
||||
|
||||
_start:
|
||||
la x1, fail
|
||||
csrw mtvec, x1
|
||||
|
@ -18,12 +22,15 @@ test1:
|
|||
csrr x2, stvec
|
||||
bnez x2, fail
|
||||
|
||||
la x1, fail
|
||||
csrw mtvec, x1
|
||||
|
||||
li x1, 9
|
||||
csrw mcause, x1
|
||||
csrr x2, mcause
|
||||
bne x2, x1, fail
|
||||
|
||||
csrr x0, pmpcfg0
|
||||
/*csrr x0, pmpcfg0
|
||||
csrw pmpcfg0, x0
|
||||
|
||||
csrr x0, pmpcfg3
|
||||
|
@ -33,7 +40,154 @@ test1:
|
|||
csrw pmpaddr0, x0
|
||||
|
||||
csrr x0, pmpaddr15
|
||||
csrw pmpaddr15, x0
|
||||
csrw pmpaddr15, x0*/
|
||||
|
||||
li TEST_ID, 2
|
||||
csrr x1, mcycle
|
||||
csrr x2, mcycle
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, minstret
|
||||
csrr x2, minstret
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, cycle
|
||||
csrr x2, cycle
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, instret
|
||||
csrr x2, instret
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, time
|
||||
csrr x2, time
|
||||
bge x1, x2, fail
|
||||
|
||||
//Test access to counters in supervisor
|
||||
machine_setup_trap
|
||||
machine_to_supervisor
|
||||
li TEST_ID, 3
|
||||
|
||||
csrr x1, cycle
|
||||
csrr x2, cycle
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, instret
|
||||
csrr x2, instret
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, time
|
||||
csrr x2, time
|
||||
bge x1, x2, fail
|
||||
|
||||
ecall
|
||||
machine_handle_trap
|
||||
|
||||
//Test access to counters in user
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
li TEST_ID, 4
|
||||
|
||||
csrr x1, cycle
|
||||
csrr x2, cycle
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, instret
|
||||
csrr x2, instret
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, time
|
||||
csrr x2, time
|
||||
bge x1, x2, fail
|
||||
ecall
|
||||
machine_handle_trap
|
||||
|
||||
//Remove user access to counters
|
||||
li x1, -1
|
||||
csrw mcounteren, x1
|
||||
li x1, 0
|
||||
csrw scounteren, x1
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_supervisor
|
||||
li TEST_ID, 3
|
||||
|
||||
csrr x1, cycle
|
||||
csrr x2, cycle
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, instret
|
||||
csrr x2, instret
|
||||
bge x1, x2, fail
|
||||
|
||||
csrr x1, time
|
||||
csrr x2, time
|
||||
bge x1, x2, fail
|
||||
|
||||
ecall
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, cycle
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, instret
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, time
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
|
||||
//Remove supervisor access to counters
|
||||
li x1, 0
|
||||
csrw mcounteren, x1
|
||||
li x1, -1
|
||||
csrw scounteren, x1
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_supervisor
|
||||
csrr x1, cycle
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_supervisor
|
||||
csrr x1, instret
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_supervisor
|
||||
csrr x1, time
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, cycle
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, instret
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
machine_setup_trap
|
||||
machine_to_user
|
||||
csrr x1, time
|
||||
j fail
|
||||
machine_handle_trap
|
||||
|
||||
|
||||
|
||||
j pass
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include "riscv_asm.h"
|
||||
|
||||
#define trap_setup \
|
||||
la x1, 1f; \
|
||||
csrw mtvec, x1; \
|
||||
addi x1, x1, 0x123; \
|
||||
csrw mtval, x1; \
|
||||
|
||||
#define trap_handle \
|
||||
j fail; \
|
||||
j fail; \
|
||||
j fail; \
|
||||
j fail; \
|
||||
.align 4; \
|
||||
1: \
|
||||
csrr x1, mepc; \
|
||||
csrr x1, mcause; \
|
||||
csrr x1, mstatus; \
|
||||
csrr x1, mtval; \
|
||||
csrr x1, mip; \
|
||||
|
||||
#define trap_handle_setup \
|
||||
trap_handle \
|
||||
trap_setup \
|
||||
|
||||
|
||||
|
||||
#define supervisor_read \
|
||||
csrr x1, sepc; \
|
||||
csrr x1, scause; \
|
||||
csrr x1, sstatus; \
|
||||
csrr x1, stval; \
|
||||
csrr x1, sip;
|
||||
|
||||
#define machine_read \
|
||||
csrr x1, mepc; \
|
||||
csrr x1, mcause; \
|
||||
csrr x1, mstatus; \
|
||||
csrr x1, mtval; \
|
||||
csrr x1, mip; \
|
||||
supervisor_read
|
||||
|
||||
#define user_read
|
||||
|
||||
#define machine_to_supervisor \
|
||||
la x1,1f ;\
|
||||
csrw mepc, x1 ;\
|
||||
li x1, MSTATUS_MPP_SUPERVISOR ;\
|
||||
csrw mstatus, x1 ;\
|
||||
mret ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
1: ;\
|
||||
supervisor_read
|
||||
|
||||
#define machine_to_supervisor_x1 \
|
||||
csrw mepc, x1 ;\
|
||||
li x1, MSTATUS_MPP_SUPERVISOR ;\
|
||||
csrw mstatus, x1 ;\
|
||||
mret ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
|
||||
|
||||
|
||||
#define machine_to_user \
|
||||
la x1,1f ;\
|
||||
csrw mepc, x1 ;\
|
||||
li x1, MSTATUS_MPP_USER ;\
|
||||
csrw mstatus, x1 ;\
|
||||
mret ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
j fail ;\
|
||||
1: ;\
|
||||
user_read
|
||||
|
||||
#define machine_setup_trap \
|
||||
la x1, 2f ;\
|
||||
csrw mtvec,x1;
|
||||
|
||||
#define machine_handle_trap \
|
||||
j fail ;\
|
||||
.align 4 ;\
|
||||
2: ;\
|
||||
machine_read
|
||||
|
||||
#define supervisor_setup_trap \
|
||||
la x1, 3f ;\
|
||||
csrw stvec,x1;
|
||||
|
||||
|
||||
#define supervisor_handle_trap \
|
||||
j fail ;\
|
||||
.align 4 ;\
|
||||
3: ;\
|
||||
supervisor_read
|
||||
|
||||
|
||||
|
||||
#define supervisor_check \
|
||||
supervisor_setup_trap \
|
||||
csrr x1, mstatus; \
|
||||
supervisor_handle_trap \
|
||||
supervisor_read
|
||||
|
||||
#define supervisor_external_interrupt_set \
|
||||
li x1, SUPERVISOR_EXTERNAL_INTERRUPT_CTRL; \
|
||||
li x2, 1; \
|
||||
sw x2, 0(x1);
|
||||
|
||||
#define supervisor_external_interrupt_clear \
|
||||
li x1, SUPERVISOR_EXTERNAL_INTERRUPT_CTRL; \
|
||||
sw x0, 0(x1);
|
||||
|
||||
#define wait_interrupt nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;j fail;
|
||||
#define delay_long nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
|
||||
|
||||
|
||||
#define machine_enable_supervisor_external_interrupt \
|
||||
li x1, 1 << CAUSE_SUPERVISOR_EXTERNAL; \
|
||||
csrw mie, x1; \
|
||||
li x1, MSTATUS_MIE ; \
|
||||
csrw mstatus, x1 ;
|
||||
|
||||
#define supervisor_enable_supervisor_external_interrupt \
|
||||
li x1, 1 << CAUSE_SUPERVISOR_EXTERNAL; \
|
||||
csrw sie, x1; \
|
||||
li x1, MSTATUS_SIE ; \
|
||||
csrw sstatus, x1 ;
|
||||
|
||||
|
||||
#define machine_trap_failure \
|
||||
la x1, 1f; \
|
||||
csrw mtvec, x1; \
|
||||
j 4f \
|
||||
1: \
|
||||
nop; \
|
||||
j fail; \
|
||||
4:
|
||||
|
||||
#define supervisor_trap_failure \
|
||||
la x1, 1f; \
|
||||
csrw stvec, x1; \
|
||||
j 4f; \
|
||||
.align 4; \
|
||||
1: \
|
||||
nop; \
|
||||
j fail; \
|
||||
4:
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
|
||||
//exceptions
|
||||
#define CAUSE_ILLEGAL_INSTRUCTION 2
|
||||
#define CAUSE_UCALL 8
|
||||
#define CAUSE_SCALL 9
|
||||
|
||||
//interrupts
|
||||
#define CAUSE_MACHINE_SOFTWARE 3
|
||||
#define CAUSE_MACHINE_TIMER 7
|
||||
#define CAUSE_MACHINE_EXTERNAL 11
|
||||
#define CAUSE_SUPERVISOR_SOFTWARE 1
|
||||
#define CAUSE_SUPERVISOR_TIMER 5
|
||||
#define CAUSE_SUPERVISOR_EXTERNAL 9
|
||||
|
||||
|
||||
#define MIE_MTIE (1 << CAUSE_MACHINE_TIMER)
|
||||
#define MIE_MEIE (1 << CAUSE_MACHINE_EXTERNAL)
|
||||
#define MIE_MSIE (1 << CAUSE_MACHINE_SOFTWARE)
|
||||
#define MIE_SEIE (1 << CAUSE_SUPERVISOR_EXTERNAL)
|
||||
|
||||
#define MEDELEG_INSTRUCTION_PAGE_FAULT (1 << 12)
|
||||
#define MEDELEG_LOAD_PAGE_FAULT (1 << 13)
|
||||
#define MEDELEG_STORE_PAGE_FAULT (1 << 15)
|
||||
#define MEDELEG_USER_ENVIRONNEMENT_CALL (1 << 8)
|
||||
#define MIDELEG_SUPERVISOR_SOFTWARE (1 << 1)
|
||||
#define MIDELEG_SUPERVISOR_TIMER (1 << 5)
|
||||
#define MIDELEG_SUPERVISOR_EXTERNAL (1 << 9)
|
||||
|
||||
|
||||
#define MSTATUS_UIE 0x00000001
|
||||
#define MSTATUS_SIE 0x00000002
|
||||
#define MSTATUS_HIE 0x00000004
|
||||
#define MSTATUS_MIE 0x00000008
|
||||
#define MSTATUS_UPIE 0x00000010
|
||||
#define MSTATUS_SPIE 0x00000020
|
||||
#define MSTATUS_HPIE 0x00000040
|
||||
#define MSTATUS_MPIE 0x00000080
|
||||
#define MSTATUS_SPP 0x00000100
|
||||
#define MSTATUS_HPP 0x00000600
|
||||
#define MSTATUS_MPP 0x00001800
|
||||
#define MSTATUS_FS 0x00006000
|
||||
#define MSTATUS_XS 0x00018000
|
||||
#define MSTATUS_MPRV 0x00020000
|
||||
#define MSTATUS_SUM 0x00040000
|
||||
#define MSTATUS_MXR 0x00080000
|
||||
#define MSTATUS_TVM 0x00100000
|
||||
#define MSTATUS_TW 0x00200000
|
||||
#define MSTATUS_TSR 0x00400000
|
||||
#define MSTATUS32_SD 0x80000000
|
||||
#define MSTATUS_UXL 0x0000000300000000
|
||||
#define MSTATUS_SXL 0x0000000C00000000
|
||||
#define MSTATUS64_SD 0x8000000000000000
|
||||
#define MSTATUS_FS_INITIAL (1 << 13)
|
||||
#define MSTATUS_FS_CLEAN (2 << 13)
|
||||
#define MSTATUS_FS_DIRTY (3 << 13)
|
||||
#define MSTATUS_FS_MASK (3 << 13)
|
||||
|
||||
|
||||
#define MSTATUS_MPP_SUPERVISOR 0x00000800
|
||||
#define MSTATUS_MPP_USER 0x00000000
|
||||
|
||||
#define SSTATUS_UIE 0x00000001
|
||||
#define SSTATUS_SIE 0x00000002
|
||||
#define SSTATUS_UPIE 0x00000010
|
||||
#define SSTATUS_SPIE 0x00000020
|
||||
#define SSTATUS_SPP 0x00000100
|
||||
#define SSTATUS_FS 0x00006000
|
||||
#define SSTATUS_XS 0x00018000
|
||||
#define SSTATUS_SUM 0x00040000
|
||||
#define SSTATUS_MXR 0x00080000
|
||||
#define SSTATUS32_SD 0x80000000
|
||||
#define SSTATUS_UXL 0x0000000300000000
|
||||
#define SSTATUS64_SD 0x8000000000000000
|
||||
|
||||
|
||||
#define PMP_R 0x01
|
||||
#define PMP_W 0x02
|
||||
#define PMP_X 0x04
|
||||
#define PMP_A 0x18
|
||||
#define PMP_L 0x80
|
||||
#define PMP_SHIFT 2
|
||||
|
||||
#define PMP_TOR 0x08
|
||||
#define PMP_NA4 0x10
|
||||
#define PMP_NAPOT 0x18
|
||||
|
||||
#define RDCYCLE 0xC00 //Read-only cycle Cycle counter for RDCYCLE instruction.
|
||||
#define RDTIME 0xC01 //Read-only time Timer for RDTIME instruction.
|
||||
#define RDINSTRET 0xC02 //Read-only instret Instructions-retired counter for RDINSTRET instruction.
|
||||
#define RDCYCLEH 0xC80 //Read-only cycleh Upper 32 bits of cycle, RV32I only.
|
||||
#define RDTIMEH 0xC81 //Read-only timeh Upper 32 bits of time, RV32I only.
|
||||
#define RDINSTRETH 0xC82 //Read-only instreth Upper 32 bits of instret, RV32I only.
|
||||
|
Loading…
Reference in New Issue