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
65 // Initialize VirtIo Mmio Device
67 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
68 sizeof (VIRTIO_DEVICE_PROTOCOL
));
69 Device
->BaseAddress
= BaseAddress
;
70 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
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 Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
84 return EFI_UNSUPPORTED
;
88 // Double-check MMIO-specific values
90 VendorId
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VENDOR_ID
);
91 if (VendorId
!= VIRTIO_VENDOR_ID
) {
93 // The ARM Base and Foundation Models do not report a valid VirtIo VendorId.
94 // They return a value of 0x0 for the VendorId.
96 DEBUG((EFI_D_WARN
, "VirtioMmioInit: Warning: The VendorId (0x%X) does not "
97 "match the VirtIo VendorId (0x%X).\n",
98 VendorId
, VIRTIO_VENDOR_ID
));
107 Uninitialize the internals of a virtio-mmio device that has been successfully
108 set up with VirtioMmioInit().
110 @param[in, out] Device The device to clean up.
118 IN VIRTIO_MMIO_DEVICE
*Device
122 // Note: This function mirrors VirtioMmioInit() that does not allocate any
123 // resources - there's nothing to free here.
128 VirtioMmioInstallDevice (
129 IN PHYSICAL_ADDRESS BaseAddress
,
134 VIRTIO_MMIO_DEVICE
*VirtIo
;
137 return EFI_INVALID_PARAMETER
;
139 if (Handle
== NULL
) {
140 return EFI_INVALID_PARAMETER
;
144 // Allocate VIRTIO_MMIO_DEVICE
146 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
147 if (VirtIo
== NULL
) {
148 return EFI_OUT_OF_RESOURCES
;
151 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
153 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
154 if (EFI_ERROR (Status
)) {
159 // Install VIRTIO_DEVICE_PROTOCOL to Handle
161 Status
= gBS
->InstallProtocolInterface (&Handle
,
162 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
163 &VirtIo
->VirtioDevice
);
164 if (EFI_ERROR (Status
)) {
171 VirtioMmioUninit (VirtIo
);
179 VirtioMmioUninstallDevice (
180 IN EFI_HANDLE DeviceHandle
183 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
184 VIRTIO_MMIO_DEVICE
*MmioDevice
;
187 Status
= gBS
->OpenProtocol (
188 DeviceHandle
, // candidate device
189 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
190 (VOID
**)&VirtioDevice
, // target pointer
191 DeviceHandle
, // requestor driver identity
192 DeviceHandle
, // requesting lookup for dev.
193 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
195 if (EFI_ERROR (Status
)) {
200 // Get the MMIO device from the VirtIo Device instance
202 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
205 // Uninstall the protocol interface
207 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
208 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
210 if (EFI_ERROR (Status
)) {
215 // Uninitialize the VirtIo Device
217 VirtioMmioUninit (MmioDevice
);
218 FreePool (MmioDevice
);