TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtioMmioDevice.c
Go to the documentation of this file.
1
14
15#include "VirtioMmioDevice.h"
16
17STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
18 0, // Revision
19 0, // SubSystemDeviceId
20 VirtioMmioGetDeviceFeatures, // GetDeviceFeatures
21 VirtioMmioSetGuestFeatures, // SetGuestFeatures
22 VirtioMmioSetQueueAddress, // SetQueueAddress
23 VirtioMmioSetQueueSel, // SetQueueSel
24 VirtioMmioSetQueueNotify, // SetQueueNotify
25 VirtioMmioSetQueueAlignment, // SetQueueAlign
26 VirtioMmioSetPageSize, // SetPageSize
27 VirtioMmioGetQueueSize, // GetQueueNumMax
28 VirtioMmioSetQueueSize, // SetQueueNum
29 VirtioMmioGetDeviceStatus, // GetDeviceStatus
30 VirtioMmioSetDeviceStatus, // SetDeviceStatus
31 VirtioMmioDeviceWrite, // WriteDevice
32 VirtioMmioDeviceRead, // ReadDevice
33 VirtioMmioAllocateSharedPages, // AllocateSharedPages
34 VirtioMmioFreeSharedPages, // FreeSharedPages
35 VirtioMmioMapSharedBuffer, // MapSharedBuffer
36 VirtioMmioUnmapSharedBuffer // UnmapSharedBuffer
37};
38
54EFIAPI
56 IN PHYSICAL_ADDRESS BaseAddress,
58 )
59{
60 UINT32 MagicValue;
61
62 //
63 // Initialize VirtIo Mmio Device
64 //
65 CopyMem (
66 &Device->VirtioDevice,
67 &mMmioDeviceProtocolTemplate,
69 );
70 Device->BaseAddress = BaseAddress;
71 Device->VirtioDevice.SubSystemDeviceId =
72 MmioRead32 (BaseAddress + VIRTIO_MMIO_OFFSET_DEVICE_ID);
73
74 //
75 // Double-check MMIO-specific values
76 //
77 MagicValue = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_MAGIC);
78 if (MagicValue != VIRTIO_MMIO_MAGIC) {
79 return EFI_UNSUPPORTED;
80 }
81
82 Device->Version = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_VERSION);
83 switch (Device->Version) {
84 case VIRTIO_MMIO_DEVICE_VERSION_0_95:
85 DEBUG ((
86 DEBUG_INFO,
87 "%a virtio 0.9.5, id %d\n",
88 __func__,
89 Device->VirtioDevice.SubSystemDeviceId
90 ));
91 Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (0, 9, 5);
92 break;
93 case VIRTIO_MMIO_DEVICE_VERSION_1_00:
94 DEBUG ((
95 DEBUG_INFO,
96 "%a virtio 1.0, id %d\n",
97 __func__,
98 Device->VirtioDevice.SubSystemDeviceId
99 ));
100 Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (1, 0, 0);
101 break;
102 default:
103 return EFI_UNSUPPORTED;
104 }
105
106 return EFI_SUCCESS;
107}
108
117STATIC
118VOID
119EFIAPI
121 IN VIRTIO_MMIO_DEVICE *Device
122 )
123{
124 //
125 // Note: This function mirrors VirtioMmioInit() that does not allocate any
126 // resources - there's nothing to free here.
127 //
128}
129
132 IN PHYSICAL_ADDRESS BaseAddress,
133 IN EFI_HANDLE Handle
134 )
135{
136 EFI_STATUS Status;
137 VIRTIO_MMIO_DEVICE *VirtIo;
138
139 if (!BaseAddress) {
140 return EFI_INVALID_PARAMETER;
141 }
142
143 if (Handle == NULL) {
144 return EFI_INVALID_PARAMETER;
145 }
146
147 //
148 // Allocate VIRTIO_MMIO_DEVICE
149 //
150 VirtIo = AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE));
151 if (VirtIo == NULL) {
152 return EFI_OUT_OF_RESOURCES;
153 }
154
155 VirtIo->Signature = VIRTIO_MMIO_DEVICE_SIGNATURE;
156
157 Status = VirtioMmioInit (BaseAddress, VirtIo);
158 if (EFI_ERROR (Status)) {
159 goto FreeVirtioMem;
160 }
161
162 //
163 // Install VIRTIO_DEVICE_PROTOCOL to Handle
164 //
165 Status = gBS->InstallProtocolInterface (
166 &Handle,
167 &gVirtioDeviceProtocolGuid,
169 &VirtIo->VirtioDevice
170 );
171 if (EFI_ERROR (Status)) {
172 goto UninitVirtio;
173 }
174
175 return EFI_SUCCESS;
176
177UninitVirtio:
178 VirtioMmioUninit (VirtIo);
179
180FreeVirtioMem:
181 FreePool (VirtIo);
182 return Status;
183}
184
187 IN EFI_HANDLE DeviceHandle
188 )
189{
190 VIRTIO_DEVICE_PROTOCOL *VirtioDevice;
191 VIRTIO_MMIO_DEVICE *MmioDevice;
192 EFI_STATUS Status;
193
194 Status = gBS->OpenProtocol (
195 DeviceHandle, // candidate device
196 &gVirtioDeviceProtocolGuid, // retrieve the VirtIo iface
197 (VOID **)&VirtioDevice, // target pointer
198 DeviceHandle, // requestor driver identity
199 DeviceHandle, // requesting lookup for dev.
200 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
201 );
202 if (EFI_ERROR (Status)) {
203 return Status;
204 }
205
206 //
207 // Get the MMIO device from the VirtIo Device instance
208 //
209 MmioDevice = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice);
210
211 //
212 // Uninstall the protocol interface
213 //
214 Status = gBS->UninstallProtocolInterface (
215 DeviceHandle,
216 &gVirtioDeviceProtocolGuid,
217 &MmioDevice->VirtioDevice
218 );
219 if (EFI_ERROR (Status)) {
220 return Status;
221 }
222
223 //
224 // Uninitialize the VirtIo Device
225 //
226 VirtioMmioUninit (MmioDevice);
227 FreePool (MmioDevice);
228
229 return EFI_SUCCESS;
230}
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
Definition: IoLib.c:262
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#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)
EFI_STATUS VirtioMmioUninstallDevice(IN EFI_HANDLE DeviceHandle)
STATIC VOID EFIAPI VirtioMmioUninit(IN VIRTIO_MMIO_DEVICE *Device)
STATIC EFI_STATUS EFIAPI VirtioMmioInit(IN PHYSICAL_ADDRESS BaseAddress, IN OUT VIRTIO_MMIO_DEVICE *Device)