2 PCI command register operations supporting functions implementation for PCI Bus module.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Operate the PCI register via PciIo function interface.
14 @param PciIoDevice Pointer to instance of PCI_IO_DEVICE.
15 @param Command Operator command.
16 @param Offset The address within the PCI configuration space for the PCI controller.
17 @param Operation Type of Operation.
18 @param PtrCommand Return buffer holding old PCI command, if operation is not EFI_SET_REGISTER.
20 @return Status of PciIo operation.
25 IN PCI_IO_DEVICE
*PciIoDevice
,
29 OUT UINT16
*PtrCommand
34 EFI_PCI_IO_PROTOCOL
*PciIo
;
37 PciIo
= &PciIoDevice
->PciIo
;
39 if (Operation
!= EFI_SET_REGISTER
) {
40 Status
= PciIo
->Pci
.Read (
48 if (Operation
== EFI_GET_REGISTER
) {
49 *PtrCommand
= OldCommand
;
54 if (Operation
== EFI_ENABLE_REGISTER
) {
55 OldCommand
= (UINT16
) (OldCommand
| Command
);
56 } else if (Operation
== EFI_DISABLE_REGISTER
) {
57 OldCommand
= (UINT16
) (OldCommand
& ~(Command
));
62 return PciIo
->Pci
.Write (
72 Check the capability supporting by given device.
74 @param PciIoDevice Pointer to instance of PCI_IO_DEVICE.
76 @retval TRUE Capability supported.
77 @retval FALSE Capability not supported.
81 PciCapabilitySupport (
82 IN PCI_IO_DEVICE
*PciIoDevice
85 if ((PciIoDevice
->Pci
.Hdr
.Status
& EFI_PCI_STATUS_CAPABILITY
) != 0) {
93 Locate capability register block per capability ID.
95 @param PciIoDevice A pointer to the PCI_IO_DEVICE.
96 @param CapId The capability ID.
97 @param Offset A pointer to the offset returned.
98 @param NextRegBlock A pointer to the next block returned.
100 @retval EFI_SUCCESS Successfully located capability register block.
101 @retval EFI_UNSUPPORTED Pci device does not support capability.
102 @retval EFI_NOT_FOUND Pci device support but can not find register block.
106 LocateCapabilityRegBlock (
107 IN PCI_IO_DEVICE
*PciIoDevice
,
109 IN OUT UINT8
*Offset
,
110 OUT UINT8
*NextRegBlock OPTIONAL
114 UINT16 CapabilityEntry
;
118 // To check the capability of this device supports
120 if (!PciCapabilitySupport (PciIoDevice
)) {
121 return EFI_UNSUPPORTED
;
125 CapabilityPtr
= *Offset
;
129 if (IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
131 PciIoDevice
->PciIo
.Pci
.Read (
134 EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR
,
140 PciIoDevice
->PciIo
.Pci
.Read (
143 PCI_CAPBILITY_POINTER_OFFSET
,
150 while ((CapabilityPtr
>= 0x40) && ((CapabilityPtr
& 0x03) == 0x00)) {
151 PciIoDevice
->PciIo
.Pci
.Read (
159 CapabilityID
= (UINT8
) CapabilityEntry
;
161 if (CapabilityID
== CapId
) {
162 *Offset
= CapabilityPtr
;
163 if (NextRegBlock
!= NULL
) {
164 *NextRegBlock
= (UINT8
) (CapabilityEntry
>> 8);
171 // Certain PCI device may incorrectly have capability pointing to itself,
172 // break to avoid dead loop.
174 if (CapabilityPtr
== (UINT8
) (CapabilityEntry
>> 8)) {
178 CapabilityPtr
= (UINT8
) (CapabilityEntry
>> 8);
181 return EFI_NOT_FOUND
;
185 Locate PciExpress capability register block per capability ID.
187 @param PciIoDevice A pointer to the PCI_IO_DEVICE.
188 @param CapId The capability ID.
189 @param Offset A pointer to the offset returned.
190 @param NextRegBlock A pointer to the next block returned.
192 @retval EFI_SUCCESS Successfully located capability register block.
193 @retval EFI_UNSUPPORTED Pci device does not support capability.
194 @retval EFI_NOT_FOUND Pci device support but can not find register block.
198 LocatePciExpressCapabilityRegBlock (
199 IN PCI_IO_DEVICE
*PciIoDevice
,
201 IN OUT UINT32
*Offset
,
202 OUT UINT32
*NextRegBlock OPTIONAL
206 UINT32 CapabilityPtr
;
207 UINT32 CapabilityEntry
;
211 // To check the capability of this device supports
213 if (!PciIoDevice
->IsPciExp
) {
214 return EFI_UNSUPPORTED
;
218 CapabilityPtr
= *Offset
;
220 CapabilityPtr
= EFI_PCIE_CAPABILITY_BASE_OFFSET
;
223 while (CapabilityPtr
!= 0) {
225 // Mask it to DWORD alignment per PCI spec
227 CapabilityPtr
&= 0xFFC;
228 Status
= PciIoDevice
->PciIo
.Pci
.Read (
235 if (EFI_ERROR (Status
)) {
239 CapabilityID
= (UINT16
) CapabilityEntry
;
241 if (CapabilityID
== CapId
) {
242 *Offset
= CapabilityPtr
;
243 if (NextRegBlock
!= NULL
) {
244 *NextRegBlock
= (CapabilityEntry
>> 20) & 0xFFF;
250 CapabilityPtr
= (CapabilityEntry
>> 20) & 0xFFF;
253 return EFI_NOT_FOUND
;