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 VirtioMmioGetQueueAddress
, // GetQueueAddress
29 VirtioMmioSetQueueAddress
, // SetQueueAddress
30 VirtioMmioSetQueueSel
, // SetQueueSel
31 VirtioMmioSetQueueNotify
, // SetQueueNotify
32 VirtioMmioSetQueueAlignment
, // SetQueueAlign
33 VirtioMmioSetPageSize
, // SetPageSize
34 VirtioMmioGetQueueSize
, // GetQueueNumMax
35 VirtioMmioSetQueueSize
, // SetQueueNum
36 VirtioMmioGetDeviceStatus
, // GetDeviceStatus
37 VirtioMmioSetDeviceStatus
, // SetDeviceStatus
38 VirtioMmioDeviceWrite
, // WriteDevice
39 VirtioMmioDeviceRead
// ReadDevice
44 Initialize the VirtIo MMIO Device
46 @param[in] BaseAddress Base Address of the VirtIo MMIO Device
48 @param[in, out] Device The driver instance to configure.
50 @retval EFI_SUCCESS Setup complete.
52 @retval EFI_UNSUPPORTED The driver is not a VirtIo MMIO device.
59 IN PHYSICAL_ADDRESS BaseAddress
,
60 IN OUT VIRTIO_MMIO_DEVICE
*Device
68 // Initialize VirtIo Mmio Device
70 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
71 sizeof (VIRTIO_DEVICE_PROTOCOL
));
72 Device
->BaseAddress
= BaseAddress
;
73 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
74 Device
->VirtioDevice
.SubSystemDeviceId
=
75 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
78 // Double-check MMIO-specific values
80 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
81 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
82 return EFI_UNSUPPORTED
;
85 Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
87 return EFI_UNSUPPORTED
;
91 // Double-check MMIO-specific values
93 VendorId
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VENDOR_ID
);
94 if (VendorId
!= VIRTIO_VENDOR_ID
) {
96 // The ARM Base and Foundation Models do not report a valid VirtIo VendorId.
97 // They return a value of 0x0 for the VendorId.
99 DEBUG((EFI_D_WARN
, "VirtioMmioInit: Warning: The VendorId (0x%X) does not "
100 "match the VirtIo VendorId (0x%X).\n",
101 VendorId
, VIRTIO_VENDOR_ID
));
110 Uninitialize the internals of a virtio-mmio device that has been successfully
111 set up with VirtioMmioInit().
113 @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
;
142 if (Handle
== NULL
) {
143 return EFI_INVALID_PARAMETER
;
147 // Allocate VIRTIO_MMIO_DEVICE
149 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
150 if (VirtIo
== NULL
) {
151 return EFI_OUT_OF_RESOURCES
;
154 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
156 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
157 if (EFI_ERROR (Status
)) {
162 // Install VIRTIO_DEVICE_PROTOCOL to Handle
164 Status
= gBS
->InstallProtocolInterface (&Handle
,
165 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
166 &VirtIo
->VirtioDevice
);
167 if (EFI_ERROR (Status
)) {
174 VirtioMmioUninit (VirtIo
);
182 VirtioMmioUninstallDevice (
183 IN EFI_HANDLE DeviceHandle
186 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
187 VIRTIO_MMIO_DEVICE
*MmioDevice
;
190 Status
= gBS
->OpenProtocol (
191 DeviceHandle
, // candidate device
192 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
193 (VOID
**)&VirtioDevice
, // target pointer
194 DeviceHandle
, // requestor driver identity
195 DeviceHandle
, // requesting lookup for dev.
196 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
198 if (EFI_ERROR (Status
)) {
203 // Get the MMIO device from the VirtIo Device instance
205 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
208 // Uninstall the protocol interface
210 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
211 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
213 if (EFI_ERROR (Status
)) {
218 // Uninitialize the VirtIo Device
220 VirtioMmioUninit (MmioDevice
);
221 FreePool (MmioDevice
);