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
) {
297 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
298 if ( Remainder
!=0 ) {
303 while ( NumberOfTicks
) {
307 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
308 if ( EFI_ERROR(Status
) ) {
312 if ( (*Result
& Mask
) == Value
) {
324 PcatRootBridgeIoPollIo (
325 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
326 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
335 UINT64 NumberOfTicks
;
338 if (Result
== NULL
) {
339 return EFI_INVALID_PARAMETER
;
342 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
343 return EFI_INVALID_PARAMETER
;
346 // No matter what, always do a single poll.
348 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
349 if ( EFI_ERROR(Status
) ) {
352 if ( (*Result
& Mask
) == Value
) {
360 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
361 if ( Remainder
!=0 ) {
366 while ( NumberOfTicks
) {
370 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
371 if ( EFI_ERROR(Status
) ) {
375 if ( (*Result
& Mask
) == Value
) {
386 PcatRootBridgeMemAddressValid (
387 IN PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
,
391 if ((Address
>= PrivateData
->PciExpressBaseAddress
) && (Address
< PrivateData
->PciExpressBaseAddress
+ 0x10000000)) {
394 if ((Address
>= PrivateData
->MemBase
) && (Address
< PrivateData
->MemLimit
)) {
403 PcatRootBridgeIoMemRead (
404 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
405 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
411 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
416 if ( Buffer
== NULL
) {
417 return EFI_INVALID_PARAMETER
;
420 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
422 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
423 return EFI_INVALID_PARAMETER
;
426 AlignMask
= (1 << (Width
& 0x03)) - 1;
427 if (Address
& AlignMask
) {
428 return EFI_INVALID_PARAMETER
;
431 Address
+= PrivateData
->PhysicalMemoryBase
;
434 Out
.buf
= (VOID
*)(UINTN
) Address
;
435 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
436 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
438 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
439 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
441 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
442 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
445 return EFI_INVALID_PARAMETER
;
450 PcatRootBridgeIoMemWrite (
451 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
452 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
458 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
463 if ( Buffer
== NULL
) {
464 return EFI_INVALID_PARAMETER
;
467 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
469 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
470 return EFI_INVALID_PARAMETER
;
473 AlignMask
= (1 << (Width
& 0x03)) - 1;
474 if (Address
& AlignMask
) {
475 return EFI_INVALID_PARAMETER
;
478 Address
+= PrivateData
->PhysicalMemoryBase
;
480 In
.buf
= (VOID
*)(UINTN
) Address
;
482 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
483 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
485 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
486 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
488 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
489 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
492 return EFI_INVALID_PARAMETER
;
497 PcatRootBridgeIoCopyMem (
498 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
499 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
500 IN UINT64 DestAddress
,
501 IN UINT64 SrcAddress
,
512 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
513 return EFI_INVALID_PARAMETER
;
516 if (DestAddress
== SrcAddress
) {
520 Stride
= (UINTN
)1 << Width
;
523 if ((DestAddress
> SrcAddress
) && (DestAddress
< (SrcAddress
+ Count
* Stride
))) {
525 SrcAddress
= SrcAddress
+ (Count
-1) * Stride
;
526 DestAddress
= DestAddress
+ (Count
-1) * Stride
;
529 for (Index
= 0;Index
< Count
;Index
++) {
530 Status
= PcatRootBridgeIoMemRead (
537 if (EFI_ERROR (Status
)) {
540 Status
= PcatRootBridgeIoMemWrite (
547 if (EFI_ERROR (Status
)) {
551 SrcAddress
+= Stride
;
552 DestAddress
+= Stride
;
554 SrcAddress
-= Stride
;
555 DestAddress
-= Stride
;
563 PcatRootBridgeIoPciRead (
564 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
565 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
571 if (Buffer
== NULL
) {
572 return EFI_INVALID_PARAMETER
;
575 return PcatRootBridgeIoPciRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
580 PcatRootBridgeIoPciWrite (
581 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
582 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
588 if (Buffer
== NULL
) {
589 return EFI_INVALID_PARAMETER
;
592 return PcatRootBridgeIoPciRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
597 PcatRootBridgeIoMap (
598 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
599 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
600 IN VOID
*HostAddress
,
601 IN OUT UINTN
*NumberOfBytes
,
602 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
608 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
610 MAP_INFO_INSTANCE
*MapInstance
;
611 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
613 if ( HostAddress
== NULL
|| NumberOfBytes
== NULL
||
614 DeviceAddress
== NULL
|| Mapping
== NULL
) {
616 return EFI_INVALID_PARAMETER
;
620 // Perform a fence operation to make sure all memory operations are flushed
625 // Initialize the return values to their defaults
630 // Make sure that Operation is valid
632 if (Operation
< 0 || Operation
>= EfiPciOperationMaximum
) {
633 return EFI_INVALID_PARAMETER
;
637 // Most PCAT like chipsets can not handle performing DMA above 4GB.
638 // If any part of the DMA transfer being mapped is above 4GB, then
639 // map the DMA transfer to a buffer below 4GB.
641 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
;
642 if ((PhysicalAddress
+ *NumberOfBytes
) > 0x100000000ULL
) {
645 // Common Buffer operations can not be remapped. If the common buffer
646 // if above 4GB, then it is not possible to generate a mapping, so return
649 if (Operation
== EfiPciOperationBusMasterCommonBuffer
|| Operation
== EfiPciOperationBusMasterCommonBuffer64
) {
650 return EFI_UNSUPPORTED
;
654 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
657 Status
= gBS
->AllocatePool (
662 if (EFI_ERROR (Status
)) {
668 // Return a pointer to the MAP_INFO structure in Mapping
673 // Initialize the MAP_INFO structure
675 MapInfo
->Operation
= Operation
;
676 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
677 MapInfo
->NumberOfPages
= EFI_SIZE_TO_PAGES(*NumberOfBytes
);
678 MapInfo
->HostAddress
= PhysicalAddress
;
679 MapInfo
->MappedHostAddress
= 0x00000000ffffffff;
682 // Allocate a buffer below 4GB to map the transfer to.
684 Status
= gBS
->AllocatePages (
687 MapInfo
->NumberOfPages
,
688 &MapInfo
->MappedHostAddress
690 if (EFI_ERROR(Status
)) {
691 gBS
->FreePool (MapInfo
);
697 // If this is a read operation from the Bus Master's point of view,
698 // then copy the contents of the real buffer into the mapped buffer
699 // so the Bus Master can read the contents of the real buffer.
701 if (Operation
== EfiPciOperationBusMasterRead
|| Operation
== EfiPciOperationBusMasterRead64
) {
703 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
704 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
705 MapInfo
->NumberOfBytes
710 Status
=gBS
->AllocatePool (
712 sizeof(MAP_INFO_INSTANCE
),
713 (VOID
**)&MapInstance
715 if (EFI_ERROR(Status
)) {
716 gBS
->FreePages (MapInfo
->MappedHostAddress
,MapInfo
->NumberOfPages
);
717 gBS
->FreePool (MapInfo
);
722 MapInstance
->Map
=MapInfo
;
723 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
724 InsertTailList(&PrivateData
->MapInfo
,&MapInstance
->Link
);
727 // The DeviceAddress is the address of the maped buffer below 4GB
729 *DeviceAddress
= MapInfo
->MappedHostAddress
;
732 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
734 *DeviceAddress
= PhysicalAddress
;
738 // Perform a fence operation to make sure all memory operations are flushed
747 PcatRootBridgeIoUnmap (
748 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
754 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
758 // Perform a fence operation to make sure all memory operations are flushed
762 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
764 // See if the Map() operation associated with this Unmap() required a mapping buffer.
765 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
767 if (Mapping
!= NULL
) {
769 // Get the MAP_INFO structure from Mapping
771 MapInfo
= (MAP_INFO
*)Mapping
;
773 for (Link
= PrivateData
->MapInfo
.ForwardLink
; Link
!= &PrivateData
->MapInfo
; Link
= Link
->ForwardLink
) {
774 if (((MAP_INFO_INSTANCE
*)Link
)->Map
== MapInfo
)
778 if (Link
== &PrivateData
->MapInfo
) {
779 return EFI_INVALID_PARAMETER
;
782 RemoveEntryList(Link
);
783 ((MAP_INFO_INSTANCE
*)Link
)->Map
= NULL
;
784 gBS
->FreePool((MAP_INFO_INSTANCE
*)Link
);
787 // If this is a write operation from the Bus Master's point of view,
788 // then copy the contents of the mapped buffer into the real buffer
789 // so the processor can read the contents of the real buffer.
791 if (MapInfo
->Operation
== EfiPciOperationBusMasterWrite
|| MapInfo
->Operation
== EfiPciOperationBusMasterWrite64
) {
793 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
794 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
795 MapInfo
->NumberOfBytes
800 // Free the mapped buffer and the MAP_INFO structure.
802 gBS
->FreePages (MapInfo
->MappedHostAddress
, MapInfo
->NumberOfPages
);
803 gBS
->FreePool (Mapping
);
807 // Perform a fence operation to make sure all memory operations are flushed
816 PcatRootBridgeIoAllocateBuffer (
817 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
818 IN EFI_ALLOCATE_TYPE Type
,
819 IN EFI_MEMORY_TYPE MemoryType
,
821 OUT VOID
**HostAddress
,
826 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
829 // Validate Attributes
831 if (Attributes
& EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER
) {
832 return EFI_UNSUPPORTED
;
836 // Check for invalid inputs
838 if (HostAddress
== NULL
) {
839 return EFI_INVALID_PARAMETER
;
843 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
845 if (MemoryType
!= EfiBootServicesData
&& MemoryType
!= EfiRuntimeServicesData
) {
846 return EFI_INVALID_PARAMETER
;
850 // Limit allocations to memory below 4GB
852 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(0xffffffff);
854 Status
= gBS
->AllocatePages (AllocateMaxAddress
, MemoryType
, Pages
, &PhysicalAddress
);
855 if (EFI_ERROR (Status
)) {
859 *HostAddress
= (VOID
*)(UINTN
)PhysicalAddress
;
866 PcatRootBridgeIoFreeBuffer (
867 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
869 OUT VOID
*HostAddress
874 if( HostAddress
== NULL
){
875 return EFI_INVALID_PARAMETER
;
877 return gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
, Pages
);
882 PcatRootBridgeIoFlush (
883 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
888 // Perform a fence operation to make sure all memory operations are flushed
897 PcatRootBridgeIoGetAttributes (
898 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
899 OUT UINT64
*Supported
, OPTIONAL
900 OUT UINT64
*Attributes
904 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
906 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
908 if (Attributes
== NULL
&& Supported
== NULL
) {
909 return EFI_INVALID_PARAMETER
;
913 // Supported is an OPTIONAL parameter. See if it is NULL
917 // This is a generic driver for a PC-AT class system. It does not have any
918 // chipset specific knowlegde, so none of the attributes can be set or
919 // cleared. Any attempt to set attribute that are already set will succeed,
920 // and any attempt to set an attribute that is not supported will fail.
922 *Supported
= PrivateData
->Attributes
;
926 // Set Attrbutes to the attributes detected when the PCI Root Bridge was initialized
930 *Attributes
= PrivateData
->Attributes
;
939 PcatRootBridgeIoSetAttributes (
940 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
941 IN UINT64 Attributes
,
942 IN OUT UINT64
*ResourceBase
,
943 IN OUT UINT64
*ResourceLength
947 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
949 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
952 // This is a generic driver for a PC-AT class system. It does not have any
953 // chipset specific knowlegde, so none of the attributes can be set or
954 // cleared. Any attempt to set attribute that are already set will succeed,
955 // and any attempt to set an attribute that is not supported will fail.
957 if (Attributes
& (~PrivateData
->Attributes
)) {
958 return EFI_UNSUPPORTED
;
966 PcatRootBridgeIoConfiguration (
967 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
972 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
974 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
976 *Resources
= PrivateData
->Configuration
;
987 PcatRootBridgeIoMemRW (
988 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
990 IN BOOLEAN InStrideFlag
,
992 IN BOOLEAN OutStrideFlag
,
999 Private service to provide the memory read/write
1003 Width of the Memory Access
1004 Count of the number of accesses to perform
1010 EFI_SUCCESS - Successful transaction
1011 EFI_INVALID_PARAMETER - Unsupported width and address combination
1020 Width
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
1021 Stride
= (UINTN
)1 << Width
;
1022 InStride
= InStrideFlag
? Stride
: 0;
1023 OutStride
= OutStrideFlag
? Stride
: 0;
1026 // Loop for each iteration and move the data
1029 case EfiPciWidthUint8
:
1030 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1036 case EfiPciWidthUint16
:
1037 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1039 *In
.ui16
= *Out
.ui16
;
1043 case EfiPciWidthUint32
:
1044 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1046 *In
.ui32
= *Out
.ui32
;
1051 return EFI_INVALID_PARAMETER
;