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 R8.x 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 Intel Corporation. <BR>
16 All rights reserved. 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
394 PciRootBridgeIoNotificationEvent (
402 DEVICE_IO_PRIVATE_DATA
*Private
;
403 EFI_DEVICE_IO_PROTOCOL
*DeviceIo
;
404 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
407 BufferSize
= sizeof (Handle
);
408 Status
= gBS
->LocateHandle (
410 &gEfiPciRootBridgeIoProtocolGuid
,
411 mPciRootBridgeIoRegistration
,
415 if (EFI_ERROR (Status
)) {
417 // Exit Path of While Loop....
423 // Skip this handle if the Device Io Protocol is already installed
425 Status
= gBS
->HandleProtocol (
427 &gEfiDeviceIoProtocolGuid
,
430 if (!EFI_ERROR (Status
)) {
435 // Retrieve the Pci Root Bridge IO Protocol
437 Status
= gBS
->HandleProtocol (
439 &gEfiPciRootBridgeIoProtocolGuid
,
440 (VOID
**)&PciRootBridgeIo
442 ASSERT_EFI_ERROR (Status
);
445 // We only install Device IO for PCI bus in Segment 0.
446 // See the file description at @file for details.
448 if (PciRootBridgeIo
->SegmentNumber
!= 0) {
453 // Allocate private data structure
455 Private
= AllocateCopyPool (sizeof (DEVICE_IO_PRIVATE_DATA
), &gDeviceIoPrivateDataTemplate
);
456 if (Private
== NULL
) {
460 Private
->PciRootBridgeIo
= PciRootBridgeIo
;
462 Status
= gBS
->HandleProtocol (
464 &gEfiDevicePathProtocolGuid
,
465 (VOID
**) &Private
->DevicePath
469 // Install Device Io onto same handle
471 Status
= gBS
->InstallMultipleProtocolInterfaces (
473 &gEfiDeviceIoProtocolGuid
,
477 ASSERT_EFI_ERROR (Status
);
482 The user Entry Point for DXE driver. The user code starts with this function
483 as the real entry point for the image goes into a library that calls this
486 @param[in] ImageHandle The firmware allocated handle for the EFI image.
487 @param[in] SystemTable A pointer to the EFI System Table.
489 @retval EFI_SUCCESS The entry point is executed successfully.
490 @retval other Some error occurs when executing this entry point.
496 IN EFI_HANDLE ImageHandle
,
497 IN EFI_SYSTEM_TABLE
*SystemTable
500 EfiCreateProtocolNotifyEvent (
501 &gEfiPciRootBridgeIoProtocolGuid
,
503 PciRootBridgeIoNotificationEvent
,
505 &mPciRootBridgeIoRegistration
512 Perform reading memory mapped I/O space of device.
514 @param This A pointer to EFI_DEVICE_IO protocol instance.
515 @param Width Width of I/O operations.
516 @param Address The base address of I/O operations.
517 @param Count The number of I/O operations to perform. Bytes
518 moves is Width size * Count, starting at Address.
519 @param Buffer The destination buffer to store results.
521 @retval EFI_SUCCESS The data was read from the device.
522 @retval EFI_INVALID_PARAMETER Width is invalid.
523 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
530 IN EFI_DEVICE_IO_PROTOCOL
*This
,
531 IN EFI_IO_WIDTH Width
,
538 DEVICE_IO_PRIVATE_DATA
*Private
;
540 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
542 if (Width
> MMIO_COPY_UINT64
) {
543 return EFI_INVALID_PARAMETER
;
545 if (Width
>= MMIO_COPY_UINT8
) {
546 Width
= (EFI_IO_WIDTH
) (Width
- MMIO_COPY_UINT8
);
547 Status
= Private
->PciRootBridgeIo
->CopyMem (
548 Private
->PciRootBridgeIo
,
549 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
550 (UINT64
) (UINTN
) Buffer
,
555 Status
= Private
->PciRootBridgeIo
->Mem
.Read (
556 Private
->PciRootBridgeIo
,
557 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
571 Perform writing memory mapped I/O space of device.
573 @param This A pointer to EFI_DEVICE_IO protocol instance.
574 @param Width Width of I/O operations.
575 @param Address The base address of I/O operations.
576 @param Count The number of I/O operations to perform. Bytes
577 moves is Width size * Count, starting at Address.
578 @param Buffer The source buffer of data to be written.
580 @retval EFI_SUCCESS The data was written to the device.
581 @retval EFI_INVALID_PARAMETER Width is invalid.
582 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
589 IN EFI_DEVICE_IO_PROTOCOL
*This
,
590 IN EFI_IO_WIDTH Width
,
597 DEVICE_IO_PRIVATE_DATA
*Private
;
599 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
601 if (Width
> MMIO_COPY_UINT64
) {
602 return EFI_INVALID_PARAMETER
;
604 if (Width
>= MMIO_COPY_UINT8
) {
605 Width
= (EFI_IO_WIDTH
) (Width
- MMIO_COPY_UINT8
);
606 Status
= Private
->PciRootBridgeIo
->CopyMem (
607 Private
->PciRootBridgeIo
,
608 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
610 (UINT64
) (UINTN
) Buffer
,
614 Status
= Private
->PciRootBridgeIo
->Mem
.Write (
615 Private
->PciRootBridgeIo
,
616 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
628 Perform reading I/O space of device.
630 @param This A pointer to EFI_DEVICE_IO protocol instance.
631 @param Width Width of I/O operations.
632 @param Address The base address of I/O operations.
633 @param Count The number of I/O operations to perform. Bytes
634 moves is Width size * Count, starting at Address.
635 @param Buffer The destination buffer to store results.
637 @retval EFI_SUCCESS The data was read from the device.
638 @retval EFI_INVALID_PARAMETER Width is invalid.
639 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
646 IN EFI_DEVICE_IO_PROTOCOL
*This
,
647 IN EFI_IO_WIDTH Width
,
654 DEVICE_IO_PRIVATE_DATA
*Private
;
656 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
658 if (Width
>= MMIO_COPY_UINT8
) {
659 return EFI_INVALID_PARAMETER
;
662 Status
= Private
->PciRootBridgeIo
->Io
.Read (
663 Private
->PciRootBridgeIo
,
664 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
675 Perform writing I/O space of device.
677 @param This A pointer to EFI_DEVICE_IO protocol instance.
678 @param Width Width of I/O operations.
679 @param Address The base address of I/O operations.
680 @param Count The number of I/O operations to perform. Bytes
681 moves is Width size * Count, starting at Address.
682 @param Buffer The source buffer of data to be written.
684 @retval EFI_SUCCESS The data was written to the device.
685 @retval EFI_INVALID_PARAMETER Width is invalid.
686 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
693 IN EFI_DEVICE_IO_PROTOCOL
*This
,
694 IN EFI_IO_WIDTH Width
,
701 DEVICE_IO_PRIVATE_DATA
*Private
;
703 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
705 if (Width
>= MMIO_COPY_UINT8
) {
706 return EFI_INVALID_PARAMETER
;
709 Status
= Private
->PciRootBridgeIo
->Io
.Write (
710 Private
->PciRootBridgeIo
,
711 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
722 Perform reading PCI configuration space of device
724 @param This A pointer to EFI_DEVICE_IO protocol instance.
725 @param Width Width of I/O operations.
726 @param Address The base address of I/O operations.
727 @param Count The number of I/O operations to perform. Bytes
728 moves is Width size * Count, starting at Address.
729 @param Buffer The destination buffer to store results.
731 @retval EFI_SUCCESS The data was read from the device.
732 @retval EFI_INVALID_PARAMETER Width is invalid.
733 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
740 IN EFI_DEVICE_IO_PROTOCOL
*This
,
741 IN EFI_IO_WIDTH Width
,
748 DEVICE_IO_PRIVATE_DATA
*Private
;
750 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
752 if (Width
< 0 || Width
>= MMIO_COPY_UINT8
) {
753 return EFI_INVALID_PARAMETER
;
756 Status
= Private
->PciRootBridgeIo
->Pci
.Read (
757 Private
->PciRootBridgeIo
,
758 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
769 Perform writing PCI configuration space of device.
771 @param This A pointer to EFI_DEVICE_IO protocol instance.
772 @param Width Width of I/O operations.
773 @param Address The base address of I/O operations.
774 @param Count The number of I/O operations to perform. Bytes
775 moves is Width size * Count, starting at Address.
776 @param Buffer The source buffer of data to be written.
778 @retval EFI_SUCCESS The data was written to the device.
779 @retval EFI_INVALID_PARAMETER Width is invalid.
780 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of
787 IN EFI_DEVICE_IO_PROTOCOL
*This
,
788 IN EFI_IO_WIDTH Width
,
795 DEVICE_IO_PRIVATE_DATA
*Private
;
797 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
799 if (Width
< 0 || Width
>= MMIO_COPY_UINT8
) {
800 return EFI_INVALID_PARAMETER
;
803 Status
= Private
->PciRootBridgeIo
->Pci
.Write (
804 Private
->PciRootBridgeIo
,
805 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
) Width
,
816 Append a PCI device path node to another device path.
818 @param Private A pointer to DEVICE_IO_PRIVATE_DATA instance.
819 @param Bus PCI bus number of the device.
820 @param Device PCI device number of the device.
821 @param Function PCI function number of the device.
822 @param DevicePath Original device path which will be appended a PCI
824 @param BridgePrimaryBus Primary bus number of the bridge.
825 @param BridgeSubordinateBus Subordinate bus number of the bridge.
827 @return Pointer to the appended PCI device path.
830 EFI_DEVICE_PATH_PROTOCOL
*
831 AppendPciDevicePath (
832 IN DEVICE_IO_PRIVATE_DATA
*Private
,
836 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
837 IN OUT UINT16
*BridgePrimaryBus
,
838 IN OUT UINT16
*BridgeSubordinateBus
845 PCI_TYPE01 PciBridge
;
847 EFI_DEVICE_PATH_PROTOCOL
*ReturnDevicePath
;
848 PCI_DEVICE_PATH PciNode
;
851 for (ThisBus
= *BridgePrimaryBus
; ThisBus
<= *BridgeSubordinateBus
; ThisBus
++) {
852 for (ThisDevice
= 0; ThisDevice
<= PCI_MAX_DEVICE
; ThisDevice
++) {
853 for (ThisFunc
= 0; ThisFunc
<= PCI_MAX_FUNC
; ThisFunc
++) {
854 Address
= EFI_PCI_ADDRESS (ThisBus
, ThisDevice
, ThisFunc
, 0);
855 ZeroMem (PciPtr
, sizeof (PCI_TYPE01
));
856 Private
->DeviceIo
.Pci
.Read (
861 &(PciPtr
->Hdr
.VendorId
)
863 if ((PciPtr
->Hdr
.VendorId
== 0xffff) && (ThisFunc
== 0)) {
866 if (PciPtr
->Hdr
.VendorId
== 0xffff) {
869 Private
->DeviceIo
.Pci
.Read (
873 sizeof (PCI_TYPE01
) / sizeof (UINT32
),
876 if (IS_PCI_BRIDGE (PciPtr
)) {
877 if (Bus
>= PciPtr
->Bridge
.SecondaryBus
&& Bus
<= PciPtr
->Bridge
.SubordinateBus
) {
879 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
880 PciNode
.Header
.SubType
= HW_PCI_DP
;
881 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
883 PciNode
.Device
= ThisDevice
;
884 PciNode
.Function
= ThisFunc
;
885 ReturnDevicePath
= AppendDevicePathNode (DevicePath
, &PciNode
.Header
);
887 *BridgePrimaryBus
= PciPtr
->Bridge
.SecondaryBus
;
888 *BridgeSubordinateBus
= PciPtr
->Bridge
.SubordinateBus
;
889 return ReturnDevicePath
;
892 if (ThisFunc
== 0 && !(PciPtr
->Hdr
.HeaderType
& HEADER_TYPE_MULTI_FUNCTION
)) {
894 // Skip sub functions, this is not a multi function device
903 ZeroMem (&PciNode
, sizeof (PciNode
));
904 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
905 PciNode
.Header
.SubType
= HW_PCI_DP
;
906 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
907 PciNode
.Device
= Device
;
908 PciNode
.Function
= Function
;
910 ReturnDevicePath
= AppendDevicePathNode (DevicePath
, &PciNode
.Header
);
912 *BridgePrimaryBus
= 0xffff;
913 *BridgeSubordinateBus
= 0xffff;
914 return ReturnDevicePath
;
919 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
921 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
922 @param Address The PCI configuration space address of the device
923 whose Device Path is going to be returned.
924 @param PciDevicePath A pointer to the pointer for the EFI Device Path
925 for PciAddress. Memory for the Device Path is
926 allocated from the pool.
928 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI
930 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device
932 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
938 DeviceIoPciDevicePath (
939 IN EFI_DEVICE_IO_PROTOCOL
*This
,
941 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PciDevicePath
944 DEVICE_IO_PRIVATE_DATA
*Private
;
946 UINT16 SubordinateBus
;
951 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
953 Bus
= (UINT8
) (((UINT32
) Address
>> 24) & 0xff);
954 Device
= (UINT8
) (((UINT32
) Address
>> 16) & 0xff);
955 Func
= (UINT8
) (((UINT32
) Address
>> 8) & 0xff);
957 if (Bus
< Private
->PrimaryBus
|| Bus
> Private
->SubordinateBus
) {
958 return EFI_UNSUPPORTED
;
961 *PciDevicePath
= Private
->DevicePath
;
962 PrimaryBus
= Private
->PrimaryBus
;
963 SubordinateBus
= Private
->SubordinateBus
;
965 *PciDevicePath
= AppendPciDevicePath (
974 if (*PciDevicePath
== NULL
) {
975 return EFI_OUT_OF_RESOURCES
;
977 } while (PrimaryBus
!= 0xffff);
984 Provides the device-specific addresses needed to access system memory.
986 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
987 @param Operation Indicates if the bus master is going to read or
988 write to system memory.
989 @param HostAddress The system memory address to map to the device.
990 @param NumberOfBytes On input the number of bytes to map. On output the
991 number of bytes that were mapped.
992 @param DeviceAddress The resulting map address for the bus master
993 device to use to access the hosts HostAddress.
994 @param Mapping A resulting value to pass to Unmap().
996 @retval EFI_SUCCESS The range was mapped for the returned
998 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.
999 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common
1001 @retval EFI_DEVICE_ERROR The system hardware could not map the requested
1003 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
1010 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1011 IN EFI_IO_OPERATION_TYPE Operation
,
1012 IN EFI_PHYSICAL_ADDRESS
*HostAddress
,
1013 IN OUT UINTN
*NumberOfBytes
,
1014 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
1019 DEVICE_IO_PRIVATE_DATA
*Private
;
1021 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1023 if (Operation
< 0 || Operation
> EfiBusMasterCommonBuffer
) {
1024 return EFI_INVALID_PARAMETER
;
1027 if (((UINTN
) (*HostAddress
) != (*HostAddress
)) && Operation
== EfiBusMasterCommonBuffer
) {
1028 return EFI_UNSUPPORTED
;
1031 Status
= Private
->PciRootBridgeIo
->Map (
1032 Private
->PciRootBridgeIo
,
1033 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION
) Operation
,
1034 (VOID
*) (UINTN
) (*HostAddress
),
1045 Completes the Map() operation and releases any corresponding resources.
1047 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1048 @param Mapping The mapping value returned from Map().
1050 @retval EFI_SUCCESS The range was unmapped.
1051 @retval EFI_DEVICE_ERROR The data was not committed to the target system
1058 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1063 DEVICE_IO_PRIVATE_DATA
*Private
;
1065 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1067 Status
= Private
->PciRootBridgeIo
->Unmap (
1068 Private
->PciRootBridgeIo
,
1077 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
1079 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1080 @param Type The type allocation to perform.
1081 @param MemoryType The type of memory to allocate,
1082 EfiBootServicesData or EfiRuntimeServicesData.
1083 @param Pages The number of pages to allocate.
1084 @param PhysicalAddress A pointer to store the base address of the
1087 @retval EFI_SUCCESS The requested memory pages were allocated.
1088 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
1089 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.
1090 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on
1096 DeviceIoAllocateBuffer (
1097 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1098 IN EFI_ALLOCATE_TYPE Type
,
1099 IN EFI_MEMORY_TYPE MemoryType
,
1101 IN OUT EFI_PHYSICAL_ADDRESS
*PhysicalAddress
1105 EFI_PHYSICAL_ADDRESS HostAddress
;
1106 DEVICE_IO_PRIVATE_DATA
*Private
;
1109 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1111 HostAddress
= *PhysicalAddress
;
1113 if ((MemoryType
!= EfiBootServicesData
) && (MemoryType
!= EfiRuntimeServicesData
)) {
1114 return EFI_INVALID_PARAMETER
;
1117 if ((Type
>= MaxAllocateType
) || (Type
< AllocateAnyPages
)) {
1118 return EFI_INVALID_PARAMETER
;
1121 if ((Type
== AllocateAddress
) && (HostAddress
+ EFI_PAGES_TO_SIZE (Pages
) - 1 > MAX_COMMON_BUFFER
)) {
1122 return EFI_UNSUPPORTED
;
1125 if ((AllocateAnyPages
== Type
) || (AllocateMaxAddress
== Type
&& HostAddress
> MAX_COMMON_BUFFER
)) {
1126 Type
= AllocateMaxAddress
;
1127 HostAddress
= MAX_COMMON_BUFFER
;
1130 HostAddress2
= (VOID
*) (UINTN
) (HostAddress
);
1131 Status
= Private
->PciRootBridgeIo
->AllocateBuffer (
1132 Private
->PciRootBridgeIo
,
1137 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE
|
1138 EFI_PCI_ATTRIBUTE_MEMORY_CACHED
1141 if (EFI_ERROR (Status
)) {
1146 *PhysicalAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) HostAddress2
;
1153 Flushes any posted write data to the device.
1155 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1157 @retval EFI_SUCCESS The buffers were flushed.
1158 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware
1165 IN EFI_DEVICE_IO_PROTOCOL
*This
1169 DEVICE_IO_PRIVATE_DATA
*Private
;
1171 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1173 Status
= Private
->PciRootBridgeIo
->Flush (Private
->PciRootBridgeIo
);
1180 Frees pages that were allocated with AllocateBuffer().
1182 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.
1183 @param Pages The number of pages to free.
1184 @param HostAddress The base address of the range to free.
1186 @retval EFI_SUCCESS The requested memory pages were freed.
1187 @retval EFI_NOT_FOUND The requested memory pages were not allocated with
1189 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is
1195 DeviceIoFreeBuffer (
1196 IN EFI_DEVICE_IO_PROTOCOL
*This
,
1198 IN EFI_PHYSICAL_ADDRESS HostAddress
1201 DEVICE_IO_PRIVATE_DATA
*Private
;
1203 Private
= DEVICE_IO_PRIVATE_DATA_FROM_THIS (This
);
1205 if (((HostAddress
& EFI_PAGE_MASK
) != 0) || (Pages
<= 0)) {
1206 return EFI_INVALID_PARAMETER
;
1209 return Private
->PciRootBridgeIo
->FreeBuffer (
1210 Private
->PciRootBridgeIo
,
1212 (VOID
*) (UINTN
) HostAddress