2 * Virtio FDT client protocol driver for virtio,mmio DT node
4 * Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>
6 * SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/DevicePathLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16 #include <Library/UefiDriverEntryPoint.h>
17 #include <Library/VirtioMmioDeviceLib.h>
19 #include <Guid/VirtioMmioTransport.h>
21 #include <Protocol/FdtClient.h>
25 VENDOR_DEVICE_PATH Vendor
;
27 EFI_DEVICE_PATH_PROTOCOL End
;
28 } VIRTIO_TRANSPORT_DEVICE_PATH
;
33 InitializeVirtioFdtDxe (
34 IN EFI_HANDLE ImageHandle
,
35 IN EFI_SYSTEM_TABLE
*SystemTable
38 EFI_STATUS Status
, FindNodeStatus
;
39 FDT_CLIENT_PROTOCOL
*FdtClient
;
43 VIRTIO_TRANSPORT_DEVICE_PATH
*DevicePath
;
47 Status
= gBS
->LocateProtocol (
48 &gFdtClientProtocolGuid
,
52 ASSERT_EFI_ERROR (Status
);
54 for (FindNodeStatus
= FdtClient
->FindCompatibleNode (
59 !EFI_ERROR (FindNodeStatus
);
60 FindNodeStatus
= FdtClient
->FindNextCompatibleNode (
67 Status
= FdtClient
->GetNodeProperty (
74 if (EFI_ERROR (Status
)) {
77 "%a: GetNodeProperty () failed (Status == %r)\n",
84 ASSERT (RegSize
== 16);
87 // Create a unique device path for this transport on the fly
89 RegBase
= SwapBytes64 (*Reg
);
90 DevicePath
= (VIRTIO_TRANSPORT_DEVICE_PATH
*)CreateDeviceNode (
93 sizeof (VIRTIO_TRANSPORT_DEVICE_PATH
)
95 if (DevicePath
== NULL
) {
96 DEBUG ((DEBUG_ERROR
, "%a: Out of memory\n", __FUNCTION__
));
100 CopyGuid (&DevicePath
->Vendor
.Guid
, &gVirtioMmioTransportGuid
);
101 DevicePath
->PhysBase
= RegBase
;
102 SetDevicePathNodeLength (
104 sizeof (*DevicePath
) - sizeof (DevicePath
->End
)
106 SetDevicePathEndNode (&DevicePath
->End
);
109 Status
= gBS
->InstallProtocolInterface (
111 &gEfiDevicePathProtocolGuid
,
112 EFI_NATIVE_INTERFACE
,
115 if (EFI_ERROR (Status
)) {
118 "%a: Failed to install the EFI_DEVICE_PATH "
119 "protocol on a new handle (Status == %r)\n",
123 FreePool (DevicePath
);
127 Status
= VirtioMmioInstallDevice (RegBase
, Handle
);
128 if (EFI_ERROR (Status
)) {
131 "%a: Failed to install VirtIO transport @ 0x%Lx "
132 "on handle %p (Status == %r)\n",
139 Status
= gBS
->UninstallProtocolInterface (
141 &gEfiDevicePathProtocolGuid
,
144 ASSERT_EFI_ERROR (Status
);
145 FreePool (DevicePath
);
150 if (EFI_ERROR (FindNodeStatus
) && (FindNodeStatus
!= EFI_NOT_FOUND
)) {
153 "%a: Error occurred while iterating DT nodes "
154 "(FindNodeStatus == %r)\n",