]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
OvmfPkg: drop redundant VendorID check in VirtioMmioDeviceLib
[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
6fb4e772
OM
61 UINT32 Version;\r
62\r
63 //\r
64 // Initialize VirtIo Mmio Device\r
65 //\r
66 CopyMem (&Device->VirtioDevice, &mMmioDeviceProtocolTemplate,\r
67 sizeof (VIRTIO_DEVICE_PROTOCOL));\r
68 Device->BaseAddress = BaseAddress;\r
69 Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (0, 9, 5);\r
70 Device->VirtioDevice.SubSystemDeviceId =\r
71 MmioRead32 (BaseAddress + VIRTIO_MMIO_OFFSET_DEVICE_ID);\r
72\r
73 //\r
74 // Double-check MMIO-specific values\r
75 //\r
76 MagicValue = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_MAGIC);\r
77 if (MagicValue != VIRTIO_MMIO_MAGIC) {\r
78 return EFI_UNSUPPORTED;\r
79 }\r
80\r
81 Version = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_VERSION);\r
82 if (Version != 1) {\r
83 return EFI_UNSUPPORTED;\r
84 }\r
85\r
6fb4e772
OM
86 return EFI_SUCCESS;\r
87}\r
88\r
89\r
90/**\r
91\r
92 Uninitialize the internals of a virtio-mmio device that has been successfully\r
93 set up with VirtioMmioInit().\r
94\r
95 @param[in, out] Device The device to clean up.\r
96\r
97**/\r
98\r
99STATIC\r
100VOID\r
101EFIAPI\r
102VirtioMmioUninit (\r
103 IN VIRTIO_MMIO_DEVICE *Device\r
104 )\r
105{\r
106 //\r
107 // Note: This function mirrors VirtioMmioInit() that does not allocate any\r
108 // resources - there's nothing to free here.\r
109 //\r
110}\r
111\r
112EFI_STATUS\r
113VirtioMmioInstallDevice (\r
114 IN PHYSICAL_ADDRESS BaseAddress,\r
115 IN EFI_HANDLE Handle\r
116 )\r
117{\r
118 EFI_STATUS Status;\r
119 VIRTIO_MMIO_DEVICE *VirtIo;\r
120\r
121 if (!BaseAddress) {\r
122 return EFI_INVALID_PARAMETER;\r
123 }\r
124 if (Handle == NULL) {\r
125 return EFI_INVALID_PARAMETER;\r
126 }\r
127\r
128 //\r
129 // Allocate VIRTIO_MMIO_DEVICE\r
130 //\r
131 VirtIo = AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE));\r
132 if (VirtIo == NULL) {\r
133 return EFI_OUT_OF_RESOURCES;\r
134 }\r
135\r
136 VirtIo->Signature = VIRTIO_MMIO_DEVICE_SIGNATURE;\r
137\r
138 Status = VirtioMmioInit (BaseAddress, VirtIo);\r
139 if (EFI_ERROR (Status)) {\r
140 goto FreeVirtioMem;\r
141 }\r
142\r
143 //\r
144 // Install VIRTIO_DEVICE_PROTOCOL to Handle\r
145 //\r
146 Status = gBS->InstallProtocolInterface (&Handle,\r
147 &gVirtioDeviceProtocolGuid, EFI_NATIVE_INTERFACE,\r
148 &VirtIo->VirtioDevice);\r
149 if (EFI_ERROR (Status)) {\r
150 goto UninitVirtio;\r
151 }\r
152\r
153 return EFI_SUCCESS;\r
154\r
155UninitVirtio:\r
156 VirtioMmioUninit (VirtIo);\r
157\r
158FreeVirtioMem:\r
159 FreePool (VirtIo);\r
160 return Status;\r
161}\r
162\r
163EFI_STATUS\r
164VirtioMmioUninstallDevice (\r
165 IN EFI_HANDLE DeviceHandle\r
166 )\r
167{\r
168 VIRTIO_DEVICE_PROTOCOL *VirtioDevice;\r
169 VIRTIO_MMIO_DEVICE *MmioDevice;\r
170 EFI_STATUS Status;\r
171\r
172 Status = gBS->OpenProtocol (\r
173 DeviceHandle, // candidate device\r
174 &gVirtioDeviceProtocolGuid, // retrieve the VirtIo iface\r
175 (VOID **)&VirtioDevice, // target pointer\r
176 DeviceHandle, // requestor driver identity\r
177 DeviceHandle, // requesting lookup for dev.\r
178 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added\r
179 );\r
180 if (EFI_ERROR (Status)) {\r
181 return Status;\r
182 }\r
183\r
184 //\r
185 // Get the MMIO device from the VirtIo Device instance\r
186 //\r
187 MmioDevice = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice);\r
188\r
189 //\r
190 // Uninstall the protocol interface\r
191 //\r
192 Status = gBS->UninstallProtocolInterface (DeviceHandle,\r
193 &gVirtioDeviceProtocolGuid, &MmioDevice->VirtioDevice\r
194 );\r
195 if (EFI_ERROR (Status)) {\r
196 return Status;\r
197 }\r
198\r
199 //\r
200 // Uninitialize the VirtIo Device\r
201 //\r
202 VirtioMmioUninit (MmioDevice);\r
203 FreePool (MmioDevice);\r
204\r
205 return EFI_SUCCESS;\r
206}\r