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
64 // Initialize VirtIo Mmio Device
66 CopyMem (&Device
->VirtioDevice
, &mMmioDeviceProtocolTemplate
,
67 sizeof (VIRTIO_DEVICE_PROTOCOL
));
68 Device
->BaseAddress
= BaseAddress
;
69 Device
->VirtioDevice
.Revision
= VIRTIO_SPEC_REVISION (0, 9, 5);
70 Device
->VirtioDevice
.SubSystemDeviceId
=
71 MmioRead32 (BaseAddress
+ VIRTIO_MMIO_OFFSET_DEVICE_ID
);
74 // Double-check MMIO-specific values
76 MagicValue
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_MAGIC
);
77 if (MagicValue
!= VIRTIO_MMIO_MAGIC
) {
78 return EFI_UNSUPPORTED
;
81 Version
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_VERSION
);
83 return EFI_UNSUPPORTED
;
92 Uninitialize the internals of a virtio-mmio device that has been successfully
93 set up with VirtioMmioInit().
95 @param[in, out] Device The device to clean up.
103 IN VIRTIO_MMIO_DEVICE
*Device
107 // Note: This function mirrors VirtioMmioInit() that does not allocate any
108 // resources - there's nothing to free here.
113 VirtioMmioInstallDevice (
114 IN PHYSICAL_ADDRESS BaseAddress
,
119 VIRTIO_MMIO_DEVICE
*VirtIo
;
122 return EFI_INVALID_PARAMETER
;
124 if (Handle
== NULL
) {
125 return EFI_INVALID_PARAMETER
;
129 // Allocate VIRTIO_MMIO_DEVICE
131 VirtIo
= AllocateZeroPool (sizeof (VIRTIO_MMIO_DEVICE
));
132 if (VirtIo
== NULL
) {
133 return EFI_OUT_OF_RESOURCES
;
136 VirtIo
->Signature
= VIRTIO_MMIO_DEVICE_SIGNATURE
;
138 Status
= VirtioMmioInit (BaseAddress
, VirtIo
);
139 if (EFI_ERROR (Status
)) {
144 // Install VIRTIO_DEVICE_PROTOCOL to Handle
146 Status
= gBS
->InstallProtocolInterface (&Handle
,
147 &gVirtioDeviceProtocolGuid
, EFI_NATIVE_INTERFACE
,
148 &VirtIo
->VirtioDevice
);
149 if (EFI_ERROR (Status
)) {
156 VirtioMmioUninit (VirtIo
);
164 VirtioMmioUninstallDevice (
165 IN EFI_HANDLE DeviceHandle
168 VIRTIO_DEVICE_PROTOCOL
*VirtioDevice
;
169 VIRTIO_MMIO_DEVICE
*MmioDevice
;
172 Status
= gBS
->OpenProtocol (
173 DeviceHandle
, // candidate device
174 &gVirtioDeviceProtocolGuid
, // retrieve the VirtIo iface
175 (VOID
**)&VirtioDevice
, // target pointer
176 DeviceHandle
, // requestor driver identity
177 DeviceHandle
, // requesting lookup for dev.
178 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// lookup only, no ref. added
180 if (EFI_ERROR (Status
)) {
185 // Get the MMIO device from the VirtIo Device instance
187 MmioDevice
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice
);
190 // Uninstall the protocol interface
192 Status
= gBS
->UninstallProtocolInterface (DeviceHandle
,
193 &gVirtioDeviceProtocolGuid
, &MmioDevice
->VirtioDevice
195 if (EFI_ERROR (Status
)) {
200 // Uninitialize the VirtIo Device
202 VirtioMmioUninit (MmioDevice
);
203 FreePool (MmioDevice
);