On 07/26/15 12:17, Peter Maydell wrote: > On 26 July 2015 at 10:31, Laszlo Ersek <ler...@redhat.com> wrote: >> On 07/25/15 11:49, Gerd Hoffmann wrote: >>> virtio-vga in vga-compat mode uses a framebuffer with the usual dirty >>> tracking logic in pci bar 0 (simliar to stdvga). Which is exactly the >>> thing causing the cache coherency issues on aarch64 if I understand >>> things correctly. >> >> Yes. :( > > The question for cache-coherency of an emulated framebuffer with > KVM is simply "does the guest set up this region of physical address > space as Normal Cacheable memory, or does it set it up as Device > or some other non-cacheable memory attribute type?". Whether the > framebuffer is part of a PCI BAR or shared with "guest RAM" doesn't > matter for this. (Of course it may matter for the guest if the > guest makes assumptions about what kind of mapping it needs to > use for any PCI BAR.) > > [NB: this is a statement about the current situation of kernel and > QEMU code and doesn't take account of any attempts we might make to > make things work better.] > >>> Programming (modesetting) works without legacy vga io >>> ports, you can use the mmio regs in pci bar 1 instead (applies to both >>> virtio-vga and stdvga btw), and QemuVideoDxe actually uses the mmio bar. >> >> True. >> >> But, as a side point, let me talk a bit about the outb() function in >> OvmfPkg/QemuVideoDxe/Driver.c. It (very correctly for a UEFI_DRIVER >> module!) uses PciIo->Io.Write() to write to IO ports. >> >> Now, the PciIo protocol implementation is platform independent. In >> practice it forwards IO space accesses to the EFI_PCI_ROOT_BRIDGE_IO >> protocol. And *that* one is platform-dependent. >> >> For x86 virtual machines, those accesses are turned into IO port >> accesses. However, the EFI_PCI_ROOT_BRIDGE_IO implementation in >> ArmVirtPkg/PciHostBridgeDxe/, which is built into AAVMF and runs on the >> "virt" machtype, maps the IO space and the IO port accesses to a special >> (fake) MMIO range of 64K "ports". >> >> In QEMU this memory region corresponds to VIRT_PCIE_PIO, in >> "hw/arm/virt.c". See create_pcie(): >> >> hwaddr base_pio = vbi->memmap[VIRT_PCIE_PIO].base; >> >> ... >> >> /* Map IO port space */ >> sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio); > > This seems to me to be confusing two things: > (1) x86-style IO ports as accessed via inb/outb insns > (2) PCI IO space > > For the ARM boards we certainly support the latter (it's part > of the PCI spec and mapping PCI IO space to some window in > physical address space is the usual approach for CPUs which > don't have x86's special-purpose io instructions). This isn't > going to go away because you need it for dealing with PCI > devices that have IO BARs. To access registers in this window > the guest needs to program the PCI card's IO BAR to make it > appear somewhere in the window. > > We don't support legacy VGO io ports, which on x86 just > always exist whether the guest programs a PCI BAR or not, > and which have fixed legacy port numbers.
I was wrong to call the PCI IO space "fake", sorry about that, and thanks for the correction. But, whatever i said about the guest firmware, should be correct. "outb" in the QemuVideoDxe source is just a familiar name that Jordan chose in 2011. However, it correctly calls PciIo->Io.Write(), which on x86 (ultimately, through several layers) results in ioport instructions, and on arm results in MMIO accesses. I may not have understood the full theoretical background of FDT_PCI_RANGE_IOPORT, but I think the firmware code that puts it to use is correct. Thanks Laszlo