TianoCore EDK2 master
Loading...
Searching...
No Matches
PciCommand.c
Go to the documentation of this file.
1
9#include "PciBus.h"
10
25 IN PCI_IO_DEVICE *PciIoDevice,
26 IN UINT16 Command,
27 IN UINT8 Offset,
28 IN UINT8 Operation,
29 OUT UINT16 *PtrCommand
30 )
31{
32 UINT16 OldCommand;
33 EFI_STATUS Status;
35
36 OldCommand = 0;
37 PciIo = &PciIoDevice->PciIo;
38
39 if (Operation != EFI_SET_REGISTER) {
40 Status = PciIo->Pci.Read (
41 PciIo,
42 EfiPciIoWidthUint16,
43 Offset,
44 1,
45 &OldCommand
46 );
47
48 if (Operation == EFI_GET_REGISTER) {
49 *PtrCommand = OldCommand;
50 return Status;
51 }
52 }
53
54 if (Operation == EFI_ENABLE_REGISTER) {
55 OldCommand = (UINT16)(OldCommand | Command);
56 } else if (Operation == EFI_DISABLE_REGISTER) {
57 OldCommand = (UINT16)(OldCommand & ~(Command));
58 } else {
59 OldCommand = Command;
60 }
61
62 return PciIo->Pci.Write (
63 PciIo,
64 EfiPciIoWidthUint16,
65 Offset,
66 1,
67 &OldCommand
68 );
69}
70
80BOOLEAN
82 IN PCI_IO_DEVICE *PciIoDevice
83 )
84{
85 if ((PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) != 0) {
86 return TRUE;
87 }
88
89 return FALSE;
90}
91
107 IN PCI_IO_DEVICE *PciIoDevice,
108 IN UINT8 CapId,
109 IN OUT UINT8 *Offset,
110 OUT UINT8 *NextRegBlock OPTIONAL
111 )
112{
113 UINT8 CapabilityPtr;
114 UINT16 CapabilityEntry;
115 UINT8 CapabilityID;
116
117 //
118 // To check the capability of this device supports
119 //
120 if (!PciCapabilitySupport (PciIoDevice)) {
121 return EFI_UNSUPPORTED;
122 }
123
124 if (*Offset != 0) {
125 CapabilityPtr = *Offset;
126 } else {
127 CapabilityPtr = 0;
128 if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
129 PciIoDevice->PciIo.Pci.Read (
130 &PciIoDevice->PciIo,
131 EfiPciIoWidthUint8,
133 1,
134 &CapabilityPtr
135 );
136 } else {
137 PciIoDevice->PciIo.Pci.Read (
138 &PciIoDevice->PciIo,
139 EfiPciIoWidthUint8,
140 PCI_CAPBILITY_POINTER_OFFSET,
141 1,
142 &CapabilityPtr
143 );
144 }
145 }
146
147 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
148 PciIoDevice->PciIo.Pci.Read (
149 &PciIoDevice->PciIo,
150 EfiPciIoWidthUint16,
151 CapabilityPtr,
152 1,
153 &CapabilityEntry
154 );
155
156 CapabilityID = (UINT8)CapabilityEntry;
157
158 if (CapabilityID == CapId) {
159 *Offset = CapabilityPtr;
160 if (NextRegBlock != NULL) {
161 *NextRegBlock = (UINT8)(CapabilityEntry >> 8);
162 }
163
164 return EFI_SUCCESS;
165 }
166
167 //
168 // Certain PCI device may incorrectly have capability pointing to itself,
169 // break to avoid dead loop.
170 //
171 if (CapabilityPtr == (UINT8)(CapabilityEntry >> 8)) {
172 break;
173 }
174
175 CapabilityPtr = (UINT8)(CapabilityEntry >> 8);
176 }
177
178 return EFI_NOT_FOUND;
179}
180
196 IN PCI_IO_DEVICE *PciIoDevice,
197 IN UINT16 CapId,
198 IN OUT UINT32 *Offset,
199 OUT UINT32 *NextRegBlock OPTIONAL
200 )
201{
202 EFI_STATUS Status;
203 UINT32 CapabilityPtr;
204 UINT32 CapabilityEntry;
205 UINT16 CapabilityID;
206
207 //
208 // To check the capability of this device supports
209 //
210 if (!PciIoDevice->IsPciExp) {
211 return EFI_UNSUPPORTED;
212 }
213
214 if (*Offset != 0) {
215 CapabilityPtr = *Offset;
216 } else {
217 CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;
218 }
219
220 while (CapabilityPtr != 0) {
221 //
222 // Mask it to DWORD alignment per PCI spec
223 //
224 CapabilityPtr &= 0xFFC;
225 Status = PciIoDevice->PciIo.Pci.Read (
226 &PciIoDevice->PciIo,
227 EfiPciIoWidthUint32,
228 CapabilityPtr,
229 1,
230 &CapabilityEntry
231 );
232 if (EFI_ERROR (Status)) {
233 break;
234 }
235
236 if (CapabilityEntry == MAX_UINT32) {
237 DEBUG ((
238 DEBUG_WARN,
239 "%a: [%02x|%02x|%02x] failed to access config space at offset 0x%x\n",
240 __func__,
241 PciIoDevice->BusNumber,
242 PciIoDevice->DeviceNumber,
243 PciIoDevice->FunctionNumber,
244 CapabilityPtr
245 ));
246 break;
247 }
248
249 CapabilityID = (UINT16)CapabilityEntry;
250
251 if (CapabilityID == CapId) {
252 *Offset = CapabilityPtr;
253 if (NextRegBlock != NULL) {
254 *NextRegBlock = (CapabilityEntry >> 20) & 0xFFF;
255 }
256
257 return EFI_SUCCESS;
258 }
259
260 CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;
261 }
262
263 return EFI_NOT_FOUND;
264}
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR
Definition: Pci22.h:637
#define IS_CARDBUS_BRIDGE(_p)
Definition: Pci22.h:515
#define EFI_PCI_STATUS_CAPABILITY
0x0010
Definition: Pci22.h:629
BOOLEAN PciCapabilitySupport(IN PCI_IO_DEVICE *PciIoDevice)
Definition: PciCommand.c:81
EFI_STATUS LocatePciExpressCapabilityRegBlock(IN PCI_IO_DEVICE *PciIoDevice, IN UINT16 CapId, IN OUT UINT32 *Offset, OUT UINT32 *NextRegBlock OPTIONAL)
Definition: PciCommand.c:195
EFI_STATUS PciOperateRegister(IN PCI_IO_DEVICE *PciIoDevice, IN UINT16 Command, IN UINT8 Offset, IN UINT8 Operation, OUT UINT16 *PtrCommand)
Definition: PciCommand.c:24
EFI_STATUS LocateCapabilityRegBlock(IN PCI_IO_DEVICE *PciIoDevice, IN UINT8 CapId, IN OUT UINT8 *Offset, OUT UINT8 *NextRegBlock OPTIONAL)
Definition: PciCommand.c:106
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232
EFI_PCI_IO_PROTOCOL_CONFIG Write
Definition: PciIo.h:236