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
65 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
66 sizeof (VIRTIO_DEVICE_PROTOCOL
));
67 Device
->BaseAddress
= BaseAddress
;
68 Device
->VirtioDevice
.SubSystemDeviceId
=
69 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
72 // Double-check MMIO-specific values
74 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
75 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
76 return EFI_UNSUPPORTED
;
79 Device
->Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
80 switch (Device
->Version
) {
81 case VIRTIO_MMIO_DEVICE_VERSION_0_95
:
82 DEBUG ((DEBUG_INFO
, "%a virtio 0.9.5, id %d\n", __FUNCTION__
,
83 Device
->VirtioDevice
.SubSystemDeviceId
));
84 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
86 case VIRTIO_MMIO_DEVICE_VERSION_1_00
:
87 DEBUG ((DEBUG_INFO
, "%a virtio 1.0, id %d\n", __FUNCTION__
,
88 Device
->VirtioDevice
.SubSystemDeviceId
));
89 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (1, 0, 0);
90 return EFI_UNSUPPORTED
;
92 return EFI_UNSUPPORTED
;
101 Uninitialize the internals of a virtio-mmio device that has been successfully
102 set up with VirtioMmioInit().
104 @param[in, out] Device The device to clean up.
112 IN VIRTIO_MMIO_DEVICE
*Device
116 // Note: This function mirrors VirtioMmioInit() that does not allocate any
117 // resources - there's nothing to free here.
122 VirtioMmioInstallDevice (
123 IN PHYSICAL_ADDRESS BaseAddress
,
128 VIRTIO_MMIO_DEVICE
*VirtIo
;
131 return EFI_INVALID_PARAMETER
;
133 if (Handle
== NULL
) {
134 return EFI_INVALID_PARAMETER
;
138 // Allocate VIRTIO_MMIO_DEVICE
140 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
141 if (VirtIo
== NULL
) {
142 return EFI_OUT_OF_RESOURCES
;
145 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
147 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
148 if (EFI_ERROR (Status
)) {
153 // Install VIRTIO_DEVICE_PROTOCOL to Handle
155 Status
= gBS
->InstallProtocolInterface (&Handle
,
156 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
157 &VirtIo
->VirtioDevice
);
158 if (EFI_ERROR (Status
)) {
165 VirtioMmioUninit (VirtIo
);
173 VirtioMmioUninstallDevice (
174 IN EFI_HANDLE DeviceHandle
177 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
178 VIRTIO_MMIO_DEVICE
*MmioDevice
;
181 Status
= gBS
->OpenProtocol (
182 DeviceHandle
, // candidate device
183 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
184 (VOID
**)&VirtioDevice
, // target pointer
185 DeviceHandle
, // requestor driver identity
186 DeviceHandle
, // requesting lookup for dev.
187 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
189 if (EFI_ERROR (Status
)) {
194 // Get the MMIO device from the VirtIo Device instance
196 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
199 // Uninstall the protocol interface
201 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
202 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
204 if (EFI_ERROR (Status
)) {
209 // Uninitialize the VirtIo Device
211 VirtioMmioUninit (MmioDevice
);
212 FreePool (MmioDevice
);