3 This driver produces Virtio Device Protocol instances for Virtio Mmio devices.
5 Copyright (C) 2013, ARM Ltd.
6 Copyright (C) 2017, AMD Inc. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
15 #include "VirtioMmioDevice.h"
17 STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate
= {
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
41 Initialize the VirtIo MMIO Device
43 @param[in] BaseAddress Base Address of the VirtIo MMIO Device
45 @param[in, out] Device The driver instance to configure.
47 @retval EFI_SUCCESS Setup complete.
49 @retval EFI_UNSUPPORTED The driver is not a VirtIo MMIO device.
56 IN PHYSICAL_ADDRESS BaseAddress
,
57 IN OUT VIRTIO_MMIO_DEVICE
*Device
63 // Initialize VirtIo Mmio Device
66 &Device
->VirtioDevice
,
67 &mMmioDeviceProtocolTemplate
,
68 sizeof (VIRTIO_DEVICE_PROTOCOL
)
70 Device
->BaseAddress
= BaseAddress
;
71 Device
->VirtioDevice
.SubSystemDeviceId
=
72 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
75 // Double-check MMIO-specific values
77 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
78 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
79 return EFI_UNSUPPORTED
;
82 Device
->Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
83 switch (Device
->Version
) {
84 case VIRTIO_MMIO_DEVICE_VERSION_0_95
:
87 "%a virtio 0.9.5, id %d\n",
89 Device
->VirtioDevice
.SubSystemDeviceId
91 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
93 case VIRTIO_MMIO_DEVICE_VERSION_1_00
:
96 "%a virtio 1.0, id %d\n",
98 Device
->VirtioDevice
.SubSystemDeviceId
100 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (1, 0, 0);
103 return EFI_UNSUPPORTED
;
111 Uninitialize the internals of a virtio-mmio device that has been successfully
112 set up with VirtioMmioInit().
114 @param[in, out] Device The device to clean up.
121 IN VIRTIO_MMIO_DEVICE
*Device
125 // Note: This function mirrors VirtioMmioInit() that does not allocate any
126 // resources - there's nothing to free here.
131 VirtioMmioInstallDevice (
132 IN PHYSICAL_ADDRESS BaseAddress
,
137 VIRTIO_MMIO_DEVICE
*VirtIo
;
140 return EFI_INVALID_PARAMETER
;
143 if (Handle
== NULL
) {
144 return EFI_INVALID_PARAMETER
;
148 // Allocate VIRTIO_MMIO_DEVICE
150 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
151 if (VirtIo
== NULL
) {
152 return EFI_OUT_OF_RESOURCES
;
155 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
157 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
158 if (EFI_ERROR (Status
)) {
163 // Install VIRTIO_DEVICE_PROTOCOL to Handle
165 Status
= gBS
->InstallProtocolInterface (
167 &gVirtioDeviceProtocolGuid
,
168 EFI_NATIVE_INTERFACE
,
169 &VirtIo
->VirtioDevice
171 if (EFI_ERROR (Status
)) {
178 VirtioMmioUninit (VirtIo
);
186 VirtioMmioUninstallDevice (
187 IN EFI_HANDLE DeviceHandle
190 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
191 VIRTIO_MMIO_DEVICE
*MmioDevice
;
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
202 if (EFI_ERROR (Status
)) {
207 // Get the MMIO device from the VirtIo Device instance
209 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
212 // Uninstall the protocol interface
214 Status
= gBS
->UninstallProtocolInterface (
216 &gVirtioDeviceProtocolGuid
,
217 &MmioDevice
->VirtioDevice
219 if (EFI_ERROR (Status
)) {
224 // Uninitialize the VirtIo Device
226 VirtioMmioUninit (MmioDevice
);
227 FreePool (MmioDevice
);