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