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