2 PCI Root Bridge Io Protocol implementation
4 Copyright (C) 2015, Red Hat, Inc.
5 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciHostBridge.h"
21 RESOURCE_CONFIGURATION mConfigurationTemplate
= {
23 { 0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0 }, // SpaceDesc[TypeIo]
24 { 0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0 }, // SpaceDesc[TypeMem32]
25 { 0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0 }, // SpaceDesc[TypePMem32]
26 { 0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0 }, // SpaceDesc[TypeMem64]
27 { 0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0 }, // SpaceDesc[TypePMem64]
28 { 0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0 } // SpaceDesc[TypeBus]
30 { 0x79, 0 } // EndDesc
34 // Protocol Member Function Prototypes
38 Polls an address in memory mapped I/O space until an exit condition is met,
41 This function provides a standard way to poll a PCI memory location. A PCI
42 memory read operation is performed at the PCI memory address specified by
43 Address for the width specified by Width. The result of this PCI memory read
44 operation is stored in Result. This PCI memory read operation is repeated
45 until either a timeout of Delay 100 ns units has expired, or (Result & Mask)
48 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
50 @param[in] Width Signifies the width of the memory operations.
52 @param[in] Address The base address of the memory operations. The caller
53 is responsible for aligning Address if required.
55 @param[in] Mask Mask used for the polling criteria. Bytes above Width
56 in Mask are ignored. The bits in the bytes below Width
57 which are zero in Mask are ignored when polling the
60 @param[in] Value The comparison value used for the polling exit
63 @param[in] Delay The number of 100 ns units to poll. Note that timer
64 available may be of poorer granularity.
66 @param[out] Result Pointer to the last value read from the memory
69 @retval EFI_SUCCESS The last data returned from the access matched
70 the poll exit criteria.
72 @retval EFI_INVALID_PARAMETER Width is invalid.
74 @retval EFI_INVALID_PARAMETER Result is NULL.
76 @retval EFI_TIMEOUT Delay expired before a match occurred.
78 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
84 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
85 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
94 Reads from the I/O space of a PCI Root Bridge. Returns when either the
95 polling exit criteria is satisfied or after a defined duration.
97 This function provides a standard way to poll a PCI I/O location. A PCI I/O
98 read operation is performed at the PCI I/O address specified by Address for
99 the width specified by Width. The result of this PCI I/O read operation is
100 stored in Result. This PCI I/O read operation is repeated until either a
101 timeout of Delay 100 ns units has expired, or (Result & Mask) is equal to
104 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
106 @param[in] Width Signifies the width of the I/O operations.
108 @param[in] Address The base address of the I/O operations. The caller is
109 responsible for aligning Address if required.
111 @param[in] Mask Mask used for the polling criteria. Bytes above Width in
112 Mask are ignored. The bits in the bytes below Width
113 which are zero in Mask are ignored when polling the I/O
116 @param[in] Value The comparison value used for the polling exit criteria.
119 @param[in] Delay The number of 100 ns units to poll. Note that timer
120 available may be of poorer granularity.
122 @param[out] Result Pointer to the last value read from the memory location.
124 @retval EFI_SUCCESS The last data returned from the access matched
125 the poll exit criteria.
127 @retval EFI_INVALID_PARAMETER Width is invalid.
129 @retval EFI_INVALID_PARAMETER Result is NULL.
131 @retval EFI_TIMEOUT Delay expired before a match occurred.
133 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
139 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
140 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
149 Enables a PCI driver to access PCI controller registers in the PCI root
152 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
153 controller registers in the PCI root bridge memory space.
154 The memory operations are carried out exactly as requested. The caller is
155 responsible for satisfying any alignment and memory width restrictions that a
156 PCI Root Bridge on a platform might require.
158 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
160 @param[in] Width Signifies the width of the memory operation.
162 @param[in] Address The base address of the memory operation. The caller
163 is responsible for aligning the Address if required.
165 @param[in] Count The number of memory operations to perform. Bytes
166 moved is Width size * Count, starting at Address.
168 @param[out] Buffer For read operations, the destination buffer to store
169 the results. For write operations, the source buffer
172 @retval EFI_SUCCESS The data was read from or written to the PCI
175 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
177 @retval EFI_INVALID_PARAMETER Buffer is NULL.
179 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
184 RootBridgeIoMemRead (
185 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
186 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
193 Enables a PCI driver to access PCI controller registers in the PCI root
196 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
197 controller registers in the PCI root bridge memory space.
198 The memory operations are carried out exactly as requested. The caller is
199 responsible for satisfying any alignment and memory width restrictions that a
200 PCI Root Bridge on a platform might require.
202 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
204 @param[in] Width Signifies the width of the memory operation.
206 @param[in] Address The base address of the memory operation. The caller
207 is responsible for aligning the Address if required.
209 @param[in] Count The number of memory operations to perform. Bytes
210 moved is Width size * Count, starting at Address.
212 @param[in] Buffer For read operations, the destination buffer to store
213 the results. For write operations, the source buffer
216 @retval EFI_SUCCESS The data was read from or written to the PCI
219 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
221 @retval EFI_INVALID_PARAMETER Buffer is NULL.
223 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
228 RootBridgeIoMemWrite (
229 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
230 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
237 Enables a PCI driver to access PCI controller registers in the PCI root
240 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
242 @param[in] Width Signifies the width of the memory operations.
244 @param[in] UserAddress The base address of the I/O operation. The caller is
245 responsible for aligning the Address if required.
247 @param[in] Count The number of I/O operations to perform. Bytes moved
248 is Width size * Count, starting at Address.
250 @param[out] UserBuffer For read operations, the destination buffer to store
251 the results. For write operations, the source buffer
255 @retval EFI_SUCCESS The data was read from or written to the PCI
258 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
260 @retval EFI_INVALID_PARAMETER Buffer is NULL.
262 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
268 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
269 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
270 IN UINT64 UserAddress
,
276 Enables a PCI driver to access PCI controller registers in the PCI root
279 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
281 @param[in] Width Signifies the width of the memory operations.
283 @param[in] UserAddress The base address of the I/O operation. The caller is
284 responsible for aligning the Address if required.
286 @param[in] Count The number of I/O operations to perform. Bytes moved
287 is Width size * Count, starting at Address.
289 @param[in] UserBuffer For read operations, the destination buffer to store
290 the results. For write operations, the source buffer
294 @retval EFI_SUCCESS The data was read from or written to the PCI
297 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
299 @retval EFI_INVALID_PARAMETER Buffer is NULL.
301 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
306 RootBridgeIoIoWrite (
307 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
308 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
309 IN UINT64 UserAddress
,
315 Enables a PCI driver to copy one region of PCI root bridge memory space to
316 another region of PCI root bridge memory space.
318 The CopyMem() function enables a PCI driver to copy one region of PCI root
319 bridge memory space to another region of PCI root bridge memory space. This
320 is especially useful for video scroll operation on a memory mapped video
322 The memory operations are carried out exactly as requested. The caller is
323 responsible for satisfying any alignment and memory width restrictions that a
324 PCI root bridge on a platform might require.
326 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
329 @param[in] Width Signifies the width of the memory operations.
331 @param[in] DestAddress The destination address of the memory operation. The
332 caller is responsible for aligning the DestAddress if
335 @param[in] SrcAddress The source address of the memory operation. The caller
336 is responsible for aligning the SrcAddress if
339 @param[in] Count The number of memory operations to perform. Bytes
340 moved is Width size * Count, starting at DestAddress
344 @retval EFI_SUCCESS The data was copied from one memory region
345 to another memory region.
347 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
349 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
354 RootBridgeIoCopyMem (
355 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
356 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
357 IN UINT64 DestAddress
,
358 IN UINT64 SrcAddress
,
363 Enables a PCI driver to access PCI controller registers in a PCI root
364 bridge's configuration space.
366 The Pci.Read() and Pci.Write() functions enable a driver to access PCI
367 configuration registers for a PCI controller.
368 The PCI Configuration operations are carried out exactly as requested. The
369 caller is responsible for any alignment and PCI configuration width issues
370 that a PCI Root Bridge on a platform might require.
372 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
374 @param[in] Width Signifies the width of the memory operations.
376 @param[in] Address The address within the PCI configuration space for the
379 @param[in] Count The number of PCI configuration operations to perform.
380 Bytes moved is Width size * Count, starting at
383 @param[out] Buffer For read operations, the destination buffer to store
384 the results. For write operations, the source buffer
388 @retval EFI_SUCCESS The data was read from or written to the PCI
391 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
393 @retval EFI_INVALID_PARAMETER Buffer is NULL.
395 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
400 RootBridgeIoPciRead (
401 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
402 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
409 Enables a PCI driver to access PCI controller registers in a PCI root
410 bridge's configuration space.
412 The Pci.Read() and Pci.Write() functions enable a driver to access PCI
413 configuration registers for a PCI controller.
414 The PCI Configuration operations are carried out exactly as requested. The
415 caller is responsible for any alignment and PCI configuration width issues
416 that a PCI Root Bridge on a platform might require.
418 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
420 @param[in] Width Signifies the width of the memory operations.
422 @param[in] Address The address within the PCI configuration space for the
425 @param[in] Count The number of PCI configuration operations to perform.
426 Bytes moved is Width size * Count, starting at
429 @param[in] Buffer For read operations, the destination buffer to store
430 the results. For write operations, the source buffer
434 @retval EFI_SUCCESS The data was read from or written to the PCI
437 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
439 @retval EFI_INVALID_PARAMETER Buffer is NULL.
441 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
446 RootBridgeIoPciWrite (
447 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
448 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
455 Provides the PCI controller-specific addresses required to access system
456 memory from a DMA bus master.
458 The Map() function provides the PCI controller specific addresses needed to
459 access system memory. This function is used to map system memory for PCI bus
462 @param[in] This A pointer to the
463 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
465 @param[in] Operation Indicates if the bus master is going to read
466 or write to system memory.
468 @param[in] HostAddress The system memory address to map to the PCI
471 @param[in, out] NumberOfBytes On input the number of bytes to map. On
472 output the number of bytes that were mapped.
474 @param[out] DeviceAddress The resulting map address for the bus master
475 PCI controller to use to access the system
476 memory's HostAddress.
478 @param[out] Mapping The value to pass to Unmap() when the bus
479 master DMA operation is complete.
481 @retval EFI_SUCCESS The range was mapped for the returned
484 @retval EFI_INVALID_PARAMETER Operation is invalid.
486 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
488 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.
490 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.
492 @retval EFI_INVALID_PARAMETER Mapping is NULL.
494 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
497 @retval EFI_DEVICE_ERROR The system hardware could not map the
500 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
506 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
507 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
508 IN VOID
*HostAddress
,
509 IN OUT UINTN
*NumberOfBytes
,
510 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
515 Completes the Map() operation and releases any corresponding resources.
517 The Unmap() function completes the Map() operation and releases any
518 corresponding resources.
519 If the operation was an EfiPciOperationBusMasterWrite or
520 EfiPciOperationBusMasterWrite64, the data is committed to the target system
522 Any resources used for the mapping are freed.
524 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
526 @param[in] Mapping The mapping value returned from Map().
528 @retval EFI_SUCCESS The range was unmapped.
530 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
533 @retval EFI_DEVICE_ERROR The data was not committed to the target
539 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
544 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer
545 or EfiPciOperationBusMasterCommonBuffer64 mapping.
547 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
549 @param Type This parameter is not used and must be ignored.
551 @param MemoryType The type of memory to allocate, EfiBootServicesData or
552 EfiRuntimeServicesData.
554 @param Pages The number of pages to allocate.
556 @param HostAddress A pointer to store the base system memory address of the
559 @param Attributes The requested bit mask of attributes for the allocated
560 range. Only the attributes
561 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,
562 EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and
563 EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this
566 @retval EFI_SUCCESS The requested memory pages were allocated.
568 @retval EFI_INVALID_PARAMETER MemoryType is invalid.
570 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
572 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
573 attribute bits are MEMORY_WRITE_COMBINE,
574 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
576 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
580 RootBridgeIoAllocateBuffer (
581 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
582 IN EFI_ALLOCATE_TYPE Type
,
583 IN EFI_MEMORY_TYPE MemoryType
,
585 OUT VOID
**HostAddress
,
590 Frees memory that was allocated with AllocateBuffer().
592 The FreeBuffer() function frees memory that was allocated with
595 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
597 @param Pages The number of pages to free.
599 @param HostAddress The base system memory address of the allocated range.
601 @retval EFI_SUCCESS The requested memory pages were freed.
603 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
604 Pages was not allocated with AllocateBuffer().
608 RootBridgeIoFreeBuffer (
609 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
611 OUT VOID
*HostAddress
615 Flushes all PCI posted write transactions from a PCI host bridge to system
618 The Flush() function flushes any PCI posted write transactions from a PCI
619 host bridge to system memory. Posted write transactions are generated by PCI
620 bus masters when they perform write transactions to target addresses in
622 This function does not flush posted write transactions from any PCI bridges.
623 A PCI controller specific action must be taken to guarantee that the posted
624 write transactions have been flushed from the PCI controller and from all the
625 PCI bridges into the PCI host bridge. This is typically done with a PCI read
626 transaction from the PCI controller prior to calling Flush().
628 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
630 @retval EFI_SUCCESS The PCI posted write transactions were flushed
631 from the PCI host bridge to system memory.
633 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed
634 from the PCI host bridge due to a hardware error.
639 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
643 Gets the attributes that a PCI root bridge supports setting with
644 SetAttributes(), and the attributes that a PCI root bridge is currently
647 The GetAttributes() function returns the mask of attributes that this PCI
648 root bridge supports and the mask of attributes that the PCI root bridge is
651 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
653 @param Supported A pointer to the mask of attributes that this PCI root
654 bridge supports setting with SetAttributes().
656 @param Attributes A pointer to the mask of attributes that this PCI root
657 bridge is currently using.
660 @retval EFI_SUCCESS If Supports is not NULL, then the attributes
661 that the PCI root bridge supports is returned
662 in Supports. If Attributes is not NULL, then
663 the attributes that the PCI root bridge is
664 currently using is returned in Attributes.
666 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
670 RootBridgeIoGetAttributes (
671 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
672 OUT UINT64
*Supported
,
673 OUT UINT64
*Attributes
677 Sets attributes for a resource range on a PCI root bridge.
679 The SetAttributes() function sets the attributes specified in Attributes for
680 the PCI root bridge on the resource range specified by ResourceBase and
681 ResourceLength. Since the granularity of setting these attributes may vary
682 from resource type to resource type, and from platform to platform, the
683 actual resource range and the one passed in by the caller may differ. As a
684 result, this function may set the attributes specified by Attributes on a
685 larger resource range than the caller requested. The actual range is returned
686 in ResourceBase and ResourceLength. The caller is responsible for verifying
687 that the actual range for which the attributes were set is acceptable.
689 @param[in] This A pointer to the
690 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
692 @param[in] Attributes The mask of attributes to set. If the
693 attribute bit MEMORY_WRITE_COMBINE,
694 MEMORY_CACHED, or MEMORY_DISABLE is set,
695 then the resource range is specified by
696 ResourceBase and ResourceLength. If
697 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
698 MEMORY_DISABLE are not set, then
699 ResourceBase and ResourceLength are ignored,
702 @param[in, out] ResourceBase A pointer to the base address of the
703 resource range to be modified by the
704 attributes specified by Attributes.
706 @param[in, out] ResourceLength A pointer to the length of the resource
707 range to be modified by the attributes
708 specified by Attributes.
710 @retval EFI_SUCCESS The current configuration of this PCI root bridge
711 was returned in Resources.
713 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
714 could not be retrieved.
716 @retval EFI_INVALID_PARAMETER Invalid pointer of
717 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
722 RootBridgeIoSetAttributes (
723 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
724 IN UINT64 Attributes
,
725 IN OUT UINT64
*ResourceBase
,
726 IN OUT UINT64
*ResourceLength
730 Retrieves the current resource settings of this PCI root bridge in the form
731 of a set of ACPI 2.0 resource descriptors.
733 There are only two resource descriptor types from the ACPI Specification that
734 may be used to describe the current resources allocated to a PCI root bridge.
735 These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1),
736 and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space
737 Descriptor can describe memory, I/O, and bus number ranges for dynamic or
738 fixed resources. The configuration of a PCI root bridge is described with one
739 or more QWORD Address Space Descriptors followed by an End Tag.
741 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
743 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that
744 describe the current configuration of this PCI root
745 bridge. The storage for the ACPI 2.0 resource
746 descriptors is allocated by this function. The
747 caller must treat the return buffer as read-only
748 data, and the buffer must not be freed by the
751 @retval EFI_SUCCESS The current configuration of this PCI root bridge
752 was returned in Resources.
754 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
755 could not be retrieved.
757 @retval EFI_INVALID_PARAMETER Invalid pointer of
758 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
762 RootBridgeIoConfiguration (
763 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
768 // Memory Controller Pci Root Bridge Io Module Variables
770 EFI_METRONOME_ARCH_PROTOCOL
*mMetronome
;
773 // Lookup table for increment values based on transfer widths
775 UINT8 mInStride
[] = {
776 1, // EfiPciWidthUint8
777 2, // EfiPciWidthUint16
778 4, // EfiPciWidthUint32
779 8, // EfiPciWidthUint64
780 0, // EfiPciWidthFifoUint8
781 0, // EfiPciWidthFifoUint16
782 0, // EfiPciWidthFifoUint32
783 0, // EfiPciWidthFifoUint64
784 1, // EfiPciWidthFillUint8
785 2, // EfiPciWidthFillUint16
786 4, // EfiPciWidthFillUint32
787 8 // EfiPciWidthFillUint64
791 // Lookup table for increment values based on transfer widths
793 UINT8 mOutStride
[] = {
794 1, // EfiPciWidthUint8
795 2, // EfiPciWidthUint16
796 4, // EfiPciWidthUint32
797 8, // EfiPciWidthUint64
798 1, // EfiPciWidthFifoUint8
799 2, // EfiPciWidthFifoUint16
800 4, // EfiPciWidthFifoUint32
801 8, // EfiPciWidthFifoUint64
802 0, // EfiPciWidthFillUint8
803 0, // EfiPciWidthFillUint16
804 0, // EfiPciWidthFillUint32
805 0 // EfiPciWidthFillUint64
809 Construct the Pci Root Bridge Io protocol
811 @param Protocol Point to protocol instance
813 @param HostBridgeHandle Handle of host bridge
815 @param Attri Attribute of host bridge
817 @param ResAperture ResourceAperture for host bridge
819 @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
822 RootBridgeConstructor (
823 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*Protocol
,
824 IN EFI_HANDLE HostBridgeHandle
,
826 IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE
*ResAperture
830 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
831 PCI_RESOURCE_TYPE Index
;
833 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol
);
836 // The host to pci bridge, the host memory and io addresses are
837 // direct mapped to pci addresses, so no need translate, set bases to 0.
839 PrivateData
->MemBase
= ResAperture
->MemBase
;
840 PrivateData
->IoBase
= ResAperture
->IoBase
;
843 // The host bridge only supports 32bit addressing for memory
844 // and standard IA32 16bit io
846 PrivateData
->MemLimit
= ResAperture
->MemLimit
;
847 PrivateData
->IoLimit
= ResAperture
->IoLimit
;
850 // Bus Aperture for this Root Bridge (Possible Range)
852 PrivateData
->BusBase
= ResAperture
->BusBase
;
853 PrivateData
->BusLimit
= ResAperture
->BusLimit
;
856 // Specific for this chipset
858 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
859 PrivateData
->ResAllocNode
[Index
].Type
= Index
;
860 PrivateData
->ResAllocNode
[Index
].Base
= 0;
861 PrivateData
->ResAllocNode
[Index
].Length
= 0;
862 PrivateData
->ResAllocNode
[Index
].Status
= ResNone
;
865 PrivateData
->RootBridgeAttrib
= Attri
;
867 PrivateData
->Supports
= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
|
868 EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
|
869 EFI_PCI_ATTRIBUTE_ISA_IO_16
|
870 EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO
|
871 EFI_PCI_ATTRIBUTE_VGA_MEMORY
|
872 EFI_PCI_ATTRIBUTE_VGA_IO_16
|
873 EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
;
874 PrivateData
->Attributes
= PrivateData
->Supports
;
876 Protocol
->ParentHandle
= HostBridgeHandle
;
878 Protocol
->PollMem
= RootBridgeIoPollMem
;
879 Protocol
->PollIo
= RootBridgeIoPollIo
;
881 Protocol
->Mem
.Read
= RootBridgeIoMemRead
;
882 Protocol
->Mem
.Write
= RootBridgeIoMemWrite
;
884 Protocol
->Io
.Read
= RootBridgeIoIoRead
;
885 Protocol
->Io
.Write
= RootBridgeIoIoWrite
;
887 Protocol
->CopyMem
= RootBridgeIoCopyMem
;
889 Protocol
->Pci
.Read
= RootBridgeIoPciRead
;
890 Protocol
->Pci
.Write
= RootBridgeIoPciWrite
;
892 Protocol
->Map
= RootBridgeIoMap
;
893 Protocol
->Unmap
= RootBridgeIoUnmap
;
895 Protocol
->AllocateBuffer
= RootBridgeIoAllocateBuffer
;
896 Protocol
->FreeBuffer
= RootBridgeIoFreeBuffer
;
898 Protocol
->Flush
= RootBridgeIoFlush
;
900 Protocol
->GetAttributes
= RootBridgeIoGetAttributes
;
901 Protocol
->SetAttributes
= RootBridgeIoSetAttributes
;
903 Protocol
->Configuration
= RootBridgeIoConfiguration
;
905 Protocol
->SegmentNumber
= 0;
907 Status
= gBS
->LocateProtocol (&gEfiMetronomeArchProtocolGuid
, NULL
,
908 (VOID
**)&mMetronome
);
909 ASSERT_EFI_ERROR (Status
);
915 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.
917 The I/O operations are carried out exactly as requested. The caller is
918 responsible for satisfying any alignment and I/O width restrictions that a PI
919 System on a platform might require. For example on some platforms, width
920 requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other
921 hand, will be handled by the driver.
923 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
925 @param[in] OperationType I/O operation type: IO/MMIO/PCI.
927 @param[in] Width Signifies the width of the I/O or Memory operation.
929 @param[in] Address The base address of the I/O operation.
931 @param[in] Count The number of I/O operations to perform. The number
932 of bytes moved is Width size * Count, starting at
935 @param[in] Buffer For read operations, the destination buffer to
936 store the results. For write operations, the source
937 buffer from which to write data.
939 @retval EFI_SUCCESS The parameters for this request pass the
942 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.
944 @retval EFI_INVALID_PARAMETER Buffer is NULL.
946 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.
948 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
949 and Count is not valid for this PI system.
952 RootBridgeIoCheckParameter (
953 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
954 IN OPERATION_TYPE OperationType
,
955 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
961 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
962 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*PciRbAddr
;
968 // Check to see if Buffer is NULL
970 if (Buffer
== NULL
) {
971 return EFI_INVALID_PARAMETER
;
975 // Check to see if Width is in the valid range
977 if ((UINT32
)Width
>= EfiPciWidthMaximum
) {
978 return EFI_INVALID_PARAMETER
;
982 // For FIFO type, the target address won't increase during the access,
983 // so treat Count as 1
985 if (Width
>= EfiPciWidthFifoUint8
&& Width
<= EfiPciWidthFifoUint64
) {
990 // Check to see if Width is in the valid range for I/O Port operations
992 Width
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
993 if ((OperationType
!= MemOperation
) && (Width
== EfiPciWidthUint64
)) {
995 return EFI_INVALID_PARAMETER
;
999 // Check to see if Address is aligned
1001 if ((Address
& (UINT64
)(mInStride
[Width
] - 1)) != 0) {
1002 return EFI_UNSUPPORTED
;
1005 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This
);
1008 // Check to see if any address associated with this transfer exceeds the
1009 // maximum allowed address. The maximum address implied by the parameters
1010 // passed in is Address + Size * Count. If the following condition is met,
1011 // then the transfer is not supported.
1013 // Address + Size * Count > Limit + 1
1015 // Since Limit can be the maximum integer value supported by the CPU and
1016 // Count can also be the maximum integer value supported by the CPU, this
1017 // range check must be adjusted to avoid all oveflow conditions.
1019 // The following form of the range check is equivalent but assumes that
1020 // Limit is of the form (2^n - 1).
1022 if (OperationType
== IoOperation
) {
1023 Base
= PrivateData
->IoBase
;
1024 Limit
= PrivateData
->IoLimit
;
1025 } else if (OperationType
== MemOperation
) {
1026 Base
= PrivateData
->MemBase
;
1027 Limit
= PrivateData
->MemLimit
;
1029 PciRbAddr
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*) &Address
;
1030 if (PciRbAddr
->Bus
< PrivateData
->BusBase
||
1031 PciRbAddr
->Bus
> PrivateData
->BusLimit
) {
1032 return EFI_INVALID_PARAMETER
;
1035 if (PciRbAddr
->Device
> MAX_PCI_DEVICE_NUMBER
||
1036 PciRbAddr
->Function
> MAX_PCI_FUNCTION_NUMBER
) {
1037 return EFI_INVALID_PARAMETER
;
1040 if (PciRbAddr
->ExtendedRegister
!= 0) {
1041 Address
= PciRbAddr
->ExtendedRegister
;
1043 Address
= PciRbAddr
->Register
;
1046 Limit
= MAX_PCI_REG_ADDRESS
;
1049 if (Address
< Base
) {
1050 return EFI_INVALID_PARAMETER
;
1054 if (Address
> Limit
) {
1055 return EFI_UNSUPPORTED
;
1058 MaxCount
= RShiftU64 (Limit
, Width
);
1059 if (MaxCount
< (Count
- 1)) {
1060 return EFI_UNSUPPORTED
;
1062 if (Address
> LShiftU64 (MaxCount
- Count
+ 1, Width
)) {
1063 return EFI_UNSUPPORTED
;
1071 Internal help function for read and write memory space.
1073 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1075 @param[in] Write Switch value for Read or Write.
1077 @param[in] Width Signifies the width of the memory operations.
1079 @param[in] UserAddress The address within the PCI configuration space for
1082 @param[in] Count The number of PCI configuration operations to
1083 perform. Bytes moved is Width size * Count,
1084 starting at Address.
1086 @param[in, out] UserBuffer For read operations, the destination buffer to
1087 store the results. For write operations, the
1088 source buffer to write data from.
1090 @retval EFI_SUCCESS The data was read from or written to the PCI
1093 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1095 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1097 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1102 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1104 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1113 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth
;
1116 Status
= RootBridgeIoCheckParameter (This
, MemOperation
, Width
, Address
,
1118 if (EFI_ERROR (Status
)) {
1122 InStride
= mInStride
[Width
];
1123 OutStride
= mOutStride
[Width
];
1124 OperationWidth
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
1125 for (Uint8Buffer
= Buffer
;
1127 Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
1129 switch (OperationWidth
) {
1130 case EfiPciWidthUint8
:
1131 MmioWrite8 ((UINTN
)Address
, *Uint8Buffer
);
1133 case EfiPciWidthUint16
:
1134 MmioWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
1136 case EfiPciWidthUint32
:
1137 MmioWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
1139 case EfiPciWidthUint64
:
1140 MmioWrite64 ((UINTN
)Address
, *((UINT64
*)Uint8Buffer
));
1144 // The RootBridgeIoCheckParameter call above will ensure that this
1145 // path is not taken.
1151 switch (OperationWidth
) {
1152 case EfiPciWidthUint8
:
1153 *Uint8Buffer
= MmioRead8 ((UINTN
)Address
);
1155 case EfiPciWidthUint16
:
1156 *((UINT16
*)Uint8Buffer
) = MmioRead16 ((UINTN
)Address
);
1158 case EfiPciWidthUint32
:
1159 *((UINT32
*)Uint8Buffer
) = MmioRead32 ((UINTN
)Address
);
1161 case EfiPciWidthUint64
:
1162 *((UINT64
*)Uint8Buffer
) = MmioRead64 ((UINTN
)Address
);
1166 // The RootBridgeIoCheckParameter call above will ensure that this
1167 // path is not taken.
1178 Internal help function for read and write IO space.
1180 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1182 @param[in] Write Switch value for Read or Write.
1184 @param[in] Width Signifies the width of the memory operations.
1186 @param[in] UserAddress The address within the PCI configuration space for
1189 @param[in] Count The number of PCI configuration operations to
1190 perform. Bytes moved is Width size * Count,
1191 starting at Address.
1193 @param[in, out] UserBuffer For read operations, the destination buffer to
1194 store the results. For write operations, the
1195 source buffer to write data from.
1198 @retval EFI_SUCCESS The data was read from or written to the PCI
1201 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1203 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1205 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1210 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1212 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1221 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth
;
1224 Status
= RootBridgeIoCheckParameter (This
, IoOperation
, Width
, Address
,
1226 if (EFI_ERROR (Status
)) {
1230 InStride
= mInStride
[Width
];
1231 OutStride
= mOutStride
[Width
];
1232 OperationWidth
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
1234 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
1235 if (InStride
== 0) {
1237 switch (OperationWidth
) {
1238 case EfiPciWidthUint8
:
1239 IoWriteFifo8 ((UINTN
) Address
, Count
, Buffer
);
1241 case EfiPciWidthUint16
:
1242 IoWriteFifo16 ((UINTN
) Address
, Count
, Buffer
);
1244 case EfiPciWidthUint32
:
1245 IoWriteFifo32 ((UINTN
) Address
, Count
, Buffer
);
1249 // The RootBridgeIoCheckParameter call above will ensure that this
1250 // path is not taken.
1256 switch (OperationWidth
) {
1257 case EfiPciWidthUint8
:
1258 IoReadFifo8 ((UINTN
) Address
, Count
, Buffer
);
1260 case EfiPciWidthUint16
:
1261 IoReadFifo16 ((UINTN
) Address
, Count
, Buffer
);
1263 case EfiPciWidthUint32
:
1264 IoReadFifo32 ((UINTN
) Address
, Count
, Buffer
);
1268 // The RootBridgeIoCheckParameter call above will ensure that this
1269 // path is not taken.
1278 for (Uint8Buffer
= Buffer
;
1280 Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
1282 switch (OperationWidth
) {
1283 case EfiPciWidthUint8
:
1284 IoWrite8 ((UINTN
)Address
, *Uint8Buffer
);
1286 case EfiPciWidthUint16
:
1287 IoWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
1289 case EfiPciWidthUint32
:
1290 IoWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
1294 // The RootBridgeIoCheckParameter call above will ensure that this
1295 // path is not taken.
1301 switch (OperationWidth
) {
1302 case EfiPciWidthUint8
:
1303 *Uint8Buffer
= IoRead8 ((UINTN
)Address
);
1305 case EfiPciWidthUint16
:
1306 *((UINT16
*)Uint8Buffer
) = IoRead16 ((UINTN
)Address
);
1308 case EfiPciWidthUint32
:
1309 *((UINT32
*)Uint8Buffer
) = IoRead32 ((UINTN
)Address
);
1313 // The RootBridgeIoCheckParameter call above will ensure that this
1314 // path is not taken.
1325 Internal help function for read and write PCI configuration space.
1327 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1329 @param[in] Write Switch value for Read or Write.
1331 @param[in] Width Signifies the width of the memory operations.
1333 @param[in] UserAddress The address within the PCI configuration space for
1336 @param[in] Count The number of PCI configuration operations to
1337 perform. Bytes moved is Width size * Count,
1338 starting at Address.
1340 @param[in, out] UserBuffer For read operations, the destination buffer to
1341 store the results. For write operations, the
1342 source buffer to write data from.
1345 @retval EFI_SUCCESS The data was read from or written to the PCI
1348 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1350 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1352 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1357 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1359 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1368 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth
;
1370 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*PciRbAddr
;
1373 Status
= RootBridgeIoCheckParameter (This
, PciOperation
, Width
, Address
,
1375 if (EFI_ERROR (Status
)) {
1379 PciRbAddr
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS
*) &Address
;
1381 PcieRegAddr
= (UINTN
) PCI_LIB_ADDRESS (
1384 PciRbAddr
->Function
,
1385 (PciRbAddr
->ExtendedRegister
!= 0) ? \
1386 PciRbAddr
->ExtendedRegister
:
1390 InStride
= mInStride
[Width
];
1391 OutStride
= mOutStride
[Width
];
1392 OperationWidth
= (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) (Width
& 0x03);
1393 for (Uint8Buffer
= Buffer
;
1395 PcieRegAddr
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
1397 switch (OperationWidth
) {
1398 case EfiPciWidthUint8
:
1399 PciWrite8 (PcieRegAddr
, *Uint8Buffer
);
1401 case EfiPciWidthUint16
:
1402 PciWrite16 (PcieRegAddr
, *((UINT16
*)Uint8Buffer
));
1404 case EfiPciWidthUint32
:
1405 PciWrite32 (PcieRegAddr
, *((UINT32
*)Uint8Buffer
));
1409 // The RootBridgeIoCheckParameter call above will ensure that this
1410 // path is not taken.
1416 switch (OperationWidth
) {
1417 case EfiPciWidthUint8
:
1418 *Uint8Buffer
= PciRead8 (PcieRegAddr
);
1420 case EfiPciWidthUint16
:
1421 *((UINT16
*)Uint8Buffer
) = PciRead16 (PcieRegAddr
);
1423 case EfiPciWidthUint32
:
1424 *((UINT32
*)Uint8Buffer
) = PciRead32 (PcieRegAddr
);
1428 // The RootBridgeIoCheckParameter call above will ensure that this
1429 // path is not taken.
1441 Polls an address in memory mapped I/O space until an exit condition is met,
1442 or a timeout occurs.
1444 This function provides a standard way to poll a PCI memory location. A PCI
1445 memory read operation is performed at the PCI memory address specified by
1446 Address for the width specified by Width. The result of this PCI memory read
1447 operation is stored in Result. This PCI memory read operation is repeated
1448 until either a timeout of Delay 100 ns units has expired, or (Result & Mask)
1451 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1453 @param[in] Width Signifies the width of the memory operations.
1455 @param[in] Address The base address of the memory operations. The caller
1456 is responsible for aligning Address if required.
1458 @param[in] Mask Mask used for the polling criteria. Bytes above Width
1459 in Mask are ignored. The bits in the bytes below Width
1460 which are zero in Mask are ignored when polling the
1463 @param[in] Value The comparison value used for the polling exit
1466 @param[in] Delay The number of 100 ns units to poll. Note that timer
1467 available may be of poorer granularity.
1469 @param[out] Result Pointer to the last value read from the memory
1472 @retval EFI_SUCCESS The last data returned from the access matched
1473 the poll exit criteria.
1475 @retval EFI_INVALID_PARAMETER Width is invalid.
1477 @retval EFI_INVALID_PARAMETER Result is NULL.
1479 @retval EFI_TIMEOUT Delay expired before a match occurred.
1481 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1486 RootBridgeIoPollMem (
1487 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1488 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1497 UINT64 NumberOfTicks
;
1500 if (Result
== NULL
) {
1501 return EFI_INVALID_PARAMETER
;
1504 if ((UINT32
)Width
> EfiPciWidthUint64
) {
1505 return EFI_INVALID_PARAMETER
;
1509 // No matter what, always do a single poll.
1511 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
1512 if (EFI_ERROR (Status
)) {
1515 if ((*Result
& Mask
) == Value
) {
1525 // Determine the proper # of metronome ticks to wait for polling the
1526 // location. The nuber of ticks is Roundup (Delay /
1527 // mMetronome->TickPeriod)+1
1528 // The "+1" to account for the possibility of the first tick being short
1529 // because we started in the middle of a tick.
1531 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
1532 // protocol definition is updated.
1534 NumberOfTicks
= DivU64x32Remainder (Delay
, (UINT32
) mMetronome
->TickPeriod
,
1536 if (Remainder
!= 0) {
1541 while (NumberOfTicks
!= 0) {
1543 mMetronome
->WaitForTick (mMetronome
, 1);
1545 Status
= This
->Mem
.Read (This
, Width
, Address
, 1, Result
);
1546 if (EFI_ERROR (Status
)) {
1550 if ((*Result
& Mask
) == Value
) {
1561 Reads from the I/O space of a PCI Root Bridge. Returns when either the
1562 polling exit criteria is satisfied or after a defined duration.
1564 This function provides a standard way to poll a PCI I/O location. A PCI I/O
1565 read operation is performed at the PCI I/O address specified by Address for
1566 the width specified by Width.
1567 The result of this PCI I/O read operation is stored in Result. This PCI I/O
1568 read operation is repeated until either a timeout of Delay 100 ns units has
1569 expired, or (Result & Mask) is equal to Value.
1571 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1573 @param[in] Width Signifies the width of the I/O operations.
1575 @param[in] Address The base address of the I/O operations. The caller is
1576 responsible for aligning Address if required.
1578 @param[in] Mask Mask used for the polling criteria. Bytes above Width in
1579 Mask are ignored. The bits in the bytes below Width
1580 which are zero in Mask are ignored when polling the I/O
1583 @param[in] Value The comparison value used for the polling exit criteria.
1585 @param[in] Delay The number of 100 ns units to poll. Note that timer
1586 available may be of poorer granularity.
1588 @param[out] Result Pointer to the last value read from the memory location.
1590 @retval EFI_SUCCESS The last data returned from the access matched
1591 the poll exit criteria.
1593 @retval EFI_INVALID_PARAMETER Width is invalid.
1595 @retval EFI_INVALID_PARAMETER Result is NULL.
1597 @retval EFI_TIMEOUT Delay expired before a match occurred.
1599 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1604 RootBridgeIoPollIo (
1605 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1606 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1615 UINT64 NumberOfTicks
;
1619 // No matter what, always do a single poll.
1622 if (Result
== NULL
) {
1623 return EFI_INVALID_PARAMETER
;
1626 if ((UINT32
)Width
> EfiPciWidthUint64
) {
1627 return EFI_INVALID_PARAMETER
;
1630 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
1631 if (EFI_ERROR (Status
)) {
1634 if ((*Result
& Mask
) == Value
) {
1644 // Determine the proper # of metronome ticks to wait for polling the
1645 // location. The number of ticks is Roundup (Delay /
1646 // mMetronome->TickPeriod)+1
1647 // The "+1" to account for the possibility of the first tick being short
1648 // because we started in the middle of a tick.
1650 NumberOfTicks
= DivU64x32Remainder (Delay
, (UINT32
)mMetronome
->TickPeriod
,
1652 if (Remainder
!= 0) {
1657 while (NumberOfTicks
!= 0) {
1659 mMetronome
->WaitForTick (mMetronome
, 1);
1661 Status
= This
->Io
.Read (This
, Width
, Address
, 1, Result
);
1662 if (EFI_ERROR (Status
)) {
1666 if ((*Result
& Mask
) == Value
) {
1677 Enables a PCI driver to access PCI controller registers in the PCI root
1678 bridge memory space.
1680 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
1681 controller registers in the PCI root bridge memory space.
1682 The memory operations are carried out exactly as requested. The caller is
1683 responsible for satisfying any alignment and memory width restrictions that a
1684 PCI Root Bridge on a platform might require.
1686 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1688 @param[in] Width Signifies the width of the memory operation.
1690 @param[in] Address The base address of the memory operation. The caller
1691 is responsible for aligning the Address if required.
1693 @param[in] Count The number of memory operations to perform. Bytes
1694 moved is Width size * Count, starting at Address.
1696 @param[out] Buffer For read operations, the destination buffer to store
1697 the results. For write operations, the source buffer
1700 @retval EFI_SUCCESS The data was read from or written to the PCI
1703 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1705 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1707 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1712 RootBridgeIoMemRead (
1713 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1714 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1720 return RootBridgeIoMemRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
1724 Enables a PCI driver to access PCI controller registers in the PCI root
1725 bridge memory space.
1727 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
1728 controller registers in the PCI root bridge memory space.
1729 The memory operations are carried out exactly as requested. The caller is
1730 responsible for satisfying any alignment and memory width restrictions that a
1731 PCI Root Bridge on a platform might require.
1733 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1735 @param[in] Width Signifies the width of the memory operation.
1737 @param[in] Address The base address of the memory operation. The caller
1738 is responsible for aligning the Address if required.
1740 @param[in] Count The number of memory operations to perform. Bytes
1741 moved is Width size * Count, starting at Address.
1743 @param[in] Buffer For read operations, the destination buffer to store
1744 the results. For write operations, the source buffer
1747 @retval EFI_SUCCESS The data was read from or written to the PCI
1750 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1752 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1754 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1759 RootBridgeIoMemWrite (
1760 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1761 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1767 return RootBridgeIoMemRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
1771 Enables a PCI driver to access PCI controller registers in the PCI root
1774 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1776 @param[in] Width Signifies the width of the memory operations.
1778 @param[in] Address The base address of the I/O operation. The caller is
1779 responsible for aligning the Address if required.
1781 @param[in] Count The number of I/O operations to perform. Bytes moved
1782 is Width size * Count, starting at Address.
1784 @param[out] Buffer For read operations, the destination buffer to store
1785 the results. For write operations, the source buffer
1789 @retval EFI_SUCCESS The data was read from or written to the PCI
1792 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1794 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1796 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1801 RootBridgeIoIoRead (
1802 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1803 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1809 return RootBridgeIoIoRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
1813 Enables a PCI driver to access PCI controller registers in the PCI root
1816 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1818 @param[in] Width Signifies the width of the memory operations.
1820 @param[in] Address The base address of the I/O operation. The caller is
1821 responsible for aligning the Address if required.
1823 @param[in] Count The number of I/O operations to perform. Bytes moved
1824 is Width size * Count, starting at Address.
1826 @param[in] Buffer For read operations, the destination buffer to store
1827 the results. For write operations, the source buffer
1830 @retval EFI_SUCCESS The data was read from or written to the PCI
1833 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1835 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1837 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1842 RootBridgeIoIoWrite (
1843 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1844 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1850 return RootBridgeIoIoRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
1854 Enables a PCI driver to copy one region of PCI root bridge memory space to
1855 another region of PCI root bridge memory space.
1857 The CopyMem() function enables a PCI driver to copy one region of PCI root
1858 bridge memory space to another region of PCI root bridge memory space. This
1859 is especially useful for video scroll operation on a memory mapped video
1861 The memory operations are carried out exactly as requested. The caller is
1862 responsible for satisfying any alignment and memory width restrictions that a
1863 PCI root bridge on a platform might require.
1865 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
1868 @param[in] Width Signifies the width of the memory operations.
1870 @param[in] DestAddress The destination address of the memory operation. The
1871 caller is responsible for aligning the DestAddress if
1874 @param[in] SrcAddress The source address of the memory operation. The caller
1875 is responsible for aligning the SrcAddress if
1878 @param[in] Count The number of memory operations to perform. Bytes
1879 moved is Width size * Count, starting at DestAddress
1882 @retval EFI_SUCCESS The data was copied from one memory region
1883 to another memory region.
1885 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1887 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1892 RootBridgeIoCopyMem (
1893 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1894 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
1895 IN UINT64 DestAddress
,
1896 IN UINT64 SrcAddress
,
1906 if ((UINT32
)Width
> EfiPciWidthUint64
) {
1907 return EFI_INVALID_PARAMETER
;
1910 if (DestAddress
== SrcAddress
) {
1914 Stride
= (UINTN
)(1 << Width
);
1917 if ((DestAddress
> SrcAddress
) &&
1918 (DestAddress
< (SrcAddress
+ Count
* Stride
))) {
1920 SrcAddress
= SrcAddress
+ (Count
-1) * Stride
;
1921 DestAddress
= DestAddress
+ (Count
-1) * Stride
;
1924 for (Index
= 0;Index
< Count
;Index
++) {
1925 Status
= RootBridgeIoMemRead (
1932 if (EFI_ERROR (Status
)) {
1935 Status
= RootBridgeIoMemWrite (
1942 if (EFI_ERROR (Status
)) {
1946 SrcAddress
+= Stride
;
1947 DestAddress
+= Stride
;
1949 SrcAddress
-= Stride
;
1950 DestAddress
-= Stride
;
1957 Enables a PCI driver to access PCI controller registers in a PCI root
1958 bridge's configuration space.
1960 The Pci.Read() and Pci.Write() functions enable a driver to access PCI
1961 configuration registers for a PCI controller.
1962 The PCI Configuration operations are carried out exactly as requested. The
1963 caller is responsible for any alignment and PCI configuration width issues
1964 that a PCI Root Bridge on a platform might require.
1966 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1968 @param[in] Width Signifies the width of the memory operations.
1970 @param[in] Address The address within the PCI configuration space for the
1973 @param[in] Count The number of PCI configuration operations to perform.
1974 Bytes moved is Width size * Count, starting at
1977 @param[out] Buffer For read operations, the destination buffer to store
1978 the results. For write operations, the source buffer
1981 @retval EFI_SUCCESS The data was read from or written to the PCI
1984 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
1986 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1988 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1993 RootBridgeIoPciRead (
1994 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
1995 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
2001 return RootBridgeIoPciRW (This
, FALSE
, Width
, Address
, Count
, Buffer
);
2005 Enables a PCI driver to access PCI controller registers in a PCI root
2006 bridge's configuration space.
2008 The Pci.Read() and Pci.Write() functions enable a driver to access PCI
2009 configuration registers for a PCI controller.
2010 The PCI Configuration operations are carried out exactly as requested. The
2011 caller is responsible for any alignment and PCI configuration width issues
2012 that a PCI Root Bridge on a platform might require.
2014 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2016 @param[in] Width Signifies the width of the memory operations.
2018 @param[in] Address The address within the PCI configuration space for the
2021 @param[in] Count The number of PCI configuration operations to perform.
2022 Bytes moved is Width size * Count, starting at
2025 @param[in] Buffer For read operations, the destination buffer to store
2026 the results. For write operations, the source buffer
2029 @retval EFI_SUCCESS The data was read from or written to the PCI
2032 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
2034 @retval EFI_INVALID_PARAMETER Buffer is NULL.
2036 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
2041 RootBridgeIoPciWrite (
2042 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2043 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
2049 return RootBridgeIoPciRW (This
, TRUE
, Width
, Address
, Count
, Buffer
);
2053 Provides the PCI controller-specific addresses required to access system
2054 memory from a DMA bus master.
2056 The Map() function provides the PCI controller specific addresses needed to
2057 access system memory. This function is used to map system memory for PCI bus
2058 master DMA accesses.
2060 @param[in] This A pointer to the
2061 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2063 @param[in] Operation Indicates if the bus master is going to read
2064 or write to system memory.
2066 @param[in] HostAddress The system memory address to map to the PCI
2069 @param[in, out] NumberOfBytes On input the number of bytes to map. On
2070 output the number of bytes that were mapped.
2072 @param[out] DeviceAddress The resulting map address for the bus master
2073 PCI controller to use to access the system
2074 memory's HostAddress.
2076 @param[out] Mapping The value to pass to Unmap() when the bus
2077 master DMA operation is complete.
2079 @retval EFI_SUCCESS The range was mapped for the returned
2082 @retval EFI_INVALID_PARAMETER Operation is invalid.
2084 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
2086 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.
2088 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.
2090 @retval EFI_INVALID_PARAMETER Mapping is NULL.
2092 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
2095 @retval EFI_DEVICE_ERROR The system hardware could not map the
2098 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
2104 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2105 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
,
2106 IN VOID
*HostAddress
,
2107 IN OUT UINTN
*NumberOfBytes
,
2108 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
2113 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
2116 if (HostAddress
== NULL
|| NumberOfBytes
== NULL
|| DeviceAddress
== NULL
||
2118 return EFI_INVALID_PARAMETER
;
2122 // Initialize the return values to their defaults
2127 // Make sure that Operation is valid
2129 if ((UINT32
)Operation
>= EfiPciOperationMaximum
) {
2130 return EFI_INVALID_PARAMETER
;
2134 // Most PCAT like chipsets can not handle performing DMA above 4GB.
2135 // If any part of the DMA transfer being mapped is above 4GB, then
2136 // map the DMA transfer to a buffer below 4GB.
2138 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress
;
2139 if ((PhysicalAddress
+ *NumberOfBytes
) > 0x100000000ULL
) {
2142 // Common Buffer operations can not be remapped. If the common buffer
2143 // if above 4GB, then it is not possible to generate a mapping, so return
2146 if (Operation
== EfiPciOperationBusMasterCommonBuffer
||
2147 Operation
== EfiPciOperationBusMasterCommonBuffer64
) {
2148 return EFI_UNSUPPORTED
;
2152 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
2155 Status
= gBS
->AllocatePool (
2156 EfiBootServicesData
,
2160 if (EFI_ERROR (Status
)) {
2166 // Return a pointer to the MAP_INFO structure in Mapping
2171 // Initialize the MAP_INFO structure
2173 MapInfo
->Operation
= Operation
;
2174 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
2175 MapInfo
->NumberOfPages
= EFI_SIZE_TO_PAGES(*NumberOfBytes
);
2176 MapInfo
->HostAddress
= PhysicalAddress
;
2177 MapInfo
->MappedHostAddress
= 0x00000000ffffffff;
2180 // Allocate a buffer below 4GB to map the transfer to.
2182 Status
= gBS
->AllocatePages (
2184 EfiBootServicesData
,
2185 MapInfo
->NumberOfPages
,
2186 &MapInfo
->MappedHostAddress
2188 if (EFI_ERROR (Status
)) {
2189 gBS
->FreePool (MapInfo
);
2195 // If this is a read operation from the Bus Master's point of view,
2196 // then copy the contents of the real buffer into the mapped buffer
2197 // so the Bus Master can read the contents of the real buffer.
2199 if (Operation
== EfiPciOperationBusMasterRead
||
2200 Operation
== EfiPciOperationBusMasterRead64
) {
2202 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
2203 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
2204 MapInfo
->NumberOfBytes
2209 // The DeviceAddress is the address of the maped buffer below 4GB
2211 *DeviceAddress
= MapInfo
->MappedHostAddress
;
2214 // The transfer is below 4GB, so the DeviceAddress is simply the
2217 *DeviceAddress
= PhysicalAddress
;
2224 Completes the Map() operation and releases any corresponding resources.
2226 The Unmap() function completes the Map() operation and releases any
2227 corresponding resources.
2228 If the operation was an EfiPciOperationBusMasterWrite or
2229 EfiPciOperationBusMasterWrite64, the data is committed to the target system
2231 Any resources used for the mapping are freed.
2233 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2235 @param[in] Mapping The mapping value returned from Map().
2237 @retval EFI_SUCCESS The range was unmapped.
2239 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
2242 @retval EFI_DEVICE_ERROR The data was not committed to the target
2248 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2255 // See if the Map() operation associated with this Unmap() required a mapping
2256 // buffer. If a mapping buffer was not required, then this function simply
2257 // returns EFI_SUCCESS.
2259 if (Mapping
!= NULL
) {
2261 // Get the MAP_INFO structure from Mapping
2263 MapInfo
= (MAP_INFO
*)Mapping
;
2266 // If this is a write operation from the Bus Master's point of view,
2267 // then copy the contents of the mapped buffer into the real buffer
2268 // so the processor can read the contents of the real buffer.
2270 if (MapInfo
->Operation
== EfiPciOperationBusMasterWrite
||
2271 MapInfo
->Operation
== EfiPciOperationBusMasterWrite64
) {
2273 (VOID
*)(UINTN
)MapInfo
->HostAddress
,
2274 (VOID
*)(UINTN
)MapInfo
->MappedHostAddress
,
2275 MapInfo
->NumberOfBytes
2280 // Free the mapped buffer and the MAP_INFO structure.
2282 gBS
->FreePages (MapInfo
->MappedHostAddress
, MapInfo
->NumberOfPages
);
2283 gBS
->FreePool (Mapping
);
2289 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer
2290 or EfiPciOperationBusMasterCommonBuffer64 mapping.
2292 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2294 @param Type This parameter is not used and must be ignored.
2296 @param MemoryType The type of memory to allocate, EfiBootServicesData or
2297 EfiRuntimeServicesData.
2299 @param Pages The number of pages to allocate.
2301 @param HostAddress A pointer to store the base system memory address of the
2304 @param Attributes The requested bit mask of attributes for the allocated
2305 range. Only the attributes
2306 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,
2307 EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and
2308 EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this
2311 @retval EFI_SUCCESS The requested memory pages were allocated.
2313 @retval EFI_INVALID_PARAMETER MemoryType is invalid.
2315 @retval EFI_INVALID_PARAMETER HostAddress is NULL.
2317 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
2318 attribute bits are MEMORY_WRITE_COMBINE,
2319 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
2321 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
2325 RootBridgeIoAllocateBuffer (
2326 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2327 IN EFI_ALLOCATE_TYPE Type
,
2328 IN EFI_MEMORY_TYPE MemoryType
,
2330 OUT VOID
**HostAddress
,
2331 IN UINT64 Attributes
2335 EFI_PHYSICAL_ADDRESS PhysicalAddress
;
2338 // Validate Attributes
2340 if ((Attributes
& EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER
) != 0) {
2341 return EFI_UNSUPPORTED
;
2345 // Check for invalid inputs
2347 if (HostAddress
== NULL
) {
2348 return EFI_INVALID_PARAMETER
;
2352 // The only valid memory types are EfiBootServicesData and
2353 // EfiRuntimeServicesData
2355 if (MemoryType
!= EfiBootServicesData
&&
2356 MemoryType
!= EfiRuntimeServicesData
) {
2357 return EFI_INVALID_PARAMETER
;
2361 // Limit allocations to memory below 4GB
2363 PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
)(0xffffffff);
2365 Status
= gBS
->AllocatePages (AllocateMaxAddress
, MemoryType
, Pages
,
2367 if (EFI_ERROR (Status
)) {
2371 *HostAddress
= (VOID
*)(UINTN
)PhysicalAddress
;
2377 Frees memory that was allocated with AllocateBuffer().
2379 The FreeBuffer() function frees memory that was allocated with
2382 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2384 @param Pages The number of pages to free.
2386 @param HostAddress The base system memory address of the allocated range.
2388 @retval EFI_SUCCESS The requested memory pages were freed.
2390 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
2391 Pages was not allocated with AllocateBuffer().
2395 RootBridgeIoFreeBuffer (
2396 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2398 OUT VOID
*HostAddress
2401 return gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress
, Pages
);
2405 Flushes all PCI posted write transactions from a PCI host bridge to system
2408 The Flush() function flushes any PCI posted write transactions from a PCI
2409 host bridge to system memory. Posted write transactions are generated by PCI
2410 bus masters when they perform write transactions to target addresses in
2412 This function does not flush posted write transactions from any PCI bridges.
2413 A PCI controller specific action must be taken to guarantee that the posted
2414 write transactions have been flushed from the PCI controller and from all the
2415 PCI bridges into the PCI host bridge. This is typically done with a PCI read
2416 transaction from the PCI controller prior to calling Flush().
2418 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2420 @retval EFI_SUCCESS The PCI posted write transactions were flushed
2421 from the PCI host bridge to system memory.
2423 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed
2424 from the PCI host bridge due to a hardware error.
2429 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
2433 // not supported yet
2439 Gets the attributes that a PCI root bridge supports setting with
2440 SetAttributes(), and the attributes that a PCI root bridge is currently
2443 The GetAttributes() function returns the mask of attributes that this PCI
2444 root bridge supports and the mask of attributes that the PCI root bridge is
2447 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2449 @param Supported A pointer to the mask of attributes that this PCI root
2450 bridge supports setting with SetAttributes().
2452 @param Attributes A pointer to the mask of attributes that this PCI root
2453 bridge is currently using.
2455 @retval EFI_SUCCESS If Supports is not NULL, then the attributes
2456 that the PCI root bridge supports is returned
2457 in Supports. If Attributes is not NULL, then
2458 the attributes that the PCI root bridge is
2459 currently using is returned in Attributes.
2461 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
2465 RootBridgeIoGetAttributes (
2466 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2467 OUT UINT64
*Supported
,
2468 OUT UINT64
*Attributes
2471 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
2473 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
2475 if (Attributes
== NULL
&& Supported
== NULL
) {
2476 return EFI_INVALID_PARAMETER
;
2480 // Set the return value for Supported and Attributes
2482 if (Supported
!= NULL
) {
2483 *Supported
= PrivateData
->Supports
;
2486 if (Attributes
!= NULL
) {
2487 *Attributes
= PrivateData
->Attributes
;
2494 Sets attributes for a resource range on a PCI root bridge.
2496 The SetAttributes() function sets the attributes specified in Attributes for
2497 the PCI root bridge on the resource range specified by ResourceBase and
2498 ResourceLength. Since the granularity of setting these attributes may vary
2499 from resource type to resource type, and from platform to platform, the
2500 actual resource range and the one passed in by the caller may differ. As a
2501 result, this function may set the attributes specified by Attributes on a
2502 larger resource range than the caller requested. The actual range is returned
2503 in ResourceBase and ResourceLength. The caller is responsible for verifying
2504 that the actual range for which the attributes were set is acceptable.
2506 @param[in] This A pointer to the
2507 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2509 @param[in] Attributes The mask of attributes to set. If the
2510 attribute bit MEMORY_WRITE_COMBINE,
2511 MEMORY_CACHED, or MEMORY_DISABLE is set,
2512 then the resource range is specified by
2513 ResourceBase and ResourceLength. If
2514 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
2515 MEMORY_DISABLE are not set, then
2516 ResourceBase and ResourceLength are ignored,
2519 @param[in, out] ResourceBase A pointer to the base address of the
2520 resource range to be modified by the
2521 attributes specified by Attributes.
2523 @param[in, out] ResourceLength A pointer to the length of the resource
2524 range to be modified by the attributes
2525 specified by Attributes.
2527 @retval EFI_SUCCESS The current configuration of this PCI root bridge
2528 was returned in Resources.
2530 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
2531 could not be retrieved.
2533 @retval EFI_INVALID_PARAMETER Invalid pointer of
2534 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
2538 RootBridgeIoSetAttributes (
2539 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2540 IN UINT64 Attributes
,
2541 IN OUT UINT64
*ResourceBase
,
2542 IN OUT UINT64
*ResourceLength
2545 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
2547 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This
);
2549 if (Attributes
!= 0) {
2550 if ((Attributes
& (~(PrivateData
->Supports
))) != 0) {
2551 return EFI_UNSUPPORTED
;
2556 // This is a generic driver for a PC-AT class system. It does not have any
2557 // chipset specific knowlegde, so none of the attributes can be set or
2558 // cleared. Any attempt to set attribute that are already set will succeed,
2559 // and any attempt to set an attribute that is not supported will fail.
2561 if (Attributes
& (~PrivateData
->Attributes
)) {
2562 return EFI_UNSUPPORTED
;
2569 Retrieves the current resource settings of this PCI root bridge in the form
2570 of a set of ACPI 2.0 resource descriptors.
2572 There are only two resource descriptor types from the ACPI Specification that
2573 may be used to describe the current resources allocated to a PCI root bridge.
2574 These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1),
2575 and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space
2576 Descriptor can describe memory, I/O, and bus number ranges for dynamic or
2577 fixed resources. The configuration of a PCI root bridge is described with one
2578 or more QWORD Address Space Descriptors followed by an End Tag.
2580 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
2582 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that
2583 describe the current configuration of this PCI root
2584 bridge. The storage for the ACPI 2.0 resource
2585 descriptors is allocated by this function. The
2586 caller must treat the return buffer as read-only
2587 data, and the buffer must not be freed by the
2590 @retval EFI_SUCCESS The current configuration of this PCI root bridge
2591 was returned in Resources.
2593 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge
2594 could not be retrieved.
2596 @retval EFI_INVALID_PARAMETER Invalid pointer of
2597 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
2601 RootBridgeIoConfiguration (
2602 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*This
,
2603 OUT VOID
**Resources
2606 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
2609 PrivateData
= DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This
);
2610 CopyMem (&PrivateData
->ConfigBuffer
, &mConfigurationTemplate
,
2611 sizeof mConfigurationTemplate
);
2613 for (Index
= 0; Index
< TypeMax
; Index
++) {
2614 if (PrivateData
->ResAllocNode
[Index
].Status
== ResAllocated
) {
2615 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
2617 Desc
= &PrivateData
->ConfigBuffer
.SpaceDesc
[Index
];
2618 Desc
->AddrRangeMin
= PrivateData
->ResAllocNode
[Index
].Base
;
2619 Desc
->AddrRangeMax
= PrivateData
->ResAllocNode
[Index
].Base
+
2620 PrivateData
->ResAllocNode
[Index
].Length
- 1;
2621 Desc
->AddrLen
= PrivateData
->ResAllocNode
[Index
].Length
;
2625 *Resources
= &PrivateData
->ConfigBuffer
;