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 This program and the accompanying materials are licensed and made available
9 under the terms and conditions of the BSD License which accompanies this
10 distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
14 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
21 #include "VirtioMmioDevice.h"
23 STATIC CONST 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
39 VirtioMmioAllocateSharedPages
, // AllocateSharedPages
40 VirtioMmioFreeSharedPages
, // FreeSharedPages
41 VirtioMmioMapSharedBuffer
, // MapSharedBuffer
42 VirtioMmioUnmapSharedBuffer
// UnmapSharedBuffer
47 Initialize the VirtIo MMIO Device
49 @param[in] BaseAddress Base Address of the VirtIo MMIO Device
51 @param[in, out] Device The driver instance to configure.
53 @retval EFI_SUCCESS Setup complete.
55 @retval EFI_UNSUPPORTED The driver is not a VirtIo MMIO device.
62 IN PHYSICAL_ADDRESS BaseAddress
,
63 IN OUT VIRTIO_MMIO_DEVICE
*Device
71 // Initialize VirtIo Mmio Device
73 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
74 sizeof (VIRTIO_DEVICE_PROTOCOL
));
75 Device
->BaseAddress
= BaseAddress
;
76 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
77 Device
->VirtioDevice
.SubSystemDeviceId
=
78 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
81 // Double-check MMIO-specific values
83 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
84 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
85 return EFI_UNSUPPORTED
;
88 Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
90 return EFI_UNSUPPORTED
;
94 // Double-check MMIO-specific values
96 VendorId
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VENDOR_ID
);
97 if (VendorId
!= VIRTIO_VENDOR_ID
) {
99 // The ARM Base and Foundation Models do not report a valid VirtIo VendorId.
100 // They return a value of 0x0 for the VendorId.
102 DEBUG((EFI_D_WARN
, "VirtioMmioInit: Warning: The VendorId (0x%X) does not "
103 "match the VirtIo VendorId (0x%X).\n",
104 VendorId
, VIRTIO_VENDOR_ID
));
113 Uninitialize the internals of a virtio-mmio device that has been successfully
114 set up with VirtioMmioInit().
116 @param[in, out] Device The device to clean up.
124 IN VIRTIO_MMIO_DEVICE
*Device
128 // Note: This function mirrors VirtioMmioInit() that does not allocate any
129 // resources - there's nothing to free here.
134 VirtioMmioInstallDevice (
135 IN PHYSICAL_ADDRESS BaseAddress
,
140 VIRTIO_MMIO_DEVICE
*VirtIo
;
143 return EFI_INVALID_PARAMETER
;
145 if (Handle
== NULL
) {
146 return EFI_INVALID_PARAMETER
;
150 // Allocate VIRTIO_MMIO_DEVICE
152 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
153 if (VirtIo
== NULL
) {
154 return EFI_OUT_OF_RESOURCES
;
157 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
159 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
160 if (EFI_ERROR (Status
)) {
165 // Install VIRTIO_DEVICE_PROTOCOL to Handle
167 Status
= gBS
->InstallProtocolInterface (&Handle
,
168 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
169 &VirtIo
->VirtioDevice
);
170 if (EFI_ERROR (Status
)) {
177 VirtioMmioUninit (VirtIo
);
185 VirtioMmioUninstallDevice (
186 IN EFI_HANDLE DeviceHandle
189 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
190 VIRTIO_MMIO_DEVICE
*MmioDevice
;
193 Status
= gBS
->OpenProtocol (
194 DeviceHandle
, // candidate device
195 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
196 (VOID
**)&VirtioDevice
, // target pointer
197 DeviceHandle
, // requestor driver identity
198 DeviceHandle
, // requesting lookup for dev.
199 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
201 if (EFI_ERROR (Status
)) {
206 // Get the MMIO device from the VirtIo Device instance
208 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
211 // Uninstall the protocol interface
213 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
214 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
216 if (EFI_ERROR (Status
)) {
221 // Uninitialize the VirtIo Device
223 VirtioMmioUninit (MmioDevice
);
224 FreePool (MmioDevice
);