]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Fdt / VirtioFdtDxe / VirtioFdtDxe.c
1 /** @file
2 * Virtio FDT client protocol driver for virtio,mmio DT node
3 *
4 * Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>
5 *
6 * SPDX-License-Identifier: BSD-2-Clause-Patent
7 *
8 **/
9
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>
18
19 #include <Guid/VirtioMmioTransport.h>
20
21 #include <Protocol/FdtClient.h>
22
23 #pragma pack (1)
24 typedef struct {
25 VENDOR_DEVICE_PATH Vendor;
26 UINT64 PhysBase;
27 EFI_DEVICE_PATH_PROTOCOL End;
28 } VIRTIO_TRANSPORT_DEVICE_PATH;
29 #pragma pack ()
30
31 EFI_STATUS
32 EFIAPI
33 InitializeVirtioFdtDxe (
34 IN EFI_HANDLE ImageHandle,
35 IN EFI_SYSTEM_TABLE *SystemTable
36 )
37 {
38 EFI_STATUS Status, FindNodeStatus;
39 FDT_CLIENT_PROTOCOL *FdtClient;
40 INT32 Node;
41 CONST UINT64 *Reg;
42 UINT32 RegSize;
43 VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;
44 EFI_HANDLE Handle;
45 UINT64 RegBase;
46
47 Status = gBS->LocateProtocol (
48 &gFdtClientProtocolGuid,
49 NULL,
50 (VOID **)&FdtClient
51 );
52 ASSERT_EFI_ERROR (Status);
53
54 for (FindNodeStatus = FdtClient->FindCompatibleNode (
55 FdtClient,
56 "virtio,mmio",
57 &Node
58 );
59 !EFI_ERROR (FindNodeStatus);
60 FindNodeStatus = FdtClient->FindNextCompatibleNode (
61 FdtClient,
62 "virtio,mmio",
63 Node,
64 &Node
65 ))
66 {
67 Status = FdtClient->GetNodeProperty (
68 FdtClient,
69 Node,
70 "reg",
71 (CONST VOID **)&Reg,
72 &RegSize
73 );
74 if (EFI_ERROR (Status)) {
75 DEBUG ((
76 DEBUG_ERROR,
77 "%a: GetNodeProperty () failed (Status == %r)\n",
78 __FUNCTION__,
79 Status
80 ));
81 continue;
82 }
83
84 ASSERT (RegSize == 16);
85
86 //
87 // Create a unique device path for this transport on the fly
88 //
89 RegBase = SwapBytes64 (*Reg);
90 DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
91 HARDWARE_DEVICE_PATH,
92 HW_VENDOR_DP,
93 sizeof (VIRTIO_TRANSPORT_DEVICE_PATH)
94 );
95 if (DevicePath == NULL) {
96 DEBUG ((DEBUG_ERROR, "%a: Out of memory\n", __FUNCTION__));
97 continue;
98 }
99
100 CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);
101 DevicePath->PhysBase = RegBase;
102 SetDevicePathNodeLength (
103 &DevicePath->Vendor,
104 sizeof (*DevicePath) - sizeof (DevicePath->End)
105 );
106 SetDevicePathEndNode (&DevicePath->End);
107
108 Handle = NULL;
109 Status = gBS->InstallProtocolInterface (
110 &Handle,
111 &gEfiDevicePathProtocolGuid,
112 EFI_NATIVE_INTERFACE,
113 DevicePath
114 );
115 if (EFI_ERROR (Status)) {
116 DEBUG ((
117 DEBUG_ERROR,
118 "%a: Failed to install the EFI_DEVICE_PATH "
119 "protocol on a new handle (Status == %r)\n",
120 __FUNCTION__,
121 Status
122 ));
123 FreePool (DevicePath);
124 continue;
125 }
126
127 Status = VirtioMmioInstallDevice (RegBase, Handle);
128 if (EFI_ERROR (Status)) {
129 DEBUG ((
130 DEBUG_ERROR,
131 "%a: Failed to install VirtIO transport @ 0x%Lx "
132 "on handle %p (Status == %r)\n",
133 __FUNCTION__,
134 RegBase,
135 Handle,
136 Status
137 ));
138
139 Status = gBS->UninstallProtocolInterface (
140 Handle,
141 &gEfiDevicePathProtocolGuid,
142 DevicePath
143 );
144 ASSERT_EFI_ERROR (Status);
145 FreePool (DevicePath);
146 continue;
147 }
148 }
149
150 if (EFI_ERROR (FindNodeStatus) && (FindNodeStatus != EFI_NOT_FOUND)) {
151 DEBUG ((
152 DEBUG_ERROR,
153 "%a: Error occurred while iterating DT nodes "
154 "(FindNodeStatus == %r)\n",
155 __FUNCTION__,
156 FindNodeStatus
157 ));
158 }
159
160 return EFI_SUCCESS;
161 }