mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			330 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			330 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
///////////////////////////////////////////
 | 
						|
// priv.S
 | 
						|
//
 | 
						|
// Written: David_Harris@hmc.edu 23 March 2023
 | 
						|
//
 | 
						|
// Purpose: Test coverage for EBU
 | 
						|
//
 | 
						|
// A component of the CORE-V-WALLY configurable RISC-V project.
 | 
						|
// https://github.com/openhwgroup/cvw
 | 
						|
// 
 | 
						|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
 | 
						|
//
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
 | 
						|
//
 | 
						|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file 
 | 
						|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You 
 | 
						|
// may obtain a copy of the License at
 | 
						|
//
 | 
						|
// https://solderpad.org/licenses/SHL-2.1/
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, any work distributed under the 
 | 
						|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 | 
						|
// either express or implied. See the License for the specific language governing permissions 
 | 
						|
// and limitations under the License.
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// load code to initalize stack, handle interrupts, terminate
 | 
						|
#include "WALLY-init-lib.h"
 | 
						|
 | 
						|
main:
 | 
						|
    # Tests sret in machine mode
 | 
						|
    la t1, sretdone
 | 
						|
    csrw sepc, t1
 | 
						|
    sret
 | 
						|
sretdone:
 | 
						|
    addi t2, x0, 42 
 | 
						|
 | 
						|
    # switch to user mode
 | 
						|
    li a0, 0   
 | 
						|
    ecall
 | 
						|
    sret #should be treated as illegal instruction
 | 
						|
    mret #mret in user mode and should be illegal
 | 
						|
 | 
						|
    # switch to supervisor mode
 | 
						|
    li a0, 1   
 | 
						|
    ecall
 | 
						|
 | 
						|
    # Test read to stimecmp fails when MCOUNTEREN_TM is not set
 | 
						|
    li t1, -3
 | 
						|
    csrw stimecmp, t1
 | 
						|
    csrr t0, stimecmp 
 | 
						|
 | 
						|
 | 
						|
    # satp write with mstatus.TVM = 1
 | 
						|
    bseti t0, zero, 20 
 | 
						|
    csrs mstatus, t0
 | 
						|
    csrw satp, zero
 | 
						|
 | 
						|
    # STIMECMP from S mode
 | 
						|
    # 1st is when MENVCFG_STCE is cleared
 | 
						|
    li a0, 3
 | 
						|
    ecall # starts in M-mode
 | 
						|
    li t1, -3
 | 
						|
    csrw stimecmp, t1 # sets stimecmp to large value to prevent it from interrupting immediately
 | 
						|
    li t0, 2 
 | 
						|
    csrs mstatus, t0 # enables sie
 | 
						|
    li t0, 32
 | 
						|
    csrs sie, t0 # enables sie.stie
 | 
						|
    csrw menvcfg, x0
 | 
						|
    li a0, 1
 | 
						|
    ecall   # enter S-mode
 | 
						|
    csrw stimecmp, zero
 | 
						|
    li a0, 3
 | 
						|
    ecall # in M-mode
 | 
						|
    li t0, 32
 | 
						|
    csrs mip, t0
 | 
						|
    li a0, 1
 | 
						|
    ecall # in S-mode and expects stimer interrupt to occur
 | 
						|
    li a0, 3
 | 
						|
    ecall   # return to M-mode
 | 
						|
    csrsi mcounteren, 2 # mcounteren_tm = 1
 | 
						|
    li a0, 1
 | 
						|
    ecall   # supervisor mode again
 | 
						|
    csrw stimecmp, zero
 | 
						|
    li a0, 3
 | 
						|
    ecall  # machine mode again
 | 
						|
 | 
						|
    # STIMECMP from S mode
 | 
						|
    # 2nd is when MENVCFG_STCE is set
 | 
						|
    csrci mcounteren, 2 # mcounteren_tm = 0
 | 
						|
    li t0, 1
 | 
						|
    slli t0, t0, 63
 | 
						|
    csrw menvcfg, t0
 | 
						|
    li a0, 1
 | 
						|
    ecall   # enter S-mode
 | 
						|
    csrw stimecmp, zero
 | 
						|
    li a0, 3
 | 
						|
    ecall   # return to M-mode
 | 
						|
    csrsi mcounteren, 2 # mcounteren_tm = 1
 | 
						|
    li a0, 1
 | 
						|
    ecall   # supervisor mode again
 | 
						|
    csrw stimecmp, zero
 | 
						|
    li a0, 3
 | 
						|
    ecall  # machine mode again
 | 
						|
 | 
						|
    # writes to FCSR
 | 
						|
    li t0, 1
 | 
						|
    slli t0, t0, 13
 | 
						|
    csrs mstatus, t0
 | 
						|
    li t0, 1
 | 
						|
    csrw fcsr, t0
 | 
						|
 | 
						|
    # switch to supervisor mode
 | 
						|
    li a0, 1   
 | 
						|
    ecall
 | 
						|
 | 
						|
    # Test write to STVAL, SCAUSE, SEPC, and STIMECMP CSRs
 | 
						|
    li t0, 0
 | 
						|
    csrw stval, t0
 | 
						|
    csrw scause, t0
 | 
						|
    csrw sepc, t0
 | 
						|
    csrw stimecmp, t0
 | 
						|
    csrw scounteren, zero
 | 
						|
    csrw satp, zero
 | 
						|
 | 
						|
 | 
						|
    # Switch to machine mode
 | 
						|
    li a0, 3   
 | 
						|
    ecall 
 | 
						|
 | 
						|
    # Write to MCOUNTINHIBIT CSR
 | 
						|
    csrw mcountinhibit, t0
 | 
						|
 | 
						|
    # Testing the HPMCOUNTERM performance counter: writing
 | 
						|
    # Base address is 2816 (MHPMCOUNTERBASE)
 | 
						|
    # There are 32 HPMCOUNTER registers
 | 
						|
    csrw 2816, t0
 | 
						|
    csrw 2817, t0
 | 
						|
    csrw 2818, t0
 | 
						|
    csrw 2819, t0
 | 
						|
    csrw 2820, t0
 | 
						|
    csrw 2821, t0
 | 
						|
    csrw 2822, t0
 | 
						|
    csrw 2823, t0
 | 
						|
    csrw 2824, t0
 | 
						|
    csrw 2825, t0
 | 
						|
    csrw 2826, t0
 | 
						|
    csrw 2827, t0
 | 
						|
    csrw 2828, t0
 | 
						|
    csrw 2829, t0
 | 
						|
    csrw 2830, t0
 | 
						|
    csrw 2831, t0  
 | 
						|
    csrw 2832, t0
 | 
						|
    csrw 2833, t0
 | 
						|
    csrw 2834, t0
 | 
						|
    csrw 2835, t0
 | 
						|
    csrw 2836, t0
 | 
						|
    csrw 2837, t0
 | 
						|
    csrw 2838, t0
 | 
						|
    csrw 2839, t0
 | 
						|
    csrw 2840, t0
 | 
						|
    csrw 2841, t0
 | 
						|
    csrw 2842, t0
 | 
						|
    csrw 2843, t0
 | 
						|
    csrw 2844, t0
 | 
						|
    csrw 2845, t0
 | 
						|
    csrw 2846, t0
 | 
						|
    csrw 2847, t0      
 | 
						|
 | 
						|
    # Testing the HPMCOUNTERM performance counter: reading
 | 
						|
    csrr t0, 2817
 | 
						|
 | 
						|
    # Test writes to pmp address registers
 | 
						|
    csrw 951, t0
 | 
						|
    csrw 952, t0
 | 
						|
    csrw 953, t0
 | 
						|
    csrw 954, t0
 | 
						|
    csrw 955, t0
 | 
						|
    csrw 956, t0
 | 
						|
    csrw 957, t0
 | 
						|
    csrw 958, t0
 | 
						|
 | 
						|
 | 
						|
    # Testing writes to MTVAL, MCAUSE    
 | 
						|
    li t0, 0
 | 
						|
    csrw mtval, t0
 | 
						|
    csrw mcause, t0
 | 
						|
 | 
						|
    # set mstatus to enable floating point registers (mstatus.FS = 11)
 | 
						|
    bseti t1, zero, 13
 | 
						|
    csrs mstatus, t1
 | 
						|
    bseti t1, zero, 14
 | 
						|
    csrs mstatus, t1
 | 
						|
 | 
						|
    # Test writes to floating point CSRs
 | 
						|
    csrw frm, t0
 | 
						|
    csrw fflags, t0
 | 
						|
    
 | 
						|
    # CSRC MCOUNTEREN Register
 | 
						|
    # Go to machine mode
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
    # Activate HPM3
 | 
						|
    li t0, -1
 | 
						|
    csrw mcounteren, t0
 | 
						|
    csrw scounteren, t0
 | 
						|
 | 
						|
    # Go to supervisor
 | 
						|
    li a0, 1
 | 
						|
    ecall
 | 
						|
    #try to write to HPMs
 | 
						|
    csrw 333, t0
 | 
						|
    #go to user mode
 | 
						|
    li a0, 0
 | 
						|
    ecall
 | 
						|
    csrr t0, hpmcounter22
 | 
						|
 | 
						|
    # setting registers bits to 0
 | 
						|
    li a0, 3 # back to machine mode
 | 
						|
    ecall
 | 
						|
    li t0, 0
 | 
						|
    csrw mcounteren, t0
 | 
						|
    csrw scounteren, t0
 | 
						|
 | 
						|
    #getting the remainder of PMD instructions
 | 
						|
 | 
						|
    #go to user mode
 | 
						|
    li a0, 0
 | 
						|
    ecall
 | 
						|
    #set status TVM to 0 by writing to bit 20 of mstatus as 0
 | 
						|
    #bseti t0, zero, 20 
 | 
						|
    sfence.vma zero, zero
 | 
						|
 | 
						|
    # Go to supervisor mode
 | 
						|
    li a0, 1
 | 
						|
    ecall
 | 
						|
 | 
						|
    sfence.vma zero, zero
 | 
						|
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
 | 
						|
    # Write to satp when status.TVM is 1 from machine mode
 | 
						|
    bseti t0, zero, 20 
 | 
						|
    csrs mstatus, t0
 | 
						|
 | 
						|
    csrw satp, t0
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    # Test checking privilege for reading counters (using counter 22 as an example)
 | 
						|
 | 
						|
    # Go to machine mode
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
 | 
						|
    # Set SCOUNTEREN to all 0s, MCOUNTEREN to all 1s
 | 
						|
    li t0, 0
 | 
						|
    csrw scounteren, t0
 | 
						|
    li t1, -1
 | 
						|
    csrw mcounteren, t1
 | 
						|
 | 
						|
 | 
						|
    # Go to supervisor mode
 | 
						|
    li a0, 1
 | 
						|
    ecall
 | 
						|
 | 
						|
    # try to read from HPM22
 | 
						|
    csrr t0, hpmcounter22
 | 
						|
 | 
						|
    # go to user mode
 | 
						|
    li a0, 0
 | 
						|
    ecall
 | 
						|
 | 
						|
    csrr t0, hpmcounter22
 | 
						|
 | 
						|
    #getting the mpp and mstatus Mpriv condition met
 | 
						|
    #go to machine mode
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
    # set bit 17 of mstatus to enable STATUS_MPRV
 | 
						|
    bseti t1, zero, 17
 | 
						|
    csrs mstatus, t1
 | 
						|
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
 | 
						|
    # set bit 21 of mstatus to 0 to disable STATUS_TW
 | 
						|
    csrr t1, mstatus
 | 
						|
    bseti t2, zero, 21
 | 
						|
    not t2, t2
 | 
						|
    and t1, t1, t2
 | 
						|
    csrs mstatus, t1
 | 
						|
 | 
						|
    # go to user mode
 | 
						|
    li a0, 0
 | 
						|
    ecall
 | 
						|
 | 
						|
    wfi
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    # Test uncovered privdec instructions
 | 
						|
    li a0, 3
 | 
						|
    ecall
 | 
						|
    # exercise sfence.inval.ir instruction
 | 
						|
    .word 0x18100073
 | 
						|
 | 
						|
    # exercise sret with rs1 not 0
 | 
						|
    .word 0x102F8073
 | 
						|
 | 
						|
 | 
						|
    # cover mret when mpp = 3 and mprv = 1
 | 
						|
    li a0, 3
 | 
						|
    ecall               # enter machine mode
 | 
						|
    bseti t0, zero, 17
 | 
						|
    csrs mstatus, t0    # set MPRV
 | 
						|
    li t1, 0x00001800   
 | 
						|
    csrs mstatus, t1    # set MPP=3
 | 
						|
    la t1, finished
 | 
						|
    csrr t0, mepc       
 | 
						|
    csrw mepc, t1       # set mepc for mret to jump to
 | 
						|
    mret
 | 
						|
 | 
						|
 | 
						|
finished: j done
 | 
						|
 | 
						|
 | 
						|
 |