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