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