3 PCI Root Bridge Io Protocol code.
5 Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciHostBridge.h"
17 #include "PciRootBridge.h"
18 #include "PciHostResource.h"
20 #define NO_MAPPING (VOID *) (UINTN) -1
23 // Lookup table for increment values based on transfer widths
26 1, // EfiPciWidthUint8
27 2, // EfiPciWidthUint16
28 4, // EfiPciWidthUint32
29 8, // EfiPciWidthUint64
30 0, // EfiPciWidthFifoUint8
31 0, // EfiPciWidthFifoUint16
32 0, // EfiPciWidthFifoUint32
33 0, // EfiPciWidthFifoUint64
34 1, // EfiPciWidthFillUint8
35 2, // EfiPciWidthFillUint16
36 4, // EfiPciWidthFillUint32
37 8 // EfiPciWidthFillUint64
41 // Lookup table for increment values based on transfer widths
43 UINT8 mOutStride
[] = {
44 1, // EfiPciWidthUint8
45 2, // EfiPciWidthUint16
46 4, // EfiPciWidthUint32
47 8, // EfiPciWidthUint64
48 1, // EfiPciWidthFifoUint8
49 2, // EfiPciWidthFifoUint16
50 4, // EfiPciWidthFifoUint32
51 8, // EfiPciWidthFifoUint64
52 0, // EfiPciWidthFillUint8
53 0, // EfiPciWidthFillUint16
54 0, // EfiPciWidthFillUint32
55 0 // EfiPciWidthFillUint64
59 Construct the Pci Root Bridge instance.
61 @param Bridge The root bridge instance.
63 @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created
64 or NULL if creation fails.
66 PCI_ROOT_BRIDGE_INSTANCE
*
68 IN PCI_ROOT_BRIDGE
*Bridge
71 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
72 PCI_RESOURCE_TYPE Index
;
73 CHAR16
*DevicePathStr
;
74 PCI_ROOT_BRIDGE_APERTURE
*Aperture
;
78 DEBUG ((EFI_D_INFO
, "RootBridge: "));
79 DEBUG ((EFI_D_INFO
, "%s\n", DevicePathStr
= ConvertDevicePathToText (Bridge
->DevicePath
, FALSE
, FALSE
)));
80 DEBUG ((EFI_D_INFO
, " Support/Attr: %lx / %lx\n", Bridge
->Supports
, Bridge
->Attributes
));
81 DEBUG ((EFI_D_INFO
, " DmaAbove4G: %s\n", Bridge
->DmaAbove4G
? L
"Yes" : L
"No"));
82 DEBUG ((EFI_D_INFO
, "NoExtConfSpace: %s\n", Bridge
->NoExtendedConfigSpace
? L
"Yes" : L
"No"));
83 DEBUG ((EFI_D_INFO
, " AllocAttr: %lx (%s%s)\n", Bridge
->AllocationAttributes
,
84 (Bridge
->AllocationAttributes
& EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
) != 0 ? L
"CombineMemPMem " : L
"",
85 (Bridge
->AllocationAttributes
& EFI_PCI_HOST_BRIDGE_MEM64_DECODE
) != 0 ? L
"Mem64Decode" : L
""
87 DEBUG ((EFI_D_INFO
, " Bus: %lx - %lx\n", Bridge
->Bus
.Base
, Bridge
->Bus
.Limit
));
88 DEBUG ((EFI_D_INFO
, " Io: %lx - %lx\n", Bridge
->Io
.Base
, Bridge
->Io
.Limit
));
89 DEBUG ((EFI_D_INFO
, " Mem: %lx - %lx\n", Bridge
->Mem
.Base
, Bridge
->Mem
.Limit
));
90 DEBUG ((EFI_D_INFO
, " MemAbove4G: %lx - %lx\n", Bridge
->MemAbove4G
.Base
, Bridge
->MemAbove4G
.Limit
));
91 DEBUG ((EFI_D_INFO
, " PMem: %lx - %lx\n", Bridge
->PMem
.Base
, Bridge
->PMem
.Limit
));
92 DEBUG ((EFI_D_INFO
, " PMemAbove4G: %lx - %lx\n", Bridge
->PMemAbove4G
.Base
, Bridge
->PMemAbove4G
.Limit
));
95 // Make sure Mem and MemAbove4G apertures are valid
97 if (Bridge
->Mem
.Base
<= Bridge
->Mem
.Limit
) {
98 ASSERT (Bridge
->Mem
.Limit
< SIZE_4GB
);
99 if (Bridge
->Mem
.Limit
>= SIZE_4GB
) {
103 if (Bridge
->MemAbove4G
.Base
<= Bridge
->MemAbove4G
.Limit
) {
104 ASSERT (Bridge
->MemAbove4G
.Base
>= SIZE_4GB
);
105 if (Bridge
->MemAbove4G
.Base
< SIZE_4GB
) {
109 if (Bridge
->PMem
.Base
<= Bridge
->PMem
.Limit
) {
110 ASSERT (Bridge
->PMem
.Limit
< SIZE_4GB
);
111 if (Bridge
->PMem
.Limit
>= SIZE_4GB
) {
115 if (Bridge
->PMemAbove4G
.Base
<= Bridge
->PMemAbove4G
.Limit
) {
116 ASSERT (Bridge
->PMemAbove4G
.Base
>= SIZE_4GB
);
117 if (Bridge
->PMemAbove4G
.Base
< SIZE_4GB
) {
123 // Ignore AllocationAttributes when resources were already assigned.
125 if (!Bridge
->ResourceAssigned
) {
126 if ((Bridge
->AllocationAttributes
& EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
) != 0) {
128 // If this bit is set, then the PCI Root Bridge does not
129 // support separate windows for Non-prefetchable and Prefetchable
132 ASSERT (Bridge
->PMem
.Base
> Bridge
->PMem
.Limit
);
133 ASSERT (Bridge
->PMemAbove4G
.Base
> Bridge
->PMemAbove4G
.Limit
);
134 if ((Bridge
->PMem
.Base
<= Bridge
->PMem
.Limit
) ||
135 (Bridge
->PMemAbove4G
.Base
<= Bridge
->PMemAbove4G
.Limit
)
141 if ((Bridge
->AllocationAttributes
& EFI_PCI_HOST_BRIDGE_MEM64_DECODE
) == 0) {
143 // If this bit is not set, then the PCI Root Bridge does not support
144 // 64 bit memory windows.
146 ASSERT (Bridge
->MemAbove4G
.Base
> Bridge
->MemAbove4G
.Limit
);
147 ASSERT (Bridge
->PMemAbove4G
.Base
> Bridge
->PMemAbove4G
.Limit
);
148 if ((Bridge
->MemAbove4G
.Base
<= Bridge
->MemAbove4G
.Limit
) ||
149 (Bridge
->PMemAbove4G
.Base
<= Bridge
->PMemAbove4G
.Limit
)
156 RootBridge
= AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE
));
157 ASSERT (RootBridge
!= NULL
);
159 RootBridge
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
160 RootBridge
->Supports
= Bridge
->Supports
;
161 RootBridge
->Attributes
= Bridge
->Attributes
;
162 RootBridge
->DmaAbove4G
= Bridge
->DmaAbove4G
;
163 RootBridge
->NoExtendedConfigSpace
= Bridge
->NoExtendedConfigSpace
;
164 RootBridge
->AllocationAttributes
= Bridge
->AllocationAttributes
;
165 RootBridge
->DevicePath
= DuplicateDevicePath (Bridge
->DevicePath
);
166 RootBridge
->DevicePathStr
= DevicePathStr
;
167 RootBridge
->ConfigBuffer
= AllocatePool (
168 TypeMax
* sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
)
170 ASSERT (RootBridge
->ConfigBuffer
!= NULL
);
171 InitializeListHead (&RootBridge
->Maps
);
173 CopyMem (&RootBridge
->Bus
, &Bridge
->Bus
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
174 CopyMem (&RootBridge
->Io
, &Bridge
->Io
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
175 CopyMem (&RootBridge
->Mem
, &Bridge
->Mem
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
176 CopyMem (&RootBridge
->MemAbove4G
, &Bridge
->MemAbove4G
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
177 CopyMem (&RootBridge
->PMem
, &Bridge
->PMem
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
178 CopyMem (&RootBridge
->PMemAbove4G
, &Bridge
->PMemAbove4G
, sizeof (PCI_ROOT_BRIDGE_APERTURE
));
180 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
183 Aperture
= &RootBridge
->Bus
;
186 Aperture
= &RootBridge
->Io
;
189 Aperture
= &RootBridge
->Mem
;
192 Aperture
= &RootBridge
->MemAbove4G
;
195 Aperture
= &RootBridge
->PMem
;
198 Aperture
= &RootBridge
->PMemAbove4G
;
204 RootBridge
->ResAllocNode
[Index
].Type
= Index
;
205 if (Bridge
->ResourceAssigned
&& (Aperture
->Limit
>= Aperture
->Base
)) {
206 RootBridge
->ResAllocNode
[Index
].Base
= Aperture
->Base
;
207 RootBridge
->ResAllocNode
[Index
].Length
= Aperture
->Limit
- Aperture
->Base
+ 1;
208 RootBridge
->ResAllocNode
[Index
].Status
= ResAllocated
;
210 RootBridge
->ResAllocNode
[Index
].Base
= 0;
211 RootBridge
->ResAllocNode
[Index
].Length
= 0;
212 RootBridge
->ResAllocNode
[Index
].Status
= ResNone
;
216 RootBridge
->RootBridgeIo
.SegmentNumber
= Bridge
->Segment
;
217 RootBridge
->RootBridgeIo
.PollMem
= RootBridgeIoPollMem
;
218 RootBridge
->RootBridgeIo
.PollIo
= RootBridgeIoPollIo
;
219 RootBridge
->RootBridgeIo
.Mem
.Read
= RootBridgeIoMemRead
;
220 RootBridge
->RootBridgeIo
.Mem
.Write
= RootBridgeIoMemWrite
;
221 RootBridge
->RootBridgeIo
.Io
.Read
= RootBridgeIoIoRead
;
222 RootBridge
->RootBridgeIo
.Io
.Write
= RootBridgeIoIoWrite
;
223 RootBridge
->RootBridgeIo
.CopyMem
= RootBridgeIoCopyMem
;
224 RootBridge
->RootBridgeIo
.Pci
.Read
= RootBridgeIoPciRead
;
225 RootBridge
->RootBridgeIo
.Pci
.Write
= RootBridgeIoPciWrite
;
226 RootBridge
->RootBridgeIo
.Map
= RootBridgeIoMap
;
227 RootBridge
->RootBridgeIo
.Unmap
= RootBridgeIoUnmap
;
228 RootBridge
->RootBridgeIo
.AllocateBuffer
= RootBridgeIoAllocateBuffer
;
229 RootBridge
->RootBridgeIo
.FreeBuffer
= RootBridgeIoFreeBuffer
;
230 RootBridge
->RootBridgeIo
.Flush
= RootBridgeIoFlush
;
231 RootBridge
->RootBridgeIo
.GetAttributes
= RootBridgeIoGetAttributes
;
232 RootBridge
->RootBridgeIo
.SetAttributes
= RootBridgeIoSetAttributes
;
233 RootBridge
->RootBridgeIo
.Configuration
= RootBridgeIoConfiguration
;
239 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
241 The I/O operations are carried out exactly as requested. The caller is
242 responsible for satisfying any alignment and I/O width restrictions that a PI
243 System on a platform might require. For example on some platforms, width
244 requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other
245 hand, will be handled by the driver.
247 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
249 @param[in] OperationType I/O operation type: IO/MMIO/PCI.
251 @param[in] Width Signifies the width of the I/O or Memory operation.
253 @param[in] Address The base address of the I/O operation.
255 @param[in] Count The number of I/O operations to perform. The number
256 of bytes moved is Width size * Count, starting at
259 @param[in] Buffer For read operations, the destination buffer to
260 store the results. For write operations, the source
261 buffer from which to write data.
263 @retval EFI_SUCCESS The parameters for this request pass the
266 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
268 @retval EFI_INVALID_PARAMETER Buffer is NULL.
270 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
272 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
273 and Count is not valid for this PI system.
276 RootBridgeIoCheckParameter (
277 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
278 IN OPERATION_TYPE OperationType
,
279 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
285 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
286 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*PciRbAddr
;
292 // Check to see if Buffer is NULL
294 if (Buffer
== NULL
) {
295 return EFI_INVALID_PARAMETER
;
299 // Check to see if Width is in the valid range
301 if ((UINT32
) Width
>= EfiPciWidthMaximum
) {
302 return EFI_INVALID_PARAMETER
;
306 // For FIFO type, the target address won't increase during the access,
307 // so treat Count as 1
309 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
313 Width
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
317 // Check to see if Address is aligned
319 if ((Address
& (Size
- 1)) != 0) {
320 return EFI_UNSUPPORTED
;
323 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
326 // Check to see if any address associated with this transfer exceeds the
327 // maximum allowed address. The maximum address implied by the parameters
328 // passed in is Address + Size * Count. If the following condition is met,
329 // then the transfer is not supported.
331 // Address + Size * Count > Limit + 1
333 // Since Limit can be the maximum integer value supported by the CPU and
334 // Count can also be the maximum integer value supported by the CPU, this
335 // range check must be adjusted to avoid all oveflow conditions.
337 if (OperationType
== IoOperation
) {
339 // Allow Legacy IO access
341 if (Address
+ MultU64x32 (Count
, Size
) <= 0x1000) {
342 if ((RootBridge
->Attributes
& (
343 EFI_PCI_ATTRIBUTE_ISA_IO
| EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
| EFI_PCI_ATTRIBUTE_VGA_IO
|
344 EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
| EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
|
345 EFI_PCI_ATTRIBUTE_ISA_IO_16
| EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
| EFI_PCI_ATTRIBUTE_VGA_IO_16
)) != 0) {
349 Base
= RootBridge
->Io
.Base
;
350 Limit
= RootBridge
->Io
.Limit
;
351 } else if (OperationType
== MemOperation
) {
353 // Allow Legacy MMIO access
355 if ((Address
>= 0xA0000) && (Address
+ MultU64x32 (Count
, Size
)) <= 0xC0000) {
356 if ((RootBridge
->Attributes
& EFI_PCI_ATTRIBUTE_VGA_MEMORY
) != 0) {
361 // By comparing the Address against Limit we know which range to be used
364 if (Address
+ MultU64x32 (Count
, Size
) <= RootBridge
->Mem
.Limit
+ 1) {
365 Base
= RootBridge
->Mem
.Base
;
366 Limit
= RootBridge
->Mem
.Limit
;
368 Base
= RootBridge
->MemAbove4G
.Base
;
369 Limit
= RootBridge
->MemAbove4G
.Limit
;
372 PciRbAddr
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*) &Address
;
373 if (PciRbAddr
->Bus
< RootBridge
->Bus
.Base
||
374 PciRbAddr
->Bus
> RootBridge
->Bus
.Limit
) {
375 return EFI_INVALID_PARAMETER
;
378 if (PciRbAddr
->Device
> PCI_MAX_DEVICE
||
379 PciRbAddr
->Function
> PCI_MAX_FUNC
) {
380 return EFI_INVALID_PARAMETER
;
383 if (PciRbAddr
->ExtendedRegister
!= 0) {
384 Address
= PciRbAddr
->ExtendedRegister
;
386 Address
= PciRbAddr
->Register
;
389 Limit
= RootBridge
->NoExtendedConfigSpace
? 0xFF : 0xFFF;
392 if (Address
< Base
) {
393 return EFI_INVALID_PARAMETER
;
396 if (Address
+ MultU64x32 (Count
, Size
) > Limit
+ 1) {
397 return EFI_INVALID_PARAMETER
;
404 Polls an address in memory mapped I/O space until an exit condition is met,
407 This function provides a standard way to poll a PCI memory location. A PCI
408 memory read operation is performed at the PCI memory address specified by
409 Address for the width specified by Width. The result of this PCI memory read
410 operation is stored in Result. This PCI memory read operation is repeated
411 until either a timeout of Delay 100 ns units has expired, or (Result & Mask)
414 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
415 @param[in] Width Signifies the width of the memory operations.
416 @param[in] Address The base address of the memory operations. The caller
417 is responsible for aligning Address if required.
418 @param[in] Mask Mask used for the polling criteria. Bytes above Width
419 in Mask are ignored. The bits in the bytes below Width
420 which are zero in Mask are ignored when polling the
422 @param[in] Value The comparison value used for the polling exit
424 @param[in] Delay The number of 100 ns units to poll. Note that timer
425 available may be of poorer granularity.
426 @param[out] Result Pointer to the last value read from the memory
429 @retval EFI_SUCCESS The last data returned from the access matched
430 the poll exit criteria.
431 @retval EFI_INVALID_PARAMETER Width is invalid.
432 @retval EFI_INVALID_PARAMETER Result is NULL.
433 @retval EFI_TIMEOUT Delay expired before a match occurred.
434 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
439 RootBridgeIoPollMem (
440 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
441 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
450 UINT64 NumberOfTicks
;
453 if (Result
== NULL
) {
454 return EFI_INVALID_PARAMETER
;
457 if ((UINT32
)Width
> EfiPciWidthUint64
) {
458 return EFI_INVALID_PARAMETER
;
462 // No matter what, always do a single poll.
464 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
465 if (EFI_ERROR (Status
)) {
469 if ((*Result
& Mask
) == Value
) {
479 // Determine the proper # of metronome ticks to wait for polling the
480 // location. The nuber of ticks is Roundup (Delay /
481 // mMetronome->TickPeriod)+1
482 // The "+1" to account for the possibility of the first tick being short
483 // because we started in the middle of a tick.
485 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
486 // protocol definition is updated.
488 NumberOfTicks
= DivU64x32Remainder (Delay
, (UINT32
) mMetronome
->TickPeriod
,
490 if (Remainder
!= 0) {
495 while (NumberOfTicks
!= 0) {
497 mMetronome
->WaitForTick (mMetronome
, 1);
499 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
500 if (EFI_ERROR (Status
)) {
504 if ((*Result
& Mask
) == Value
) {
515 Reads from the I/O space of a PCI Root Bridge. Returns when either the
516 polling exit criteria is satisfied or after a defined duration.
518 This function provides a standard way to poll a PCI I/O location. A PCI I/O
519 read operation is performed at the PCI I/O address specified by Address for
520 the width specified by Width.
521 The result of this PCI I/O read operation is stored in Result. This PCI I/O
522 read operation is repeated until either a timeout of Delay 100 ns units has
523 expired, or (Result & Mask) is equal to Value.
525 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
526 @param[in] Width Signifies the width of the I/O operations.
527 @param[in] Address The base address of the I/O operations. The caller is
528 responsible for aligning Address if required.
529 @param[in] Mask Mask used for the polling criteria. Bytes above Width in
530 Mask are ignored. The bits in the bytes below Width
531 which are zero in Mask are ignored when polling the I/O
533 @param[in] Value The comparison value used for the polling exit criteria.
534 @param[in] Delay The number of 100 ns units to poll. Note that timer
535 available may be of poorer granularity.
536 @param[out] Result Pointer to the last value read from the memory location.
538 @retval EFI_SUCCESS The last data returned from the access matched
539 the poll exit criteria.
540 @retval EFI_INVALID_PARAMETER Width is invalid.
541 @retval EFI_INVALID_PARAMETER Result is NULL.
542 @retval EFI_TIMEOUT Delay expired before a match occurred.
543 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
549 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
550 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
559 UINT64 NumberOfTicks
;
563 // No matter what, always do a single poll.
566 if (Result
== NULL
) {
567 return EFI_INVALID_PARAMETER
;
570 if ((UINT32
)Width
> EfiPciWidthUint64
) {
571 return EFI_INVALID_PARAMETER
;
574 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
575 if (EFI_ERROR (Status
)) {
578 if ((*Result
& Mask
) == Value
) {
588 // Determine the proper # of metronome ticks to wait for polling the
589 // location. The number of ticks is Roundup (Delay /
590 // mMetronome->TickPeriod)+1
591 // The "+1" to account for the possibility of the first tick being short
592 // because we started in the middle of a tick.
594 NumberOfTicks
= DivU64x32Remainder (Delay
, (UINT32
)mMetronome
->TickPeriod
,
596 if (Remainder
!= 0) {
601 while (NumberOfTicks
!= 0) {
603 mMetronome
->WaitForTick (mMetronome
, 1);
605 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
606 if (EFI_ERROR (Status
)) {
610 if ((*Result
& Mask
) == Value
) {
621 Enables a PCI driver to access PCI controller registers in the PCI root
624 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
625 controller registers in the PCI root bridge memory space.
626 The memory operations are carried out exactly as requested. The caller is
627 responsible for satisfying any alignment and memory width restrictions that a
628 PCI Root Bridge on a platform might require.
630 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
631 @param[in] Width Signifies the width of the memory operation.
632 @param[in] Address The base address of the memory operation. The caller
633 is responsible for aligning the Address if required.
634 @param[in] Count The number of memory operations to perform. Bytes
635 moved is Width size * Count, starting at Address.
636 @param[out] Buffer For read operations, the destination buffer to store
637 the results. For write operations, the source buffer
640 @retval EFI_SUCCESS The data was read from or written to the PCI
642 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
643 @retval EFI_INVALID_PARAMETER Buffer is NULL.
644 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
649 RootBridgeIoMemRead (
650 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
651 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
659 Status
= RootBridgeIoCheckParameter (This
, MemOperation
, Width
, Address
,
661 if (EFI_ERROR (Status
)) {
664 return mCpuIo
->Mem
.Read (mCpuIo
, (EFI_CPU_IO_PROTOCOL_WIDTH
) Width
, Address
, Count
, Buffer
);
668 Enables a PCI driver to access PCI controller registers in the PCI root
671 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
672 controller registers in the PCI root bridge memory space.
673 The memory operations are carried out exactly as requested. The caller is
674 responsible for satisfying any alignment and memory width restrictions that a
675 PCI Root Bridge on a platform might require.
677 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
678 @param[in] Width Signifies the width of the memory operation.
679 @param[in] Address The base address of the memory operation. The caller
680 is responsible for aligning the Address if required.
681 @param[in] Count The number of memory operations to perform. Bytes
682 moved is Width size * Count, starting at Address.
683 @param[in] Buffer For read operations, the destination buffer to store
684 the results. For write operations, the source buffer
687 @retval EFI_SUCCESS The data was read from or written to the PCI
689 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
690 @retval EFI_INVALID_PARAMETER Buffer is NULL.
691 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
696 RootBridgeIoMemWrite (
697 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
698 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
706 Status
= RootBridgeIoCheckParameter (This
, MemOperation
, Width
, Address
,
708 if (EFI_ERROR (Status
)) {
711 return mCpuIo
->Mem
.Write (mCpuIo
, (EFI_CPU_IO_PROTOCOL_WIDTH
) Width
, Address
, Count
, Buffer
);
715 Enables a PCI driver to access PCI controller registers in the PCI root
718 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
719 @param[in] Width Signifies the width of the memory operations.
720 @param[in] Address The base address of the I/O operation. The caller is
721 responsible for aligning the Address if required.
722 @param[in] Count The number of I/O operations to perform. Bytes moved
723 is Width size * Count, starting at Address.
724 @param[out] Buffer For read operations, the destination buffer to store
725 the results. For write operations, the source buffer
728 @retval EFI_SUCCESS The data was read from or written to the PCI
730 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
731 @retval EFI_INVALID_PARAMETER Buffer is NULL.
732 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
738 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
739 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
746 Status
= RootBridgeIoCheckParameter (
747 This
, IoOperation
, Width
,
748 Address
, Count
, Buffer
750 if (EFI_ERROR (Status
)) {
753 return mCpuIo
->Io
.Read (mCpuIo
, (EFI_CPU_IO_PROTOCOL_WIDTH
) Width
, Address
, Count
, Buffer
);
757 Enables a PCI driver to access PCI controller registers in the PCI root
760 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
761 @param[in] Width Signifies the width of the memory operations.
762 @param[in] Address The base address of the I/O operation. The caller is
763 responsible for aligning the Address if required.
764 @param[in] Count The number of I/O operations to perform. Bytes moved
765 is Width size * Count, starting at Address.
766 @param[in] Buffer For read operations, the destination buffer to store
767 the results. For write operations, the source buffer
770 @retval EFI_SUCCESS The data was read from or written to the PCI
772 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
773 @retval EFI_INVALID_PARAMETER Buffer is NULL.
774 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
779 RootBridgeIoIoWrite (
780 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
781 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
788 Status
= RootBridgeIoCheckParameter (
789 This
, IoOperation
, Width
,
790 Address
, Count
, Buffer
792 if (EFI_ERROR (Status
)) {
795 return mCpuIo
->Io
.Write (mCpuIo
, (EFI_CPU_IO_PROTOCOL_WIDTH
) Width
, Address
, Count
, Buffer
);
799 Enables a PCI driver to copy one region of PCI root bridge memory space to
800 another region of PCI root bridge memory space.
802 The CopyMem() function enables a PCI driver to copy one region of PCI root
803 bridge memory space to another region of PCI root bridge memory space. This
804 is especially useful for video scroll operation on a memory mapped video
806 The memory operations are carried out exactly as requested. The caller is
807 responsible for satisfying any alignment and memory width restrictions that a
808 PCI root bridge on a platform might require.
810 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
812 @param[in] Width Signifies the width of the memory operations.
813 @param[in] DestAddress The destination address of the memory operation. The
814 caller is responsible for aligning the DestAddress if
816 @param[in] SrcAddress The source address of the memory operation. The caller
817 is responsible for aligning the SrcAddress if
819 @param[in] Count The number of memory operations to perform. Bytes
820 moved is Width size * Count, starting at DestAddress
823 @retval EFI_SUCCESS The data was copied from one memory region
824 to another memory region.
825 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
826 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
831 RootBridgeIoCopyMem (
832 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
833 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
834 IN UINT64 DestAddress
,
835 IN UINT64 SrcAddress
,
845 if ((UINT32
) Width
> EfiPciWidthUint64
) {
846 return EFI_INVALID_PARAMETER
;
849 if (DestAddress
== SrcAddress
) {
853 Stride
= (UINTN
) (1 << Width
);
856 if ((DestAddress
> SrcAddress
) &&
857 (DestAddress
< (SrcAddress
+ Count
* Stride
))) {
859 SrcAddress
= SrcAddress
+ (Count
- 1) * Stride
;
860 DestAddress
= DestAddress
+ (Count
- 1) * Stride
;
863 for (Index
= 0; Index
< Count
; Index
++) {
864 Status
= RootBridgeIoMemRead (
871 if (EFI_ERROR (Status
)) {
874 Status
= RootBridgeIoMemWrite (
881 if (EFI_ERROR (Status
)) {
885 SrcAddress
+= Stride
;
886 DestAddress
+= Stride
;
888 SrcAddress
-= Stride
;
889 DestAddress
-= Stride
;
897 PCI configuration space access.
899 @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
900 @param Read TRUE indicating it's a read operation.
901 @param Width Signifies the width of the memory operation.
902 @param Address The address within the PCI configuration space
903 for the PCI controller.
904 @param Count The number of PCI configuration operations
906 @param Buffer The destination buffer to store the results.
908 @retval EFI_SUCCESS The data was read/written from/to the PCI root bridge.
909 @retval EFI_INVALID_PARAMETER Invalid parameters found.
913 RootBridgeIoPciAccess (
914 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
916 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
923 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
924 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
;
930 Status
= RootBridgeIoCheckParameter (This
, PciOperation
, Width
, Address
, Count
, Buffer
);
931 if (EFI_ERROR (Status
)) {
936 // Read Pci configuration space
938 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
939 CopyMem (&PciAddress
, &Address
, sizeof (PciAddress
));
941 if (PciAddress
.ExtendedRegister
== 0) {
942 PciAddress
.ExtendedRegister
= PciAddress
.Register
;
945 Address
= PCI_SEGMENT_LIB_ADDRESS (
946 RootBridge
->RootBridgeIo
.SegmentNumber
,
950 PciAddress
.ExtendedRegister
954 // Select loop based on the width of the transfer
956 InStride
= mInStride
[Width
];
957 OutStride
= mOutStride
[Width
];
958 Size
= (UINTN
) (1 << (Width
& 0x03));
959 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
961 PciSegmentReadBuffer (Address
, Size
, Uint8Buffer
);
963 PciSegmentWriteBuffer (Address
, Size
, Uint8Buffer
);
970 Allows read from PCI configuration space.
972 @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
973 @param Width Signifies the width of the memory operation.
974 @param Address The address within the PCI configuration space
975 for the PCI controller.
976 @param Count The number of PCI configuration operations
978 @param Buffer The destination buffer to store the results.
980 @retval EFI_SUCCESS The data was read from the PCI root bridge.
981 @retval EFI_INVALID_PARAMETER Invalid parameters found.
985 RootBridgeIoPciRead (
986 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
987 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
993 return RootBridgeIoPciAccess (This
, TRUE
, Width
, Address
, Count
, Buffer
);
997 Allows write to PCI configuration space.
999 @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
1000 @param Width Signifies the width of the memory operation.
1001 @param Address The address within the PCI configuration space
1002 for the PCI controller.
1003 @param Count The number of PCI configuration operations
1005 @param Buffer The source buffer to get the results.
1007 @retval EFI_SUCCESS The data was written to the PCI root bridge.
1008 @retval EFI_INVALID_PARAMETER Invalid parameters found.
1012 RootBridgeIoPciWrite (
1013 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1014 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1020 return RootBridgeIoPciAccess (This
, FALSE
, Width
, Address
, Count
, Buffer
);
1024 Provides the PCI controller-specific address needed to access
1025 system memory for DMA.
1027 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1028 @param Operation Indicate if the bus master is going to read or write
1030 @param HostAddress The system memory address to map on the PCI controller.
1031 @param NumberOfBytes On input the number of bytes to map.
1032 On output the number of bytes that were mapped.
1033 @param DeviceAddress The resulting map address for the bus master PCI
1034 controller to use to access the system memory's HostAddress.
1035 @param Mapping The value to pass to Unmap() when the bus master DMA
1036 operation is complete.
1038 @retval EFI_SUCCESS Success.
1039 @retval EFI_INVALID_PARAMETER Invalid parameters found.
1040 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
1041 @retval EFI_DEVICE_ERROR The System hardware could not map the requested address.
1042 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of resources.
1047 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1048 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
1049 IN VOID
*HostAddress
,
1050 IN OUT UINTN
*NumberOfBytes
,
1051 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
1056 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1057 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
1060 if (HostAddress
== NULL
|| NumberOfBytes
== NULL
|| DeviceAddress
== NULL
||
1062 return EFI_INVALID_PARAMETER
;
1066 // Make sure that Operation is valid
1068 if ((UINT32
) Operation
>= EfiPciOperationMaximum
) {
1069 return EFI_INVALID_PARAMETER
;
1072 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1074 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress
;
1075 if (!RootBridge
->DmaAbove4G
&& ((PhysicalAddress
+ *NumberOfBytes
) > SIZE_4GB
)) {
1077 // If the root bridge can not handle performing DMA above 4GB but
1078 // any part of the DMA transfer being mapped is above 4GB, then
1079 // map the DMA transfer to a buffer below 4GB.
1082 if (Operation
== EfiPciOperationBusMasterCommonBuffer
||
1083 Operation
== EfiPciOperationBusMasterCommonBuffer64
) {
1085 // Common Buffer operations can not be remapped. If the common buffer
1086 // if above 4GB, then it is not possible to generate a mapping, so return
1089 return EFI_UNSUPPORTED
;
1093 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
1096 MapInfo
= AllocatePool (sizeof (MAP_INFO
));
1097 if (MapInfo
== NULL
) {
1099 return EFI_OUT_OF_RESOURCES
;
1103 // Initialize the MAP_INFO structure
1105 MapInfo
->Signature
= MAP_INFO_SIGNATURE
;
1106 MapInfo
->Operation
= Operation
;
1107 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
1108 MapInfo
->NumberOfPages
= EFI_SIZE_TO_PAGES (MapInfo
->NumberOfBytes
);
1109 MapInfo
->HostAddress
= PhysicalAddress
;
1110 MapInfo
->MappedHostAddress
= SIZE_4GB
- 1;
1113 // Allocate a buffer below 4GB to map the transfer to.
1115 Status
= gBS
->AllocatePages (
1117 EfiBootServicesData
,
1118 MapInfo
->NumberOfPages
,
1119 &MapInfo
->MappedHostAddress
1121 if (EFI_ERROR (Status
)) {
1128 // If this is a read operation from the Bus Master's point of view,
1129 // then copy the contents of the real buffer into the mapped buffer
1130 // so the Bus Master can read the contents of the real buffer.
1132 if (Operation
== EfiPciOperationBusMasterRead
||
1133 Operation
== EfiPciOperationBusMasterRead64
) {
1135 (VOID
*) (UINTN
) MapInfo
->MappedHostAddress
,
1136 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
1137 MapInfo
->NumberOfBytes
1141 InsertTailList (&RootBridge
->Maps
, &MapInfo
->Link
);
1144 // The DeviceAddress is the address of the maped buffer below 4GB
1146 *DeviceAddress
= MapInfo
->MappedHostAddress
;
1148 // Return a pointer to the MAP_INFO structure in Mapping
1153 // If the root bridge CAN handle performing DMA above 4GB or
1154 // the transfer is below 4GB, so the DeviceAddress is simply the
1157 *DeviceAddress
= PhysicalAddress
;
1158 *Mapping
= NO_MAPPING
;
1165 Completes the Map() operation and releases any corresponding resources.
1167 The Unmap() function completes the Map() operation and releases any
1168 corresponding resources.
1169 If the operation was an EfiPciOperationBusMasterWrite or
1170 EfiPciOperationBusMasterWrite64, the data is committed to the target system
1172 Any resources used for the mapping are freed.
1174 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1175 @param[in] Mapping The mapping value returned from Map().
1177 @retval EFI_SUCCESS The range was unmapped.
1178 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
1179 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
1184 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1190 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1192 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1194 // See if the Map() operation associated with this Unmap() required a mapping
1195 // buffer. If a mapping buffer was not required, then this function simply
1196 // returns EFI_SUCCESS.
1198 if (Mapping
== NO_MAPPING
) {
1202 MapInfo
= NO_MAPPING
;
1203 for (Link
= GetFirstNode (&RootBridge
->Maps
)
1204 ; !IsNull (&RootBridge
->Maps
, Link
)
1205 ; Link
= GetNextNode (&RootBridge
->Maps
, Link
)
1207 MapInfo
= MAP_INFO_FROM_LINK (Link
);
1208 if (MapInfo
== Mapping
) {
1213 // Mapping is not a valid value returned by Map()
1215 if (MapInfo
!= Mapping
) {
1216 return EFI_INVALID_PARAMETER
;
1218 RemoveEntryList (&MapInfo
->Link
);
1221 // If this is a write operation from the Bus Master's point of view,
1222 // then copy the contents of the mapped buffer into the real buffer
1223 // so the processor can read the contents of the real buffer.
1225 if (MapInfo
->Operation
== EfiPciOperationBusMasterWrite
||
1226 MapInfo
->Operation
== EfiPciOperationBusMasterWrite64
) {
1228 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
1229 (VOID
*) (UINTN
) MapInfo
->MappedHostAddress
,
1230 MapInfo
->NumberOfBytes
1235 // Free the mapped buffer and the MAP_INFO structure.
1237 gBS
->FreePages (MapInfo
->MappedHostAddress
, MapInfo
->NumberOfPages
);
1243 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer
1244 or EfiPciOperationBusMasterCommonBuffer64 mapping.
1246 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1247 @param Type This parameter is not used and must be ignored.
1248 @param MemoryType The type of memory to allocate, EfiBootServicesData or
1249 EfiRuntimeServicesData.
1250 @param Pages The number of pages to allocate.
1251 @param HostAddress A pointer to store the base system memory address of the
1253 @param Attributes The requested bit mask of attributes for the allocated
1254 range. Only the attributes
1255 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,
1256 EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and
1257 EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this
1260 @retval EFI_SUCCESS The requested memory pages were allocated.
1261 @retval EFI_INVALID_PARAMETER MemoryType is invalid.
1262 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
1263 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
1264 attribute bits are MEMORY_WRITE_COMBINE,
1265 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
1266 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
1270 RootBridgeIoAllocateBuffer (
1271 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1272 IN EFI_ALLOCATE_TYPE Type
,
1273 IN EFI_MEMORY_TYPE MemoryType
,
1275 OUT VOID
**HostAddress
,
1276 IN UINT64 Attributes
1280 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
1281 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1282 EFI_ALLOCATE_TYPE AllocateType
;
1285 // Validate Attributes
1287 if ((Attributes
& EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER
) != 0) {
1288 return EFI_UNSUPPORTED
;
1292 // Check for invalid inputs
1294 if (HostAddress
== NULL
) {
1295 return EFI_INVALID_PARAMETER
;
1299 // The only valid memory types are EfiBootServicesData and
1300 // EfiRuntimeServicesData
1302 if (MemoryType
!= EfiBootServicesData
&&
1303 MemoryType
!= EfiRuntimeServicesData
) {
1304 return EFI_INVALID_PARAMETER
;
1307 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1309 AllocateType
= AllocateAnyPages
;
1310 if (!RootBridge
->DmaAbove4G
) {
1312 // Limit allocations to memory below 4GB
1314 AllocateType
= AllocateMaxAddress
;
1315 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1);
1317 Status
= gBS
->AllocatePages (
1323 if (!EFI_ERROR (Status
)) {
1324 *HostAddress
= (VOID
*) (UINTN
) PhysicalAddress
;
1331 Frees memory that was allocated with AllocateBuffer().
1333 The FreeBuffer() function frees memory that was allocated with
1336 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1337 @param Pages The number of pages to free.
1338 @param HostAddress The base system memory address of the allocated range.
1340 @retval EFI_SUCCESS The requested memory pages were freed.
1341 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
1342 Pages was not allocated with AllocateBuffer().
1346 RootBridgeIoFreeBuffer (
1347 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1349 OUT VOID
*HostAddress
1352 return gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress
, Pages
);
1356 Flushes all PCI posted write transactions from a PCI host bridge to system
1359 The Flush() function flushes any PCI posted write transactions from a PCI
1360 host bridge to system memory. Posted write transactions are generated by PCI
1361 bus masters when they perform write transactions to target addresses in
1363 This function does not flush posted write transactions from any PCI bridges.
1364 A PCI controller specific action must be taken to guarantee that the posted
1365 write transactions have been flushed from the PCI controller and from all the
1366 PCI bridges into the PCI host bridge. This is typically done with a PCI read
1367 transaction from the PCI controller prior to calling Flush().
1369 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1371 @retval EFI_SUCCESS The PCI posted write transactions were flushed
1372 from the PCI host bridge to system memory.
1373 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed
1374 from the PCI host bridge due to a hardware error.
1379 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
1386 Gets the attributes that a PCI root bridge supports setting with
1387 SetAttributes(), and the attributes that a PCI root bridge is currently
1390 The GetAttributes() function returns the mask of attributes that this PCI
1391 root bridge supports and the mask of attributes that the PCI root bridge is
1394 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1395 @param Supported A pointer to the mask of attributes that this PCI root
1396 bridge supports setting with SetAttributes().
1397 @param Attributes A pointer to the mask of attributes that this PCI root
1398 bridge is currently using.
1400 @retval EFI_SUCCESS If Supports is not NULL, then the attributes
1401 that the PCI root bridge supports is returned
1402 in Supports. If Attributes is not NULL, then
1403 the attributes that the PCI root bridge is
1404 currently using is returned in Attributes.
1405 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
1409 RootBridgeIoGetAttributes (
1410 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1411 OUT UINT64
*Supported
,
1412 OUT UINT64
*Attributes
1415 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1417 if (Attributes
== NULL
&& Supported
== NULL
) {
1418 return EFI_INVALID_PARAMETER
;
1421 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1423 // Set the return value for Supported and Attributes
1425 if (Supported
!= NULL
) {
1426 *Supported
= RootBridge
->Supports
;
1429 if (Attributes
!= NULL
) {
1430 *Attributes
= RootBridge
->Attributes
;
1437 Sets attributes for a resource range on a PCI root bridge.
1439 The SetAttributes() function sets the attributes specified in Attributes for
1440 the PCI root bridge on the resource range specified by ResourceBase and
1441 ResourceLength. Since the granularity of setting these attributes may vary
1442 from resource type to resource type, and from platform to platform, the
1443 actual resource range and the one passed in by the caller may differ. As a
1444 result, this function may set the attributes specified by Attributes on a
1445 larger resource range than the caller requested. The actual range is returned
1446 in ResourceBase and ResourceLength. The caller is responsible for verifying
1447 that the actual range for which the attributes were set is acceptable.
1449 @param This A pointer to the
1450 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1451 @param Attributes The mask of attributes to set. If the
1452 attribute bit MEMORY_WRITE_COMBINE,
1453 MEMORY_CACHED, or MEMORY_DISABLE is set,
1454 then the resource range is specified by
1455 ResourceBase and ResourceLength. If
1456 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
1457 MEMORY_DISABLE are not set, then
1458 ResourceBase and ResourceLength are ignored,
1460 @param ResourceBase A pointer to the base address of the
1461 resource range to be modified by the
1462 attributes specified by Attributes.
1463 @param ResourceLength A pointer to the length of the resource
1464 range to be modified by the attributes
1465 specified by Attributes.
1467 @retval EFI_SUCCESS The current configuration of this PCI root bridge
1468 was returned in Resources.
1469 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
1470 could not be retrieved.
1474 RootBridgeIoSetAttributes (
1475 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1476 IN UINT64 Attributes
,
1477 IN OUT UINT64
*ResourceBase
,
1478 IN OUT UINT64
*ResourceLength
1481 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1483 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1485 if ((Attributes
& (~RootBridge
->Supports
)) != 0) {
1486 return EFI_UNSUPPORTED
;
1489 RootBridge
->Attributes
= Attributes
;
1494 Retrieves the current resource settings of this PCI root bridge in the form
1495 of a set of ACPI 2.0 resource descriptors.
1497 There are only two resource descriptor types from the ACPI Specification that
1498 may be used to describe the current resources allocated to a PCI root bridge.
1499 These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1),
1500 and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space
1501 Descriptor can describe memory, I/O, and bus number ranges for dynamic or
1502 fixed resources. The configuration of a PCI root bridge is described with one
1503 or more QWORD Address Space Descriptors followed by an End Tag.
1505 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1506 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that
1507 describe the current configuration of this PCI root
1508 bridge. The storage for the ACPI 2.0 resource
1509 descriptors is allocated by this function. The
1510 caller must treat the return buffer as read-only
1511 data, and the buffer must not be freed by the
1514 @retval EFI_SUCCESS The current configuration of this PCI root bridge
1515 was returned in Resources.
1516 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
1517 could not be retrieved.
1521 RootBridgeIoConfiguration (
1522 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1523 OUT VOID
**Resources
1526 PCI_RESOURCE_TYPE Index
;
1527 PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
;
1528 PCI_RES_NODE
*ResAllocNode
;
1529 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptor
;
1530 EFI_ACPI_END_TAG_DESCRIPTOR
*End
;
1533 // Get this instance of the Root Bridge.
1535 RootBridge
= ROOT_BRIDGE_FROM_THIS (This
);
1537 RootBridge
->ConfigBuffer
,
1538 TypeMax
* sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
)
1540 Descriptor
= RootBridge
->ConfigBuffer
;
1541 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
1543 ResAllocNode
= &RootBridge
->ResAllocNode
[Index
];
1545 if (ResAllocNode
->Status
!= ResAllocated
) {
1549 Descriptor
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1550 Descriptor
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1551 Descriptor
->AddrRangeMin
= ResAllocNode
->Base
;
1552 Descriptor
->AddrRangeMax
= ResAllocNode
->Base
+ ResAllocNode
->Length
- 1;
1553 Descriptor
->AddrLen
= ResAllocNode
->Length
;
1554 switch (ResAllocNode
->Type
) {
1557 Descriptor
->ResType
= ACPI_ADDRESS_SPACE_TYPE_IO
;
1561 Descriptor
->SpecificFlag
= EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
;
1563 Descriptor
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1564 Descriptor
->AddrSpaceGranularity
= 32;
1568 Descriptor
->SpecificFlag
= EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
;
1570 Descriptor
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1571 Descriptor
->AddrSpaceGranularity
= 64;
1575 Descriptor
->ResType
= ACPI_ADDRESS_SPACE_TYPE_BUS
;
1585 // Terminate the entries.
1587 End
= (EFI_ACPI_END_TAG_DESCRIPTOR
*) Descriptor
;
1588 End
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
1589 End
->Checksum
= 0x0;
1591 *Resources
= RootBridge
->ConfigBuffer
;