219 lines
7.7 KiB
Diff
219 lines
7.7 KiB
Diff
From ceb82e7d081399dd91cc6e0e8eabd5b7260afac0 Mon Sep 17 00:00:00 2001
|
|
From: Adttil <2429917001@qq.com>
|
|
Date: Fri, 29 Nov 2024 08:35:27 +0800
|
|
Subject: [PATCH 1/3] VirtioDxe: add support of MMIO Bar for virtio devices
|
|
|
|
As some virtio devices support MMIO BAR, add support for
|
|
it in Virtio10Dxe and VirtioPciDeviceDXE.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
OvmfPkg/Include/Protocol/VirtioDevice.h | 12 +++
|
|
.../VirtioMmioDeviceLib/VirtioMmioDevice.c | 1 +
|
|
OvmfPkg/Virtio10Dxe/Virtio10.c | 1 +
|
|
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 89 +++++++++++++++----
|
|
4 files changed, 85 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
|
index ad37f4e3..802b8970 100644
|
|
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
|
|
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
|
@@ -466,6 +466,16 @@ EFI_STATUS
|
|
IN VOID *Mapping
|
|
);
|
|
|
|
+/**
|
|
+ * Note: Zero virtio devices has BAR0 of type MMIO but not PIO which do not
|
|
+ * flow the virtio 0.95 spec due to hw limiation. We extend edk2 to support
|
|
+ * such variant.
|
|
+ */
|
|
+typedef enum {
|
|
+ VirtioCfgSpaceAcessIo = 0,
|
|
+ VirtioCfgSpaceAcessMem
|
|
+} VIRTIO_CFG_SPACE_ACCESS_MODE;
|
|
+
|
|
///
|
|
/// This protocol provides an abstraction over the VirtIo transport layer
|
|
///
|
|
@@ -482,6 +492,8 @@ struct _VIRTIO_DEVICE_PROTOCOL {
|
|
//
|
|
INT32 SubSystemDeviceId;
|
|
|
|
+ VIRTIO_CFG_SPACE_ACCESS_MODE CfgAccessMode;
|
|
+
|
|
VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures;
|
|
VIRTIO_SET_GUEST_FEATURES SetGuestFeatures;
|
|
|
|
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
|
index fac32422..a340711d 100644
|
|
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
|
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
|
@@ -17,6 +17,7 @@
|
|
STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
|
|
0, // Revision
|
|
0, // SubSystemDeviceId
|
|
+ 0, // CfgAccessMode
|
|
VirtioMmioGetDeviceFeatures, // GetDeviceFeatures
|
|
VirtioMmioSetGuestFeatures, // SetGuestFeatures
|
|
VirtioMmioSetQueueAddress, // SetQueueAddress
|
|
diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
|
index 970524f6..b968b016 100644
|
|
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
|
|
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
|
@@ -954,6 +954,7 @@ Virtio10UnmapSharedBuffer (
|
|
STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
|
|
VIRTIO_SPEC_REVISION (1, 0, 0),
|
|
0, // SubSystemDeviceId, filled in dynamically
|
|
+ 0, // CfgAccessMode
|
|
Virtio10GetDeviceFeatures,
|
|
Virtio10SetGuestFeatures,
|
|
Virtio10SetQueueAddress,
|
|
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
|
index b4ac195b..61ff376d 100644
|
|
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
|
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
|
@@ -23,6 +23,7 @@
|
|
STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
|
|
0, // Revision
|
|
0, // SubSystemDeviceId
|
|
+ 0, // CfgAccessMode
|
|
VirtioPciGetDeviceFeatures, // GetDeviceFeatures
|
|
VirtioPciSetGuestFeatures, // SetGuestFeatures
|
|
VirtioPciSetQueueAddress, // SetQueueAddress
|
|
@@ -117,14 +118,25 @@ VirtioPciIoRead (
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
- return PciIo->Io.Read (
|
|
- PciIo,
|
|
- Width,
|
|
- PCI_BAR_IDX0,
|
|
- FieldOffset,
|
|
- Count,
|
|
- Buffer
|
|
- );
|
|
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
|
+ return PciIo->Io.Read (
|
|
+ PciIo,
|
|
+ Width,
|
|
+ PCI_BAR_IDX0,
|
|
+ FieldOffset,
|
|
+ Count,
|
|
+ Buffer
|
|
+ );
|
|
+ } else {
|
|
+ return PciIo->Mem.Read (
|
|
+ PciIo,
|
|
+ Width,
|
|
+ PCI_BAR_IDX0,
|
|
+ FieldOffset,
|
|
+ Count,
|
|
+ Buffer
|
|
+ );
|
|
+ }
|
|
}
|
|
|
|
/**
|
|
@@ -197,14 +209,25 @@ VirtioPciIoWrite (
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
- return PciIo->Io.Write (
|
|
- PciIo,
|
|
- Width,
|
|
- PCI_BAR_IDX0,
|
|
- FieldOffset,
|
|
- Count,
|
|
- &Value
|
|
- );
|
|
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
|
+ return PciIo->Io.Write (
|
|
+ PciIo,
|
|
+ Width,
|
|
+ PCI_BAR_IDX0,
|
|
+ FieldOffset,
|
|
+ Count,
|
|
+ &Value
|
|
+ );
|
|
+ } else {
|
|
+ return PciIo->Mem.Write (
|
|
+ PciIo,
|
|
+ Width,
|
|
+ PCI_BAR_IDX0,
|
|
+ FieldOffset,
|
|
+ Count,
|
|
+ &Value
|
|
+ );
|
|
+ }
|
|
}
|
|
|
|
/**
|
|
@@ -332,6 +355,7 @@ VirtioPciInit (
|
|
EFI_STATUS Status;
|
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
|
PCI_TYPE00 Pci;
|
|
+ VOID *Resources;
|
|
|
|
ASSERT (Device != NULL);
|
|
PciIo = Device->PciIo;
|
|
@@ -373,6 +397,27 @@ VirtioPciInit (
|
|
Device->DeviceSpecificConfigurationOffset =
|
|
VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
|
|
|
|
+ Status = PciIo->GetBarAttributes(PciIo, PCI_BAR_IDX0, NULL, &Resources);
|
|
+ if (EFI_ERROR (Status)) {
|
|
+ return Status;
|
|
+ }
|
|
+
|
|
+ if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) {
|
|
+ EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
|
|
+
|
|
+ Descriptor = Resources;
|
|
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
|
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessMem;
|
|
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio MMIO BAR used.\n", __FUNCTION__));
|
|
+ } else {
|
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
|
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio IO BAR used.\n", __FUNCTION__));
|
|
+ }
|
|
+ } else {
|
|
+ DEBUG ((DEBUG_WARN, "%a: Cannot determine BAR0 type, assume IO.\n", __FUNCTION__));
|
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
|
+ }
|
|
+
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
@@ -434,6 +479,7 @@ VirtioPciDeviceBindingStart (
|
|
{
|
|
VIRTIO_PCI_DEVICE *Device;
|
|
EFI_STATUS Status;
|
|
+ UINT64 Attributes;
|
|
|
|
Device = (VIRTIO_PCI_DEVICE *)AllocateZeroPool (sizeof *Device);
|
|
if (Device == NULL) {
|
|
@@ -473,11 +519,18 @@ VirtioPciDeviceBindingStart (
|
|
goto ClosePciIo;
|
|
}
|
|
|
|
+ Status = Device->PciIo->Attributes (Device->PciIo,
|
|
+ EfiPciIoAttributeOperationSupported,
|
|
+ 0, &Attributes);
|
|
+ if (EFI_ERROR (Status)) {
|
|
+ goto ClosePciIo;
|
|
+ }
|
|
+
|
|
+ Attributes &= (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO);
|
|
Status = Device->PciIo->Attributes (
|
|
Device->PciIo,
|
|
EfiPciIoAttributeOperationEnable,
|
|
- (EFI_PCI_IO_ATTRIBUTE_IO |
|
|
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
|
|
+ Attributes | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
--
|
|
2.43.0
|
|
|