Have you ever succeeded in performing a Stage-1 MMU translation using
LPAE (Long Physical Address Extension) on the FVP_Base_RevC-2xAEMvA
platform model running in AArch32 Hyp mode (CONFIG64=0) into any other
Memory but Strongly-Ordered?
My environment is
- FVP_Base_RevC-2xAEMvA booting SW stack from bullet point below
- SW stack from Yocto, 'meta-arm'. I use 'fvp-base-arm32' that builds
bl1, bl2, bl32, bl33, Linux kernel and rootfs.
The only component that works there at PL2 HYP mode is u-boot (bl33).
Whichever attributes I assign there Normal Memory with Inner or Outer
Cacheability, Write-Through, or Write-Back, or Non-cacheable I always
end up with Strongly-Ordered.
To me it looks like it doesn't read the MAIR correctly and/or ignores
the Cachability in HCTR.
I inspected the MMU code thoroughly there, compared with the other
codes for MMU, from trusted-firmware-a, xen, and Linux kernel and it
seems u-boot does it correct. U-boot sets there identity-mapping for
all 4GB with 0GB through 2GB Strongly-Ordered, 3G - 4G Normal Memory,
Cachable Write-Back Write-Allocate, Non-Shareable and the last 1GB
also Strongly-Ordered. Here is a brief execution steps it goes
through:
#1 Sets up the 2M-block at the 2nd level table with attributes.
- sample block descriptor for translating from 0x8000_0000 virt to
phys: 0x8000044d
- bits[1:0] = 0b01 -> valid descriptor, descriptor type: block
- bits[4:2] = 0b011 -> AttrIndx[2:0] points to MAIR0[3] . MAIR0[3] is 0xff
- bits[5] = 0b0 - Non-secure
- bits[7:6] = 0b01 - Access Permission: Read/write
- bits[9:8] = 0b00 -> Shareability: non-shareable
#2 Sets up 1st level table descriptor pointing to the descriptor shown
above. It sets bits[1:0] to 0b11 meaning it is a table descriptor and
valid.
#3 Set control registers as follows
HTCR is: 0x80000500 so
- bits[9:8] = 0b01 -> Inner Cacheability to Normal memory, Outer
Write-Back Write-Allocate Cacheable
- bits[11:10] = 0b01 -> Outer Cacheability to Normal memory, Outer
Write-Back Write-Allocate Cacheable
- bits[13:12] = 0b00 -> Non-shareable
HTTBR is: 0x00000000feff4000 -> points to 1st lavel table set in #2
HMAIR0 is: 0xffeeaa00 -> as shown above AttrIndx[2:0] points to MAIR0
and the four nibble being 0xff. 0xff is Normal memory, Inner
Write-Back Cacheablea, Non-transientb
HMAIR1 is: 0x00000000 - I set it to zero there as not used.
#4 Finally it sets the M and C bits in HSCTLR registers
Inspecting the page tables with amrds the region 3GB through 4GB that
should be Normal and Cachable is Strongly-Ordered
- 0x80000000 | L2 Block | NP:0x0000000080000000 | XN=0, PXN=0,
Contiguous=0, nG=0, AF=1, SH=0x0, AP=0x1, AttrIndx=0x3
- H:0x80000000-0xFEFFFFFF | NP:0x80000000-0xFEFFFFFF |
Strongly-ordered | NA | False | True | True
Least not last are the parameters I pass to the model:
FVP_Base_RevC-2xAEMvA --parameter bp.ve_sysregs.exit_on_shutdown=1
--parameter bp.virtio_net.enabled=1 --parameter
bp.virtio_net.hostbridge.userNetworking=1 --parameter
bp.virtio_net.hostbridge.userNetPorts=8022=22 --parameter
cache_state_modelled=0 --parameter
bp.secureflashloader.fname=/home/ubuntu/yocto/poky/arm32-aem-build/tmp/deploy/images/fvp-base-arm32/bl1-fvp.bin
--parameter bp.flashloader0.fname=/home/ubuntu/yocto/poky/arm32-aem-build/tmp/deploy/images/fvp-base-arm32/fip-fvp.bin
--parameter bp.virtioblockdevice.image_path=/home/ubuntu/yocto/poky/arm32-aem-build/tmp/deploy/images/fvp-base-arm32/core-image-minimal-fvp-base-arm32-20250630100348.rootfs.wic
--parameter cluster0.has_arm_v8-4=1 --parameter
cluster1.has_arm_v8-4=1 --parameter cluster0.cpu0.CONFIG64=0
--parameter cluster0.cpu1.CONFIG64=0 --parameter
cluster0.cpu2.CONFIG64=0 --parameter cluster0.cpu3.CONFIG64=0
--parameter cluster1.cpu0.CONFIG64=0 --parameter
cluster1.cpu1.CONFIG64=0 --parameter cluster1.cpu2.CONFIG64=0
--parameter cluster1.cpu3.CONFIG64=0 --data
cluster0.cpu0=/home/ubuntu/yocto/poky/arm32-aem-build/tmp/deploy/images/fvp-base-arm32/zImage@0x80080000
--data cluster0.cpu0=/home/ubuntu/yocto/poky/arm32-aem-build/tmp/deploy/images/fvp-base-arm32/fvp-base-revc.dtb@0x8fc00000
--parameter 'bp.terminal_0.terminal_command=tmux new-window -n
"%title" "telnet localhost %port"' --parameter
bp.terminal_1.start_telnet=0 --parameter bp.terminal_2.start_telnet=0
--parameter bp.terminal_3.start_telnet=0 --iris-server --iris-port
7102 --iris-allow-remote
And an interrupted (not full for longevity) console log:
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.8(debug):dd37aa5be-dirty
NOTICE: BL1: Built : 20:04:50, Aug 4 2025
NOTICE: BL1: Booting BL2
NOTICE: BL2: v2.8(debug):dd37aa5be-dirty
NOTICE: BL2: Built : 20:04:50, Aug 4 2025
NOTICE: BL1: Booting BL32
WARNING: FCONF: Invalid config id 26
INFO: SP_MIN FCONF: HW_CONFIG address = 0x7f00000
INFO: FCONF: Reading HW_CONFIG firmware configuration file from: 0x7f00000
INFO: FCONF: Reading firmware configuration information for: cpu_timer
INFO: FCONF: Reading firmware configuration information for: uart_config
INFO: FCONF: Reading firmware configuration information for: topology
INFO: FCONF: Reading firmware configuration information for: gicv3_config
NOTICE: SP_MIN: v2.8(debug):dd37aa5be-dirty
NOTICE: SP_MIN: Built : 20:04:50, Aug 4 2025
U-Boot 2022.04 (Aug 06 2025 - 16:41:21 +0000) vexpress_aemv8a fvp aarch32
DRAM: 2 GiB
WARNING: Caches not enabled
Core: 2 devices, 2 uclasses
Flash: 64 MiB
MMC:
Loading Environment from nowhere... OK
In: serial_pl01x
Out: serial_pl01x
Err: serial_pl01x
Net: SMC91111-0
Error: SMC91111-0 address not set.
Hit any key to stop autoboot: 0
fvp32# dcache on
fvp32# run bootcmd
OTE: Dereference aliases by omitting the leading '/', e.g. fdt print ethernet0.
Kernel image @ 0x80080000 [ 0x000000 - 0x687970 ]
## Flattened Device Tree blob at 8fc00000
Booting using the fdt blob at 0x8fc00000
Loading Device Tree to feb8b000, end feb90fff ... OK
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 6.1.57-yocto-standard (oe-user@oe-host)
(arm-poky-linux-gnueabi-gcc (GCC) 12.3.0, GNU ld (GNU Binutils)
2.40.0.20230703) #1 SMP PREEMPT Wed Oct 11 23:03:27 UTC 2023
CPU: ARMv7 Processor [410fd0f0] revision 0 (ARMv7), cr=10c5387d
CPU: div instructions available: patching division code
CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
OF: fdt: Machine model: FVP Base RevC
earlycon: pl11 at MMIO 0x1c090000 (options '')
amba 1c1f0000.clcd: deferred probe pending
Poky (Yocto Project Reference Distro) 4.2.4 fvp-base-arm32 /dev/ttyAMA0
fvp-base-arm32 login: root
root@fvp-base-arm32:~# random: crng init done
random: 1 urandom warning(s) missed due to ratelimiting
root@fvp-base-arm32:~#
Is there a chance FVP_Base_RevC-2xAEMvA doesn't support the 1-stage
MMU translation for anything else but Strongly-Ordered?
Thanks,
Marek