From: Laszlo Ersek <lersek@redhat.com>
To: edk2-devel-01 <edk2-devel@lists.01.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Liming Gao <liming.gao@intel.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: Re: [PATCH 0/7] MdePkg, OvmfPkg, ArmVirtPkg: add and use PCI(E) Capabilities Library
Date: Mon, 14 May 2018 15:15:56 +0200 [thread overview]
Message-ID: <bbcab1be-28f1-955f-0170-9611bef03033@redhat.com> (raw)
In-Reply-To: <20180504213637.11266-1-lersek@redhat.com>
ping
On 05/04/18 23:36, Laszlo Ersek wrote:
> Repo: https://github.com/lersek/edk2.git
> Branch: pci_cap
>
> In message [1], Jordan suggested a general "capabilities helper lib that
> could iterate & read the PCI capability structs". Patch #1 introduces
> that library (class and central BASE instance) to MdePkg; the library
> class is called PciCapLib.
>
> [1] http://mid.mail-archive.com/150696619010.2454.9266470245604846575@jljusten-skl
>
> PciCapLib offers APIs to parse capabilities lists, and to locate,
> describe, read and write capabilities.
>
> The library class targets a wide range of client module types; for
> example, platform PEIMs, platform DXE drivers, and UEFI drivers that
> follow the UEFI Driver Model. For this reason, the library class is
> designed with PCI config access abstracted away, even beyond the PPI /
> Protocol level, since those cannot cross the PEI / DXE boundary.
>
> This (minimal) config space access method abstraction is called
> PCI_CAP_DEV. It is *conceptually* a protocol. Client modules plug
> PCI_CAP_DEV instances into PciCapLib for config space access, similarly
> to how DiskIo and BlockIo instances are plugged into filesystem drivers.
> Similarly to the filesystem driver example, PciCapLib is an example for
> the "strategy pattern".
>
> Patches #2 and #3 introduce small "factory" libraries that help client
> modules produce PCI_CAP_DEV instances:
>
> - PciCapPciSegmentLib -- incl. class and central BASE instance -- from
> patch #2 produces PCI_CAP_DEV instances on top of PciSegmentLib, using
> the "Segment:Bus:Device.Function" notation. This is meant for platform
> modules (PEIMs and DXE drivers), which generally have a working
> PciSegmentLib instance available.
>
> - PciCapPciIoLib -- incl. class and central UEFI instance -- from patch
> #3 lets client modules produce PCI_CAP_DEV instances on top of
> EFI_PCI_IO_PROTOCOL instances. This is meant for UEFI drivers.
>
> Patches #4 and #5 resolve the three new lib classes to their respective
> central instances in the OvmfPkg and ArmVirtPkg DSC files.
>
> Patch #6 converts OvmfPkg/PciHotPlugInitDxe to the new APIs, from manual
> capability list parsing. Because PciHotPlugInitDxe is a platform DXE
> driver, this conversion uses PciCapPciSegmentLib and PciCapLib.
>
> Patch #7 converts OvmfPkg/Virtio10Dxe to the new APIs, from manual
> capability list parsing. Because Virtio10Dxe is a UEFI driver, this
> conversion uses PciCapPciIoLib and PciCapLib.
>
> ----[ jump to the patches now, and return if you have questions: I
> have answers, but you might find them too verbose in advance ]----
>
> Q1: If PCI config access needs to be abstracted from PciCapLib, then why
> don't we provide multiple instances of PciCapLib? In other words,
> why the PCI_CAP_DEV "protocol" rather than multiple instances of
> PciCapLib?
>
> A1: The point of lib classes and instances is that the class provides a
> common interface, and the instances provide different
> implementations. We have the opposite use case here (hence the
> "strategy pattern"): the implementation of the higher level
> algorithm is common, and the objects that plug into it differ at the
> *interface* level ("Segment:Bus:Device.Function" notation versus
> PciIo protocol).
>
> None of those notations are suitable for inclusion in the PciCapLib
> *class*; a more abstract interface is needed for identifying the PCI
> device to the library, for parsing of capabilities lists.
>
> Q2: OK, let's say we can't (and shouldn't) include both notations in the
> PciCapLib class; can we settle on one of them, rather than
> PCI_CAP_DEV?
>
> A2: No, we can't. PciIo is obviously unusable in PEIMs (and in quite a
> few platform DXE drivers too).
>
> It takes a bit longer to explain why the other choice, i.e. adopting
> the "Segment:Bus:Device.Function" notation for the PciCapLib
> interface, is not good either. It has to do with the portability of
> UEFI drivers that bind PciIo protocol instances:
>
> It is indeed easy enough to call PciIo->GetLocation() and plug the
> output values into a theoretical "Segment:Bus:Device.Function"
> interface. However, about the only two things that could consume
> such location identifiers and actually *implement* config space
> access would be:
>
> (a) the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read/Write member
> functions, where the member functions themselves take the
> "Bus:Device.Function" part, and the "Segment" part must be used
> for selecting the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance
> itself, through the SegmentNumber member;
>
> (b) the PciSegmentLib interfaces.
>
> Building a PciCapLib instance that uses (a) into a UEFI driver is a
> bad idea, because there are platforms that provide PciIo instances
> -- hence the driver can generally run on them -- but don't provide
> PciRootBridgeIo instances.
>
> Building a PciCapLib instance that uses (b) into a UEFI driver is
> worse. The PciSegmentLib interfaces are not capable of returning
> errors. For example, if a device appears as PCI Express (implying
> its extended config space exists, potentially containing extended
> capabilities), but the underlying platform does not support extended
> config space access (for example because it only supports
> 0xCF8/0xCFC, and not ECAM), then peeking at the extended config
> space of the device may invoke undefined behavior within
> PciSegmentLib, and the PciCapLib instance will be none the wiser.
>
> (In fact, for the same reason, even PciCapPciSegmentLib has to
> extend the "Segment:Bus:Device.Function" notation slightly; so that
> such issues are caught *before* the call is made to PciSegmentLib.)
>
> Q3: Wait, I thought it wasn't possible for a PCI Express device to
> appear on a platform that lacked ECAM.
>
> A3: Is that a question? :) Yes, it is plenty possible [2]. Same way as
> garbage / looped config spaces are [3].
>
> [2] https://github.com/tianocore/edk2/commit/014b472053ae3
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=02d578e5edd9
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>
> Thanks,
> Laszlo
>
> Laszlo Ersek (7):
> MdePkg: introduce PciCapLib
> MdePkg: introduce PciCapPciSegmentLib
> MdePkg: introduce PciCapPciIoLib
> OvmfPkg: resolve PciCapLib, PciCapPciSegmentLib, PciCapPciIoLib
> ArmVirtPkg: resolve PciCapLib, PciCapPciSegmentLib, PciCapPciIoLib
> OvmfPkg/PciHotPlugInitDxe: convert to PciCapLib
> OvmfPkg/Virtio10Dxe: convert to PciCapLib
>
> ArmVirtPkg/ArmVirt.dsc.inc | 3 +
> MdePkg/Include/Library/PciCapLib.h | 429 +++++++++
> MdePkg/Include/Library/PciCapPciIoLib.h | 58 ++
> MdePkg/Include/Library/PciCapPciSegmentLib.h | 82 ++
> MdePkg/Library/BasePciCapLib/BasePciCapLib.c | 1007 ++++++++++++++++++++
> MdePkg/Library/BasePciCapLib/BasePciCapLib.h | 60 ++
> MdePkg/Library/BasePciCapLib/BasePciCapLib.inf | 37 +
> MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.c | 226 +++++
> MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.h | 47 +
> MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf | 34 +
> MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.c | 243 +++++
> MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.h | 44 +
> MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf | 35 +
> MdePkg/MdePkg.dec | 14 +
> MdePkg/MdePkg.dsc | 3 +
> OvmfPkg/Include/IndustryStandard/Virtio10.h | 7 +-
> OvmfPkg/OvmfPkgIa32.dsc | 3 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 3 +
> OvmfPkg/OvmfPkgX64.dsc | 3 +
> OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c | 267 ++----
> OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf | 5 +
> OvmfPkg/Virtio10Dxe/Virtio10.c | 135 +--
> OvmfPkg/Virtio10Dxe/Virtio10.inf | 2 +
> 23 files changed, 2485 insertions(+), 262 deletions(-)
> create mode 100644 MdePkg/Include/Library/PciCapLib.h
> create mode 100644 MdePkg/Include/Library/PciCapPciIoLib.h
> create mode 100644 MdePkg/Include/Library/PciCapPciSegmentLib.h
> create mode 100644 MdePkg/Library/BasePciCapLib/BasePciCapLib.c
> create mode 100644 MdePkg/Library/BasePciCapLib/BasePciCapLib.h
> create mode 100644 MdePkg/Library/BasePciCapLib/BasePciCapLib.inf
> create mode 100644 MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.c
> create mode 100644 MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.h
> create mode 100644 MdePkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
> create mode 100644 MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.c
> create mode 100644 MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.h
> create mode 100644 MdePkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
>
next prev parent reply other threads:[~2018-05-14 13:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-04 21:36 [PATCH 0/7] MdePkg, OvmfPkg, ArmVirtPkg: add and use PCI(E) Capabilities Library Laszlo Ersek
2018-05-04 21:36 ` [PATCH 1/7] MdePkg: introduce PciCapLib Laszlo Ersek
2018-05-04 21:36 ` [PATCH 2/7] MdePkg: introduce PciCapPciSegmentLib Laszlo Ersek
2018-05-04 21:36 ` [PATCH 3/7] MdePkg: introduce PciCapPciIoLib Laszlo Ersek
2018-05-04 21:36 ` [PATCH 4/7] OvmfPkg: resolve PciCapLib, PciCapPciSegmentLib, PciCapPciIoLib Laszlo Ersek
2018-05-04 21:36 ` [PATCH 5/7] ArmVirtPkg: " Laszlo Ersek
2018-05-04 21:36 ` [PATCH 6/7] OvmfPkg/PciHotPlugInitDxe: convert to PciCapLib Laszlo Ersek
2018-05-04 21:36 ` [PATCH 7/7] OvmfPkg/Virtio10Dxe: " Laszlo Ersek
2018-05-14 13:15 ` Laszlo Ersek [this message]
2018-05-14 15:06 ` [PATCH 0/7] MdePkg, OvmfPkg, ArmVirtPkg: add and use PCI(E) Capabilities Library Gao, Liming
2018-05-14 17:19 ` 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=bbcab1be-28f1-955f-0170-9611bef03033@redhat.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