]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
qemu-arm: round down memory to multiple of 2MB for LPAE
authorIgor Opaniuk <igor.opaniuk@foundries.io>
Thu, 1 Feb 2024 12:40:54 +0000 (13:40 +0100)
committerTom Rini <trini@konsulko.com>
Sat, 2 Mar 2024 17:25:14 +0000 (12:25 -0500)
QEMU's -m option can take fractional megabyte values,
and lowest granularity seems to be 0x2000.
For example, run qemu with amount of memory set to 100005k (0x61A9400):

$ qemu-system-arm -machine virt -cpu cortex-a15 -m 100005k \
-bios denx/u-boot.bin -nographic

=> fdt addr $fdt_addr
=> fdt print /memory@40000000
memory@40000000 {
        reg = <0x00000000 0x40000000 0x00000000 0x061aa000>;
        device_type = "memory";
};

When LPAE is enabled, 1:1 mapping is created using 2 MB blocks.
In case amount of memory provided to QEMU is not multiple
of 2 MB, hang occurs during MMU initialization.

How to reproduce:
qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin - boots
qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin - hangs

DRAM:  1 GiB
initcall: 60011df8
initcall: 60011904
New Stack Pointer is: 80fffe90
initcall: 60011a20
initcall: 60011bcc
initcall: 60011bd4
initcall: 600119b4
Relocation Offset is: 22042000
Relocating to 82042000, new gd at 81001ed0, sp at 80fffe90
initcall: 60011b8c
initcall: 82053ea0
initcall: 82053ea8
initcall: 60012040 (relocated to 82054040)
dram_bank_mmu_setup: bank: 0
- hang here during mmu init -

This patches rounds down to the nearest multiple of 2MB when
CONFIG_ARMV7_LPAE=y.

Fixes: 3fa914af82("arm: qemu: implement enable_caches()")
Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io>
board/emulation/qemu-arm/qemu-arm.c

index 942f1fff571720f15a90647b082a5535c9f513c5..ecfd19f1a7eddfd101608028c9670993d7936585 100644 (file)
@@ -127,6 +127,18 @@ int dram_init(void)
        if (fdtdec_setup_mem_size_base() != 0)
                return -EINVAL;
 
+       /*
+        * When LPAE is enabled (ARMv7),
+        * 1:1 mapping is created using 2 MB blocks.
+        *
+        * In case amount of memory provided to QEMU
+        * is not multiple of 2 MB, round down the amount
+        * of available memory to avoid hang during MMU
+        * initialization.
+        */
+       if (CONFIG_IS_ENABLED(ARMV7_LPAE))
+               gd->ram_size -= (gd->ram_size % 0x200000);
+
        return 0;
 }