3 Copyright (c) 2005 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 EFI PC AT PCI Root Bridge Io Protocol
23 #include "PcatPciRootBridge.h"
26 // Protocol Member Function Prototypes
30 PcatRootBridgeIoPollMem (
31 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
32 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
42 PcatRootBridgeIoPollIo (
43 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
44 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
54 PcatRootBridgeIoMemRead (
55 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
56 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
64 PcatRootBridgeIoMemWrite (
65 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
66 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
74 PcatRootBridgeIoIoRead (
75 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
76 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
77 IN UINT64 UserAddress
,
79 IN OUT VOID
*UserBuffer
84 PcatRootBridgeIoIoWrite (
85 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
86 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
87 IN UINT64 UserAddress
,
89 IN OUT VOID
*UserBuffer
94 PcatRootBridgeIoCopyMem (
95 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
96 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
97 IN UINT64 DestAddress
,
104 PcatRootBridgeIoPciRead (
105 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
106 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
114 PcatRootBridgeIoPciWrite (
115 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
116 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
124 PcatRootBridgeIoMap (
125 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
126 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
127 IN VOID
*HostAddress
,
128 IN OUT UINTN
*NumberOfBytes
,
129 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
135 PcatRootBridgeIoUnmap (
136 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
142 PcatRootBridgeIoAllocateBuffer (
143 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
144 IN EFI_ALLOCATE_TYPE Type
,
145 IN EFI_MEMORY_TYPE MemoryType
,
147 OUT VOID
**HostAddress
,
153 PcatRootBridgeIoFreeBuffer (
154 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
156 OUT VOID
*HostAddress
161 PcatRootBridgeIoFlush (
162 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
167 PcatRootBridgeIoGetAttributes (
168 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
169 OUT UINT64
*Supported
,
170 OUT UINT64
*Attributes
175 PcatRootBridgeIoSetAttributes (
176 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
177 IN UINT64 Attributes
,
178 IN OUT UINT64
*ResourceBase
,
179 IN OUT UINT64
*ResourceLength
184 PcatRootBridgeIoConfiguration (
185 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
190 // Private Function Prototypes
194 PcatRootBridgeIoMemRW (
195 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
197 IN BOOLEAN InStrideFlag
,
199 IN BOOLEAN OutStrideFlag
,
204 PcatRootBridgeIoConstructor (
205 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*Protocol
,
206 IN UINTN SegmentNumber
212 Contruct the Pci Root Bridge Io protocol
216 Protocol - protocol to initialize
224 Protocol
->ParentHandle
= NULL
;
226 Protocol
->PollMem
= PcatRootBridgeIoPollMem
;
227 Protocol
->PollIo
= PcatRootBridgeIoPollIo
;
229 Protocol
->Mem
.Read
= PcatRootBridgeIoMemRead
;
230 Protocol
->Mem
.Write
= PcatRootBridgeIoMemWrite
;
232 Protocol
->Io
.Read
= PcatRootBridgeIoIoRead
;
233 Protocol
->Io
.Write
= PcatRootBridgeIoIoWrite
;
235 Protocol
->CopyMem
= PcatRootBridgeIoCopyMem
;
237 Protocol
->Pci
.Read
= PcatRootBridgeIoPciRead
;
238 Protocol
->Pci
.Write
= PcatRootBridgeIoPciWrite
;
240 Protocol
->Map
= PcatRootBridgeIoMap
;
241 Protocol
->Unmap
= PcatRootBridgeIoUnmap
;
243 Protocol
->AllocateBuffer
= PcatRootBridgeIoAllocateBuffer
;
244 Protocol
->FreeBuffer
= PcatRootBridgeIoFreeBuffer
;
246 Protocol
->Flush
= PcatRootBridgeIoFlush
;
248 Protocol
->GetAttributes
= PcatRootBridgeIoGetAttributes
;
249 Protocol
->SetAttributes
= PcatRootBridgeIoSetAttributes
;
251 Protocol
->Configuration
= PcatRootBridgeIoConfiguration
;
253 Protocol
->SegmentNumber
= (UINT32
)SegmentNumber
;
260 PcatRootBridgeIoPollMem (
261 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
262 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
271 UINT64 NumberOfTicks
;
274 if (Result
== NULL
) {
275 return EFI_INVALID_PARAMETER
;
279 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
280 return EFI_INVALID_PARAMETER
;
283 // No matter what, always do a single poll.
285 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
286 if ( EFI_ERROR(Status
) ) {
289 if ( (*Result
& Mask
) == Value
) {
295 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
296 if ( Remainder
!=0 ) {
301 while ( NumberOfTicks
) {
305 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
306 if ( EFI_ERROR(Status
) ) {
310 if ( (*Result
& Mask
) == Value
) {
322 PcatRootBridgeIoPollIo (
323 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
324 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
333 UINT64 NumberOfTicks
;
336 if (Result
== NULL
) {
337 return EFI_INVALID_PARAMETER
;
340 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
341 return EFI_INVALID_PARAMETER
;
344 // No matter what, always do a single poll.
346 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
347 if ( EFI_ERROR(Status
) ) {
350 if ( (*Result
& Mask
) == Value
) {
356 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
357 if ( Remainder
!=0 ) {
362 while ( NumberOfTicks
) {
366 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
367 if ( EFI_ERROR(Status
) ) {
371 if ( (*Result
& Mask
) == Value
) {
382 PcatRootBridgeMemAddressValid (
383 IN PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
,
387 if ((Address
>= PrivateData
->PciExpressBaseAddress
) && (Address
< PrivateData
->PciExpressBaseAddress
+ 0x10000000)) {
390 if ((Address
>= PrivateData
->MemBase
) && (Address
< PrivateData
->MemLimit
)) {
399 PcatRootBridgeIoMemRead (
400 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
401 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
407 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
412 if ( Buffer
== NULL
) {
413 return EFI_INVALID_PARAMETER
;
416 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
418 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
419 return EFI_INVALID_PARAMETER
;
422 AlignMask
= (1 << (Width
& 0x03)) - 1;
423 if (Address
& AlignMask
) {
424 return EFI_INVALID_PARAMETER
;
427 Address
+= PrivateData
->PhysicalMemoryBase
;
430 Out
.buf
= (VOID
*)(UINTN
) Address
;
431 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
432 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
434 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
435 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
437 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
438 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
441 return EFI_INVALID_PARAMETER
;
446 PcatRootBridgeIoMemWrite (
447 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
448 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
454 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
459 if ( Buffer
== NULL
) {
460 return EFI_INVALID_PARAMETER
;
463 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
465 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
466 return EFI_INVALID_PARAMETER
;
469 AlignMask
= (1 << (Width
& 0x03)) - 1;
470 if (Address
& AlignMask
) {
471 return EFI_INVALID_PARAMETER
;
474 Address
+= PrivateData
->PhysicalMemoryBase
;
476 In
.buf
= (VOID
*)(UINTN
) Address
;
478 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
479 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
481 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
482 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
484 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
485 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
488 return EFI_INVALID_PARAMETER
;
493 PcatRootBridgeIoCopyMem (
494 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
495 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
496 IN UINT64 DestAddress
,
497 IN UINT64 SrcAddress
,
508 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
509 return EFI_INVALID_PARAMETER
;
512 if (DestAddress
== SrcAddress
) {
516 Stride
= (UINTN
)1 << Width
;
519 if ((DestAddress
> SrcAddress
) && (DestAddress
< (SrcAddress
+ Count
* Stride
))) {
521 SrcAddress
= SrcAddress
+ (Count
-1) * Stride
;
522 DestAddress
= DestAddress
+ (Count
-1) * Stride
;
525 for (Index
= 0;Index
< Count
;Index
++) {
526 Status
= PcatRootBridgeIoMemRead (
533 if (EFI_ERROR (Status
)) {
536 Status
= PcatRootBridgeIoMemWrite (
543 if (EFI_ERROR (Status
)) {
547 SrcAddress
+= Stride
;
548 DestAddress
+= Stride
;
550 SrcAddress
-= Stride
;
551 DestAddress
-= Stride
;
559 PcatRootBridgeIoPciRead (
560 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
561 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
567 if (Buffer
== NULL
) {
568 return EFI_INVALID_PARAMETER
;
571 return PcatRootBridgeIoPciRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
576 PcatRootBridgeIoPciWrite (
577 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
578 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
584 if (Buffer
== NULL
) {
585 return EFI_INVALID_PARAMETER
;
588 return PcatRootBridgeIoPciRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
593 PcatRootBridgeIoMap (
594 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
595 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
596 IN VOID
*HostAddress
,
597 IN OUT UINTN
*NumberOfBytes
,
598 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
604 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
606 MAP_INFO_INSTANCE
*MapInstance
;
607 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
609 if ( HostAddress
== NULL
|| NumberOfBytes
== NULL
||
610 DeviceAddress
== NULL
|| Mapping
== NULL
) {
612 return EFI_INVALID_PARAMETER
;
616 // Perform a fence operation to make sure all memory operations are flushed
621 // Initialize the return values to their defaults
626 // Make sure that Operation is valid
628 if (Operation
< 0 || Operation
>= EfiPciOperationMaximum
) {
629 return EFI_INVALID_PARAMETER
;
633 // Most PCAT like chipsets can not handle performing DMA above 4GB.
634 // If any part of the DMA transfer being mapped is above 4GB, then
635 // map the DMA transfer to a buffer below 4GB.
637 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
;
638 if ((PhysicalAddress
+ *NumberOfBytes
) > 0x100000000ULL
) {
641 // Common Buffer operations can not be remapped. If the common buffer
642 // if above 4GB, then it is not possible to generate a mapping, so return
645 if (Operation
== EfiPciOperationBusMasterCommonBuffer
|| Operation
== EfiPciOperationBusMasterCommonBuffer64
) {
646 return EFI_UNSUPPORTED
;
650 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
653 Status
= gBS
->AllocatePool (
658 if (EFI_ERROR (Status
)) {
664 // Return a pointer to the MAP_INFO structure in Mapping
669 // Initialize the MAP_INFO structure
671 MapInfo
->Operation
= Operation
;
672 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
673 MapInfo
->NumberOfPages
= EFI_SIZE_TO_PAGES(*NumberOfBytes
);
674 MapInfo
->HostAddress
= PhysicalAddress
;
675 MapInfo
->MappedHostAddress
= 0x00000000ffffffff;
678 // Allocate a buffer below 4GB to map the transfer to.
680 Status
= gBS
->AllocatePages (
683 MapInfo
->NumberOfPages
,
684 &MapInfo
->MappedHostAddress
686 if (EFI_ERROR(Status
)) {
687 gBS
->FreePool (MapInfo
);
693 // If this is a read operation from the Bus Master's point of view,
694 // then copy the contents of the real buffer into the mapped buffer
695 // so the Bus Master can read the contents of the real buffer.
697 if (Operation
== EfiPciOperationBusMasterRead
|| Operation
== EfiPciOperationBusMasterRead64
) {
699 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
700 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
701 MapInfo
->NumberOfBytes
706 Status
=gBS
->AllocatePool (
708 sizeof(MAP_INFO_INSTANCE
),
709 (VOID
**)&MapInstance
711 if (EFI_ERROR(Status
)) {
712 gBS
->FreePages (MapInfo
->MappedHostAddress
,MapInfo
->NumberOfPages
);
713 gBS
->FreePool (MapInfo
);
718 MapInstance
->Map
=MapInfo
;
719 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
720 InsertTailList(&PrivateData
->MapInfo
,&MapInstance
->Link
);
723 // The DeviceAddress is the address of the maped buffer below 4GB
725 *DeviceAddress
= MapInfo
->MappedHostAddress
;
728 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
730 *DeviceAddress
= PhysicalAddress
;
734 // Perform a fence operation to make sure all memory operations are flushed
743 PcatRootBridgeIoUnmap (
744 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
750 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
754 // Perform a fence operation to make sure all memory operations are flushed
758 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
760 // See if the Map() operation associated with this Unmap() required a mapping buffer.
761 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
763 if (Mapping
!= NULL
) {
765 // Get the MAP_INFO structure from Mapping
767 MapInfo
= (MAP_INFO
*)Mapping
;
769 for (Link
= PrivateData
->MapInfo
.ForwardLink
; Link
!= &PrivateData
->MapInfo
; Link
= Link
->ForwardLink
) {
770 if (((MAP_INFO_INSTANCE
*)Link
)->Map
== MapInfo
)
774 if (Link
== &PrivateData
->MapInfo
) {
775 return EFI_INVALID_PARAMETER
;
778 RemoveEntryList(Link
);
779 ((MAP_INFO_INSTANCE
*)Link
)->Map
= NULL
;
780 gBS
->FreePool((MAP_INFO_INSTANCE
*)Link
);
783 // If this is a write operation from the Bus Master's point of view,
784 // then copy the contents of the mapped buffer into the real buffer
785 // so the processor can read the contents of the real buffer.
787 if (MapInfo
->Operation
== EfiPciOperationBusMasterWrite
|| MapInfo
->Operation
== EfiPciOperationBusMasterWrite64
) {
789 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
790 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
791 MapInfo
->NumberOfBytes
796 // Free the mapped buffer and the MAP_INFO structure.
798 gBS
->FreePages (MapInfo
->MappedHostAddress
, MapInfo
->NumberOfPages
);
799 gBS
->FreePool (Mapping
);
803 // Perform a fence operation to make sure all memory operations are flushed
812 PcatRootBridgeIoAllocateBuffer (
813 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
814 IN EFI_ALLOCATE_TYPE Type
,
815 IN EFI_MEMORY_TYPE MemoryType
,
817 OUT VOID
**HostAddress
,
822 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
825 // Validate Attributes
827 if (Attributes
& EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER
) {
828 return EFI_UNSUPPORTED
;
832 // Check for invalid inputs
834 if (HostAddress
== NULL
) {
835 return EFI_INVALID_PARAMETER
;
839 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
841 if (MemoryType
!= EfiBootServicesData
&& MemoryType
!= EfiRuntimeServicesData
) {
842 return EFI_INVALID_PARAMETER
;
846 // Limit allocations to memory below 4GB
848 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(0xffffffff);
850 Status
= gBS
->AllocatePages (AllocateMaxAddress
, MemoryType
, Pages
, &PhysicalAddress
);
851 if (EFI_ERROR (Status
)) {
855 *HostAddress
= (VOID
*)(UINTN
)PhysicalAddress
;
862 PcatRootBridgeIoFreeBuffer (
863 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
865 OUT VOID
*HostAddress
870 if( HostAddress
== NULL
){
871 return EFI_INVALID_PARAMETER
;
873 return gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
, Pages
);
878 PcatRootBridgeIoFlush (
879 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
884 // Perform a fence operation to make sure all memory operations are flushed
893 PcatRootBridgeIoGetAttributes (
894 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
895 OUT UINT64
*Supported
, OPTIONAL
896 OUT UINT64
*Attributes
900 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
902 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
904 if (Attributes
== NULL
&& Supported
== NULL
) {
905 return EFI_INVALID_PARAMETER
;
909 // Supported is an OPTIONAL parameter. See if it is NULL
913 // This is a generic driver for a PC-AT class system. It does not have any
914 // chipset specific knowlegde, so none of the attributes can be set or
915 // cleared. Any attempt to set attribute that are already set will succeed,
916 // and any attempt to set an attribute that is not supported will fail.
918 *Supported
= PrivateData
->Attributes
;
922 // Set Attrbutes to the attributes detected when the PCI Root Bridge was initialized
926 *Attributes
= PrivateData
->Attributes
;
935 PcatRootBridgeIoSetAttributes (
936 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
937 IN UINT64 Attributes
,
938 IN OUT UINT64
*ResourceBase
,
939 IN OUT UINT64
*ResourceLength
943 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
945 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
948 // This is a generic driver for a PC-AT class system. It does not have any
949 // chipset specific knowlegde, so none of the attributes can be set or
950 // cleared. Any attempt to set attribute that are already set will succeed,
951 // and any attempt to set an attribute that is not supported will fail.
953 if (Attributes
& (~PrivateData
->Attributes
)) {
954 return EFI_UNSUPPORTED
;
962 PcatRootBridgeIoConfiguration (
963 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
968 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
970 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
972 *Resources
= PrivateData
->Configuration
;
983 PcatRootBridgeIoMemRW (
984 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
986 IN BOOLEAN InStrideFlag
,
988 IN BOOLEAN OutStrideFlag
,
995 Private service to provide the memory read/write
999 Width of the Memory Access
1000 Count of the number of accesses to perform
1006 EFI_SUCCESS - Successful transaction
1007 EFI_INVALID_PARAMETER - Unsupported width and address combination
1016 Width
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
1017 Stride
= (UINTN
)1 << Width
;
1018 InStride
= InStrideFlag
? Stride
: 0;
1019 OutStride
= OutStrideFlag
? Stride
: 0;
1022 // Loop for each iteration and move the data
1025 case EfiPciWidthUint8
:
1026 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1032 case EfiPciWidthUint16
:
1033 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1035 *In
.ui16
= *Out
.ui16
;
1039 case EfiPciWidthUint32
:
1040 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1042 *In
.ui32
= *Out
.ui32
;
1047 return EFI_INVALID_PARAMETER
;