+++ /dev/null
-/** @file\r
-* Virtio FDT client protocol driver for virtio,mmio DT node\r
-*\r
-* Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>\r
-*\r
-* SPDX-License-Identifier: BSD-2-Clause-Patent\r
-*\r
-**/\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/VirtioMmioDeviceLib.h>\r
-\r
-#include <Guid/VirtioMmioTransport.h>\r
-\r
-#include <Protocol/FdtClient.h>\r
-\r
-#pragma pack (1)\r
-typedef struct {\r
- VENDOR_DEVICE_PATH Vendor;\r
- UINT64 PhysBase;\r
- EFI_DEVICE_PATH_PROTOCOL End;\r
-} VIRTIO_TRANSPORT_DEVICE_PATH;\r
-#pragma pack ()\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeVirtioFdtDxe (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status, FindNodeStatus;\r
- FDT_CLIENT_PROTOCOL *FdtClient;\r
- INT32 Node;\r
- CONST UINT64 *Reg;\r
- UINT32 RegSize;\r
- VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;\r
- EFI_HANDLE Handle;\r
- UINT64 RegBase;\r
-\r
- Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
- (VOID **)&FdtClient);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,\r
- "virtio,mmio", &Node);\r
- !EFI_ERROR (FindNodeStatus);\r
- FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,\r
- "virtio,mmio", Node, &Node)) {\r
-\r
- Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",\r
- (CONST VOID **)&Reg, &RegSize);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",\r
- __FUNCTION__, Status));\r
- continue;\r
- }\r
-\r
- ASSERT (RegSize == 16);\r
-\r
- //\r
- // Create a unique device path for this transport on the fly\r
- //\r
- RegBase = SwapBytes64 (*Reg);\r
- DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));\r
- if (DevicePath == NULL) {\r
- DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));\r
- continue;\r
- }\r
-\r
- CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);\r
- DevicePath->PhysBase = RegBase;\r
- SetDevicePathNodeLength (&DevicePath->Vendor,\r
- sizeof (*DevicePath) - sizeof (DevicePath->End));\r
- SetDevicePathEndNode (&DevicePath->End);\r
-\r
- Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (&Handle,\r
- &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,\r
- DevicePath);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "\r
- "protocol on a new handle (Status == %r)\n",\r
- __FUNCTION__, Status));\r
- FreePool (DevicePath);\r
- continue;\r
- }\r
-\r
- Status = VirtioMmioInstallDevice (RegBase, Handle);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a: Failed to install VirtIO transport @ 0x%Lx "\r
- "on handle %p (Status == %r)\n", __FUNCTION__, RegBase,\r
- Handle, Status));\r
-\r
- Status = gBS->UninstallProtocolInterface (Handle,\r
- &gEfiDevicePathProtocolGuid, DevicePath);\r
- ASSERT_EFI_ERROR (Status);\r
- FreePool (DevicePath);\r
- continue;\r
- }\r
- }\r
-\r
- if (EFI_ERROR (FindNodeStatus) && FindNodeStatus != EFI_NOT_FOUND) {\r
- DEBUG ((EFI_D_ERROR, "%a: Error occurred while iterating DT nodes "\r
- "(FindNodeStatus == %r)\n", __FUNCTION__, FindNodeStatus));\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r