Message ID | 20240201124054.2094572-1-igor.opaniuk@foundries.io |
---|---|
State | Accepted |
Commit | 1fa38ca9aae45aca58e9394a121bec6baa166f31 |
Delegated to: | Tom Rini |
Headers | show |
Series | [v2] qemu-arm: round down memory to multiple of 2MB for LPAE | expand |
On Thu, Feb 1, 2024, 14:41 Igor Opaniuk <igor.opaniuk@foundries.io> wrote: > 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 <igor.opaniuk@foundries.io>> > --- > > Changes in v2: > - Adjust commit message, add more details > > board/emulation/qemu-arm/qemu-arm.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/board/emulation/qemu-arm/qemu-arm.c > b/board/emulation/qemu-arm/qemu-arm.c > index 942f1fff571..ecfd19f1a7e 100644 > --- a/board/emulation/qemu-arm/qemu-arm.c > +++ b/board/emulation/qemu-arm/qemu-arm.c > @@ -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; > } > > -- > 2.34.1 > >
On Thu, Feb 01, 2024 at 01:40:54PM +0100, Igor Opaniuk wrote: > 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 Applied to u-boot/next, thanks!
diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 942f1fff571..ecfd19f1a7e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -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; }
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> --- Changes in v2: - Adjust commit message, add more details board/emulation/qemu-arm/qemu-arm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)