Description
Facts
On ARM64 we can MMU-map a memory region in two different ways:
- Directly interfacing with the MMU code
- Going through the Zephyr MMU / device MMIO APIs.
Direct interface with MMU code for direct mapping
This is done by the ARM64 MMU code to setup the basic Zephyr regions (text, data, etc..) in:
Lines 649 to 679 in bfec3b2
but it also used by the soc-specific code to map regions for peripherals that do not support the device MMIO APIs, for example in:
zephyr/soc/arm64/qemu_cortex_a53/mmu_regions.c
Lines 11 to 22 in bfec3b2
This mapping is done directly in the MMU driver code and it is usually a direct (1:1) mapping.
Using the device MMIO (or MMU) APIs
There has been lately a certain effort to make the drivers using the device MMIO APIs. These API are leveraging the Zephyr MMU code to map the physical MMIO region of a peripheral to a virtual memory region automatically at init time (see include/zephyr/sys/device_mmio.h
)
In general the mapping is not a direct mapping, but instead the virtual region is carved out from a memory pool of virtual addresses configured using CONFIG_KERNEL_VM_BASE
and CONFIG_KERNEL_VM_SIZE
.
Problems
There are several.
- The two methods are orthogonal, the only point of contact is the MMU driver that is actually doing the mapping.
- The Zephyr MMU code is using a simple mechanism to keep tracking of the allocated pages that is being bypassed by the direct interface with the MMU code, so in theory could be conflicts.
- Especially on ARM64 we have (theoretically) plenty of virtual memory so we really would like to do direct mapping for MMIO driver regions but this is not currently possible with the Zephyr MMU code.
Solution?
The easiest one is to give up the direct interface and instead relying exclusively on the Zephyr MMU code. This would force us to give up the 1:1 mapping or adding support for that.
Tagging the main actors involved @dcpleung @npitre @povergoing