]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/PciBusNoEnumerationDxe/PciCommand.c
1654952d0317b5bde2222e13b0ea83293c287b46
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciCommand.c
1 /*++
2
3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PciCommand.c
15
16 Abstract:
17
18 PCI Bus Driver
19
20 Revision History
21
22 --*/
23
24 #include "PciBus.h"
25
26
27 EFI_STATUS
28 PciReadCommandRegister (
29 IN PCI_IO_DEVICE *PciIoDevice,
30 OUT UINT16 *Command
31 )
32 /*++
33
34 Routine Description:
35
36 Arguments:
37
38 Returns:
39
40 None
41
42 --*/
43 {
44
45 EFI_PCI_IO_PROTOCOL *PciIo;
46
47 *Command = 0;
48 PciIo = &PciIoDevice->PciIo;
49
50 return PciIo->Pci.Read (
51 PciIo,
52 EfiPciIoWidthUint16,
53 PCI_COMMAND_OFFSET,
54 1,
55 Command
56 );
57 }
58
59 EFI_STATUS
60 PciSetCommandRegister (
61 IN PCI_IO_DEVICE *PciIoDevice,
62 IN UINT16 Command
63 )
64 /*++
65
66 Routine Description:
67
68 Arguments:
69
70 Returns:
71
72 None
73
74 --*/
75 {
76 UINT16 Temp;
77 EFI_PCI_IO_PROTOCOL *PciIo;
78
79 Temp = Command;
80 PciIo = &PciIoDevice->PciIo;
81
82 return PciIo->Pci.Write (
83 PciIo,
84 EfiPciIoWidthUint16,
85 PCI_COMMAND_OFFSET,
86 1,
87 &Temp
88 );
89
90 }
91
92
93 EFI_STATUS
94 PciEnableCommandRegister (
95 IN PCI_IO_DEVICE *PciIoDevice,
96 IN UINT16 Command
97 )
98 /*++
99
100 Routine Description:
101
102 Arguments:
103
104 Returns:
105
106 None
107
108 --*/
109 {
110 UINT16 OldCommand;
111 EFI_PCI_IO_PROTOCOL *PciIo;
112
113 OldCommand = 0;
114 PciIo = &PciIoDevice->PciIo;
115
116 PciIo->Pci.Read (
117 PciIo,
118 EfiPciIoWidthUint16,
119 PCI_COMMAND_OFFSET,
120 1,
121 &OldCommand
122 );
123
124 OldCommand |= Command;
125
126 return PciIo->Pci.Write (
127 PciIo,
128 EfiPciIoWidthUint16,
129 PCI_COMMAND_OFFSET,
130 1,
131 &OldCommand
132 );
133
134 }
135
136
137 EFI_STATUS
138 PciDisableCommandRegister (
139 IN PCI_IO_DEVICE *PciIoDevice,
140 IN UINT16 Command
141 )
142 /*++
143
144 Routine Description:
145
146 Arguments:
147
148 Returns:
149
150 None
151
152 --*/
153 {
154 UINT16 OldCommand;
155 EFI_PCI_IO_PROTOCOL *PciIo;
156
157 OldCommand = 0;
158 PciIo = &PciIoDevice->PciIo;
159
160 PciIo->Pci.Read (
161 PciIo,
162 EfiPciIoWidthUint16,
163 PCI_COMMAND_OFFSET,
164 1,
165 &OldCommand
166 );
167
168 OldCommand &= ~(Command);
169
170 return PciIo->Pci.Write (
171 PciIo,
172 EfiPciIoWidthUint16,
173 PCI_COMMAND_OFFSET,
174 1,
175 &OldCommand
176 );
177
178 }
179
180
181
182 EFI_STATUS
183 PciSetBridgeControlRegister (
184 IN PCI_IO_DEVICE *PciIoDevice,
185 IN UINT16 Command
186 )
187 /*++
188
189 Routine Description:
190
191 Arguments:
192
193 Returns:
194
195 None
196
197 --*/
198 {
199 UINT16 Temp;
200 EFI_PCI_IO_PROTOCOL *PciIo;
201
202 Temp = Command;
203 PciIo = &PciIoDevice->PciIo;
204
205 return PciIo->Pci.Write (
206 PciIo,
207 EfiPciIoWidthUint16,
208 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
209 1,
210 &Temp
211 );
212
213 }
214
215
216 EFI_STATUS
217 PciEnableBridgeControlRegister (
218 IN PCI_IO_DEVICE *PciIoDevice,
219 IN UINT16 Command
220 )
221 /*++
222
223 Routine Description:
224
225 Arguments:
226
227 Returns:
228
229 None
230
231 --*/
232 {
233 UINT16 OldCommand;
234 EFI_PCI_IO_PROTOCOL *PciIo;
235
236 OldCommand = 0;
237 PciIo = &PciIoDevice->PciIo;
238
239 PciIo->Pci.Read (
240 PciIo,
241 EfiPciIoWidthUint16,
242 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
243 1,
244 &OldCommand
245 );
246
247 OldCommand |= Command;
248
249 return PciIo->Pci.Write (
250 PciIo,
251 EfiPciIoWidthUint16,
252 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
253 1,
254 &OldCommand
255 );
256
257 }
258
259 EFI_STATUS
260 PciDisableBridgeControlRegister (
261 IN PCI_IO_DEVICE *PciIoDevice,
262 IN UINT16 Command
263 )
264 /*++
265
266 Routine Description:
267
268 Arguments:
269
270 Returns:
271
272 None
273
274 --*/
275 {
276 UINT16 OldCommand;
277 EFI_PCI_IO_PROTOCOL *PciIo;
278
279 OldCommand = 0;
280 PciIo = &PciIoDevice->PciIo;
281
282 PciIo->Pci.Read (
283 PciIo,
284 EfiPciIoWidthUint16,
285 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
286 1,
287 &OldCommand
288 );
289
290 OldCommand &= ~(Command);
291
292 return PciIo->Pci.Write (
293 PciIo,
294 EfiPciIoWidthUint16,
295 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
296 1,
297 &OldCommand
298 );
299
300 }
301
302
303
304 EFI_STATUS
305 PciReadBridgeControlRegister (
306 IN PCI_IO_DEVICE *PciIoDevice,
307 OUT UINT16 *Command
308 )
309 /*++
310
311 Routine Description:
312
313 Arguments:
314
315 Returns:
316
317 None
318
319 --*/
320 {
321
322 EFI_PCI_IO_PROTOCOL *PciIo;
323
324 *Command = 0;
325 PciIo = &PciIoDevice->PciIo;
326
327 return PciIo->Pci.Read (
328 PciIo,
329 EfiPciIoWidthUint16,
330 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
331 1,
332 Command
333 );
334
335 }
336
337 BOOLEAN
338 PciCapabilitySupport (
339 IN PCI_IO_DEVICE *PciIoDevice
340 )
341 /*++
342
343 Routine Description:
344
345 Arguments:
346
347 Returns:
348
349 None
350
351 --*/
352 // TODO: PciIoDevice - add argument and description to function comment
353 {
354
355 if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {
356 return TRUE;
357 }
358
359 return FALSE;
360 }
361
362 EFI_STATUS
363 LocateCapabilityRegBlock (
364 IN PCI_IO_DEVICE *PciIoDevice,
365 IN UINT8 CapId,
366 IN OUT UINT8 *Offset,
367 OUT UINT8 *NextRegBlock OPTIONAL
368 )
369 /*++
370
371 Routine Description:
372
373 Locate Capability register.
374
375 Arguments:
376
377 PciIoDevice - A pointer to the PCI_IO_DEVICE.
378 CapId - The capability ID.
379 Offset - A pointer to the offset.
380 As input: the default offset;
381 As output: the offset of the found block.
382 NextRegBlock - An optional pointer to return the value of next block.
383
384 Returns:
385
386 EFI_UNSUPPORTED - The Pci Io device is not supported.
387 EFI_NOT_FOUND - The Pci Io device cannot be found.
388 EFI_SUCCESS - The Pci Io device is successfully located.
389
390 --*/
391 {
392 UINT8 CapabilityPtr;
393 UINT16 CapabilityEntry;
394 UINT8 CapabilityID;
395 UINT32 Temp;
396
397 //
398 // To check the capability of this device supports
399 //
400 if (!PciCapabilitySupport (PciIoDevice)) {
401 return EFI_UNSUPPORTED;
402 }
403
404 if (*Offset != 0) {
405 CapabilityPtr = *Offset;
406 } else {
407
408 CapabilityPtr = 0;
409 if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
410
411 PciIoDevice->PciIo.Pci.Read (
412 &PciIoDevice->PciIo,
413 EfiPciIoWidthUint8,
414 EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
415 1,
416 &CapabilityPtr
417 );
418 } else {
419
420 PciIoDevice->PciIo.Pci.Read (
421 &PciIoDevice->PciIo,
422 EfiPciIoWidthUint32,
423 EFI_PCI_CAPABILITY_PTR,
424 1,
425 &Temp
426 );
427 //
428 // Do not get byte read directly, because some PCI card will return 0xFF
429 // when perform PCI-Express byte read, while return correct 0x00
430 // when perform PCI-Express dword read, or PCI dword read.
431 //
432 CapabilityPtr = (UINT8)Temp;
433 }
434 }
435
436 while (CapabilityPtr > 0x3F) {
437 //
438 // Mask it to DWORD alignment per PCI spec
439 //
440 CapabilityPtr &= 0xFC;
441 PciIoDevice->PciIo.Pci.Read (
442 &PciIoDevice->PciIo,
443 EfiPciIoWidthUint16,
444 CapabilityPtr,
445 1,
446 &CapabilityEntry
447 );
448
449 CapabilityID = (UINT8) CapabilityEntry;
450
451 if (CapabilityID == CapId) {
452 *Offset = CapabilityPtr;
453 if (NextRegBlock != NULL) {
454 *NextRegBlock = (UINT8) (CapabilityEntry >> 8);
455 }
456
457 return EFI_SUCCESS;
458 }
459
460 CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
461 }
462
463 return EFI_NOT_FOUND;
464 }