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