blob: 92d2b4990d5bb1c4ebabae5b7eac1ee0e5e5b80c [file] [log] [blame]
# See LICENSE for license details.
#*****************************************************************************
# napot.S
#-----------------------------------------------------------------------------
#
# Test Svnapot
#
#include "riscv_test.h"
#include "test_macros.h"
#if (DRAM_BASE >> 30 << 30) != DRAM_BASE
# error This test requires DRAM_BASE be SV39 superpage-aligned
#endif
#if __riscv_xlen != 64
# error This test requires RV64
#endif
RVTEST_RV64M
RVTEST_CODE_BEGIN
# Construct the page table
#define MY_VA 0x40201010
# VPN 2 == VPN 1 == VPN 0 == 0x1
# Page offset == 0x10
####
# Level 0 PTE contents
# PPN
la a0, my_data
srl a0, a0, 12
# adjust the PPN to be in NAPOT form
li a1, ~0xF
and a0, a0, a1
ori a0, a0, 0x8
# attributes
sll a0, a0, PTE_PPN_SHIFT
li a1, PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D | PTE_N
or a0, a0, a1
# Level 0 PTE address
la a1, page_table
addi a1, a1, ((MY_VA >> 12) & 0x1FF) * 8
# Level 0 PTE store
sd a0, (a1)
####
# Level 1 PTE contents
la a0, page_table
srl a0, a0, 12
sll a0, a0, PTE_PPN_SHIFT
li a1, PTE_V
or a0, a0, a1
# Level 1 PTE address
la a1, page_table
addi a1, a1, ((MY_VA >> 21) & 0x1FF) * 8
li a2, 1 << 12
add a1, a1, a2
# Level 1 PTE store
sd a0, (a1)
####
# Level 2 PTE contents
la a0, page_table
li a1, 1 << 12
add a0, a0, a1
srl a0, a0, 12
sll a0, a0, PTE_PPN_SHIFT
li a1, PTE_V
or a0, a0, a1
# Level 2 PTE address
la a1, page_table
addi a1, a1, ((MY_VA >> 30) & 0x1FF) * 8
li a2, 2 << 12
add a1, a1, a2
# Level 2 PTE store
sd a0, (a1)
####
# Do a load from the PA that would be written if the PTE were misinterpreted as non-NAPOT
la a0, my_data
li a1, ~0xFFFF
and a0, a0, a1
li a1, 0x8000 | (MY_VA & 0xFFF)
or a3, a0, a1
li a1, 0
sw a1, (a3)
####
li TESTNUM, 1
## Turn on VM
la a1, page_table
li a2, 2 << 12
add a1, a1, a2
srl a1, a1, 12
li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
or a0, a0, a1
csrw satp, a0
sfence.vma
# Set up MPRV with MPP=S and SUM=1, so loads and stores use S-mode and S can access U pages
li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV | MSTATUS_SUM
csrs mstatus, a1
# Do a store to MY_VA
li a0, MY_VA
li a1, 42
sw a1, (a0)
# Clear MPRV
li a1, MSTATUS_MPRV
csrc mstatus, a1
# Do a load from the PA that would be written if the PTE were misinterpreted as non-NAPOT
lw a1, (a3)
# Check the result
li a0, 42
beq a1, a0, die
# Do a load from the PA for MY_VA
la a0, my_data
li a1, MY_VA & 0xFFFF
add a0, a0, a1
lw a1, (a0)
li a2, 42
# Check the result
bne a1, a2, die
####
RVTEST_PASS
TEST_PASSFAIL
.align 2
.global mtvec_handler
mtvec_handler:
die:
RVTEST_FAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
.align 20
page_table: .dword 0
.align 20
my_data: .dword 0
RVTEST_DATA_END