Virtual Memory

This tutorial walks you through testing virtual memory functionality with RiescueD, covering page mapping, address translation, and memory access patterns.

Virtual memory testing helps verify that your processor correctly handles address translation, page table management, and memory protection. This tutorial shows how to create tests that exercise these critical system features.

Setting Up Virtual Memory

Let’s start with a complete virtual memory test. Here’s the example file:


;#test.arch       rv64
;#test.priv       user super
;#test.env        bare_metal
;#test.paging     sv39 sv48 sv57

.section .code, "ax"

test_setup:
    ;#test_passed()

;#random_data(name=my_word, type=bits32, and_mask=0xFFFFFFFF)

;#random_addr(name=physical_address, type=physical)
;#random_addr(name=virtual_address,  type=linear)
;#page_mapping(lin_name=virtual_address, phys_name=physical_address, v=1, r=1, w=1, a=1, d=1, pagesize=['any'])

;#discrete_test(test=test_paging)
test_paging:
    li t0, virtual_address
    lw t1, 0(t0)
    li t2, my_word
    beq t1, t2, paging_passed # Assert the loaded virtual address is reading data correctly
    ;#test_failed()
paging_passed:
    ;#test_passed()

test_cleanup:
    ;#test_passed()

.section .data
;#init_memory @virtual_address
    .word my_word

We can run the test using:

riescued --testname virtual_memory.s --run_iss

This test creates a virtual-to-physical address mapping and verifies that data can be correctly accessed through the virtual address.

Test Configuration Headers

The virtual memory test introduces several important headers:

;#test.paging Header

;#test.paging     sv39 sv48 sv57

This header specifies which paging modes the test supports. The test will run for each specified mode:

  • sv39 - 39-bit virtual addressing (3-level page table)

  • sv48 - 48-bit virtual addressing (4-level page table)

  • sv57 - 57-bit virtual addressing (5-level page table)

;#test.priv - Setting Supervisor or User

Previous tutorials have been using ;#test.priv machine, but this example is set to user super. Some Test Headers can be set to multiple values separated by spaces, and randomly select one of the values.

This example will randomly select either user or supervisor privilege mode for the test code.

Virtual memory operations typically [1] require supervisor privileges for page table setup to function correctly, so it should be set for the examples.

Random Address Generation

The test uses two types of random addresses for comprehensive testing:

;#random_addr - Physical Address

;#random_addr(name=physical_address, type=physical)

This generates a random physical address where the actual data will be stored in memory. The type=physical parameter specifies this is a physical memory location.

;#random_addr - Virtual Address

;#random_addr(name=virtual_address, type=linear)

This generates a random virtual address that will be mapped to the physical address. The type=linear parameter indicates this is a linear (virtual) address that requires translation.

Page Mapping Configuration

The core of virtual memory testing is the page mapping directive:

;#page_mapping - Creating Address Mappings

;#page_mapping(lin_name=virtual_address, phys_name=physical_address, v=1, r=1, w=1, a=1, d=1, pagesize=['any'])

This creates a page table entry that maps the virtual address to the physical address. The parameters control page permissions:

  • lin_name=virtual_address - The virtual address symbol to map from

  • phys_name=physical_address - The physical address symbol to map to

  • v=1 - Valid bit (page is present)

  • r=1 - Read permission

  • w=1 - Write permission

  • a=1 - Accessed bit

  • d=1 - Dirty bit

  • pagesize=['any'] - Allow any supported page size

Memory Initialization

To test the mapping, we need to place data at the virtual address:

;#init_memory - Populating Virtual Memory

;#init_memory @virtual_address
    .word my_word

This directive places the random word value at the virtual address location. The framework handles the address translation to store the data at the correct physical location.

Virtual Memory Test Patterns

The test demonstrates a common virtual memory verification pattern:

test_paging:
    li t0, virtual_address      # Load virtual address
    lw t1, 0(t0)               # Read through virtual address
    li t2, my_word             # Load expected value
    beq t1, t2, paging_passed  # Verify data matches
    ;#test_failed()

This pattern:

  1. Loads the virtual address into a register

  2. Performs a memory access through the virtual address

  3. Compares the loaded value with the expected data

  4. Passes if the virtual-to-physical translation worked correctly

Advanced Features

The framework supports additional virtual memory testing features:

Multiple Page Sizes

You can specify exact page sizes instead of just ['any']:

;#page_mapping(lin_name=vaddr, phys_name=paddr, v=1, r=1, w=1, pagesize=['4kb', '2mb', '1gb', '512gb', '256tb', 'any'])

Any will pick a random page size from the supported page sizes, with larger page sizes having a lower chance of being picked.

Note

both 512 GiB ('512gb') and 256 TiB ('256tb') are supported, but they are execluded from being randomly selected.

Currently supported page sizes are:

  • 4kb

  • 2mb

  • 1gb

  • 512gb

  • 256tb

Note

Page sizes are required to be naturally aligned to the page size. For testing purposes, test writers may want to use large values to check for page size alignment issues.

Warning

However, this assumes that the memory map supports very large page sizes in the first place. If a 512 GiB page is requested and the memory map cannot allocate that, it will fail address generation.

For this reason, it’s recommended to use that only if the memory map supports very large page sizes. Additionally, 256tb TiB is disabled by default.

Permission Testing

Test different permission combinations:

;#page_mapping(lin_name=readonly_addr, phys_name=phys_addr, v=1, r=1, w=0)

For complete documentation of all available directives, see the RiESCUE Directives Reference and Test Headers Reference.