VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/SmmPciExpressLib/PciExpressLib.c@ 91375

最後變更 在這個檔案從91375是 89983,由 vboxsync 提交於 4 年 前

Devices/EFI: Merge edk-stable202105 and openssl 1.1.1j and make it build, bugref:4643

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette