From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Laszlo Ersek <lersek@redhat.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@ml01.01.org>,
Leif Lindholm <leif.lindholm@linaro.org>
Subject: Re: [PATCH v2 0/6] ArmVirtQemu: move to generic PciHostBridgeDxe
Date: Fri, 2 Sep 2016 17:26:34 +0100 [thread overview]
Message-ID: <CAKv+Gu-Ec=E+3bB95E1xW3m4rQWNWB6wwL2-a0vxxVFuO5E-oA@mail.gmail.com> (raw)
In-Reply-To: <f538d747-45ba-e76b-cc54-82f7b085ac4f@redhat.com>
On 2 September 2016 at 17:13, Laszlo Ersek <lersek@redhat.com> wrote:
> On 09/02/16 17:27, Laszlo Ersek wrote:
>> On 09/02/16 16:58, Ard Biesheuvel wrote:
>>> (on the road atm, will reply in full later)
>>>
>>>> On 2 sep. 2016, at 14:09, Laszlo Ersek <lersek@redhat.com> wrote:
>>
>>>> (2) aarch64 KVM, using virtio-gpu-pci and USB 2 keyboard and
>>>> tablet. I actually booted a Fedora 24 guest with this, and in the
>>>> guest, everything works just fine (display, keyboard,
>>>> mouse/tablet). Most of the firmware log looks good too.
>>>>
>>>> (2a) However, the USB 2 keyboard is broken while in the firmware
>>>> (in spite of it working well in the guest OS).
>>>>
>>>> -device ich9-usb-ehci1,multifunction=on,id=ehci,addr=05.0 \
>>>> -device ich9-usb-uhci1,multifunction=on,masterbus=ehci.0,firstport=0,addr=05.1 \
>>>> -device ich9-usb-uhci2,multifunction=on,masterbus=ehci.0,firstport=2,addr=05.2 \
>>>> -device ich9-usb-uhci3,multifunction=on,masterbus=ehci.0,firstport=4,addr=05.3 \
>>>> -device usb-kbd,bus=ehci.0 \
>>>> -device usb-tablet,bus=ehci.0 \
>>>>
>>>> My QEMU has your commit 5d636e21c44e ("hw/arm/virt: mark the PCIe
>>>> host controller as DMA coherent in the DT"), but I guess the EHCI
>>>> driver in edk2 doesn't comply with the "guest drivers should use
>>>> cacheable accesses as well when running under KVM" part. :(
>>>>
>>>> The following snippet repeats in the log:
>>>>
>>>> EhcClearLegacySupport: called to clear legacy support
>>>> processing error - resetting ehci HC
>>>> EhcInitHC: failed to enable period schedule
>>>> EhcDriverBindingStart: failed to init host controller
>>>> EhcCreateUsb2Hc: capability length 32
>>>>
>>>> Interestingly, if I back out your series, then USB2 works in the
>>>> firmware. I don't understand this, given that my build includes
>>>> commit 3ef3209d3028 ("ArmVirtPkg: remove
>>>> PcdKludgeMapPciMmioAsCached") from the master branch!
>>>>
>>>
>>> Does it work when you limit DMA to < 4 GB?
>>
>> You are one wicked genius, man; the following change
>>
>>> diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
>>> index efccedcca14f..1f0f87cac8a9 100644
>>> --- a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
>>> +++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
>>> @@ -317,7 +317,7 @@ PciHostBridgeGetRootBridges (
>>> EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
>>> mRootBridge.Attributes = mRootBridge.Supports;
>>>
>>> - mRootBridge.DmaAbove4G = TRUE;
>>> + mRootBridge.DmaAbove4G = FALSE;
>>> mRootBridge.NoExtendedConfigSpace = FALSE;
>>> mRootBridge.ResourceAssigned = FALSE;
>>>
>>
>> does make it work! Excellent!
>>
>> Explain please. :) (Although, I'll look into PciHostBridgeDxe in a moment too. :))
>
Thanks. You seem to have a good handle on things already, though :-)
> Well okay, I reviewed the RootBridgeIoMap() and RootBridgeIoUnmap()
> functions in "MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c".
> They implement bounce buffering when DmaAbove4G is set to FALSE, and
> when the original RAM buffer, to be DMA'd from or to by the PCI device,
> would end outside of 32-bit space.
>
> For common buffer operations (when device and CPU collaborate on memory
> repeatedly, without intervening Map() and Unmap() calls), Map() and
> Unmap() cannot implement bounce buffering, so the initial buffer must be
> allocated low enough. This is what RootBridgeIoAllocateBuffer() does,
> and yes it considers DmaAbove4G as well.
>
> EhciDxe uses these functions quite a bit. And, my test VM has 4G of
> memory, with a base at 0x4000_0000 (1GB); the base is fixed of course,
> from "-M virt". So, I guess, some buffers that EhciDxe allocated itself,
> for DMA'ing from/to the device, and some buffers that it allocated with
> AllocateBuffer(), for common operations with the device, ended up in the
> 4GB..5GB range. Due to DmaAbove4G = TRUE, those host addresses got
> passed to the PCI device (the USB 2 host controller) verbatim, but that
> device can only access host RAM in the 32-bit address range?....
>
> Hm, let me check the QEMU code (hw/usb/hcd-ehci.c)...
>
> Alright, I've found it. According to the EHCI specification
> ("ehci-specification-for-usb.pdf", link found under
> <https://en.wikipedia.org/wiki/Extensible_Host_Controller_Interface#References>),
> revision 1.0, section "2.2.4 HCCPARAMS -- Capability Parameters", bit #0
> (value 1) in the HCCPARAMS capability register stands for:
>
>
> 64-bit Addressing Capability. This field documents the addressing
> range capability of this implementation. The value of this field
> determines whether software should use the data structures defined
> in Section 3 (32-bit) or those defined in Appendix B (64-bit).
> Values for this field have the following interpretation:
>
> 0b data structures using 32-bit address memory pointers
> 1b data structures using 64-bit address memory pointers
>
> Furthermore, the HCCPARAMS register lives at address "Base + (08h)".
>
> Now, looking at the QEMU code, we have usb_ehci_init()
> [hw/usb/hcd-ehci.c] performing the following assignment:
>
> s->caps[0x08] = 0x80; /* We can cache whole frame, no 64-bit */
>
> (And, the "cache whole frame" reference, for bit #7, is consistent with
> the documentation of that bit in the spec: "When bit [7] is a
> one, then host software assumes the host controller may cache an
> isochronous data structure for an entire frame.")
>
> So, bingo. Please flip DmaAbove4G to FALSE in patch #3, and please drop
> the "DMA above 4 GB" paragraph from the commit message of patch #4.
>
Actually, I suspect this is a bug in PciHostBridgeDxe. It ignores the
absence of the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute, which
should be set by the driver if it knows the device is capable of
64-bit DMA.
Could you please try the below?
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index b2d76d67afa2..b53b9a834816 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -1308,7 +1308,8 @@ RootBridgeIoAllocateBuffer (
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
AllocateType = AllocateAnyPages;
- if (!RootBridge->DmaAbove4G) {
+ if (!RootBridge->DmaAbove4G ||
+ (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
//
// Limit allocations to memory below 4GB
//
Thanks,
Ard.
next prev parent reply other threads:[~2016-09-02 16:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-31 17:59 [PATCH v2 0/6] ArmVirtQemu: move to generic PciHostBridgeDxe Ard Biesheuvel
2016-08-31 17:59 ` [PATCH v2 1/6] ArmVirtPkg/PciHostBridgeDxe: don't set linux, pci-probe-only DT property Ard Biesheuvel
2016-08-31 17:59 ` [PATCH v2 2/6] ArmVirtPkg/FdtPciPcdProducerLib: add handling of PcdPciIoTranslation Ard Biesheuvel
2016-09-02 11:19 ` Laszlo Ersek
2016-08-31 17:59 ` [PATCH v2 3/6] ArmVirtPkg: implement FdtPciHostBridgeLib Ard Biesheuvel
2016-09-02 10:15 ` Laszlo Ersek
2016-08-31 17:59 ` [PATCH v2 4/6] ArmVirtPkg/ArmVirtQemu: switch to generic PciHostBridgeDxe Ard Biesheuvel
2016-08-31 17:59 ` [PATCH v2 5/6] ArmVirtPkg/FdtPciHostBridgeLib: add MMIO64 support Ard Biesheuvel
2016-09-02 10:44 ` Laszlo Ersek
2016-08-31 17:59 ` [PATCH v2 6/6] ArmVirtPkg: remove now unused PciHostBridgeDxe Ard Biesheuvel
2016-09-02 13:09 ` [PATCH v2 0/6] ArmVirtQemu: move to generic PciHostBridgeDxe Laszlo Ersek
2016-09-02 13:17 ` Laszlo Ersek
2016-09-02 14:58 ` Ard Biesheuvel
2016-09-02 15:27 ` Laszlo Ersek
2016-09-02 16:13 ` Laszlo Ersek
2016-09-02 16:26 ` Ard Biesheuvel [this message]
2016-09-02 17:21 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAKv+Gu-Ec=E+3bB95E1xW3m4rQWNWB6wwL2-a0vxxVFuO5E-oA@mail.gmail.com' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox