[#100581] riscv: Fix counter access control

tmp: separate test
diff --git a/src/Infrastructure b/src/Infrastructure
index ec0b8b4..b3c5b94 160000
--- a/src/Infrastructure
+++ b/src/Infrastructure
@@ -1 +1 @@
-Subproject commit ec0b8b45bcba6c40963c3f05af5efd3b82fd5297
+Subproject commit b3c5b94fb42fbd9131e409e286199db331f7b90d
diff --git a/tests/tests.yaml b/tests/tests.yaml
index 733a896..6e89aef 100644
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -37,6 +37,7 @@
 - tests/unit-tests/demos.robot
 - tests/unit-tests/robot-integration.robot
 - tests/unit-tests/riscv-unit-tests.robot
+- tests/unit-tests/riscv-priv.robot
 - tests/unit-tests/riscv-amocas.robot
 - tests/unit-tests/mpu.robot
 - tests/unit-tests/arm-atomic.robot
diff --git a/tests/unit-tests/riscv-priv.robot b/tests/unit-tests/riscv-priv.robot
new file mode 100644
index 0000000..d95573f
--- /dev/null
+++ b/tests/unit-tests/riscv-priv.robot
@@ -0,0 +1,264 @@
+*** Variables ***
+${starting_pc}                      0x2000
+${mtvec}                            0x1010
+${illegal_instruction}              0x2
+${load_misaligned}                  0x4
+${store_misaligned}                 0x6
+${user_mode}                        0x0
+${supervisor_mode}                  0x1
+${hypervisor_mode}                  0x2
+${machine_mode}                     0x3
+
+*** Keywords ***
+Create Machine
+    [Arguments]                     ${bitness}  ${init_pc}
+    Execute Command                 using sysbus
+    Execute Command                 mach create "risc-v"
+
+    Execute Command                 machine LoadPlatformDescriptionFromString "clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 { frequency: 66000000 }"
+    Execute Command                 machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV${bitness} @ sysbus { timeProvider: clint; cpuType: \\"rv${bitness}imafd_zicsr_zifencei_c_v_zba_zbb_zbc_zbs_zfh_zacas_zcb\\" }"
+    Execute Command                 machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x1000 { size: 0x40000 }"
+
+    IF  ${init_pc}
+        Execute Command                 cpu PC ${starting_pc}
+        Execute Command                 cpu SetRegister "mtvec" ${mtvec}
+    END
+
+Create Machine 32
+    Create Machine                  bitness=32  init_pc=True
+
+Create Machine 64
+    Create Machine                  bitness=64  init_pc=True
+
+Set Register
+    [Arguments]                     ${register}  ${value}
+    Execute Command                 cpu SetRegister ${register} ${value}
+
+Register Should Be Equal
+    [Arguments]                     ${register}  ${value}
+    ${register_value}=              Execute Command  cpu GetRegister ${register}
+    Should Be Equal As Numbers      ${value}  ${register_value}
+
+Change Privilege
+    [Arguments]                     ${mode}
+    Set Register                    "priv"  ${mode}
+
+Assemble At Current Pc
+    [Arguments]                     ${program}
+    ${length}=                      Execute Command  cpu AssembleBlock `cpu PC` ${program}
+    ${length}=                      Convert To Integer  ${length}
+    RETURN                          ${length}
+
+Run Assembly
+    [Arguments]                     ${program}
+    ${length}=                      Assemble At Current Pc  ${program}
+    ${pc}=                          Execute Command  cpu PC
+    ${current_pc}=                  Convert To Integer  ${pc}
+    ${last_pc}=                     Evaluate  ${current_pc} + ${length}
+
+    WHILE  ${current_pc} != ${last_pc}  limit=${length}
+        ${current_pc}=                  Execute Command  cpu Step
+        ${current_pc}=                  Convert To Integer  ${current_pc}
+        IF  ${current_pc} == ${mtvec} # Don't fail on traps
+            BREAK
+        END
+    END
+
+Should Trap
+    [Arguments]                     ${cause}
+    ${pc}=                          Execute Command  cpu GetRegister "pc"
+    Should Be Equal As Numbers      ${mtvec}  ${pc}
+    ${mcause}=                      Execute Command  cpu GetRegister "mcause"
+    Should Be Equal As Numbers      ${mcause}  ${cause}
+
+Untrap
+    ${mepc}=                        Execute Command  cpu GetRegister "mepc"
+    Execute Command                 cpu SetRegister "pc" ${mepc}
+
+*** Test Cases ***
+Should Fail On Counter Access
+    Create Machine 64
+
+    Change Privilege                ${machine_mode}
+    Run Assembly                    "li t0, 0; csrw mcounteren, t0"
+
+    Change Privilege                ${supervisor_mode}
+    Run Assembly                    "li t0, 7; csrw scounteren, t0"
+
+    Change Privilege                ${user_mode}
+
+    Run Assembly                    "csrr a0, mcycle"
+    Should Trap                     ${illegal_instruction}
+
+    Untrap
+    Change Privilege                ${user_mode}
+    Run Assembly                    "rdinstret a0"
+    Should Trap                     ${illegal_instruction}
+
+Should Increment MCYCLE RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             csrr a1, mcycle
+    ...                             nop
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0x2
+
+Should Increment MINSTRET RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             csrr a1, minstret
+    ...                             nop
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0x2
+
+Should Increment MCYCLE RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             csrr a1, mcycle
+    ...                             nop
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0x2
+
+Should Increment MINSTRET RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             csrr a1, minstret
+    ...                             nop
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0x2
+
+Should Inhibit MCYCLE RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 1
+    ...                             csrw mcountinhibit, a0
+    ...                             csrr a1, mcycle
+    ...                             nop
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0
+
+Should Inhibit MINSTRET RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 4
+    ...                             csrw mcountinhibit, a0
+    ...                             csrr a1, minstret
+    ...                             nop
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0
+
+Should Inhibit MCYCLE RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 1
+    ...                             csrw mcountinhibit, a0
+    ...                             csrr a1, mcycle
+    ...                             nop
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0
+
+Should Inhibit MINSTRET RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 4
+    ...                             csrw mcountinhibit, a0
+    ...                             csrr a1, minstret
+    ...                             nop
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  0
+
+Should Inhibit MCYCLE After Write Finishes RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 1
+    ...                             li t0, 0
+    ...                             csrr a1, mcycle
+    ...                             csrw mcountinhibit, a0
+    ...                             nop
+    ...                             csrw mcountinhibit, t0
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  2
+
+Should Inhibit MINSTRET After Write Finishes RV64
+    Create Machine 64
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 4
+    ...                             li t0, 0
+    ...                             csrr a1, minstret
+    ...                             csrw mcountinhibit, a0
+    ...                             nop
+    ...                             csrw mcountinhibit, t0
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  2
+
+Should Inhibit MCYCLE After Write Finishes RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 1
+    ...                             li t0, 0
+    ...                             csrr a1, mcycle
+    ...                             csrw mcountinhibit, a0
+    ...                             nop
+    ...                             csrw mcountinhibit, t0
+    ...                             csrr a2, mcycle
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  2
+
+Should Inhibit MINSTRET After Write Finishes RV32
+    Create Machine 32
+
+    ${assembly}=                    Catenate  SEPARATOR=\n
+    ...                             li a0, 4
+    ...                             li t0, 0
+    ...                             csrr a1, minstret
+    ...                             csrw mcountinhibit, a0
+    ...                             nop
+    ...                             csrw mcountinhibit, t0
+    ...                             csrr a2, minstret
+    ...                             sub a3, a2, a1
+    Run Assembly                    """${assembly}"""
+
+    Register Should Be Equal        "a3"  2