Renode tests for SMMU translation with Armv8-A and Armv8-R
Published:
Topics: Open simulation, Open source tools, Open software libraries
In previous years, we described how Renode support for the Armv8-A CPU architecture profile was enhanced for end-to-end Linux support, and how virtualization can be added for Armv8-R as exemplified by the Cortex-R52 CPU. Now, Antmicro has modeled a System Memory Management Unit (SMMU), which translates virtual addresses into physical ones for platforms running on Armv8-A and Armv8-R CPUs. As a result, we have enabled the use of Renode to test the drivers of the SMMU, and of I/O devices that use external Input-Output Memory Management Unit (IOMMU) translation. By extension, the SMMU translation process itself is also tested for these CPUs and devices.
This article explains the process and importance of SMMU address translation, the way Antmicro has implemented it for the Renode simulation, and how Renode facilitates its testing for embedded development in such use cases as custom operating systems (OSes) and bare-metal applications. A demo recording will show you how SMMU accesses and commands are executed in Renode.
SMMU translation overview
The SMMU is a specific implementation of the IOMMU concept, which is in turn derived from the traditional MMU translating CPU virtual addresses into physical ones. The IOMMU performs the same actions for Direct Memory Access (DMA) on the virtual addresses of I/O devices, such as GPUs or network controllers. It’s a widely used solution among users who connect their GPUs to virtual machines (VMs). The SMMU is an IOMMU designed by Arm to work with platforms powered by their CPUs. The MMU, IOMMU, and SMMU work with physical memory, such as RAM, and memory-mapped regions, such as peripheral registers.
The SMMU ensures security by isolating the places to which each I/O device can write. The virtual-physical address translation is based on translation tables, which specify the output address and memory attributes. The tables are supplemented by configuration parameters of the SMMU itself, such as translation granule size and fault behavior. The granule size determines the smallest size of a single page (memory block), and faults can be configured to either immediately raise an event (such as a warning) or stall the memory transaction until it is resumed by an SMMU driver.
Currently, Renode supports scenarios where the source address originates either from an I/O device, thus being a virtual address, or from a CPU or VM, being an intermediate physical address (IPA). Both virtual addresses and IPAs are translated into physical addresses. Renode also supports the SMMU’s bypass mode, which disables the translation for a device or transaction. This mode is most useful when a CPU is placed behind the SMMU to allow it to configure its own page tables at boot time easily.
As a future possibility, Antmicro may add support for a third scenario, with additional memory access attribute transformation. In such a case, instead of translating the address, the SMMU will only replace or modify the attributes of an already generated physical address from a source device that wants to access the main memory. In other words, the SMMU can also ensure security when no translation is needed.
Using the SMMU is important to make sure that no faulty or malicious device writes to memory regions not assigned to it, and that devices in general access only their own memory buffers. Hence, a correctly working SMMU adds extra security to the performance stemming from DMA that bypasses the CPU.
Thanks to Renode, you don’t need to test the SMMU in your actual, non-virtualized OS or bare-metal applications. Many peripherals and cores are already implemented, so you don’t need to create every single script and parameter specific to your platform but can focus on the testing itself. Our simulator provides the following components that streamline the process:
- Sample scripts to use as a basis for your own scenarios.
- Debugging logs that enable you to see the values programmed into the SMMU.
- The possibility to set peripheral access hooks, which can execute any Python code with full access to the Renode API.
Antmicro’s implementation, test setup, and demo
Antmicro has implemented SMMUv3 in Renode with the following components:
This implementation has been created on top of Renode’s existing external MMU infrastructure and comes with two tests (each with the 4 KB granule size for the highest accuracy):
| Test | Entity tested | Arm profile | Entity configuring SMMU and tables |
|---|---|---|---|
| Test 1 | SMMU translation (bare-metal application) | Armv8-R (32-bit) | Helper script |
| Test 2 | SMMU translation with I/O devices and Zynq UltraScale+ | Armv8-A (64-bit) | Linux kernel |
The Armv8-R architecture profile is designed for time-sensitive and safety-critical embedded systems: optimized for applications where the correctness of a computation depends on both its logical correctness and completion time, as in real-time OSes. It comes in 64-bit and 32-bit versions thanks to the AArch64 and AArch32 execution states, respectively. The Armv8-R profile is generally associated with the 32-bit version, as 64-bit support was added at a later time.
In Test 1, we are using the 32-bit version of Armv8-R as a contrast to the Armv8-A 64-bit profile from Test 2. Armv8-A is designed to run performance-intensive applications, from mobile phones to servers. It has both AArch64 and AArch32, thus being compatible with 32-bit systems.
Please note that the newer the Armv8.X architecture extension, the more features are added that work only in the 64-bit version.
The helper script from Test 1 provides two mappings:
0x0translated into0x0: an identity mapping where a virtual address is translated into the same physical one.0x1000translated into0x00000001'00000000: a mapping of one physical page above 4 GB to make it visible to a 32-bit CPU core.
In Test 2, the role of the helper is taken by the Linux kernel, which is used in the Zynq UltraScale+ multi-processor system-on-chip (MPSoC). Zynq UltraScale+, developed by AMD (originally by Xilinx), integrates an Arm multicore processor with an FPGA and features multiple processing subsystems and IP cores for graphics, video, and other functions like packet processing, making it suitable for high-performance applications. We’re using this MPSoC with an Ethernet adapter whose memory accesses go through the SMMU.
For our test purposes, we have modified the device tree to use SMMUv3, even though the actual Zynq UltraScale+ uses SMMUv2.
You can see how Test 2 is performed in the demo below:
To reproduce the demo, you need to first install Renode. Afterward, run the following command:
renode-test tests/platforms/zynqmp.robot -f SMMU
For full operating instructions, see Renode - documentation.
Customized Renode testing for your platforms
This latest Renode addition enables you to test SMMU behavior precisely in a simple way to ensure memory integrity. Since our framework supports simulating heterogeneous multi-core systems, you can choose a variety of different CPUs to work with.
Antmicro has the required experience to commercially support custom OS and bare-metal application developers in simulating the SMMU translation in Renode. In addition, we can extend our simulator’s functionality to cover other CPU architectures or even mix them together. Explore other Renode possibilities and the currently supported OSes. If you require a streamlined testing solution that would work for your custom project, get in touch with us at contact@antmicro.com.