]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.c
ArmVirtPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / ArmVirtPkg / VirtioFdtDxe / VirtioFdtDxe.c
CommitLineData
57b6122f
AB
1/** @file\r
2* Virtio FDT client protocol driver for virtio,mmio DT node\r
3*\r
4* Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>\r
5*\r
9792fb0e 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
57b6122f
AB
7*\r
8**/\r
9\r
10#include <Library/BaseLib.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/DevicePathLib.h>\r
14#include <Library/MemoryAllocationLib.h>\r
15#include <Library/UefiBootServicesTableLib.h>\r
16#include <Library/UefiDriverEntryPoint.h>\r
17#include <Library/VirtioMmioDeviceLib.h>\r
18\r
19#include <Guid/VirtioMmioTransport.h>\r
20\r
21#include <Protocol/FdtClient.h>\r
22\r
23#pragma pack (1)\r
24typedef struct {\r
25 VENDOR_DEVICE_PATH Vendor;\r
26 UINT64 PhysBase;\r
27 EFI_DEVICE_PATH_PROTOCOL End;\r
28} VIRTIO_TRANSPORT_DEVICE_PATH;\r
29#pragma pack ()\r
30\r
31EFI_STATUS\r
32EFIAPI\r
33InitializeVirtioFdtDxe (\r
34 IN EFI_HANDLE ImageHandle,\r
35 IN EFI_SYSTEM_TABLE *SystemTable\r
36 )\r
37{\r
38 EFI_STATUS Status, FindNodeStatus;\r
39 FDT_CLIENT_PROTOCOL *FdtClient;\r
40 INT32 Node;\r
41 CONST UINT64 *Reg;\r
42 UINT32 RegSize;\r
43 VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;\r
44 EFI_HANDLE Handle;\r
45 UINT64 RegBase;\r
46\r
47 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
48 (VOID **)&FdtClient);\r
49 ASSERT_EFI_ERROR (Status);\r
50\r
51 for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,\r
52 "virtio,mmio", &Node);\r
53 !EFI_ERROR (FindNodeStatus);\r
54 FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,\r
55 "virtio,mmio", Node, &Node)) {\r
56\r
57 Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",\r
58 (CONST VOID **)&Reg, &RegSize);\r
59 if (EFI_ERROR (Status)) {\r
60 DEBUG ((EFI_D_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",\r
61 __FUNCTION__, Status));\r
62 continue;\r
63 }\r
64\r
65 ASSERT (RegSize == 16);\r
66\r
67 //\r
68 // Create a unique device path for this transport on the fly\r
69 //\r
70 RegBase = SwapBytes64 (*Reg);\r
71 DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (\r
72 HARDWARE_DEVICE_PATH,\r
73 HW_VENDOR_DP,\r
74 sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));\r
75 if (DevicePath == NULL) {\r
76 DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));\r
77 continue;\r
78 }\r
79\r
80 CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);\r
81 DevicePath->PhysBase = RegBase;\r
82 SetDevicePathNodeLength (&DevicePath->Vendor,\r
83 sizeof (*DevicePath) - sizeof (DevicePath->End));\r
84 SetDevicePathEndNode (&DevicePath->End);\r
85\r
86 Handle = NULL;\r
87 Status = gBS->InstallProtocolInterface (&Handle,\r
88 &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,\r
89 DevicePath);\r
90 if (EFI_ERROR (Status)) {\r
91 DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "\r
92 "protocol on a new handle (Status == %r)\n",\r
93 __FUNCTION__, Status));\r
94 FreePool (DevicePath);\r
95 continue;\r
96 }\r
97\r
98 Status = VirtioMmioInstallDevice (RegBase, Handle);\r
99 if (EFI_ERROR (Status)) {\r
100 DEBUG ((EFI_D_ERROR, "%a: Failed to install VirtIO transport @ 0x%Lx "\r
101 "on handle %p (Status == %r)\n", __FUNCTION__, RegBase,\r
102 Handle, Status));\r
103\r
104 Status = gBS->UninstallProtocolInterface (Handle,\r
105 &gEfiDevicePathProtocolGuid, DevicePath);\r
106 ASSERT_EFI_ERROR (Status);\r
107 FreePool (DevicePath);\r
108 continue;\r
109 }\r
110 }\r
111\r
112 if (EFI_ERROR (FindNodeStatus) && FindNodeStatus != EFI_NOT_FOUND) {\r
113 DEBUG ((EFI_D_ERROR, "%a: Error occurred while iterating DT nodes "\r
114 "(FindNodeStatus == %r)\n", __FUNCTION__, FindNodeStatus));\r
115 }\r
116\r
117 return EFI_SUCCESS;\r
118}\r