3 Copyright (c) 2005 - 2007, 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
195 PcatRootBridgeIoMemRW (
196 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
198 IN BOOLEAN InStrideFlag
,
200 IN BOOLEAN OutStrideFlag
,
205 PcatRootBridgeIoConstructor (
206 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*Protocol
,
207 IN UINTN SegmentNumber
213 Contruct the Pci Root Bridge Io protocol
217 Protocol - protocol to initialize
225 Protocol
->ParentHandle
= NULL
;
227 Protocol
->PollMem
= PcatRootBridgeIoPollMem
;
228 Protocol
->PollIo
= PcatRootBridgeIoPollIo
;
230 Protocol
->Mem
.Read
= PcatRootBridgeIoMemRead
;
231 Protocol
->Mem
.Write
= PcatRootBridgeIoMemWrite
;
233 Protocol
->Io
.Read
= PcatRootBridgeIoIoRead
;
234 Protocol
->Io
.Write
= PcatRootBridgeIoIoWrite
;
236 Protocol
->CopyMem
= PcatRootBridgeIoCopyMem
;
238 Protocol
->Pci
.Read
= PcatRootBridgeIoPciRead
;
239 Protocol
->Pci
.Write
= PcatRootBridgeIoPciWrite
;
241 Protocol
->Map
= PcatRootBridgeIoMap
;
242 Protocol
->Unmap
= PcatRootBridgeIoUnmap
;
244 Protocol
->AllocateBuffer
= PcatRootBridgeIoAllocateBuffer
;
245 Protocol
->FreeBuffer
= PcatRootBridgeIoFreeBuffer
;
247 Protocol
->Flush
= PcatRootBridgeIoFlush
;
249 Protocol
->GetAttributes
= PcatRootBridgeIoGetAttributes
;
250 Protocol
->SetAttributes
= PcatRootBridgeIoSetAttributes
;
252 Protocol
->Configuration
= PcatRootBridgeIoConfiguration
;
254 Protocol
->SegmentNumber
= (UINT32
)SegmentNumber
;
261 PcatRootBridgeIoPollMem (
262 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
263 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
272 UINT64 NumberOfTicks
;
275 if (Result
== NULL
) {
276 return EFI_INVALID_PARAMETER
;
280 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
281 return EFI_INVALID_PARAMETER
;
284 // No matter what, always do a single poll.
286 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
287 if ( EFI_ERROR(Status
) ) {
290 if ( (*Result
& Mask
) == Value
) {
296 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
297 if ( Remainder
!=0 ) {
302 while ( NumberOfTicks
) {
306 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
307 if ( EFI_ERROR(Status
) ) {
311 if ( (*Result
& Mask
) == Value
) {
323 PcatRootBridgeIoPollIo (
324 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
325 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
334 UINT64 NumberOfTicks
;
337 if (Result
== NULL
) {
338 return EFI_INVALID_PARAMETER
;
341 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
342 return EFI_INVALID_PARAMETER
;
345 // No matter what, always do a single poll.
347 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
348 if ( EFI_ERROR(Status
) ) {
351 if ( (*Result
& Mask
) == Value
) {
357 NumberOfTicks
= DivU64x32Remainder (Delay
, 100, &Remainder
);
358 if ( Remainder
!=0 ) {
363 while ( NumberOfTicks
) {
367 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
368 if ( EFI_ERROR(Status
) ) {
372 if ( (*Result
& Mask
) == Value
) {
383 PcatRootBridgeMemAddressValid (
384 IN PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
,
388 if ((Address
>= PrivateData
->PciExpressBaseAddress
) && (Address
< PrivateData
->PciExpressBaseAddress
+ 0x10000000)) {
391 if ((Address
>= PrivateData
->MemBase
) && (Address
< PrivateData
->MemLimit
)) {
400 PcatRootBridgeIoMemRead (
401 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
402 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
408 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
413 if ( Buffer
== NULL
) {
414 return EFI_INVALID_PARAMETER
;
417 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
419 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
420 return EFI_INVALID_PARAMETER
;
423 AlignMask
= (1 << (Width
& 0x03)) - 1;
424 if (Address
& AlignMask
) {
425 return EFI_INVALID_PARAMETER
;
428 Address
+= PrivateData
->PhysicalMemoryBase
;
431 Out
.buf
= (VOID
*)(UINTN
) Address
;
432 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
433 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
435 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
436 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
438 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
439 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
442 return EFI_INVALID_PARAMETER
;
447 PcatRootBridgeIoMemWrite (
448 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
449 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
455 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
460 if ( Buffer
== NULL
) {
461 return EFI_INVALID_PARAMETER
;
464 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
466 if (!PcatRootBridgeMemAddressValid (PrivateData
, Address
)) {
467 return EFI_INVALID_PARAMETER
;
470 AlignMask
= (1 << (Width
& 0x03)) - 1;
471 if (Address
& AlignMask
) {
472 return EFI_INVALID_PARAMETER
;
475 Address
+= PrivateData
->PhysicalMemoryBase
;
477 In
.buf
= (VOID
*)(UINTN
) Address
;
479 if (Width
>= EfiPciWidthUint8
&& Width
<= EfiPciWidthUint64
) {
480 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, TRUE
, Out
);
482 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
483 return PcatRootBridgeIoMemRW (Width
, Count
, FALSE
, In
, TRUE
, Out
);
485 if (Width
>= EfiPciWidthFillUint8
&& Width
<= EfiPciWidthFillUint64
) {
486 return PcatRootBridgeIoMemRW (Width
, Count
, TRUE
, In
, FALSE
, Out
);
489 return EFI_INVALID_PARAMETER
;
494 PcatRootBridgeIoCopyMem (
495 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
496 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
497 IN UINT64 DestAddress
,
498 IN UINT64 SrcAddress
,
509 if (Width
< 0 || Width
> EfiPciWidthUint64
) {
510 return EFI_INVALID_PARAMETER
;
513 if (DestAddress
== SrcAddress
) {
517 Stride
= (UINTN
)1 << Width
;
520 if ((DestAddress
> SrcAddress
) && (DestAddress
< (SrcAddress
+ Count
* Stride
))) {
522 SrcAddress
= SrcAddress
+ (Count
-1) * Stride
;
523 DestAddress
= DestAddress
+ (Count
-1) * Stride
;
526 for (Index
= 0;Index
< Count
;Index
++) {
527 Status
= PcatRootBridgeIoMemRead (
534 if (EFI_ERROR (Status
)) {
537 Status
= PcatRootBridgeIoMemWrite (
544 if (EFI_ERROR (Status
)) {
548 SrcAddress
+= Stride
;
549 DestAddress
+= Stride
;
551 SrcAddress
-= Stride
;
552 DestAddress
-= Stride
;
560 PcatRootBridgeIoPciRead (
561 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
562 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
568 if (Buffer
== NULL
) {
569 return EFI_INVALID_PARAMETER
;
572 return PcatRootBridgeIoPciRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
577 PcatRootBridgeIoPciWrite (
578 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
579 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
585 if (Buffer
== NULL
) {
586 return EFI_INVALID_PARAMETER
;
589 return PcatRootBridgeIoPciRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
594 PcatRootBridgeIoMap (
595 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
596 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
597 IN VOID
*HostAddress
,
598 IN OUT UINTN
*NumberOfBytes
,
599 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
605 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
607 MAP_INFO_INSTANCE
*MapInstance
;
608 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
610 if ( HostAddress
== NULL
|| NumberOfBytes
== NULL
||
611 DeviceAddress
== NULL
|| Mapping
== NULL
) {
613 return EFI_INVALID_PARAMETER
;
617 // Perform a fence operation to make sure all memory operations are flushed
622 // Initialize the return values to their defaults
627 // Make sure that Operation is valid
629 if (Operation
< 0 || Operation
>= EfiPciOperationMaximum
) {
630 return EFI_INVALID_PARAMETER
;
634 // Most PCAT like chipsets can not handle performing DMA above 4GB.
635 // If any part of the DMA transfer being mapped is above 4GB, then
636 // map the DMA transfer to a buffer below 4GB.
638 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
;
639 if ((PhysicalAddress
+ *NumberOfBytes
) > 0x100000000) {
642 // Common Buffer operations can not be remapped. If the common buffer
643 // if above 4GB, then it is not possible to generate a mapping, so return
646 if (Operation
== EfiPciOperationBusMasterCommonBuffer
|| Operation
== EfiPciOperationBusMasterCommonBuffer64
) {
647 return EFI_UNSUPPORTED
;
651 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
654 Status
= gBS
->AllocatePool (
659 if (EFI_ERROR (Status
)) {
665 // Return a pointer to the MAP_INFO structure in Mapping
670 // Initialize the MAP_INFO structure
672 MapInfo
->Operation
= Operation
;
673 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
674 MapInfo
->NumberOfPages
= EFI_SIZE_TO_PAGES(*NumberOfBytes
);
675 MapInfo
->HostAddress
= PhysicalAddress
;
676 MapInfo
->MappedHostAddress
= 0x00000000ffffffff;
679 // Allocate a buffer below 4GB to map the transfer to.
681 Status
= gBS
->AllocatePages (
684 MapInfo
->NumberOfPages
,
685 &MapInfo
->MappedHostAddress
687 if (EFI_ERROR(Status
)) {
688 gBS
->FreePool (MapInfo
);
694 // If this is a read operation from the Bus Master's point of view,
695 // then copy the contents of the real buffer into the mapped buffer
696 // so the Bus Master can read the contents of the real buffer.
698 if (Operation
== EfiPciOperationBusMasterRead
|| Operation
== EfiPciOperationBusMasterRead64
) {
700 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
701 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
702 MapInfo
->NumberOfBytes
707 Status
=gBS
->AllocatePool (
709 sizeof(MAP_INFO_INSTANCE
),
712 if (EFI_ERROR(Status
)) {
713 gBS
->FreePages (MapInfo
->MappedHostAddress
,MapInfo
->NumberOfPages
);
714 gBS
->FreePool (MapInfo
);
719 MapInstance
->Map
=MapInfo
;
720 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
721 InsertTailList(&PrivateData
->MapInfo
,&MapInstance
->Link
);
724 // The DeviceAddress is the address of the maped buffer below 4GB
726 *DeviceAddress
= MapInfo
->MappedHostAddress
;
729 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
731 *DeviceAddress
= PhysicalAddress
;
735 // Perform a fence operation to make sure all memory operations are flushed
744 PcatRootBridgeIoUnmap (
745 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
751 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
755 // Perform a fence operation to make sure all memory operations are flushed
759 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
761 // See if the Map() operation associated with this Unmap() required a mapping buffer.
762 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
764 if (Mapping
!= NULL
) {
766 // Get the MAP_INFO structure from Mapping
768 MapInfo
= (MAP_INFO
*)Mapping
;
770 for (Link
= PrivateData
->MapInfo
.ForwardLink
; Link
!= &PrivateData
->MapInfo
; Link
= Link
->ForwardLink
) {
771 if (((MAP_INFO_INSTANCE
*)Link
)->Map
== MapInfo
)
775 if (Link
== &PrivateData
->MapInfo
) {
776 return EFI_INVALID_PARAMETER
;
779 RemoveEntryList(Link
);
780 ((MAP_INFO_INSTANCE
*)Link
)->Map
= NULL
;
781 gBS
->FreePool((MAP_INFO_INSTANCE
*)Link
);
784 // If this is a write operation from the Bus Master's point of view,
785 // then copy the contents of the mapped buffer into the real buffer
786 // so the processor can read the contents of the real buffer.
788 if (MapInfo
->Operation
== EfiPciOperationBusMasterWrite
|| MapInfo
->Operation
== EfiPciOperationBusMasterWrite64
) {
790 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
791 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
792 MapInfo
->NumberOfBytes
797 // Free the mapped buffer and the MAP_INFO structure.
799 gBS
->FreePages (MapInfo
->MappedHostAddress
, MapInfo
->NumberOfPages
);
800 gBS
->FreePool (Mapping
);
804 // Perform a fence operation to make sure all memory operations are flushed
813 PcatRootBridgeIoAllocateBuffer (
814 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
815 IN EFI_ALLOCATE_TYPE Type
,
816 IN EFI_MEMORY_TYPE MemoryType
,
818 OUT VOID
**HostAddress
,
823 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
826 // Validate Attributes
828 if (Attributes
& EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER
) {
829 return EFI_UNSUPPORTED
;
833 // Check for invalid inputs
835 if (HostAddress
== NULL
) {
836 return EFI_INVALID_PARAMETER
;
840 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
842 if (MemoryType
!= EfiBootServicesData
&& MemoryType
!= EfiRuntimeServicesData
) {
843 return EFI_INVALID_PARAMETER
;
847 // Limit allocations to memory below 4GB
849 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(0xffffffff);
851 Status
= gBS
->AllocatePages (AllocateMaxAddress
, MemoryType
, Pages
, &PhysicalAddress
);
852 if (EFI_ERROR (Status
)) {
856 *HostAddress
= (VOID
*)(UINTN
)PhysicalAddress
;
863 PcatRootBridgeIoFreeBuffer (
864 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
866 OUT VOID
*HostAddress
871 if( HostAddress
== NULL
){
872 return EFI_INVALID_PARAMETER
;
874 return gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)HostAddress
, Pages
);
879 PcatRootBridgeIoFlush (
880 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
885 // Perform a fence operation to make sure all memory operations are flushed
894 PcatRootBridgeIoGetAttributes (
895 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
896 OUT UINT64
*Supported
, OPTIONAL
897 OUT UINT64
*Attributes
901 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
903 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
905 if (Attributes
== NULL
&& Supported
== NULL
) {
906 return EFI_INVALID_PARAMETER
;
910 // Supported is an OPTIONAL parameter. See if it is NULL
914 // This is a generic driver for a PC-AT class system. It does not have any
915 // chipset specific knowlegde, so none of the attributes can be set or
916 // cleared. Any attempt to set attribute that are already set will succeed,
917 // and any attempt to set an attribute that is not supported will fail.
919 *Supported
= PrivateData
->Attributes
;
923 // Set Attrbutes to the attributes detected when the PCI Root Bridge was initialized
927 *Attributes
= PrivateData
->Attributes
;
936 PcatRootBridgeIoSetAttributes (
937 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
938 IN UINT64 Attributes
,
939 IN OUT UINT64
*ResourceBase
,
940 IN OUT UINT64
*ResourceLength
944 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
946 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
949 // This is a generic driver for a PC-AT class system. It does not have any
950 // chipset specific knowlegde, so none of the attributes can be set or
951 // cleared. Any attempt to set attribute that are already set will succeed,
952 // and any attempt to set an attribute that is not supported will fail.
954 if (Attributes
& (~PrivateData
->Attributes
)) {
955 return EFI_UNSUPPORTED
;
963 PcatRootBridgeIoConfiguration (
964 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
969 PCAT_PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
971 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
973 *Resources
= PrivateData
->Configuration
;
985 PcatRootBridgeIoMemRW (
986 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
988 IN BOOLEAN InStrideFlag
,
990 IN BOOLEAN OutStrideFlag
,
997 Private service to provide the memory read/write
1001 Width of the Memory Access
1002 Count of the number of accesses to perform
1008 EFI_SUCCESS - Successful transaction
1009 EFI_INVALID_PARAMETER - Unsupported width and address combination
1018 Width
= Width
& 0x03;
1019 Stride
= (UINTN
)1 << Width
;
1020 InStride
= InStrideFlag
? Stride
: 0;
1021 OutStride
= OutStrideFlag
? Stride
: 0;
1024 // Loop for each iteration and move the data
1027 case EfiPciWidthUint8
:
1028 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1034 case EfiPciWidthUint16
:
1035 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1037 *In
.ui16
= *Out
.ui16
;
1041 case EfiPciWidthUint32
:
1042 for (;Count
> 0; Count
--, In
.buf
+= InStride
, Out
.buf
+= OutStride
) {
1044 *In
.ui32
= *Out
.ui32
;
1049 return EFI_INVALID_PARAMETER
;