Files
system76-edk2/OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.h
Laszlo Ersek 02b9a8343f OvmfPkg: introduce PciCapPciIoLib
Add a library class, and a UEFI_DRIVER lib instance, that are layered on
top of PciCapLib, and allow clients to plug an EFI_PCI_IO_PROTOCOL backend
into PciCapLib, for config space access.

(Side note:

Although the UEFI spec says that EFI_PCI_IO_PROTOCOL_CONFIG() returns
EFI_UNSUPPORTED if "[t]he address range specified by Offset, Width, and
Count is not valid for the PCI configuration header of the PCI
controller", this patch doesn't directly document the EFI_UNSUPPORTED
error code, for ProtoDevTransferConfig() and its callers
ProtoDevReadConfig() and ProtoDevWriteConfig(). Instead, the patch refers
to "unspecified error codes". The reason is that in edk2, the
PciIoConfigRead() and PciIoConfigWrite() functions [1] can also return
EFI_INVALID_PARAMETER for the above situation.

Namely, PciIoConfigRead() and PciIoConfigWrite() first call
PciIoVerifyConfigAccess(), which indeed produces the standard
EFI_UNSUPPORTED error code, if the device's config space is exceeded.
However, if PciIoVerifyConfigAccess() passes, and we reach
RootBridgeIoPciRead() and RootBridgeIoPciWrite() [2], then
RootBridgeIoCheckParameter() can still fail, e.g. if the root bridge
doesn't support extended config space (see commit 014b472053).

For all kinds of Limit violations in IO, MMIO, and config space,
RootBridgeIoCheckParameter() returns EFI_INVALID_PARAMETER, not
EFI_UNSUPPORTED. That error code is then propagated up to, and out of,
PciIoConfigRead() and PciIoConfigWrite().

[1] MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
[2] MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-05-24 21:20:42 +02:00

45 lines
1.3 KiB
C

/** @file
Plug an EFI_PCI_IO_PROTOCOL backend into PciCapLib, for config space access
-- internal macro and type definitions.
Copyright (C) 2018, Red Hat, Inc.
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __UEFI_PCI_CAP_PCI_IO_LIB_H__
#define __UEFI_PCI_CAP_PCI_IO_LIB_H__
#include <Library/DebugLib.h>
#include <Library/PciCapPciIoLib.h>
#define PROTO_DEV_SIG SIGNATURE_64 ('P', 'C', 'P', 'I', 'O', 'P', 'R', 'T')
typedef struct {
//
// Signature identifying the derived class.
//
UINT64 Signature;
//
// Members added by the derived class, specific to the use of
// EFI_PCI_IO_PROTOCOL.
//
EFI_PCI_IO_PROTOCOL *PciIo;
//
// Base class.
//
PCI_CAP_DEV BaseDevice;
} PROTO_DEV;
#define PROTO_DEV_FROM_PCI_CAP_DEV(PciDevice) \
CR (PciDevice, PROTO_DEV, BaseDevice, PROTO_DEV_SIG)
#endif // __UEFI_PCI_CAP_PCI_IO_LIB_H__