]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
OvmfPkg: replace old EFI_D_ debug levels with new DEBUG_ ones
[mirror_edk2.git] / OvmfPkg / Library / VirtioMmioDeviceLib / VirtioMmioDevice.c
CommitLineData
6fb4e772
OM
1/** @file\r
2\r
3 This driver produces Virtio Device Protocol instances for Virtio Mmio devices.\r
4\r
5 Copyright (C) 2013, ARM Ltd.\r
084cfc1a 6 Copyright (C) 2017, AMD Inc. All rights reserved.<BR>\r
6fb4e772 7\r
b26f0cf9 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6fb4e772
OM
9\r
10**/\r
11\r
12#include <Library/BaseMemoryLib.h>\r
6fb4e772
OM
13#include <Library/UefiBootServicesTableLib.h>\r
14\r
15#include "VirtioMmioDevice.h"\r
16\r
4120bb49 17STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {\r
6fb4e772
OM
18 0, // Revision\r
19 0, // SubSystemDeviceId\r
20 VirtioMmioGetDeviceFeatures, // GetDeviceFeatures\r
21 VirtioMmioSetGuestFeatures, // SetGuestFeatures\r
6fb4e772
OM
22 VirtioMmioSetQueueAddress, // SetQueueAddress\r
23 VirtioMmioSetQueueSel, // SetQueueSel\r
24 VirtioMmioSetQueueNotify, // SetQueueNotify\r
25 VirtioMmioSetQueueAlignment, // SetQueueAlign\r
26 VirtioMmioSetPageSize, // SetPageSize\r
27 VirtioMmioGetQueueSize, // GetQueueNumMax\r
28 VirtioMmioSetQueueSize, // SetQueueNum\r
29 VirtioMmioGetDeviceStatus, // GetDeviceStatus\r
30 VirtioMmioSetDeviceStatus, // SetDeviceStatus\r
31 VirtioMmioDeviceWrite, // WriteDevice\r
084cfc1a
BS
32 VirtioMmioDeviceRead, // ReadDevice\r
33 VirtioMmioAllocateSharedPages, // AllocateSharedPages\r
34 VirtioMmioFreeSharedPages, // FreeSharedPages\r
35 VirtioMmioMapSharedBuffer, // MapSharedBuffer\r
36 VirtioMmioUnmapSharedBuffer // UnmapSharedBuffer\r
6fb4e772
OM
37};\r
38\r
39/**\r
40\r
41 Initialize the VirtIo MMIO Device\r
42\r
43 @param[in] BaseAddress Base Address of the VirtIo MMIO Device\r
44\r
45 @param[in, out] Device The driver instance to configure.\r
46\r
47 @retval EFI_SUCCESS Setup complete.\r
48\r
49 @retval EFI_UNSUPPORTED The driver is not a VirtIo MMIO device.\r
50\r
51**/\r
52STATIC\r
53EFI_STATUS\r
54EFIAPI\r
55VirtioMmioInit (\r
56 IN PHYSICAL_ADDRESS BaseAddress,\r
57 IN OUT VIRTIO_MMIO_DEVICE *Device\r
58 )\r
59{\r
60 UINT32 MagicValue;\r
61 UINT32 VendorId;\r
62 UINT32 Version;\r
63\r
64 //\r
65 // Initialize VirtIo Mmio Device\r
66 //\r
67 CopyMem (&Device->VirtioDevice, &mMmioDeviceProtocolTemplate,\r
68 sizeof (VIRTIO_DEVICE_PROTOCOL));\r
69 Device->BaseAddress = BaseAddress;\r
70 Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (0, 9, 5);\r
71 Device->VirtioDevice.SubSystemDeviceId =\r
72 MmioRead32 (BaseAddress + VIRTIO_MMIO_OFFSET_DEVICE_ID);\r
73\r
74 //\r
75 // Double-check MMIO-specific values\r
76 //\r
77 MagicValue = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_MAGIC);\r
78 if (MagicValue != VIRTIO_MMIO_MAGIC) {\r
79 return EFI_UNSUPPORTED;\r
80 }\r
81\r
82 Version = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_VERSION);\r
83 if (Version != 1) {\r
84 return EFI_UNSUPPORTED;\r
85 }\r
86\r
87 //\r
88 // Double-check MMIO-specific values\r
89 //\r
90 VendorId = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_VENDOR_ID);\r
91 if (VendorId != VIRTIO_VENDOR_ID) {\r
92 //\r
93 // The ARM Base and Foundation Models do not report a valid VirtIo VendorId.\r
94 // They return a value of 0x0 for the VendorId.\r
95 //\r
70d5086c 96 DEBUG((DEBUG_WARN, "VirtioMmioInit: Warning: The VendorId (0x%X) does not "\r
6fb4e772
OM
97 "match the VirtIo VendorId (0x%X).\n",\r
98 VendorId, VIRTIO_VENDOR_ID));\r
99 }\r
100\r
101 return EFI_SUCCESS;\r
102}\r
103\r
104\r
105/**\r
106\r
107 Uninitialize the internals of a virtio-mmio device that has been successfully\r
108 set up with VirtioMmioInit().\r
109\r
110 @param[in, out] Device The device to clean up.\r
111\r
112**/\r
113\r
114STATIC\r
115VOID\r
116EFIAPI\r
117VirtioMmioUninit (\r
118 IN VIRTIO_MMIO_DEVICE *Device\r
119 )\r
120{\r
121 //\r
122 // Note: This function mirrors VirtioMmioInit() that does not allocate any\r
123 // resources - there's nothing to free here.\r
124 //\r
125}\r
126\r
127EFI_STATUS\r
128VirtioMmioInstallDevice (\r
129 IN PHYSICAL_ADDRESS BaseAddress,\r
130 IN EFI_HANDLE Handle\r
131 )\r
132{\r
133 EFI_STATUS Status;\r
134 VIRTIO_MMIO_DEVICE *VirtIo;\r
135\r
136 if (!BaseAddress) {\r
137 return EFI_INVALID_PARAMETER;\r
138 }\r
139 if (Handle == NULL) {\r
140 return EFI_INVALID_PARAMETER;\r
141 }\r
142\r
143 //\r
144 // Allocate VIRTIO_MMIO_DEVICE\r
145 //\r
146 VirtIo = AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE));\r
147 if (VirtIo == NULL) {\r
148 return EFI_OUT_OF_RESOURCES;\r
149 }\r
150\r
151 VirtIo->Signature = VIRTIO_MMIO_DEVICE_SIGNATURE;\r
152\r
153 Status = VirtioMmioInit (BaseAddress, VirtIo);\r
154 if (EFI_ERROR (Status)) {\r
155 goto FreeVirtioMem;\r
156 }\r
157\r
158 //\r
159 // Install VIRTIO_DEVICE_PROTOCOL to Handle\r
160 //\r
161 Status = gBS->InstallProtocolInterface (&Handle,\r
162 &gVirtioDeviceProtocolGuid, EFI_NATIVE_INTERFACE,\r
163 &VirtIo->VirtioDevice);\r
164 if (EFI_ERROR (Status)) {\r
165 goto UninitVirtio;\r
166 }\r
167\r
168 return EFI_SUCCESS;\r
169\r
170UninitVirtio:\r
171 VirtioMmioUninit (VirtIo);\r
172\r
173FreeVirtioMem:\r
174 FreePool (VirtIo);\r
175 return Status;\r
176}\r
177\r
178EFI_STATUS\r
179VirtioMmioUninstallDevice (\r
180 IN EFI_HANDLE DeviceHandle\r
181 )\r
182{\r
183 VIRTIO_DEVICE_PROTOCOL *VirtioDevice;\r
184 VIRTIO_MMIO_DEVICE *MmioDevice;\r
185 EFI_STATUS Status;\r
186\r
187 Status = gBS->OpenProtocol (\r
188 DeviceHandle, // candidate device\r
189 &gVirtioDeviceProtocolGuid, // retrieve the VirtIo iface\r
190 (VOID **)&VirtioDevice, // target pointer\r
191 DeviceHandle, // requestor driver identity\r
192 DeviceHandle, // requesting lookup for dev.\r
193 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added\r
194 );\r
195 if (EFI_ERROR (Status)) {\r
196 return Status;\r
197 }\r
198\r
199 //\r
200 // Get the MMIO device from the VirtIo Device instance\r
201 //\r
202 MmioDevice = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice);\r
203\r
204 //\r
205 // Uninstall the protocol interface\r
206 //\r
207 Status = gBS->UninstallProtocolInterface (DeviceHandle,\r
208 &gVirtioDeviceProtocolGuid, &MmioDevice->VirtioDevice\r
209 );\r
210 if (EFI_ERROR (Status)) {\r
211 return Status;\r
212 }\r
213\r
214 //\r
215 // Uninitialize the VirtIo Device\r
216 //\r
217 VirtioMmioUninit (MmioDevice);\r
218 FreePool (MmioDevice);\r
219\r
220 return EFI_SUCCESS;\r
221}\r