From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3AEC92112E024 for ; Sun, 16 Sep 2018 03:19:59 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8D05A3081D95; Sun, 16 Sep 2018 10:19:58 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-22.rdu2.redhat.com [10.10.120.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4A1D7104255A; Sun, 16 Sep 2018 10:19:56 +0000 (UTC) To: "Kirkendall, Garrett" References: Cc: "edk2-devel@lists.01.org" , Ruiyu Ni From: Laszlo Ersek Message-ID: <7559c32e-28e0-123b-c392-36b601bf63d2@redhat.com> Date: Sun, 16 Sep 2018 12:19:55 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Sun, 16 Sep 2018 10:19:58 +0000 (UTC) Subject: Re: How do I access Prefetchable Memory region through EFI_PCI_IO_PROTOCOL X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 16 Sep 2018 10:19:59 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Adding Ray, and a comment at the bottom: On 09/14/18 20:24, Kirkendall, Garrett wrote: > Hopefully someone can help me understand. > > I assume I should be able to access MMIO pointed to by a PCI devices Prefetchable Memory BAR. I would think I would use EFI_PCI_IO_PROTOCOL.Mem.Read or Write. This in turn will send the request up to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Mem.Read or Write. > > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c: RootBridgeIoMemRead (Write) calls RootBridgeIoCheckParameter() to verify that the request falls within the confines of the PCI root bridge. The below code verifies the address against non-prefetchable MMIO regions and skips the prefetchable memory regions. Is this correct, and if so what is the method to read/write prefetchable memory regions? If I force EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM, then I can access prefetchable memory regions because they are forced within Mem.* and MemAbove4G.* > > > > EFI_STATUS > RootBridgeIoCheckParameter ( > IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, > IN OPERATION_TYPE OperationType, > IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, > IN UINT64 Address, > IN UINTN Count, > IN VOID *Buffer > ) > { > ... > } else if (OperationType == MemOperation) { > // > // Allow Legacy MMIO access > // > if ((Address >= 0xA0000) && (Address + MultU64x32 (Count, Size)) <= 0xC0000) { > if ((RootBridge->Attributes & EFI_PCI_ATTRIBUTE_VGA_MEMORY) != 0) { > return EFI_SUCCESS; > } > } > // > // By comparing the Address against Limit we know which range to be used > // for checking > // > if (Address + MultU64x32 (Count, Size) <= RootBridge->Mem.Limit + 1) { > Base = RootBridge->Mem.Base; > Limit = RootBridge->Mem.Limit; > } else { > Base = RootBridge->MemAbove4G.Base; > Limit = RootBridge->MemAbove4G.Limit; > } > } else { > ... > I'm not a PCI expert, but I think you are right; the code should permit access to the PMem / PMemAbove4G apertures as well. According to the PCI spec (--> fair use citation below), "A PCI Express Function requesting memory resources through a BAR must set the BAR's Prefetchable bit unless the range contains locations with read side effects or locations in which the Function does not tolerate write merging." IOW "prefetchable" means "there are no side effects to reading, and the Function tolerates write merging". I don't see why that's reason for RootBridgeIoCheckParameter() to reject the access. Ray, what's your take? Thanks Laszlo