TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtioFdtDxe.c
Go to the documentation of this file.
1
10#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
18
20
21#include <Protocol/FdtClient.h>
22
23#pragma pack (1)
24typedef struct {
25 VENDOR_DEVICE_PATH Vendor;
26 UINT64 PhysBase;
29#pragma pack ()
30
32EFIAPI
33InitializeVirtioFdtDxe (
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;
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 __func__,
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);
94 );
95 if (DevicePath == NULL) {
96 DEBUG ((DEBUG_ERROR, "%a: Out of memory\n", __func__));
97 continue;
98 }
99
100 CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);
101 DevicePath->PhysBase = RegBase;
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,
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 __func__,
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 __func__,
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 __func__,
156 FindNodeStatus
157 ));
158 }
159
160 return EFI_SUCCESS;
161}
UINT64 EFIAPI SwapBytes64(IN UINT64 Value)
Definition: SwapBytes64.c:25
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI CreateDeviceNode(IN UINT8 NodeType, IN UINT8 NodeSubType, IN UINT16 NodeLength)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_STATUS VirtioMmioInstallDevice(IN PHYSICAL_ADDRESS BaseAddress, IN EFI_HANDLE Handle)