3 This driver produces Virtio Device Protocol instances for Virtio Mmio devices.
5 Copyright (C) 2013, ARM Ltd.
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
21 #include "VirtioMmioDevice.h"
23 static VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate
= {
25 0, // SubSystemDeviceId
26 VirtioMmioGetDeviceFeatures
, // GetDeviceFeatures
27 VirtioMmioSetGuestFeatures
, // SetGuestFeatures
28 VirtioMmioSetQueueAddress
, // SetQueueAddress
29 VirtioMmioSetQueueSel
, // SetQueueSel
30 VirtioMmioSetQueueNotify
, // SetQueueNotify
31 VirtioMmioSetQueueAlignment
, // SetQueueAlign
32 VirtioMmioSetPageSize
, // SetPageSize
33 VirtioMmioGetQueueSize
, // GetQueueNumMax
34 VirtioMmioSetQueueSize
, // SetQueueNum
35 VirtioMmioGetDeviceStatus
, // GetDeviceStatus
36 VirtioMmioSetDeviceStatus
, // SetDeviceStatus
37 VirtioMmioDeviceWrite
, // WriteDevice
38 VirtioMmioDeviceRead
// ReadDevice
43 Initialize the VirtIo MMIO Device
45 @param[in] BaseAddress Base Address of the VirtIo MMIO Device
47 @param[in, out] Device The driver instance to configure.
49 @retval EFI_SUCCESS Setup complete.
51 @retval EFI_UNSUPPORTED The driver is not a VirtIo MMIO device.
58 IN PHYSICAL_ADDRESS BaseAddress
,
59 IN OUT VIRTIO_MMIO_DEVICE
*Device
67 // Initialize VirtIo Mmio Device
69 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
70 sizeof (VIRTIO_DEVICE_PROTOCOL
));
71 Device
->BaseAddress
= BaseAddress
;
72 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
73 Device
->VirtioDevice
.SubSystemDeviceId
=
74 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
77 // Double-check MMIO-specific values
79 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
80 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
81 return EFI_UNSUPPORTED
;
84 Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
86 return EFI_UNSUPPORTED
;
90 // Double-check MMIO-specific values
92 VendorId
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VENDOR_ID
);
93 if (VendorId
!= VIRTIO_VENDOR_ID
) {
95 // The ARM Base and Foundation Models do not report a valid VirtIo VendorId.
96 // They return a value of 0x0 for the VendorId.
98 DEBUG((EFI_D_WARN
, "VirtioMmioInit: Warning: The VendorId (0x%X) does not "
99 "match the VirtIo VendorId (0x%X).\n",
100 VendorId
, VIRTIO_VENDOR_ID
));
109 Uninitialize the internals of a virtio-mmio device that has been successfully
110 set up with VirtioMmioInit().
112 @param[in, out] Device The device to clean up.
120 IN VIRTIO_MMIO_DEVICE
*Device
124 // Note: This function mirrors VirtioMmioInit() that does not allocate any
125 // resources - there's nothing to free here.
130 VirtioMmioInstallDevice (
131 IN PHYSICAL_ADDRESS BaseAddress
,
136 VIRTIO_MMIO_DEVICE
*VirtIo
;
139 return EFI_INVALID_PARAMETER
;
141 if (Handle
== NULL
) {
142 return EFI_INVALID_PARAMETER
;
146 // Allocate VIRTIO_MMIO_DEVICE
148 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
149 if (VirtIo
== NULL
) {
150 return EFI_OUT_OF_RESOURCES
;
153 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
155 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
156 if (EFI_ERROR (Status
)) {
161 // Install VIRTIO_DEVICE_PROTOCOL to Handle
163 Status
= gBS
->InstallProtocolInterface (&Handle
,
164 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
165 &VirtIo
->VirtioDevice
);
166 if (EFI_ERROR (Status
)) {
173 VirtioMmioUninit (VirtIo
);
181 VirtioMmioUninstallDevice (
182 IN EFI_HANDLE DeviceHandle
185 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
186 VIRTIO_MMIO_DEVICE
*MmioDevice
;
189 Status
= gBS
->OpenProtocol (
190 DeviceHandle
, // candidate device
191 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
192 (VOID
**)&VirtioDevice
, // target pointer
193 DeviceHandle
, // requestor driver identity
194 DeviceHandle
, // requesting lookup for dev.
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
197 if (EFI_ERROR (Status
)) {
202 // Get the MMIO device from the VirtIo Device instance
204 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
207 // Uninstall the protocol interface
209 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
210 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
212 if (EFI_ERROR (Status
)) {
217 // Uninitialize the VirtIo Device
219 VirtioMmioUninit (MmioDevice
);
220 FreePool (MmioDevice
);