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