The Cortex-M1 processor implements a Memory Protection Unit (MPU) to provide memory access control and address translation capabilities. When accessing DDR memory connected to the Processor Subsystem (PS), the Cortex-M1 MPU performs address translation to map virtual addresses used by the CPU to physical addresses in DDR memory.
Cortex-M1 MPU Overview
The Cortex-M1 MPU supports configuring up to 16 memory regions with individual access permission controls. Each MPU region is defined by:
- Start address – Base address of the memory region
- End address – Limit address of the region
- Access permissions – Read/Write/Execute permissions
- XN attribute – Instruction fetch disable flag
- Region size – Determines region matching logic
- Enable flag – To enable/disable the region
The MPU checks every memory access from the CPU against the configured regions to validate the access and perform address translation if enabled. By default, address translation is disabled and the MPU performs only access permission checks.
Enabling MPU for DDR Access
To enable address translation for DDR accesses, the DDR memory range must be configured as an MPU region with address translation enabled. For example: MPU_Region DDR_region; DDR_region.base_addr = DDR_PHYS_BASE; // e.g. 0x80000000 DDR_region.end_addr = DDR_PHYS_END; // e.g. 0x81FFFFFF DDR_region.access_perm = FULL_ACCESS; DDR_region.xn = NOT_EXECUTE; DDR_region.enable = ENABLED; DDR_region.addr_translate = ENABLED; MPU_ConfigureRegion(&DDR_region);
This configures an MPU region covering the full DDR physical address range with read/write/execute permissions. Address translation is enabled by setting the addr_translate field.
Cortex-M1 Address Translation
With MPU address translation enabled, the processor converts the virtual addresses from the CPU core into physical addresses to access DDR memory. This translation uses a first-level table called the Translation Table Base Register (TTBR).
The TTBR points to a translation table in memory with descriptors that contain the mapping information. An area of DDR memory needs to be allocated for the translation table. The descriptor format determines the page size – 4KB or 64KB.
For a 4KB page table, the virtual address is split into:
- Top 20 bits – Point to the descriptor entry in the translation table
- Next 12 bits – 4KB page offset
The processor uses the top bits to look up the descriptor, which contains the 20-bit physical page number. This gets concatenated with the 12-bit offset to form the 32-bit physical address.
Translation Process
So in summary, the Cortex-M1 performs these steps for address translation:
- Split virtual address into PTBR index and page offset bits
- Read entry from translation table pointed to by TTBR
- Get page number from descriptor entry
- Concatenate page number and offset to form physical address
- Access memory using physical address
The MPU also checks the descriptor entry access permissions before allowing the access. Any violation causes a memory fault exception.
Setting up the Translation Table
The translation table is normally set up by the platform boot firmware. A region of DDR memory must be allocated for the table. Some key steps are:
- Allocate translation table memory and clear entries
- Create descriptors for mapping DDR memory
- Set TTBR to point to base of table
- Enable MPU and address translation
The descriptors need to map the DDR memory address range contiguously, with access permissions enabled. The PS virtual address space for DDR can be identity mapped 1:1 to the physical addresses.
Enabling Cache with MMU
The Cortex-M1 has 8KB instruction and data caches. Cacheability attributes can be set in the translation table descriptors. This controls whether memory regions are cached or bypass the cache.
The inner cache must be enabled along with the MMU translation. This ensures cache coherency and that cache invalidate operations work correctly with address translation enabled.
Handling Translation Faults
In case of any translation fault, the Cortex-M1 raises a memory management fault exception. The fault status registers indicate the fault reason, which can be:
- Access permission violation
- Translation fault – Invalid descriptor entry
- Domain fault – Access to unsupported domain
- Alignment fault e.g. unaligned access
The fault handler needs to examine the fault status and take appropriate action – fix invalid table entry, change permission, or terminate the process. The translation table contents may need to be modified dynamically at runtime in some cases.
Using the MPU for Software Processes
The Cortex-M1 MPU and MMU can be used to implement memory protection and virtual addressing for supervisor software and application processes running on the processor. Some examples:
- Isolate processes into separate virtual address spaces
- Limit process memory access to allowed regions
- Map memory areas with different cache attributes
- Dynamically expand/shrink process memory regions
The MPU provides the basic mechanisms for memory access control and address translation needed for robust software processes in embedded applications using the Cortex-M1 processor.
Conclusion
The Cortex-M1 MPU provides configurable regions with access control and address translation capabilities to remap CPU addresses when accessing DDR memory. The translation table setup is important to map the DDR address range contiguously and enable cacheability as needed. Proper fault handling and dynamically modifying table entries are required to support virtual memory management of software processes.