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