代码拉取完成,页面将自动刷新
From ceb82e7d081399dd91cc6e0e8eabd5b7260afac0 Mon Sep 17 00:00:00 2001
From: Adttil <[email protected]>
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 <[email protected]>
---
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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。