[ARM/PL011] Wrong UART register spacing reported in DBG2/SPCR
Host environment
qemu-system-aarch64 -nodefaults -no-reboot -display none -serial mon:stdio -smp 4 -m 4G -cpu max -M virt,virtualization=on,secure=off,gic-version=3,iommu=smmuv3'
Description of problem
QEMU reports the UART address on aarch64 (for PL011 UART) via the ACPI DBG2 and SPCR tables using the ACPI GAS structure. According to MSFT documentation at https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table:
- The Register Bit Width field contains the register stride and must be a power of 2 that is at least as large as the access size. On 32-bit platforms this value cannot exceed 32. On 64-bit platforms this value cannot exceed 64.
- The Access Size field is used to determine whether byte, WORD, DWORD, or QWORD accesses are to be used. QWORD accesses are only valid on 64-bit architectures.
For the PL011, the MMIO registers are:
- spaced 4 bytes apart; therefore the reported bit width should be 32 instead of 8.
- 16 bits wide; therefore the access width should be 2 instead of 1.
In other words:
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6b674231c2..cd284676d7 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -482,7 +482,7 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
/* Base Address */
- build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 2,
vms->memmap[VIRT_UART].base);
/* Interrupt Type */
build_append_int_noprefix(table_data,
@@ -673,7 +673,7 @@ build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 34, 2);
/* BaseAddressRegister[] */
- build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 2,
vms->memmap[VIRT_UART].base);
/* AddressSize[] */
Edited by Udo Steinberg