]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxePciLibPciRootBridgeIo/PciLib.c
Add following library instances to MDE package:
[mirror_edk2.git] / MdePkg / Library / DxePciLibPciRootBridgeIo / PciLib.c
1 /** @file
2 PCI Library using PCI Root Bridge I/O Protocol.
3
4 Copyright (c) 2007 - 2008, Intel Corporation All rights
5 reserved. This program and the accompanying materials are
6 licensed and made available under the terms and conditions of
7 the BSD License which accompanies this distribution. The full
8 text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <PiDxe.h>
17
18 #include <Protocol/PciRootBridgeIo.h>
19
20 #include <Library/PciLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/DebugLib.h>
24
25 /**
26 Assert the validity of a PCI address. A valid PCI address should contain 1's
27 only in the low 28 bits.
28
29 @param A The address to validate.
30 @param M Additional bits to assert to be zero.
31
32 **/
33 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
34 ASSERT (((A) & (~0xfffffff | (M))) == 0)
35
36 /**
37 Translate PCI Lib address into format of PCI CFG2 PPI.
38
39 @param A Address that encodes the PCI Bus, Device, Function and
40 Register.
41
42 **/
43 #define PCI_TO_PCICFG2_ADDRESS(A) \
44 (((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | ((UINT64)((A) & 0xFFF) << 32)
45
46 //
47 // Global varible to cache pointer to PCI Root Bridge I/O protocol.
48 //
49 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo = NULL;
50
51 /**
52 The constructor function caches the pointer to PCI Root Bridge I/O protocol.
53
54 The constructor function locates PCI Root Bridge I/O protocol from protocol database.
55 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
56
57 @param ImageHandle The firmware allocated handle for the EFI image.
58 @param SystemTable A pointer to the EFI System Table.
59
60 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
61
62 **/
63 EFI_STATUS
64 EFIAPI
65 PciLibConstructor (
66 IN EFI_HANDLE ImageHandle,
67 IN EFI_SYSTEM_TABLE *SystemTable
68 )
69 {
70 EFI_STATUS Status;
71
72 Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**) &mPciRootBridgeIo);
73 ASSERT_EFI_ERROR (Status);
74 ASSERT (mPciRootBridgeIo != NULL);
75
76 return EFI_SUCCESS;
77 }
78
79 /**
80 Internal worker function to read a PCI configuration register.
81
82 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
83 It reads and returns the PCI configuration register specified by Address,
84 the width of data is specified by Width.
85
86 @param Address Address that encodes the PCI Bus, Device, Function and
87 Register.
88 @param Width Width of data to read
89
90 @return The value read from the PCI configuration register.
91
92 **/
93 UINT32
94 DxePciLibPciRootBridgeIoReadWorker (
95 IN UINTN Address,
96 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
97 )
98 {
99 UINT32 Data;
100
101 mPciRootBridgeIo->Pci.Read (
102 mPciRootBridgeIo,
103 Width,
104 PCI_TO_PCICFG2_ADDRESS (Address),
105 1,
106 &Data
107 );
108
109 return Data;
110 }
111
112 /**
113 Internal worker function to writes a PCI configuration register.
114
115 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
116 It writes the PCI configuration register specified by Address with the
117 value specified by Data. The width of data is specifed by Width.
118 Data is returned.
119
120 @param Address Address that encodes the PCI Bus, Device, Function and
121 Register.
122 @param Width Width of data to write
123 @param Data The value to write.
124
125 @return The value written to the PCI configuration register.
126
127 **/
128 UINT32
129 DxePciLibPciRootBridgeIoWriteWorker (
130 IN UINTN Address,
131 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
132 IN UINT32 Data
133 )
134 {
135 mPciRootBridgeIo->Pci.Write (
136 mPciRootBridgeIo,
137 Width,
138 PCI_TO_PCICFG2_ADDRESS (Address),
139 1,
140 &Data
141 );
142 return Data;
143 }
144
145 /**
146 Reads an 8-bit PCI configuration register.
147
148 Reads and returns the 8-bit PCI configuration register specified by Address.
149 This function must guarantee that all PCI read and write operations are
150 serialized.
151
152 If Address > 0x0FFFFFFF, then ASSERT().
153
154 @param Address Address that encodes the PCI Bus, Device, Function and
155 Register.
156
157 @return The value read from the PCI configuration register.
158
159 **/
160 UINT8
161 EFIAPI
162 PciRead8 (
163 IN UINTN Address
164 )
165 {
166 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
167
168 return (UINT8) DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);
169 }
170
171 /**
172 Writes an 8-bit PCI configuration register.
173
174 Writes the 8-bit PCI configuration register specified by Address with the
175 value specified by Value. Value is returned. This function must guarantee
176 that all PCI read and write operations are serialized.
177
178 If Address > 0x0FFFFFFF, then ASSERT().
179
180 @param Address Address that encodes the PCI Bus, Device, Function and
181 Register.
182 @param Data The value to write.
183
184 @return The value written to the PCI configuration register.
185
186 **/
187 UINT8
188 EFIAPI
189 PciWrite8 (
190 IN UINTN Address,
191 IN UINT8 Data
192 )
193 {
194 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
195
196 return (UINT8) DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Data);
197 }
198
199 /**
200 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
201 an 8-bit value.
202
203 Reads the 8-bit PCI configuration register specified by Address, performs a
204 bitwise inclusive OR between the read result and the value specified by
205 OrData, and writes the result to the 8-bit PCI configuration register
206 specified by Address. The value written to the PCI configuration register is
207 returned. This function must guarantee that all PCI read and write operations
208 are serialized.
209
210 If Address > 0x0FFFFFFF, then ASSERT().
211
212 @param Address Address that encodes the PCI Bus, Device, Function and
213 Register.
214 @param OrData The value to OR with the PCI configuration register.
215
216 @return The value written back to the PCI configuration register.
217
218 **/
219 UINT8
220 EFIAPI
221 PciOr8 (
222 IN UINTN Address,
223 IN UINT8 OrData
224 )
225 {
226 return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));
227 }
228
229 /**
230 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
231 value.
232
233 Reads the 8-bit PCI configuration register specified by Address, performs a
234 bitwise AND between the read result and the value specified by AndData, and
235 writes the result to the 8-bit PCI configuration register specified by
236 Address. The value written to the PCI configuration register is returned.
237 This function must guarantee that all PCI read and write operations are
238 serialized.
239
240 If Address > 0x0FFFFFFF, then ASSERT().
241
242 @param Address Address that encodes the PCI Bus, Device, Function and
243 Register.
244 @param AndData The value to AND with the PCI configuration register.
245
246 @return The value written back to the PCI configuration register.
247
248 **/
249 UINT8
250 EFIAPI
251 PciAnd8 (
252 IN UINTN Address,
253 IN UINT8 AndData
254 )
255 {
256 return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));
257 }
258
259 /**
260 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
261 value, followed a bitwise inclusive OR with another 8-bit value.
262
263 Reads the 8-bit PCI configuration register specified by Address, performs a
264 bitwise AND between the read result and the value specified by AndData,
265 performs a bitwise inclusive OR between the result of the AND operation and
266 the value specified by OrData, and writes the result to the 8-bit PCI
267 configuration register specified by Address. The value written to the PCI
268 configuration register is returned. This function must guarantee that all PCI
269 read and write operations are serialized.
270
271 If Address > 0x0FFFFFFF, then ASSERT().
272
273 @param Address Address that encodes the PCI Bus, Device, Function and
274 Register.
275 @param AndData The value to AND with the PCI configuration register.
276 @param OrData The value to OR with the result of the AND operation.
277
278 @return The value written back to the PCI configuration register.
279
280 **/
281 UINT8
282 EFIAPI
283 PciAndThenOr8 (
284 IN UINTN Address,
285 IN UINT8 AndData,
286 IN UINT8 OrData
287 )
288 {
289 return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));
290 }
291
292 /**
293 Reads a bit field of a PCI configuration register.
294
295 Reads the bit field in an 8-bit PCI configuration register. The bit field is
296 specified by the StartBit and the EndBit. The value of the bit field is
297 returned.
298
299 If Address > 0x0FFFFFFF, then ASSERT().
300 If StartBit is greater than 7, then ASSERT().
301 If EndBit is greater than 7, then ASSERT().
302 If EndBit is less than StartBit, then ASSERT().
303
304 @param Address PCI configuration register to read.
305 @param StartBit The ordinal of the least significant bit in the bit field.
306 Range 0..7.
307 @param EndBit The ordinal of the most significant bit in the bit field.
308 Range 0..7.
309
310 @return The value of the bit field read from the PCI configuration register.
311
312 **/
313 UINT8
314 EFIAPI
315 PciBitFieldRead8 (
316 IN UINTN Address,
317 IN UINTN StartBit,
318 IN UINTN EndBit
319 )
320 {
321 return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);
322 }
323
324 /**
325 Writes a bit field to a PCI configuration register.
326
327 Writes Value to the bit field of the PCI configuration register. The bit
328 field is specified by the StartBit and the EndBit. All other bits in the
329 destination PCI configuration register are preserved. The new value of the
330 8-bit register is returned.
331
332 If Address > 0x0FFFFFFF, then ASSERT().
333 If StartBit is greater than 7, then ASSERT().
334 If EndBit is greater than 7, then ASSERT().
335 If EndBit is less than StartBit, then ASSERT().
336
337 @param Address PCI configuration register to write.
338 @param StartBit The ordinal of the least significant bit in the bit field.
339 Range 0..7.
340 @param EndBit The ordinal of the most significant bit in the bit field.
341 Range 0..7.
342 @param Value New value of the bit field.
343
344 @return The value written back to the PCI configuration register.
345
346 **/
347 UINT8
348 EFIAPI
349 PciBitFieldWrite8 (
350 IN UINTN Address,
351 IN UINTN StartBit,
352 IN UINTN EndBit,
353 IN UINT8 Value
354 )
355 {
356 return PciWrite8 (
357 Address,
358 BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)
359 );
360 }
361
362 /**
363 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
364 writes the result back to the bit field in the 8-bit port.
365
366 Reads the 8-bit PCI configuration register specified by Address, performs a
367 bitwise inclusive OR between the read result and the value specified by
368 OrData, and writes the result to the 8-bit PCI configuration register
369 specified by Address. The value written to the PCI configuration register is
370 returned. This function must guarantee that all PCI read and write operations
371 are serialized. Extra left bits in OrData are stripped.
372
373 If Address > 0x0FFFFFFF, then ASSERT().
374 If StartBit is greater than 7, then ASSERT().
375 If EndBit is greater than 7, then ASSERT().
376 If EndBit is less than StartBit, then ASSERT().
377
378 @param Address PCI configuration register to write.
379 @param StartBit The ordinal of the least significant bit in the bit field.
380 Range 0..7.
381 @param EndBit The ordinal of the most significant bit in the bit field.
382 Range 0..7.
383 @param OrData The value to OR with the PCI configuration register.
384
385 @return The value written back to the PCI configuration register.
386
387 **/
388 UINT8
389 EFIAPI
390 PciBitFieldOr8 (
391 IN UINTN Address,
392 IN UINTN StartBit,
393 IN UINTN EndBit,
394 IN UINT8 OrData
395 )
396 {
397 return PciWrite8 (
398 Address,
399 BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)
400 );
401 }
402
403 /**
404 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
405 AND, and writes the result back to the bit field in the 8-bit register.
406
407 Reads the 8-bit PCI configuration register specified by Address, performs a
408 bitwise AND between the read result and the value specified by AndData, and
409 writes the result to the 8-bit PCI configuration register specified by
410 Address. The value written to the PCI configuration register is returned.
411 This function must guarantee that all PCI read and write operations are
412 serialized. Extra left bits in AndData are stripped.
413
414 If Address > 0x0FFFFFFF, then ASSERT().
415 If StartBit is greater than 7, then ASSERT().
416 If EndBit is greater than 7, then ASSERT().
417 If EndBit is less than StartBit, then ASSERT().
418
419 @param Address PCI configuration register to write.
420 @param StartBit The ordinal of the least significant bit in the bit field.
421 Range 0..7.
422 @param EndBit The ordinal of the most significant bit in the bit field.
423 Range 0..7.
424 @param AndData The value to AND with the PCI configuration register.
425
426 @return The value written back to the PCI configuration register.
427
428 **/
429 UINT8
430 EFIAPI
431 PciBitFieldAnd8 (
432 IN UINTN Address,
433 IN UINTN StartBit,
434 IN UINTN EndBit,
435 IN UINT8 AndData
436 )
437 {
438 return PciWrite8 (
439 Address,
440 BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)
441 );
442 }
443
444 /**
445 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
446 bitwise inclusive OR, and writes the result back to the bit field in the
447 8-bit port.
448
449 Reads the 8-bit PCI configuration register specified by Address, performs a
450 bitwise AND followed by a bitwise inclusive OR between the read result and
451 the value specified by AndData, and writes the result to the 8-bit PCI
452 configuration register specified by Address. The value written to the PCI
453 configuration register is returned. This function must guarantee that all PCI
454 read and write operations are serialized. Extra left bits in both AndData and
455 OrData are stripped.
456
457 If Address > 0x0FFFFFFF, then ASSERT().
458 If StartBit is greater than 7, then ASSERT().
459 If EndBit is greater than 7, then ASSERT().
460 If EndBit is less than StartBit, then ASSERT().
461
462 @param Address PCI configuration register to write.
463 @param StartBit The ordinal of the least significant bit in the bit field.
464 Range 0..7.
465 @param EndBit The ordinal of the most significant bit in the bit field.
466 Range 0..7.
467 @param AndData The value to AND with the PCI configuration register.
468 @param OrData The value to OR with the result of the AND operation.
469
470 @return The value written back to the PCI configuration register.
471
472 **/
473 UINT8
474 EFIAPI
475 PciBitFieldAndThenOr8 (
476 IN UINTN Address,
477 IN UINTN StartBit,
478 IN UINTN EndBit,
479 IN UINT8 AndData,
480 IN UINT8 OrData
481 )
482 {
483 return PciWrite8 (
484 Address,
485 BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)
486 );
487 }
488
489 /**
490 Reads a 16-bit PCI configuration register.
491
492 Reads and returns the 16-bit PCI configuration register specified by Address.
493 This function must guarantee that all PCI read and write operations are
494 serialized.
495
496 If Address > 0x0FFFFFFF, then ASSERT().
497 If Address is not aligned on a 16-bit boundary, then ASSERT().
498
499 @param Address Address that encodes the PCI Bus, Device, Function and
500 Register.
501
502 @return The value read from the PCI configuration register.
503
504 **/
505 UINT16
506 EFIAPI
507 PciRead16 (
508 IN UINTN Address
509 )
510 {
511 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
512
513 return (UINT16) DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);
514 }
515
516 /**
517 Writes a 16-bit PCI configuration register.
518
519 Writes the 16-bit PCI configuration register specified by Address with the
520 value specified by Value. Value is returned. This function must guarantee
521 that all PCI read and write operations are serialized.
522
523 If Address > 0x0FFFFFFF, then ASSERT().
524 If Address is not aligned on a 16-bit boundary, then ASSERT().
525
526 @param Address Address that encodes the PCI Bus, Device, Function and
527 Register.
528 @param Data The value to write.
529
530 @return The value written to the PCI configuration register.
531
532 **/
533 UINT16
534 EFIAPI
535 PciWrite16 (
536 IN UINTN Address,
537 IN UINT16 Data
538 )
539 {
540 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
541
542 return (UINT16) DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Data);
543 }
544
545 /**
546 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
547 a 16-bit value.
548
549 Reads the 16-bit PCI configuration register specified by Address, performs a
550 bitwise inclusive OR between the read result and the value specified by
551 OrData, and writes the result to the 16-bit PCI configuration register
552 specified by Address. The value written to the PCI configuration register is
553 returned. This function must guarantee that all PCI read and write operations
554 are serialized.
555
556 If Address > 0x0FFFFFFF, then ASSERT().
557 If Address is not aligned on a 16-bit boundary, then ASSERT().
558
559 @param Address Address that encodes the PCI Bus, Device, Function and
560 Register.
561 @param OrData The value to OR with the PCI configuration register.
562
563 @return The value written back to the PCI configuration register.
564
565 **/
566 UINT16
567 EFIAPI
568 PciOr16 (
569 IN UINTN Address,
570 IN UINT16 OrData
571 )
572 {
573 return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));
574 }
575
576 /**
577 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
578 value.
579
580 Reads the 16-bit PCI configuration register specified by Address, performs a
581 bitwise AND between the read result and the value specified by AndData, and
582 writes the result to the 16-bit PCI configuration register specified by
583 Address. The value written to the PCI configuration register is returned.
584 This function must guarantee that all PCI read and write operations are
585 serialized.
586
587 If Address > 0x0FFFFFFF, then ASSERT().
588 If Address is not aligned on a 16-bit boundary, then ASSERT().
589
590 @param Address Address that encodes the PCI Bus, Device, Function and
591 Register.
592 @param AndData The value to AND with the PCI configuration register.
593
594 @return The value written back to the PCI configuration register.
595
596 **/
597 UINT16
598 EFIAPI
599 PciAnd16 (
600 IN UINTN Address,
601 IN UINT16 AndData
602 )
603 {
604 return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));
605 }
606
607 /**
608 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
609 value, followed a bitwise inclusive OR with another 16-bit value.
610
611 Reads the 16-bit PCI configuration register specified by Address, performs a
612 bitwise AND between the read result and the value specified by AndData,
613 performs a bitwise inclusive OR between the result of the AND operation and
614 the value specified by OrData, and writes the result to the 16-bit PCI
615 configuration register specified by Address. The value written to the PCI
616 configuration register is returned. This function must guarantee that all PCI
617 read and write operations are serialized.
618
619 If Address > 0x0FFFFFFF, then ASSERT().
620 If Address is not aligned on a 16-bit boundary, then ASSERT().
621
622 @param Address Address that encodes the PCI Bus, Device, Function and
623 Register.
624 @param AndData The value to AND with the PCI configuration register.
625 @param OrData The value to OR with the result of the AND operation.
626
627 @return The value written back to the PCI configuration register.
628
629 **/
630 UINT16
631 EFIAPI
632 PciAndThenOr16 (
633 IN UINTN Address,
634 IN UINT16 AndData,
635 IN UINT16 OrData
636 )
637 {
638 return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));
639 }
640
641 /**
642 Reads a bit field of a PCI configuration register.
643
644 Reads the bit field in a 16-bit PCI configuration register. The bit field is
645 specified by the StartBit and the EndBit. The value of the bit field is
646 returned.
647
648 If Address > 0x0FFFFFFF, then ASSERT().
649 If Address is not aligned on a 16-bit boundary, then ASSERT().
650 If StartBit is greater than 15, then ASSERT().
651 If EndBit is greater than 15, then ASSERT().
652 If EndBit is less than StartBit, then ASSERT().
653
654 @param Address PCI configuration register to read.
655 @param StartBit The ordinal of the least significant bit in the bit field.
656 Range 0..15.
657 @param EndBit The ordinal of the most significant bit in the bit field.
658 Range 0..15.
659
660 @return The value of the bit field read from the PCI configuration register.
661
662 **/
663 UINT16
664 EFIAPI
665 PciBitFieldRead16 (
666 IN UINTN Address,
667 IN UINTN StartBit,
668 IN UINTN EndBit
669 )
670 {
671 return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);
672 }
673
674 /**
675 Writes a bit field to a PCI configuration register.
676
677 Writes Value to the bit field of the PCI configuration register. The bit
678 field is specified by the StartBit and the EndBit. All other bits in the
679 destination PCI configuration register are preserved. The new value of the
680 16-bit register is returned.
681
682 If Address > 0x0FFFFFFF, then ASSERT().
683 If Address is not aligned on a 16-bit boundary, then ASSERT().
684 If StartBit is greater than 15, then ASSERT().
685 If EndBit is greater than 15, then ASSERT().
686 If EndBit is less than StartBit, then ASSERT().
687
688 @param Address PCI configuration register to write.
689 @param StartBit The ordinal of the least significant bit in the bit field.
690 Range 0..15.
691 @param EndBit The ordinal of the most significant bit in the bit field.
692 Range 0..15.
693 @param Value New value of the bit field.
694
695 @return The value written back to the PCI configuration register.
696
697 **/
698 UINT16
699 EFIAPI
700 PciBitFieldWrite16 (
701 IN UINTN Address,
702 IN UINTN StartBit,
703 IN UINTN EndBit,
704 IN UINT16 Value
705 )
706 {
707 return PciWrite16 (
708 Address,
709 BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)
710 );
711 }
712
713 /**
714 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
715 writes the result back to the bit field in the 16-bit port.
716
717 Reads the 16-bit PCI configuration register specified by Address, performs a
718 bitwise inclusive OR between the read result and the value specified by
719 OrData, and writes the result to the 16-bit PCI configuration register
720 specified by Address. The value written to the PCI configuration register is
721 returned. This function must guarantee that all PCI read and write operations
722 are serialized. Extra left bits in OrData are stripped.
723
724 If Address > 0x0FFFFFFF, then ASSERT().
725 If Address is not aligned on a 16-bit boundary, then ASSERT().
726 If StartBit is greater than 15, then ASSERT().
727 If EndBit is greater than 15, then ASSERT().
728 If EndBit is less than StartBit, then ASSERT().
729
730 @param Address PCI configuration register to write.
731 @param StartBit The ordinal of the least significant bit in the bit field.
732 Range 0..15.
733 @param EndBit The ordinal of the most significant bit in the bit field.
734 Range 0..15.
735 @param OrData The value to OR with the PCI configuration register.
736
737 @return The value written back to the PCI configuration register.
738
739 **/
740 UINT16
741 EFIAPI
742 PciBitFieldOr16 (
743 IN UINTN Address,
744 IN UINTN StartBit,
745 IN UINTN EndBit,
746 IN UINT16 OrData
747 )
748 {
749 return PciWrite16 (
750 Address,
751 BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)
752 );
753 }
754
755 /**
756 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
757 AND, and writes the result back to the bit field in the 16-bit register.
758
759 Reads the 16-bit PCI configuration register specified by Address, performs a
760 bitwise AND between the read result and the value specified by AndData, and
761 writes the result to the 16-bit PCI configuration register specified by
762 Address. The value written to the PCI configuration register is returned.
763 This function must guarantee that all PCI read and write operations are
764 serialized. Extra left bits in AndData are stripped.
765
766 If Address > 0x0FFFFFFF, then ASSERT().
767 If Address is not aligned on a 16-bit boundary, then ASSERT().
768 If StartBit is greater than 15, then ASSERT().
769 If EndBit is greater than 15, then ASSERT().
770 If EndBit is less than StartBit, then ASSERT().
771
772 @param Address PCI configuration register to write.
773 @param StartBit The ordinal of the least significant bit in the bit field.
774 Range 0..15.
775 @param EndBit The ordinal of the most significant bit in the bit field.
776 Range 0..15.
777 @param AndData The value to AND with the PCI configuration register.
778
779 @return The value written back to the PCI configuration register.
780
781 **/
782 UINT16
783 EFIAPI
784 PciBitFieldAnd16 (
785 IN UINTN Address,
786 IN UINTN StartBit,
787 IN UINTN EndBit,
788 IN UINT16 AndData
789 )
790 {
791 return PciWrite16 (
792 Address,
793 BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)
794 );
795 }
796
797 /**
798 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
799 bitwise inclusive OR, and writes the result back to the bit field in the
800 16-bit port.
801
802 Reads the 16-bit PCI configuration register specified by Address, performs a
803 bitwise AND followed by a bitwise inclusive OR between the read result and
804 the value specified by AndData, and writes the result to the 16-bit PCI
805 configuration register specified by Address. The value written to the PCI
806 configuration register is returned. This function must guarantee that all PCI
807 read and write operations are serialized. Extra left bits in both AndData and
808 OrData are stripped.
809
810 If Address > 0x0FFFFFFF, then ASSERT().
811 If Address is not aligned on a 16-bit boundary, then ASSERT().
812 If StartBit is greater than 15, then ASSERT().
813 If EndBit is greater than 15, then ASSERT().
814 If EndBit is less than StartBit, then ASSERT().
815
816 @param Address PCI configuration register to write.
817 @param StartBit The ordinal of the least significant bit in the bit field.
818 Range 0..15.
819 @param EndBit The ordinal of the most significant bit in the bit field.
820 Range 0..15.
821 @param AndData The value to AND with the PCI configuration register.
822 @param OrData The value to OR with the result of the AND operation.
823
824 @return The value written back to the PCI configuration register.
825
826 **/
827 UINT16
828 EFIAPI
829 PciBitFieldAndThenOr16 (
830 IN UINTN Address,
831 IN UINTN StartBit,
832 IN UINTN EndBit,
833 IN UINT16 AndData,
834 IN UINT16 OrData
835 )
836 {
837 return PciWrite16 (
838 Address,
839 BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)
840 );
841 }
842
843 /**
844 Reads a 32-bit PCI configuration register.
845
846 Reads and returns the 32-bit PCI configuration register specified by Address.
847 This function must guarantee that all PCI read and write operations are
848 serialized.
849
850 If Address > 0x0FFFFFFF, then ASSERT().
851 If Address is not aligned on a 32-bit boundary, then ASSERT().
852
853 @param Address Address that encodes the PCI Bus, Device, Function and
854 Register.
855
856 @return The value read from the PCI configuration register.
857
858 **/
859 UINT32
860 EFIAPI
861 PciRead32 (
862 IN UINTN Address
863 )
864 {
865 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
866
867 return DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);
868 }
869
870 /**
871 Writes a 32-bit PCI configuration register.
872
873 Writes the 32-bit PCI configuration register specified by Address with the
874 value specified by Value. Value is returned. This function must guarantee
875 that all PCI read and write operations are serialized.
876
877 If Address > 0x0FFFFFFF, then ASSERT().
878 If Address is not aligned on a 32-bit boundary, then ASSERT().
879
880 @param Address Address that encodes the PCI Bus, Device, Function and
881 Register.
882 @param Data The value to write.
883
884 @return The value written to the PCI configuration register.
885
886 **/
887 UINT32
888 EFIAPI
889 PciWrite32 (
890 IN UINTN Address,
891 IN UINT32 Data
892 )
893 {
894 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
895
896 return DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Data);
897 }
898
899 /**
900 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
901 a 32-bit value.
902
903 Reads the 32-bit PCI configuration register specified by Address, performs a
904 bitwise inclusive OR between the read result and the value specified by
905 OrData, and writes the result to the 32-bit PCI configuration register
906 specified by Address. The value written to the PCI configuration register is
907 returned. This function must guarantee that all PCI read and write operations
908 are serialized.
909
910 If Address > 0x0FFFFFFF, then ASSERT().
911 If Address is not aligned on a 32-bit boundary, then ASSERT().
912
913 @param Address Address that encodes the PCI Bus, Device, Function and
914 Register.
915 @param OrData The value to OR with the PCI configuration register.
916
917 @return The value written back to the PCI configuration register.
918
919 **/
920 UINT32
921 EFIAPI
922 PciOr32 (
923 IN UINTN Address,
924 IN UINT32 OrData
925 )
926 {
927 return PciWrite32 (Address, PciRead32 (Address) | OrData);
928 }
929
930 /**
931 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
932 value.
933
934 Reads the 32-bit PCI configuration register specified by Address, performs a
935 bitwise AND between the read result and the value specified by AndData, and
936 writes the result to the 32-bit PCI configuration register specified by
937 Address. The value written to the PCI configuration register is returned.
938 This function must guarantee that all PCI read and write operations are
939 serialized.
940
941 If Address > 0x0FFFFFFF, then ASSERT().
942 If Address is not aligned on a 32-bit boundary, then ASSERT().
943
944 @param Address Address that encodes the PCI Bus, Device, Function and
945 Register.
946 @param AndData The value to AND with the PCI configuration register.
947
948 @return The value written back to the PCI configuration register.
949
950 **/
951 UINT32
952 EFIAPI
953 PciAnd32 (
954 IN UINTN Address,
955 IN UINT32 AndData
956 )
957 {
958 return PciWrite32 (Address, PciRead32 (Address) & AndData);
959 }
960
961 /**
962 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
963 value, followed a bitwise inclusive OR with another 32-bit value.
964
965 Reads the 32-bit PCI configuration register specified by Address, performs a
966 bitwise AND between the read result and the value specified by AndData,
967 performs a bitwise inclusive OR between the result of the AND operation and
968 the value specified by OrData, and writes the result to the 32-bit PCI
969 configuration register specified by Address. The value written to the PCI
970 configuration register is returned. This function must guarantee that all PCI
971 read and write operations are serialized.
972
973 If Address > 0x0FFFFFFF, then ASSERT().
974 If Address is not aligned on a 32-bit boundary, then ASSERT().
975
976 @param Address Address that encodes the PCI Bus, Device, Function and
977 Register.
978 @param AndData The value to AND with the PCI configuration register.
979 @param OrData The value to OR with the result of the AND operation.
980
981 @return The value written back to the PCI configuration register.
982
983 **/
984 UINT32
985 EFIAPI
986 PciAndThenOr32 (
987 IN UINTN Address,
988 IN UINT32 AndData,
989 IN UINT32 OrData
990 )
991 {
992 return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);
993 }
994
995 /**
996 Reads a bit field of a PCI configuration register.
997
998 Reads the bit field in a 32-bit PCI configuration register. The bit field is
999 specified by the StartBit and the EndBit. The value of the bit field is
1000 returned.
1001
1002 If Address > 0x0FFFFFFF, then ASSERT().
1003 If Address is not aligned on a 32-bit boundary, then ASSERT().
1004 If StartBit is greater than 31, then ASSERT().
1005 If EndBit is greater than 31, then ASSERT().
1006 If EndBit is less than StartBit, then ASSERT().
1007
1008 @param Address PCI configuration register to read.
1009 @param StartBit The ordinal of the least significant bit in the bit field.
1010 Range 0..31.
1011 @param EndBit The ordinal of the most significant bit in the bit field.
1012 Range 0..31.
1013
1014 @return The value of the bit field read from the PCI configuration register.
1015
1016 **/
1017 UINT32
1018 EFIAPI
1019 PciBitFieldRead32 (
1020 IN UINTN Address,
1021 IN UINTN StartBit,
1022 IN UINTN EndBit
1023 )
1024 {
1025 return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);
1026 }
1027
1028 /**
1029 Writes a bit field to a PCI configuration register.
1030
1031 Writes Value to the bit field of the PCI configuration register. The bit
1032 field is specified by the StartBit and the EndBit. All other bits in the
1033 destination PCI configuration register are preserved. The new value of the
1034 32-bit register is returned.
1035
1036 If Address > 0x0FFFFFFF, then ASSERT().
1037 If Address is not aligned on a 32-bit boundary, then ASSERT().
1038 If StartBit is greater than 31, then ASSERT().
1039 If EndBit is greater than 31, then ASSERT().
1040 If EndBit is less than StartBit, then ASSERT().
1041
1042 @param Address PCI configuration register to write.
1043 @param StartBit The ordinal of the least significant bit in the bit field.
1044 Range 0..31.
1045 @param EndBit The ordinal of the most significant bit in the bit field.
1046 Range 0..31.
1047 @param Value New value of the bit field.
1048
1049 @return The value written back to the PCI configuration register.
1050
1051 **/
1052 UINT32
1053 EFIAPI
1054 PciBitFieldWrite32 (
1055 IN UINTN Address,
1056 IN UINTN StartBit,
1057 IN UINTN EndBit,
1058 IN UINT32 Value
1059 )
1060 {
1061 return PciWrite32 (
1062 Address,
1063 BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)
1064 );
1065 }
1066
1067 /**
1068 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1069 writes the result back to the bit field in the 32-bit port.
1070
1071 Reads the 32-bit PCI configuration register specified by Address, performs a
1072 bitwise inclusive OR between the read result and the value specified by
1073 OrData, and writes the result to the 32-bit PCI configuration register
1074 specified by Address. The value written to the PCI configuration register is
1075 returned. This function must guarantee that all PCI read and write operations
1076 are serialized. Extra left bits in OrData are stripped.
1077
1078 If Address > 0x0FFFFFFF, then ASSERT().
1079 If Address is not aligned on a 32-bit boundary, then ASSERT().
1080 If StartBit is greater than 31, then ASSERT().
1081 If EndBit is greater than 31, then ASSERT().
1082 If EndBit is less than StartBit, then ASSERT().
1083
1084 @param Address PCI configuration register to write.
1085 @param StartBit The ordinal of the least significant bit in the bit field.
1086 Range 0..31.
1087 @param EndBit The ordinal of the most significant bit in the bit field.
1088 Range 0..31.
1089 @param OrData The value to OR with the PCI configuration register.
1090
1091 @return The value written back to the PCI configuration register.
1092
1093 **/
1094 UINT32
1095 EFIAPI
1096 PciBitFieldOr32 (
1097 IN UINTN Address,
1098 IN UINTN StartBit,
1099 IN UINTN EndBit,
1100 IN UINT32 OrData
1101 )
1102 {
1103 return PciWrite32 (
1104 Address,
1105 BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)
1106 );
1107 }
1108
1109 /**
1110 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1111 AND, and writes the result back to the bit field in the 32-bit register.
1112
1113 Reads the 32-bit PCI configuration register specified by Address, performs a
1114 bitwise AND between the read result and the value specified by AndData, and
1115 writes the result to the 32-bit PCI configuration register specified by
1116 Address. The value written to the PCI configuration register is returned.
1117 This function must guarantee that all PCI read and write operations are
1118 serialized. Extra left bits in AndData are stripped.
1119
1120 If Address > 0x0FFFFFFF, then ASSERT().
1121 If Address is not aligned on a 32-bit boundary, then ASSERT().
1122 If StartBit is greater than 31, then ASSERT().
1123 If EndBit is greater than 31, then ASSERT().
1124 If EndBit is less than StartBit, then ASSERT().
1125
1126 @param Address PCI configuration register to write.
1127 @param StartBit The ordinal of the least significant bit in the bit field.
1128 Range 0..31.
1129 @param EndBit The ordinal of the most significant bit in the bit field.
1130 Range 0..31.
1131 @param AndData The value to AND with the PCI configuration register.
1132
1133 @return The value written back to the PCI configuration register.
1134
1135 **/
1136 UINT32
1137 EFIAPI
1138 PciBitFieldAnd32 (
1139 IN UINTN Address,
1140 IN UINTN StartBit,
1141 IN UINTN EndBit,
1142 IN UINT32 AndData
1143 )
1144 {
1145 return PciWrite32 (
1146 Address,
1147 BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)
1148 );
1149 }
1150
1151 /**
1152 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1153 bitwise inclusive OR, and writes the result back to the bit field in the
1154 32-bit port.
1155
1156 Reads the 32-bit PCI configuration register specified by Address, performs a
1157 bitwise AND followed by a bitwise inclusive OR between the read result and
1158 the value specified by AndData, and writes the result to the 32-bit PCI
1159 configuration register specified by Address. The value written to the PCI
1160 configuration register is returned. This function must guarantee that all PCI
1161 read and write operations are serialized. Extra left bits in both AndData and
1162 OrData are stripped.
1163
1164 If Address > 0x0FFFFFFF, then ASSERT().
1165 If Address is not aligned on a 32-bit boundary, then ASSERT().
1166 If StartBit is greater than 31, then ASSERT().
1167 If EndBit is greater than 31, then ASSERT().
1168 If EndBit is less than StartBit, then ASSERT().
1169
1170 @param Address PCI configuration register to write.
1171 @param StartBit The ordinal of the least significant bit in the bit field.
1172 Range 0..31.
1173 @param EndBit The ordinal of the most significant bit in the bit field.
1174 Range 0..31.
1175 @param AndData The value to AND with the PCI configuration register.
1176 @param OrData The value to OR with the result of the AND operation.
1177
1178 @return The value written back to the PCI configuration register.
1179
1180 **/
1181 UINT32
1182 EFIAPI
1183 PciBitFieldAndThenOr32 (
1184 IN UINTN Address,
1185 IN UINTN StartBit,
1186 IN UINTN EndBit,
1187 IN UINT32 AndData,
1188 IN UINT32 OrData
1189 )
1190 {
1191 return PciWrite32 (
1192 Address,
1193 BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)
1194 );
1195 }
1196
1197 /**
1198 Reads a range of PCI configuration registers into a caller supplied buffer.
1199
1200 Reads the range of PCI configuration registers specified by StartAddress and
1201 Size into the buffer specified by Buffer. This function only allows the PCI
1202 configuration registers from a single PCI function to be read. Size is
1203 returned. When possible 32-bit PCI configuration read cycles are used to read
1204 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1205 and 16-bit PCI configuration read cycles may be used at the beginning and the
1206 end of the range.
1207
1208 If StartAddress > 0x0FFFFFFF, then ASSERT().
1209 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1210 If Size > 0 and Buffer is NULL, then ASSERT().
1211
1212 @param StartAddress Starting address that encodes the PCI Bus, Device,
1213 Function and Register.
1214 @param Size Size in bytes of the transfer.
1215 @param Buffer Pointer to a buffer receiving the data read.
1216
1217 @return Size
1218
1219 **/
1220 UINTN
1221 EFIAPI
1222 PciReadBuffer (
1223 IN UINTN StartAddress,
1224 IN UINTN Size,
1225 OUT VOID *Buffer
1226 )
1227 {
1228 UINTN ReturnValue;
1229
1230 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1231 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1232
1233 if (Size == 0) {
1234 return Size;
1235 }
1236
1237 ASSERT (Buffer != NULL);
1238
1239 //
1240 // Save Size for return
1241 //
1242 ReturnValue = Size;
1243
1244 if ((StartAddress & 1) != 0) {
1245 //
1246 // Read a byte if StartAddress is byte aligned
1247 //
1248 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);
1249 StartAddress += sizeof (UINT8);
1250 Size -= sizeof (UINT8);
1251 Buffer = (UINT8*)Buffer + 1;
1252 }
1253
1254 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1255 //
1256 // Read a word if StartAddress is word aligned
1257 //
1258 *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);
1259 StartAddress += sizeof (UINT16);
1260 Size -= sizeof (UINT16);
1261 Buffer = (UINT16*)Buffer + 1;
1262 }
1263
1264 while (Size >= sizeof (UINT32)) {
1265 //
1266 // Read as many double words as possible
1267 //
1268 *(volatile UINT32 *)Buffer = PciRead32 (StartAddress);
1269 StartAddress += sizeof (UINT32);
1270 Size -= sizeof (UINT32);
1271 Buffer = (UINT32*)Buffer + 1;
1272 }
1273
1274 if (Size >= sizeof (UINT16)) {
1275 //
1276 // Read the last remaining word if exist
1277 //
1278 *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);
1279 StartAddress += sizeof (UINT16);
1280 Size -= sizeof (UINT16);
1281 Buffer = (UINT16*)Buffer + 1;
1282 }
1283
1284 if (Size >= sizeof (UINT8)) {
1285 //
1286 // Read the last remaining byte if exist
1287 //
1288 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);
1289 }
1290
1291 return ReturnValue;
1292 }
1293
1294 /**
1295 Copies the data in a caller supplied buffer to a specified range of PCI
1296 configuration space.
1297
1298 Writes the range of PCI configuration registers specified by StartAddress and
1299 Size from the buffer specified by Buffer. This function only allows the PCI
1300 configuration registers from a single PCI function to be written. Size is
1301 returned. When possible 32-bit PCI configuration write cycles are used to
1302 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1303 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1304 and the end of the range.
1305
1306 If StartAddress > 0x0FFFFFFF, then ASSERT().
1307 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1308 If Size > 0 and Buffer is NULL, then ASSERT().
1309
1310 @param StartAddress Starting address that encodes the PCI Bus, Device,
1311 Function and Register.
1312 @param Size Size in bytes of the transfer.
1313 @param Buffer Pointer to a buffer containing the data to write.
1314
1315 @return Size
1316
1317 **/
1318 UINTN
1319 EFIAPI
1320 PciWriteBuffer (
1321 IN UINTN StartAddress,
1322 IN UINTN Size,
1323 IN VOID *Buffer
1324 )
1325 {
1326 UINTN ReturnValue;
1327
1328 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1329 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1330
1331 if (Size == 0) {
1332 return 0;
1333 }
1334
1335 ASSERT (Buffer != NULL);
1336
1337 //
1338 // Save Size for return
1339 //
1340 ReturnValue = Size;
1341
1342 if ((StartAddress & 1) != 0) {
1343 //
1344 // Write a byte if StartAddress is byte aligned
1345 //
1346 PciWrite8 (StartAddress, *(UINT8*)Buffer);
1347 StartAddress += sizeof (UINT8);
1348 Size -= sizeof (UINT8);
1349 Buffer = (UINT8*)Buffer + 1;
1350 }
1351
1352 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1353 //
1354 // Write a word if StartAddress is word aligned
1355 //
1356 PciWrite16 (StartAddress, *(UINT16*)Buffer);
1357 StartAddress += sizeof (UINT16);
1358 Size -= sizeof (UINT16);
1359 Buffer = (UINT16*)Buffer + 1;
1360 }
1361
1362 while (Size >= sizeof (UINT32)) {
1363 //
1364 // Write as many double words as possible
1365 //
1366 PciWrite32 (StartAddress, *(UINT32*)Buffer);
1367 StartAddress += sizeof (UINT32);
1368 Size -= sizeof (UINT32);
1369 Buffer = (UINT32*)Buffer + 1;
1370 }
1371
1372 if (Size >= sizeof (UINT16)) {
1373 //
1374 // Write the last remaining word if exist
1375 //
1376 PciWrite16 (StartAddress, *(UINT16*)Buffer);
1377 StartAddress += sizeof (UINT16);
1378 Size -= sizeof (UINT16);
1379 Buffer = (UINT16*)Buffer + 1;
1380 }
1381
1382 if (Size >= sizeof (UINT8)) {
1383 //
1384 // Write the last remaining byte if exist
1385 //
1386 PciWrite8 (StartAddress, *(UINT8*)Buffer);
1387 }
1388
1389 return ReturnValue;
1390 }