2 Module produces Device I/O on top of PCI Root Bridge I/O for Segment 0 only.
3 This is a valid assumption because many of the EFI 1.02/EFI 1.10 systems that may have provided
4 Device I/O were single segment platforms. The goal of the ECP is to provide compatibility with the
5 drivers/apps that may have used Device I/O.
7 Device I/O is on list of deprecated protocols for UEFI 2.0 and later.
8 This module module layers Device I/O on top of PCI Root Bridge I/O (Segment 0)
10 There are no EDK modules present that produces Device I/O
11 EFI drivers included that consume Device I/O
12 Platform required to support EFI drivers that consume Device I/O
13 Platform required to support EFI applications that consume Device I/O
15 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
16 This program and the accompanying materials
17 are licensed and made available under the terms and conditions of the BSD License
18 which accompanies this distribution. The full text of the license may be found at
19 http://opensource.org/licenses/bsd-license.php
21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
22 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #include <IndustryStandard/Pci.h>
28 #include <Protocol/DeviceIo.h>
29 #include <Protocol/PciRootBridgeIo.h>
30 #include <Library/BaseLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/UefiBootServicesTableLib.h>
34 #include <Library/UefiDriverEntryPoint.h>
35 #include <Library/UefiLib.h>
36 #include <Library/MemoryAllocationLib.h>
37 #include <Library/DevicePathLib.h>
41 Perform reading memory mapped I/O space of device.
43 @param This A pointer to EFI_DEVICE_IO protocol instance.
44 @param Width Width of I/O operations.
45 @param Address The base address of I/O operations.
46 @param Count The number of I/O operations to perform. Bytes
47 moves is Width size * Count, starting at Address.
48 @param Buffer The destination buffer to store results.
50 @retval EFI_SUCCESS The data was read from the device.
51 @retval EFI_INVALID_PARAMETER Width is invalid.
52 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
59 IN EFI_DEVICE_IO_PROTOCOL
*This
,
60 IN EFI_IO_WIDTH Width
,
68 Perform writing memory mapped I/O space of device.
70 @param This A pointer to EFI_DEVICE_IO protocol instance.
71 @param Width Width of I/O operations.
72 @param Address The base address of I/O operations.
73 @param Count The number of I/O operations to perform. Bytes
74 moves is Width size * Count, starting at Address.
75 @param Buffer The source buffer of data to be written.
77 @retval EFI_SUCCESS The data was written to the device.
78 @retval EFI_INVALID_PARAMETER Width is invalid.
79 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
86 IN EFI_DEVICE_IO_PROTOCOL
*This
,
87 IN EFI_IO_WIDTH Width
,
94 Perform reading I/O space of device.
96 @param This A pointer to EFI_DEVICE_IO protocol instance.
97 @param Width Width of I/O operations.
98 @param Address The base address of I/O operations.
99 @param Count The number of I/O operations to perform. Bytes
100 moves is Width size * Count, starting at Address.
101 @param Buffer The destination buffer to store results.
103 @retval EFI_SUCCESS The data was read from the device.
104 @retval EFI_INVALID_PARAMETER Width is invalid.
105 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
112 IN EFI_DEVICE_IO_PROTOCOL
*This
,
113 IN EFI_IO_WIDTH Width
,
120 Perform writing I/O space of device.
122 @param This A pointer to EFI_DEVICE_IO protocol instance.
123 @param Width Width of I/O operations.
124 @param Address The base address of I/O operations.
125 @param Count The number of I/O operations to perform. Bytes
126 moves is Width size * Count, starting at Address.
127 @param Buffer The source buffer of data to be written.
129 @retval EFI_SUCCESS The data was written to the device.
130 @retval EFI_INVALID_PARAMETER Width is invalid.
131 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
138 IN EFI_DEVICE_IO_PROTOCOL
*This
,
139 IN EFI_IO_WIDTH Width
,
146 Perform reading PCI configuration space of device
148 @param This A pointer to EFI_DEVICE_IO protocol instance.
149 @param Width Width of I/O operations.
150 @param Address The base address of I/O operations.
151 @param Count The number of I/O operations to perform. Bytes
152 moves is Width size * Count, starting at Address.
153 @param Buffer The destination buffer to store results.
155 @retval EFI_SUCCESS The data was read from the device.
156 @retval EFI_INVALID_PARAMETER Width is invalid.
157 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
164 IN EFI_DEVICE_IO_PROTOCOL
*This
,
165 IN EFI_IO_WIDTH Width
,
172 Perform writing PCI configuration space of device.
174 @param This A pointer to EFI_DEVICE_IO protocol instance.
175 @param Width Width of I/O operations.
176 @param Address The base address of I/O operations.
177 @param Count The number of I/O operations to perform. Bytes
178 moves is Width size * Count, starting at Address.
179 @param Buffer The source buffer of data to be written.
181 @retval EFI_SUCCESS The data was written to the device.
182 @retval EFI_INVALID_PARAMETER Width is invalid.
183 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
190 IN EFI_DEVICE_IO_PROTOCOL
*This
,
191 IN EFI_IO_WIDTH Width
,
198 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
200 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
201 @param Address The PCI configuration space address of the device
202 whose Device Path is going to be returned.
203 @param PciDevicePath A pointer to the pointer for the EFI Device Path
204 for PciAddress. Memory for the Device Path is
205 allocated from the pool.
207 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI
209 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device
211 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
217 DeviceIoPciDevicePath (
218 IN EFI_DEVICE_IO_PROTOCOL
*This
,
220 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PciDevicePath
224 Provides the device-specific addresses needed to access system memory.
226 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
227 @param Operation Indicates if the bus master is going to read or
228 write to system memory.
229 @param HostAddress The system memory address to map to the device.
230 @param NumberOfBytes On input the number of bytes to map. On output the
231 number of bytes that were mapped.
232 @param DeviceAddress The resulting map address for the bus master
233 device to use to access the hosts HostAddress.
234 @param Mapping A resulting value to pass to Unmap().
236 @retval EFI_SUCCESS The range was mapped for the returned
238 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.
239 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
241 @retval EFI_DEVICE_ERROR The system hardware could not map the requested
243 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
250 IN EFI_DEVICE_IO_PROTOCOL
*This
,
251 IN EFI_IO_OPERATION_TYPE Operation
,
252 IN EFI_PHYSICAL_ADDRESS
*HostAddress
,
253 IN OUT UINTN
*NumberOfBytes
,
254 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
259 Completes the Map() operation and releases any corresponding resources.
261 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
262 @param Mapping The mapping value returned from Map().
264 @retval EFI_SUCCESS The range was unmapped.
265 @retval EFI_DEVICE_ERROR The data was not committed to the target system
272 IN EFI_DEVICE_IO_PROTOCOL
*This
,
277 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
279 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
280 @param Type The type allocation to perform.
281 @param MemoryType The type of memory to allocate,
282 EfiBootServicesData or EfiRuntimeServicesData.
283 @param Pages The number of pages to allocate.
284 @param PhysicalAddress A pointer to store the base address of the
287 @retval EFI_SUCCESS The requested memory pages were allocated.
288 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
289 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.
290 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on
296 DeviceIoAllocateBuffer (
297 IN EFI_DEVICE_IO_PROTOCOL
*This
,
298 IN EFI_ALLOCATE_TYPE Type
,
299 IN EFI_MEMORY_TYPE MemoryType
,
301 IN OUT EFI_PHYSICAL_ADDRESS
*PhysicalAddress
305 Flushes any posted write data to the device.
307 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
309 @retval EFI_SUCCESS The buffers were flushed.
310 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware
317 IN EFI_DEVICE_IO_PROTOCOL
*This
321 Frees pages that were allocated with AllocateBuffer().
323 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
324 @param Pages The number of pages to free.
325 @param HostAddress The base address of the range to free.
327 @retval EFI_SUCCESS The requested memory pages were freed.
328 @retval EFI_NOT_FOUND The requested memory pages were not allocated with
330 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is
337 IN EFI_DEVICE_IO_PROTOCOL
*This
,
339 IN EFI_PHYSICAL_ADDRESS HostAddress
343 #define DEVICE_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('D', 'e', 'I', 'O')
347 EFI_DEVICE_IO_PROTOCOL DeviceIo
;
348 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
349 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
351 UINT16 SubordinateBus
;
352 } DEVICE_IO_PRIVATE_DATA
;
354 #define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)
356 #define MAX_COMMON_BUFFER 0x00000000FFFFFFFF
359 EFI_EVENT mPciRootBridgeIoRegistration
;
362 // Device Io Volume Protocol template
364 DEVICE_IO_PRIVATE_DATA gDeviceIoPrivateDataTemplate
= {
365 DEVICE_IO_PRIVATE_DATA_SIGNATURE
,
380 DeviceIoPciDevicePath
,
382 DeviceIoAllocateBuffer
,
386 NULL
, // PciRootBridgeIo
389 255 // SubordinateBus
393 This notification function is invoked when an instance of the
394 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL is produced. It installs another instance of the
395 EFI_DEVICE_IO_PROTOCOL on the same handle.
397 @param Event The event that occured
398 @param Context Context of event. Not used in this nofication function.
403 PciRootBridgeIoNotificationEvent (
411 DEVICE_IO_PRIVATE_DATA
*Private
;
412 EFI_DEVICE_IO_PROTOCOL
*DeviceIo
;
413 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
416 BufferSize
= sizeof (Handle
);
417 Status
= gBS
->LocateHandle (
419 &gEfiPciRootBridgeIoProtocolGuid
,
420 mPciRootBridgeIoRegistration
,
424 if (EFI_ERROR (Status
)) {
426 // Exit Path of While Loop....
432 // Skip this handle if the Device Io Protocol is already installed
434 Status
= gBS
->HandleProtocol (
436 &gEfiDeviceIoProtocolGuid
,
439 if (!EFI_ERROR (Status
)) {
444 // Retrieve the Pci Root Bridge IO Protocol
446 Status
= gBS
->HandleProtocol (
448 &gEfiPciRootBridgeIoProtocolGuid
,
449 (VOID
**)&PciRootBridgeIo
451 ASSERT_EFI_ERROR (Status
);
454 // We only install Device IO for PCI bus in Segment 0.
455 // See the file description at @file for details.
457 if (PciRootBridgeIo
->SegmentNumber
!= 0) {
462 // Allocate private data structure
464 Private
= AllocateCopyPool (sizeof (DEVICE_IO_PRIVATE_DATA
), &gDeviceIoPrivateDataTemplate
);
465 if (Private
== NULL
) {
469 Private
->PciRootBridgeIo
= PciRootBridgeIo
;
471 Status
= gBS
->HandleProtocol (
473 &gEfiDevicePathProtocolGuid
,
474 (VOID
**) &Private
->DevicePath
478 // Install Device Io onto same handle
480 Status
= gBS
->InstallMultipleProtocolInterfaces (
482 &gEfiDeviceIoProtocolGuid
,
486 ASSERT_EFI_ERROR (Status
);
491 The user Entry Point for DXE driver. The user code starts with this function
492 as the real entry point for the image goes into a library that calls this
495 @param[in] ImageHandle The firmware allocated handle for the EFI image.
496 @param[in] SystemTable A pointer to the EFI System Table.
498 @retval EFI_SUCCESS The entry point is executed successfully.
499 @retval other Some error occurs when executing this entry point.
505 IN EFI_HANDLE ImageHandle
,
506 IN EFI_SYSTEM_TABLE
*SystemTable
509 EfiCreateProtocolNotifyEvent (
510 &gEfiPciRootBridgeIoProtocolGuid
,
512 PciRootBridgeIoNotificationEvent
,
514 &mPciRootBridgeIoRegistration
521 Perform reading memory mapped I/O space of device.
523 @param This A pointer to EFI_DEVICE_IO protocol instance.
524 @param Width Width of I/O operations.
525 @param Address The base address of I/O operations.
526 @param Count The number of I/O operations to perform. Bytes
527 moves is Width size * Count, starting at Address.
528 @param Buffer The destination buffer to store results.
530 @retval EFI_SUCCESS The data was read from the device.
531 @retval EFI_INVALID_PARAMETER Width is invalid.
532 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
539 IN EFI_DEVICE_IO_PROTOCOL
*This
,
540 IN EFI_IO_WIDTH Width
,
547 DEVICE_IO_PRIVATE_DATA
*Private
;
549 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
551 if (Width
> MMIO_COPY_UINT64
) {
552 return EFI_INVALID_PARAMETER
;
554 if (Width
>= MMIO_COPY_UINT8
) {
555 Width
= (EFI_IO_WIDTH
) (Width
- MMIO_COPY_UINT8
);
556 Status
= Private
->PciRootBridgeIo
->CopyMem (
557 Private
->PciRootBridgeIo
,
558 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
559 (UINT64
) (UINTN
) Buffer
,
564 Status
= Private
->PciRootBridgeIo
->Mem
.Read (
565 Private
->PciRootBridgeIo
,
566 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
580 Perform writing memory mapped I/O space of device.
582 @param This A pointer to EFI_DEVICE_IO protocol instance.
583 @param Width Width of I/O operations.
584 @param Address The base address of I/O operations.
585 @param Count The number of I/O operations to perform. Bytes
586 moves is Width size * Count, starting at Address.
587 @param Buffer The source buffer of data to be written.
589 @retval EFI_SUCCESS The data was written to the device.
590 @retval EFI_INVALID_PARAMETER Width is invalid.
591 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
598 IN EFI_DEVICE_IO_PROTOCOL
*This
,
599 IN EFI_IO_WIDTH Width
,
606 DEVICE_IO_PRIVATE_DATA
*Private
;
608 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
610 if (Width
> MMIO_COPY_UINT64
) {
611 return EFI_INVALID_PARAMETER
;
613 if (Width
>= MMIO_COPY_UINT8
) {
614 Width
= (EFI_IO_WIDTH
) (Width
- MMIO_COPY_UINT8
);
615 Status
= Private
->PciRootBridgeIo
->CopyMem (
616 Private
->PciRootBridgeIo
,
617 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
619 (UINT64
) (UINTN
) Buffer
,
623 Status
= Private
->PciRootBridgeIo
->Mem
.Write (
624 Private
->PciRootBridgeIo
,
625 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
637 Perform reading I/O space of device.
639 @param This A pointer to EFI_DEVICE_IO protocol instance.
640 @param Width Width of I/O operations.
641 @param Address The base address of I/O operations.
642 @param Count The number of I/O operations to perform. Bytes
643 moves is Width size * Count, starting at Address.
644 @param Buffer The destination buffer to store results.
646 @retval EFI_SUCCESS The data was read from the device.
647 @retval EFI_INVALID_PARAMETER Width is invalid.
648 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
655 IN EFI_DEVICE_IO_PROTOCOL
*This
,
656 IN EFI_IO_WIDTH Width
,
663 DEVICE_IO_PRIVATE_DATA
*Private
;
665 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
667 if (Width
>= MMIO_COPY_UINT8
) {
668 return EFI_INVALID_PARAMETER
;
671 Status
= Private
->PciRootBridgeIo
->Io
.Read (
672 Private
->PciRootBridgeIo
,
673 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
684 Perform writing I/O space of device.
686 @param This A pointer to EFI_DEVICE_IO protocol instance.
687 @param Width Width of I/O operations.
688 @param Address The base address of I/O operations.
689 @param Count The number of I/O operations to perform. Bytes
690 moves is Width size * Count, starting at Address.
691 @param Buffer The source buffer of data to be written.
693 @retval EFI_SUCCESS The data was written to the device.
694 @retval EFI_INVALID_PARAMETER Width is invalid.
695 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
702 IN EFI_DEVICE_IO_PROTOCOL
*This
,
703 IN EFI_IO_WIDTH Width
,
710 DEVICE_IO_PRIVATE_DATA
*Private
;
712 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
714 if (Width
>= MMIO_COPY_UINT8
) {
715 return EFI_INVALID_PARAMETER
;
718 Status
= Private
->PciRootBridgeIo
->Io
.Write (
719 Private
->PciRootBridgeIo
,
720 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
731 Perform reading PCI configuration space of device
733 @param This A pointer to EFI_DEVICE_IO protocol instance.
734 @param Width Width of I/O operations.
735 @param Address The base address of I/O operations.
736 @param Count The number of I/O operations to perform. Bytes
737 moves is Width size * Count, starting at Address.
738 @param Buffer The destination buffer to store results.
740 @retval EFI_SUCCESS The data was read from the device.
741 @retval EFI_INVALID_PARAMETER Width is invalid.
742 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
749 IN EFI_DEVICE_IO_PROTOCOL
*This
,
750 IN EFI_IO_WIDTH Width
,
757 DEVICE_IO_PRIVATE_DATA
*Private
;
759 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
761 if ((UINT32
)Width
>= MMIO_COPY_UINT8
) {
762 return EFI_INVALID_PARAMETER
;
765 Status
= Private
->PciRootBridgeIo
->Pci
.Read (
766 Private
->PciRootBridgeIo
,
767 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
778 Perform writing PCI configuration space of device.
780 @param This A pointer to EFI_DEVICE_IO protocol instance.
781 @param Width Width of I/O operations.
782 @param Address The base address of I/O operations.
783 @param Count The number of I/O operations to perform. Bytes
784 moves is Width size * Count, starting at Address.
785 @param Buffer The source buffer of data to be written.
787 @retval EFI_SUCCESS The data was written to the device.
788 @retval EFI_INVALID_PARAMETER Width is invalid.
789 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
796 IN EFI_DEVICE_IO_PROTOCOL
*This
,
797 IN EFI_IO_WIDTH Width
,
804 DEVICE_IO_PRIVATE_DATA
*Private
;
806 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
808 if ((UINT32
)Width
>= MMIO_COPY_UINT8
) {
809 return EFI_INVALID_PARAMETER
;
812 Status
= Private
->PciRootBridgeIo
->Pci
.Write (
813 Private
->PciRootBridgeIo
,
814 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
825 Append a PCI device path node to another device path.
827 @param Private A pointer to DEVICE_IO_PRIVATE_DATA instance.
828 @param Bus PCI bus number of the device.
829 @param Device PCI device number of the device.
830 @param Function PCI function number of the device.
831 @param DevicePath Original device path which will be appended a PCI
833 @param BridgePrimaryBus Primary bus number of the bridge.
834 @param BridgeSubordinateBus Subordinate bus number of the bridge.
836 @return Pointer to the appended PCI device path.
839 EFI_DEVICE_PATH_PROTOCOL
*
840 AppendPciDevicePath (
841 IN DEVICE_IO_PRIVATE_DATA
*Private
,
845 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
846 IN OUT UINT16
*BridgePrimaryBus
,
847 IN OUT UINT16
*BridgeSubordinateBus
854 PCI_TYPE01 PciBridge
;
856 EFI_DEVICE_PATH_PROTOCOL
*ReturnDevicePath
;
857 PCI_DEVICE_PATH PciNode
;
860 for (ThisBus
= *BridgePrimaryBus
; ThisBus
<= *BridgeSubordinateBus
; ThisBus
++) {
861 for (ThisDevice
= 0; ThisDevice
<= PCI_MAX_DEVICE
; ThisDevice
++) {
862 for (ThisFunc
= 0; ThisFunc
<= PCI_MAX_FUNC
; ThisFunc
++) {
863 Address
= EFI_PCI_ADDRESS (ThisBus
, ThisDevice
, ThisFunc
, 0);
864 ZeroMem (PciPtr
, sizeof (PCI_TYPE01
));
865 Private
->DeviceIo
.Pci
.Read (
870 &(PciPtr
->Hdr
.VendorId
)
872 if ((PciPtr
->Hdr
.VendorId
== 0xffff) && (ThisFunc
== 0)) {
875 if (PciPtr
->Hdr
.VendorId
== 0xffff) {
878 Private
->DeviceIo
.Pci
.Read (
882 sizeof (PCI_TYPE01
) / sizeof (UINT32
),
885 if (IS_PCI_BRIDGE (PciPtr
)) {
886 if (Bus
>= PciPtr
->Bridge
.SecondaryBus
&& Bus
<= PciPtr
->Bridge
.SubordinateBus
) {
888 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
889 PciNode
.Header
.SubType
= HW_PCI_DP
;
890 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
892 PciNode
.Device
= ThisDevice
;
893 PciNode
.Function
= ThisFunc
;
894 ReturnDevicePath
= AppendDevicePathNode (DevicePath
, &PciNode
.Header
);
896 *BridgePrimaryBus
= PciPtr
->Bridge
.SecondaryBus
;
897 *BridgeSubordinateBus
= PciPtr
->Bridge
.SubordinateBus
;
898 return ReturnDevicePath
;
901 if (ThisFunc
== 0 && ((PciPtr
->Hdr
.HeaderType
& HEADER_TYPE_MULTI_FUNCTION
) != HEADER_TYPE_MULTI_FUNCTION
)) {
903 // Skip sub functions, this is not a multi function device
912 ZeroMem (&PciNode
, sizeof (PciNode
));
913 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
914 PciNode
.Header
.SubType
= HW_PCI_DP
;
915 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
916 PciNode
.Device
= Device
;
917 PciNode
.Function
= Function
;
919 ReturnDevicePath
= AppendDevicePathNode (DevicePath
, &PciNode
.Header
);
921 *BridgePrimaryBus
= 0xffff;
922 *BridgeSubordinateBus
= 0xffff;
923 return ReturnDevicePath
;
928 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
930 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
931 @param Address The PCI configuration space address of the device
932 whose Device Path is going to be returned.
933 @param PciDevicePath A pointer to the pointer for the EFI Device Path
934 for PciAddress. Memory for the Device Path is
935 allocated from the pool.
937 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI
939 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device
941 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
947 DeviceIoPciDevicePath (
948 IN EFI_DEVICE_IO_PROTOCOL
*This
,
950 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PciDevicePath
953 DEVICE_IO_PRIVATE_DATA
*Private
;
955 UINT16 SubordinateBus
;
960 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
962 Bus
= (UINT8
) (((UINT32
) Address
>> 24) & 0xff);
963 Device
= (UINT8
) (((UINT32
) Address
>> 16) & 0xff);
964 Func
= (UINT8
) (((UINT32
) Address
>> 8) & 0xff);
966 if (Bus
< Private
->PrimaryBus
|| Bus
> Private
->SubordinateBus
) {
967 return EFI_UNSUPPORTED
;
970 *PciDevicePath
= Private
->DevicePath
;
971 PrimaryBus
= Private
->PrimaryBus
;
972 SubordinateBus
= Private
->SubordinateBus
;
974 *PciDevicePath
= AppendPciDevicePath (
983 if (*PciDevicePath
== NULL
) {
984 return EFI_OUT_OF_RESOURCES
;
986 } while (PrimaryBus
!= 0xffff);
993 Provides the device-specific addresses needed to access system memory.
995 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
996 @param Operation Indicates if the bus master is going to read or
997 write to system memory.
998 @param HostAddress The system memory address to map to the device.
999 @param NumberOfBytes On input the number of bytes to map. On output the
1000 number of bytes that were mapped.
1001 @param DeviceAddress The resulting map address for the bus master
1002 device to use to access the hosts HostAddress.
1003 @param Mapping A resulting value to pass to Unmap().
1005 @retval EFI_SUCCESS The range was mapped for the returned
1007 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.
1008 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
1010 @retval EFI_DEVICE_ERROR The system hardware could not map the requested
1012 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
1019 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1020 IN EFI_IO_OPERATION_TYPE Operation
,
1021 IN EFI_PHYSICAL_ADDRESS
*HostAddress
,
1022 IN OUT UINTN
*NumberOfBytes
,
1023 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
1028 DEVICE_IO_PRIVATE_DATA
*Private
;
1030 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1032 if ((UINT32
)Operation
> EfiBusMasterCommonBuffer
) {
1033 return EFI_INVALID_PARAMETER
;
1036 if (((UINTN
) (*HostAddress
) != (*HostAddress
)) && Operation
== EfiBusMasterCommonBuffer
) {
1037 return EFI_UNSUPPORTED
;
1040 Status
= Private
->PciRootBridgeIo
->Map (
1041 Private
->PciRootBridgeIo
,
1042 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION
) Operation
,
1043 (VOID
*) (UINTN
) (*HostAddress
),
1054 Completes the Map() operation and releases any corresponding resources.
1056 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1057 @param Mapping The mapping value returned from Map().
1059 @retval EFI_SUCCESS The range was unmapped.
1060 @retval EFI_DEVICE_ERROR The data was not committed to the target system
1067 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1072 DEVICE_IO_PRIVATE_DATA
*Private
;
1074 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1076 Status
= Private
->PciRootBridgeIo
->Unmap (
1077 Private
->PciRootBridgeIo
,
1086 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
1088 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1089 @param Type The type allocation to perform.
1090 @param MemoryType The type of memory to allocate,
1091 EfiBootServicesData or EfiRuntimeServicesData.
1092 @param Pages The number of pages to allocate.
1093 @param PhysicalAddress A pointer to store the base address of the
1096 @retval EFI_SUCCESS The requested memory pages were allocated.
1097 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
1098 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.
1099 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on
1105 DeviceIoAllocateBuffer (
1106 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1107 IN EFI_ALLOCATE_TYPE Type
,
1108 IN EFI_MEMORY_TYPE MemoryType
,
1110 IN OUT EFI_PHYSICAL_ADDRESS
*PhysicalAddress
1114 EFI_PHYSICAL_ADDRESS HostAddress
;
1115 DEVICE_IO_PRIVATE_DATA
*Private
;
1118 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1120 HostAddress
= *PhysicalAddress
;
1122 if ((MemoryType
!= EfiBootServicesData
) && (MemoryType
!= EfiRuntimeServicesData
)) {
1123 return EFI_INVALID_PARAMETER
;
1126 if ((UINT32
)Type
>= MaxAllocateType
) {
1127 return EFI_INVALID_PARAMETER
;
1130 if ((Type
== AllocateAddress
) && (HostAddress
+ EFI_PAGES_TO_SIZE (Pages
) - 1 > MAX_COMMON_BUFFER
)) {
1131 return EFI_UNSUPPORTED
;
1134 if ((AllocateAnyPages
== Type
) || (AllocateMaxAddress
== Type
&& HostAddress
> MAX_COMMON_BUFFER
)) {
1135 Type
= AllocateMaxAddress
;
1136 HostAddress
= MAX_COMMON_BUFFER
;
1139 HostAddress2
= (VOID
*) (UINTN
) (HostAddress
);
1140 Status
= Private
->PciRootBridgeIo
->AllocateBuffer (
1141 Private
->PciRootBridgeIo
,
1146 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE
|
1147 EFI_PCI_ATTRIBUTE_MEMORY_CACHED
1150 if (EFI_ERROR (Status
)) {
1155 *PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress2
;
1162 Flushes any posted write data to the device.
1164 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1166 @retval EFI_SUCCESS The buffers were flushed.
1167 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware
1174 IN EFI_DEVICE_IO_PROTOCOL
*This
1178 DEVICE_IO_PRIVATE_DATA
*Private
;
1180 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1182 Status
= Private
->PciRootBridgeIo
->Flush (Private
->PciRootBridgeIo
);
1189 Frees pages that were allocated with AllocateBuffer().
1191 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1192 @param Pages The number of pages to free.
1193 @param HostAddress The base address of the range to free.
1195 @retval EFI_SUCCESS The requested memory pages were freed.
1196 @retval EFI_NOT_FOUND The requested memory pages were not allocated with
1198 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is
1204 DeviceIoFreeBuffer (
1205 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1207 IN EFI_PHYSICAL_ADDRESS HostAddress
1210 DEVICE_IO_PRIVATE_DATA
*Private
;
1212 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1214 if (((HostAddress
& EFI_PAGE_MASK
) != 0) || (Pages
<= 0)) {
1215 return EFI_INVALID_PARAMETER
;
1218 return Private
->PciRootBridgeIo
->FreeBuffer (
1219 Private
->PciRootBridgeIo
,
1221 (VOID
*) (UINTN
) HostAddress