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