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