* [PATCH v3 01/17] OvmfPkg/PvScsiDxe: Create empty driver
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 02/17] OvmfPkg/PvScsiDxe: Install DriverBinding protocol Liran Alon
` (17 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
In preparation for support booting from PvScsi devices, create a
basic scaffolding for a driver.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 8 ++++++++
OvmfPkg/OvmfPkgIa32.fdf | 3 +++
OvmfPkg/OvmfPkgIa32X64.dsc | 8 ++++++++
OvmfPkg/OvmfPkgIa32X64.fdf | 3 +++
OvmfPkg/OvmfPkgX64.dsc | 8 ++++++++
OvmfPkg/OvmfPkgX64.fdf | 3 +++
OvmfPkg/PvScsiDxe/PvScsi.c | 26 ++++++++++++++++++++++++++
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 27 +++++++++++++++++++++++++++
8 files changed, 86 insertions(+)
create mode 100644 OvmfPkg/PvScsiDxe/PvScsi.c
create mode 100644 OvmfPkg/PvScsiDxe/PvScsiDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 19728f20b34e..af985b4f7826 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -44,6 +44,11 @@
!include NetworkPkg/NetworkDefines.dsc.inc
+ #
+ # Device drivers
+ #
+ DEFINE PVSCSI_ENABLE = TRUE
+
#
# Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to
# one of the supported values, in place of any of the convenience macros, is
@@ -718,6 +723,9 @@
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+ OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index 63607551ed75..a442e133b952 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -227,6 +227,9 @@ INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 3c0c229e3a72..267a83bf86e2 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -44,6 +44,11 @@
!include NetworkPkg/NetworkDefines.dsc.inc
+ #
+ # Device drivers
+ #
+ DEFINE PVSCSI_ENABLE = TRUE
+
#
# Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to
# one of the supported values, in place of any of the convenience macros, is
@@ -731,6 +736,9 @@
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+ OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 0488e5d95ffe..5fddaac2b0cb 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -228,6 +228,9 @@ INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index f6c1d8d228c6..98cc2a955c3e 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -44,6 +44,11 @@
!include NetworkPkg/NetworkDefines.dsc.inc
+ #
+ # Device drivers
+ #
+ DEFINE PVSCSI_ENABLE = TRUE
+
#
# Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to
# one of the supported values, in place of any of the convenience macros, is
@@ -729,6 +734,9 @@
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+ OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 0488e5d95ffe..5fddaac2b0cb 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -228,6 +228,9 @@ INF OvmfPkg/VirtioRngDxe/VirtioRng.inf
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+!if $(PVSCSI_ENABLE) == TRUE
+INF OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+!endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
new file mode 100644
index 000000000000..1ae4de9869c1
--- /dev/null
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -0,0 +1,26 @@
+/** @file
+
+ This driver produces Extended SCSI Pass Thru Protocol instances for
+ pvscsi devices.
+
+ Copyright (C) 2020, Oracle and/or its affiliates.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiSpec.h>
+
+//
+// Entry Point
+//
+
+EFI_STATUS
+EFIAPI
+PvScsiEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
new file mode 100644
index 000000000000..093cc0171338
--- /dev/null
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -0,0 +1,27 @@
+## @file
+#
+# This driver produces Extended SCSI Pass Thru Protocol instances for
+# pvscsi devices.
+#
+# Copyright (C) 2020, Oracle and/or its affiliates.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = PvScsiDxe
+ FILE_GUID = 30346B14-1580-4781-879D-BA0C55AE9BB2
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PvScsiEntryPoint
+
+[Sources]
+ PvScsi.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 02/17] OvmfPkg/PvScsiDxe: Install DriverBinding protocol
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
2020-03-28 20:00 ` [PATCH v3 01/17] OvmfPkg/PvScsiDxe: Create empty driver Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 03/17] OvmfPkg/PvScsiDxe: Report name of driver Liran Alon
` (16 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
In order to probe and connect to the PvScsi device we need this
protocol. Currently it does nothing.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 66 ++++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 1 +
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 1ae4de9869c1..77b28b326784 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -9,8 +9,65 @@
**/
+#include <Library/UefiLib.h>
#include <Uefi/UefiSpec.h>
+//
+// Higher versions will be used before lower, 0x10-0xffffffef is the version
+// range for IHV (Indie Hardware Vendors)
+//
+#define PVSCSI_BINDING_VERSION 0x10
+
+//
+// Driver Binding
+//
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC EFI_DRIVER_BINDING_PROTOCOL mPvScsiDriverBinding = {
+ &PvScsiDriverBindingSupported,
+ &PvScsiDriverBindingStart,
+ &PvScsiDriverBindingStop,
+ PVSCSI_BINDING_VERSION,
+ NULL, // ImageHandle, filled by EfiLibInstallDriverBindingComponentName2()
+ NULL // DriverBindingHandle, filled as well
+};
+
//
// Entry Point
//
@@ -22,5 +79,12 @@ PvScsiEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- return EFI_UNSUPPORTED;
+ return EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mPvScsiDriverBinding,
+ ImageHandle,
+ NULL, // TODO Component name
+ NULL // TODO Component name
+ );
}
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index 093cc0171338..d1d0e963f96d 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -25,3 +25,4 @@
[LibraryClasses]
UefiDriverEntryPoint
+ UefiLib
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 03/17] OvmfPkg/PvScsiDxe: Report name of driver
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
2020-03-28 20:00 ` [PATCH v3 01/17] OvmfPkg/PvScsiDxe: Create empty driver Liran Alon
2020-03-28 20:00 ` [PATCH v3 02/17] OvmfPkg/PvScsiDxe: Install DriverBinding protocol Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 04/17] OvmfPkg/PvScsiDxe: Probe PCI devices and look for PvScsi Liran Alon
` (15 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Install Component Name protocols to have a nice display name for the
driver in places such as UEFI shell.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 59 ++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 77b28b326784..51b03f709040 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -68,6 +68,61 @@ STATIC EFI_DRIVER_BINDING_PROTOCOL mPvScsiDriverBinding = {
NULL // DriverBindingHandle, filled as well
};
+//
+// Component Name
+//
+
+STATIC EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
+ { "eng;en", L"PVSCSI Host Driver" },
+ { NULL, NULL }
+};
+
+STATIC EFI_COMPONENT_NAME_PROTOCOL mComponentName;
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &mComponentName) // Iso639Language
+ );
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiGetDeviceName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_HANDLE ChildHandle,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC EFI_COMPONENT_NAME_PROTOCOL mComponentName = {
+ &PvScsiGetDriverName,
+ &PvScsiGetDeviceName,
+ "eng" // SupportedLanguages, ISO 639-2 language codes
+};
+
+STATIC EFI_COMPONENT_NAME2_PROTOCOL mComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &PvScsiGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &PvScsiGetDeviceName,
+ "en" // SupportedLanguages, RFC 4646 language codes
+};
+
//
// Entry Point
//
@@ -84,7 +139,7 @@ PvScsiEntryPoint (
SystemTable,
&mPvScsiDriverBinding,
ImageHandle,
- NULL, // TODO Component name
- NULL // TODO Component name
+ &mComponentName,
+ &mComponentName2
);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 04/17] OvmfPkg/PvScsiDxe: Probe PCI devices and look for PvScsi
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (2 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 03/17] OvmfPkg/PvScsiDxe: Report name of driver Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 05/17] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Liran Alon
` (14 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
PvScsiControllerSupported() is called on handles passed in
by the ConnectController() boot service and if the handle is the
PVSCSI controller, the function would return success. A success
return value will attach our driver to the device.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/Include/IndustryStandard/PvScsi.h | 21 ++++++++++
OvmfPkg/PvScsiDxe/PvScsi.c | 49 ++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 5 +++
3 files changed, 74 insertions(+), 1 deletion(-)
create mode 100644 OvmfPkg/Include/IndustryStandard/PvScsi.h
diff --git a/OvmfPkg/Include/IndustryStandard/PvScsi.h b/OvmfPkg/Include/IndustryStandard/PvScsi.h
new file mode 100644
index 000000000000..004c0af84989
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/PvScsi.h
@@ -0,0 +1,21 @@
+/** @file
+
+ VMware PVSCSI Device specific type and macro definitions.
+
+ Copyright (C) 2020, Oracle and/or its affiliates.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PVSCSI_H_
+#define __PVSCSI_H_
+
+//
+// Device offsets and constants
+//
+
+#define PCI_VENDOR_ID_VMWARE (0x15ad)
+#define PCI_DEVICE_ID_VMWARE_PVSCSI (0x07c0)
+
+#endif // __PVSCSI_H_
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 51b03f709040..9923a31d25d7 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -9,7 +9,11 @@
**/
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/PvScsi.h>
+#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
+#include <Protocol/PciIo.h>
#include <Uefi/UefiSpec.h>
//
@@ -31,7 +35,50 @@ PvScsiDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ if ((Pci.Hdr.VendorId != PCI_VENDOR_ID_VMWARE) ||
+ (Pci.Hdr.DeviceId != PCI_DEVICE_ID_VMWARE_PVSCSI)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = EFI_SUCCESS;
+
+Done:
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
}
STATIC
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index d1d0e963f96d..c1f0663832ed 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -22,7 +22,12 @@
[Packages]
MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
+ UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
+
+[Protocols]
+ gEfiPciIoProtocolGuid ## TO_START
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 05/17] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (3 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 04/17] OvmfPkg/PvScsiDxe: Probe PCI devices and look for PvScsi Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 06/17] OvmfPkg/PvScsiDxe: Report the number of targets and LUNs Liran Alon
` (13 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Support dynamic insertion and removal of the protocol.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 209 +++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 29 +++++
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 6 +-
3 files changed, 241 insertions(+), 3 deletions(-)
create mode 100644 OvmfPkg/PvScsiDxe/PvScsi.h
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 9923a31d25d7..04c08036b799 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -11,17 +11,156 @@
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/PvScsi.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/PciIo.h>
#include <Uefi/UefiSpec.h>
+#include "PvScsi.h"
+
//
// Higher versions will be used before lower, 0x10-0xffffffef is the version
// range for IHV (Indie Hardware Vendors)
//
#define PVSCSI_BINDING_VERSION 0x10
+//
+// Ext SCSI Pass Thru
+//
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiPassThru (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+ IN EFI_EVENT Event OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiGetNextTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target,
+ IN OUT UINT64 *Lun
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiBuildDevicePath (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiGetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT8 **Target,
+ OUT UINT64 *Lun
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiResetChannel (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiResetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+PvScsiGetNextTarget (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+PvScsiInit (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ //
+ // Populate the exported interface's attributes
+ //
+ Dev->PassThru.Mode = &Dev->PassThruMode;
+ Dev->PassThru.PassThru = &PvScsiPassThru;
+ Dev->PassThru.GetNextTargetLun = &PvScsiGetNextTargetLun;
+ Dev->PassThru.BuildDevicePath = &PvScsiBuildDevicePath;
+ Dev->PassThru.GetTargetLun = &PvScsiGetTargetLun;
+ Dev->PassThru.ResetChannel = &PvScsiResetChannel;
+ Dev->PassThru.ResetTargetLun = &PvScsiResetTargetLun;
+ Dev->PassThru.GetNextTarget = &PvScsiGetNextTarget;
+
+ //
+ // AdapterId is a target for which no handle will be created during bus scan.
+ // Prevent any conflict with real devices.
+ //
+ Dev->PassThruMode.AdapterId = MAX_UINT32;
+
+ //
+ // Set both physical and logical attributes for non-RAID SCSI channel
+ //
+ Dev->PassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
+ EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
+
+ //
+ // No restriction on transfer buffer alignment
+ //
+ Dev->PassThruMode.IoAlign = 0;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+PvScsiUninit (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ // Currently nothing to do here
+}
+
//
// Driver Binding
//
@@ -90,7 +229,42 @@ PvScsiDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ PVSCSI_DEV *Dev;
+ EFI_STATUS Status;
+
+ Dev = (PVSCSI_DEV *) AllocateZeroPool (sizeof (*Dev));
+ if (Dev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PvScsiInit (Dev);
+ if (EFI_ERROR (Status)) {
+ goto FreePvScsi;
+ }
+
+ //
+ // Setup complete, attempt to export the driver instance's PassThru interface
+ //
+ Dev->Signature = PVSCSI_SIG;
+ Status = gBS->InstallProtocolInterface (
+ &ControllerHandle,
+ &gEfiExtScsiPassThruProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &Dev->PassThru
+ );
+ if (EFI_ERROR (Status)) {
+ goto UninitDev;
+ }
+
+ return EFI_SUCCESS;
+
+UninitDev:
+ PvScsiUninit (Dev);
+
+FreePvScsi:
+ FreePool (Dev);
+
+ return Status;
}
STATIC
@@ -103,7 +277,38 @@ PvScsiDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;
+ PVSCSI_DEV *Dev;
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiExtScsiPassThruProtocolGuid,
+ (VOID **)&PassThru,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Dev = PVSCSI_FROM_PASS_THRU (PassThru);
+
+ Status = gBS->UninstallProtocolInterface (
+ ControllerHandle,
+ &gEfiExtScsiPassThruProtocolGuid,
+ &Dev->PassThru
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PvScsiUninit (Dev);
+
+ FreePool (Dev);
+
+ return EFI_SUCCESS;
}
STATIC EFI_DRIVER_BINDING_PROTOCOL mPvScsiDriverBinding = {
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
new file mode 100644
index 000000000000..3940b4c20019
--- /dev/null
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -0,0 +1,29 @@
+/** @file
+
+ Internal definitions for the PVSCSI driver, which produces Extended SCSI
+ Pass Thru Protocol instances for pvscsi devices.
+
+ Copyright (C) 2020, Oracle and/or its affiliates.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PVSCSI_DXE_H_
+#define __PVSCSI_DXE_H_
+
+#include <Library/DebugLib.h>
+#include <Protocol/ScsiPassThruExt.h>
+
+#define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
+ EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
+} PVSCSI_DEV;
+
+#define PVSCSI_FROM_PASS_THRU(PassThruPointer) \
+ CR (PassThruPointer, PVSCSI_DEV, PassThru, PVSCSI_SIG)
+
+#endif // __PVSCSI_DXE_H_
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index c1f0663832ed..f4d452c6c3d2 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -19,15 +19,19 @@
[Sources]
PvScsi.c
+ PvScsi.h
[Packages]
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
+ DebugLib
+ MemoryAllocationLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
[Protocols]
- gEfiPciIoProtocolGuid ## TO_START
+ gEfiExtScsiPassThruProtocolGuid ## BY_START
+ gEfiPciIoProtocolGuid ## TO_START
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 06/17] OvmfPkg/PvScsiDxe: Report the number of targets and LUNs
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (4 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 05/17] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 07/17] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath Liran Alon
` (12 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Implement EXT_SCSI_PASS_THRU.GetNextTarget() and
EXT_SCSI_PASS_THRU.GetNextTargetLun().
ScsiBusDxe scans all MaxTarget * MaxLun possible devices.
This can take unnecessarily long for large number of targets.
To deal with this, VirtioScsiDxe has defined PCDs to limit the
MaxTarget & MaxLun to desired values which gives sufficient
performance. It is very important in virtio-scsi as it can have
very big MaxTarget & MaxLun.
Even though a common PVSCSI device has a default MaxTarget=64 and
MaxLun=0, we implement similar mechanism as virtio-scsi for completeness.
This may be useful in the future when PVSCSI will have bigger values
for MaxTarget and MaxLun.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/OvmfPkg.dec | 9 +++
OvmfPkg/PvScsiDxe/PvScsi.c | 122 +++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 2 +
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 5 ++
4 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4c5b6511cb97..a04aee5c2cd4 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -121,6 +121,15 @@
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7
+ ## Sets the *inclusive* number of targets and LUNs that PvScsi exposes for
+ # scan by ScsiBusDxe.
+ # As specified above for VirtioScsi, ScsiBusDxe scans all MaxTarget * MaxLun
+ # possible devices, which can take extremely long. Thus, the below constants
+ # are used so that scanning the number of devices given by their product
+ # is still acceptably fast.
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit|64|UINT8|0x36
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit|0|UINT8|0x37
+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 04c08036b799..7f51ada19a1a 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -11,6 +11,7 @@
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/PvScsi.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
@@ -25,6 +26,30 @@
//
#define PVSCSI_BINDING_VERSION 0x10
+//
+// Ext SCSI Pass Thru utilities
+//
+
+/**
+ Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
+ EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
+**/
+STATIC
+BOOLEAN
+IsTargetInitialized (
+ IN UINT8 *Target
+ )
+{
+ UINTN Idx;
+
+ for (Idx = 0; Idx < TARGET_MAX_BYTES; ++Idx) {
+ if (Target[Idx] != 0xFF) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
//
// Ext SCSI Pass Thru
//
@@ -52,7 +77,54 @@ PvScsiGetNextTargetLun (
IN OUT UINT64 *Lun
)
{
- return EFI_UNSUPPORTED;
+ UINT8 *TargetPtr;
+ UINT8 LastTarget;
+ PVSCSI_DEV *Dev;
+
+ if (Target == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The Target input parameter is unnecessarily a pointer-to-pointer
+ //
+ TargetPtr = *Target;
+
+ //
+ // If target not initialized, return first target & LUN
+ //
+ if (!IsTargetInitialized (TargetPtr)) {
+ ZeroMem (TargetPtr, TARGET_MAX_BYTES);
+ *Lun = 0;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // We only use first byte of target identifer
+ //
+ LastTarget = *TargetPtr;
+
+ //
+ // Increment (target, LUN) pair if valid on input
+ //
+ Dev = PVSCSI_FROM_PASS_THRU (This);
+ if (LastTarget > Dev->MaxTarget || *Lun > Dev->MaxLun) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*Lun < Dev->MaxLun) {
+ ++*Lun;
+ return EFI_SUCCESS;
+ }
+
+ if (LastTarget < Dev->MaxTarget) {
+ *Lun = 0;
+ ++LastTarget;
+ *TargetPtr = LastTarget;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
}
STATIC
@@ -111,7 +183,47 @@ PvScsiGetNextTarget (
IN OUT UINT8 **Target
)
{
- return EFI_UNSUPPORTED;
+ UINT8 *TargetPtr;
+ UINT8 LastTarget;
+ PVSCSI_DEV *Dev;
+
+ if (Target == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The Target input parameter is unnecessarily a pointer-to-pointer
+ //
+ TargetPtr = *Target;
+
+ //
+ // If target not initialized, return first target
+ //
+ if (!IsTargetInitialized (TargetPtr)) {
+ ZeroMem (TargetPtr, TARGET_MAX_BYTES);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // We only use first byte of target identifer
+ //
+ LastTarget = *TargetPtr;
+
+ //
+ // Increment target if valid on input
+ //
+ Dev = PVSCSI_FROM_PASS_THRU (This);
+ if (LastTarget > Dev->MaxTarget) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LastTarget < Dev->MaxTarget) {
+ ++LastTarget;
+ *TargetPtr = LastTarget;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
}
STATIC
@@ -120,6 +232,12 @@ PvScsiInit (
IN OUT PVSCSI_DEV *Dev
)
{
+ //
+ // Init configuration
+ //
+ Dev->MaxTarget = PcdGet8 (PcdPvScsiMaxTargetLimit);
+ Dev->MaxLun = PcdGet8 (PcdPvScsiMaxLunLimit);
+
//
// Populate the exported interface's attributes
//
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index 3940b4c20019..dd3e0c68e6da 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -19,6 +19,8 @@
typedef struct {
UINT32 Signature;
+ UINT8 MaxTarget;
+ UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
} PVSCSI_DEV;
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index f4d452c6c3d2..fcffc90d46c8 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -26,6 +26,7 @@
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
+ BaseMemoryLib
DebugLib
MemoryAllocationLib
UefiBootServicesTableLib
@@ -35,3 +36,7 @@
[Protocols]
gEfiExtScsiPassThruProtocolGuid ## BY_START
gEfiPciIoProtocolGuid ## TO_START
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit ## CONSUMES
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 07/17] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (5 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 06/17] OvmfPkg/PvScsiDxe: Report the number of targets and LUNs Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 08/17] OvmfPkg/PvScsiDxe: Open PciIo protocol for later use Liran Alon
` (11 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Implement EXT_SCSI_PASS_THRU.BuildDevicePath() and
EXT_SCSI_PASS_THRU.GetTargetLun().
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 61 ++++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 7f51ada19a1a..76fc1eb910f2 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -137,7 +137,38 @@ PvScsiBuildDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
)
{
- return EFI_UNSUPPORTED;
+ UINT8 TargetValue;
+ PVSCSI_DEV *Dev;
+ SCSI_DEVICE_PATH *ScsiDevicePath;
+
+ if (DevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // We only use first byte of target identifer
+ //
+ TargetValue = *Target;
+
+ Dev = PVSCSI_FROM_PASS_THRU (This);
+ if (TargetValue > Dev->MaxTarget || Lun > Dev->MaxLun) {
+ return EFI_NOT_FOUND;
+ }
+
+ ScsiDevicePath = AllocatePool (sizeof (*ScsiDevicePath));
+ if (ScsiDevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ScsiDevicePath->Header.Type = MESSAGING_DEVICE_PATH;
+ ScsiDevicePath->Header.SubType = MSG_SCSI_DP;
+ ScsiDevicePath->Header.Length[0] = (UINT8)sizeof (*ScsiDevicePath);
+ ScsiDevicePath->Header.Length[1] = (UINT8)(sizeof (*ScsiDevicePath) >> 8);
+ ScsiDevicePath->Pun = TargetValue;
+ ScsiDevicePath->Lun = (UINT16)Lun;
+
+ *DevicePath = &ScsiDevicePath->Header;
+ return EFI_SUCCESS;
}
STATIC
@@ -150,7 +181,33 @@ PvScsiGetTargetLun (
OUT UINT64 *Lun
)
{
- return EFI_UNSUPPORTED;
+ SCSI_DEVICE_PATH *ScsiDevicePath;
+ PVSCSI_DEV *Dev;
+
+ if (DevicePath == NULL || Target == NULL || *Target == NULL || Lun == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DevicePath->Type != MESSAGING_DEVICE_PATH ||
+ DevicePath->SubType != MSG_SCSI_DP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath;
+ Dev = PVSCSI_FROM_PASS_THRU (This);
+ if (ScsiDevicePath->Pun > Dev->MaxTarget ||
+ ScsiDevicePath->Lun > Dev->MaxLun) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // We only use first byte of target identifer
+ //
+ **Target = (UINT8)ScsiDevicePath->Pun;
+ ZeroMem (*Target + 1, TARGET_MAX_BYTES - 1);
+ *Lun = ScsiDevicePath->Lun;
+
+ return EFI_SUCCESS;
}
STATIC
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 08/17] OvmfPkg/PvScsiDxe: Open PciIo protocol for later use
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (6 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 07/17] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 09/17] OvmfPkg/PvScsiDxe: Backup/Restore PCI attributes on Init/UnInit Liran Alon
` (10 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
This will give us an exclusive access to the PciIo of this device
after it was started and until it will be stopped.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 29 ++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 1 +
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 76fc1eb910f2..e0380d729b3c 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -412,11 +412,23 @@ PvScsiDriverBindingStart (
return EFI_OUT_OF_RESOURCES;
}
- Status = PvScsiInit (Dev);
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&Dev->PciIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
if (EFI_ERROR (Status)) {
goto FreePvScsi;
}
+ Status = PvScsiInit (Dev);
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
//
// Setup complete, attempt to export the driver instance's PassThru interface
//
@@ -436,6 +448,14 @@ PvScsiDriverBindingStart (
UninitDev:
PvScsiUninit (Dev);
+ClosePciIo:
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
FreePvScsi:
FreePool (Dev);
@@ -481,6 +501,13 @@ PvScsiDriverBindingStop (
PvScsiUninit (Dev);
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
FreePool (Dev);
return EFI_SUCCESS;
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index dd3e0c68e6da..e1e5ae18ebf2 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -19,6 +19,7 @@
typedef struct {
UINT32 Signature;
+ EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 MaxTarget;
UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 09/17] OvmfPkg/PvScsiDxe: Backup/Restore PCI attributes on Init/UnInit
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (7 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 08/17] OvmfPkg/PvScsiDxe: Open PciIo protocol for later use Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 10/17] OvmfPkg/PvScsiDxe: Enable MMIO-Space & Bus-Mastering in PCI attributes Liran Alon
` (9 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
This commit doesn't change semantics.
It is done as a preparation for future commits which will modify
PCI attributes.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 54 +++++++++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 1 +
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index e0380d729b3c..5566b4cce467 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -283,18 +283,70 @@ PvScsiGetNextTarget (
return EFI_NOT_FOUND;
}
+STATIC
+EFI_STATUS
+PvScsiSetPciAttributes (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Backup original PCI Attributes
+ //
+ Status = Dev->PciIo->Attributes (
+ Dev->PciIo,
+ EfiPciIoAttributeOperationGet,
+ 0,
+ &Dev->OriginalPciAttributes
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // TODO: Change PCI Attributes
+ //
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+PvScsiRestorePciAttributes (
+ IN PVSCSI_DEV *Dev
+ )
+{
+ Dev->PciIo->Attributes (
+ Dev->PciIo,
+ EfiPciIoAttributeOperationSet,
+ Dev->OriginalPciAttributes,
+ NULL
+ );
+}
+
STATIC
EFI_STATUS
PvScsiInit (
IN OUT PVSCSI_DEV *Dev
)
{
+ EFI_STATUS Status;
+
//
// Init configuration
//
Dev->MaxTarget = PcdGet8 (PcdPvScsiMaxTargetLimit);
Dev->MaxLun = PcdGet8 (PcdPvScsiMaxLunLimit);
+ //
+ // Set PCI Attributes
+ //
+ Status = PvScsiSetPciAttributes (Dev);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
//
// Populate the exported interface's attributes
//
@@ -333,7 +385,7 @@ PvScsiUninit (
IN OUT PVSCSI_DEV *Dev
)
{
- // Currently nothing to do here
+ PvScsiRestorePciAttributes (Dev);
}
//
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index e1e5ae18ebf2..5f611dbbc98c 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -20,6 +20,7 @@
typedef struct {
UINT32 Signature;
EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 OriginalPciAttributes;
UINT8 MaxTarget;
UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 10/17] OvmfPkg/PvScsiDxe: Enable MMIO-Space & Bus-Mastering in PCI attributes
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (8 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 09/17] OvmfPkg/PvScsiDxe: Backup/Restore PCI attributes on Init/UnInit Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 11/17] OvmfPkg/PvScsiDxe: Define device interface structures and constants Liran Alon
` (8 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Enable MMIO-Space & Bus-Mastering PCI attributes when device is started.
Note that original PCI attributes are restored when device is stopped.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 5566b4cce467..531bed4e5ab7 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -305,8 +305,18 @@ PvScsiSetPciAttributes (
}
//
- // TODO: Change PCI Attributes
+ // Enable MMIO-Space & Bus-Mastering
//
+ Status = Dev->PciIo->Attributes (
+ Dev->PciIo,
+ EfiPciIoAttributeOperationEnable,
+ (EFI_PCI_IO_ATTRIBUTE_MEMORY |
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
return EFI_SUCCESS;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 11/17] OvmfPkg/PvScsiDxe: Define device interface structures and constants
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (9 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 10/17] OvmfPkg/PvScsiDxe: Enable MMIO-Space & Bus-Mastering in PCI attributes Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-28 20:00 ` [PATCH v3 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init Liran Alon
` (7 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
These definitions will be used by the following commits to complete the
implementation of PVSCSI device driver.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/Include/IndustryStandard/PvScsi.h | 165 ++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/OvmfPkg/Include/IndustryStandard/PvScsi.h b/OvmfPkg/Include/IndustryStandard/PvScsi.h
index 004c0af84989..a4d6634f3ba0 100644
--- a/OvmfPkg/Include/IndustryStandard/PvScsi.h
+++ b/OvmfPkg/Include/IndustryStandard/PvScsi.h
@@ -18,4 +18,169 @@
#define PCI_VENDOR_ID_VMWARE (0x15ad)
#define PCI_DEVICE_ID_VMWARE_PVSCSI (0x07c0)
+//
+// CDB (Command Descriptor Block) with size above this constant
+// should be considered out-of-band
+//
+#define PVSCSI_CDB_MAX_SIZE (16)
+
+typedef enum {
+ PvScsiRegOffsetCommand = 0x0,
+ PvScsiRegOffsetCommandData = 0x4,
+ PvScsiRegOffsetCommandStatus = 0x8,
+ PvScsiRegOffsetLastSts0 = 0x100,
+ PvScsiRegOffsetLastSts1 = 0x104,
+ PvScsiRegOffsetLastSts2 = 0x108,
+ PvScsiRegOffsetLastSts3 = 0x10c,
+ PvScsiRegOffsetIntrStatus = 0x100c,
+ PvScsiRegOffsetIntrMask = 0x2010,
+ PvScsiRegOffsetKickNonRwIo = 0x3014,
+ PvScsiRegOffsetDebug = 0x3018,
+ PvScsiRegOffsetKickRwIo = 0x4018,
+} PVSCSI_BAR0_OFFSETS;
+
+//
+// Define Interrupt-Status register flags
+//
+#define PVSCSI_INTR_CMPL_0 BIT0
+#define PVSCSI_INTR_CMPL_1 BIT1
+#define PVSCSI_INTR_CMPL_MASK (PVSCSI_INTR_CMPL_0 | PVSCSI_INTR_CMPL_1)
+
+typedef enum {
+ PvScsiCmdFirst = 0,
+ PvScsiCmdAdapterReset = 1,
+ PvScsiCmdIssueScsi = 2,
+ PvScsiCmdSetupRings = 3,
+ PvScsiCmdResetBus = 4,
+ PvScsiCmdResetDevice = 5,
+ PvScsiCmdAbortCmd = 6,
+ PvScsiCmdConfig = 7,
+ PvScsiCmdSetupMsgRing = 8,
+ PvScsiCmdDeviceUnplug = 9,
+ PvScsiCmdLast = 10
+} PVSCSI_COMMANDS;
+
+#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES (32)
+
+#pragma pack (1)
+typedef struct {
+ UINT32 ReqRingNumPages;
+ UINT32 CmpRingNumPages;
+ UINT64 RingsStatePPN;
+ UINT64 ReqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
+ UINT64 CmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
+} PVSCSI_CMD_DESC_SETUP_RINGS;
+#pragma pack ()
+
+#define PVSCSI_MAX_CMD_DATA_WORDS \
+ (sizeof (PVSCSI_CMD_DESC_SETUP_RINGS) / sizeof (UINT32))
+
+#pragma pack (1)
+typedef struct {
+ UINT32 ReqProdIdx;
+ UINT32 ReqConsIdx;
+ UINT32 ReqNumEntriesLog2;
+
+ UINT32 CmpProdIdx;
+ UINT32 CmpConsIdx;
+ UINT32 CmpNumEntriesLog2;
+
+ UINT8 Pad[104];
+
+ UINT32 MsgProdIdx;
+ UINT32 MsgConsIdx;
+ UINT32 MsgNumEntriesLog2;
+} PVSCSI_RINGS_STATE;
+#pragma pack ()
+
+//
+// Define PVSCSI request descriptor tags
+//
+#define PVSCSI_SIMPLE_QUEUE_TAG (0x20)
+
+//
+// Define PVSCSI request descriptor flags
+//
+#define PVSCSI_FLAG_CMD_WITH_SG_LIST BIT0
+#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB BIT1
+#define PVSCSI_FLAG_CMD_DIR_NONE BIT2
+#define PVSCSI_FLAG_CMD_DIR_TOHOST BIT3
+#define PVSCSI_FLAG_CMD_DIR_TODEVICE BIT4
+
+#pragma pack (1)
+typedef struct {
+ UINT64 Context;
+ UINT64 DataAddr;
+ UINT64 DataLen;
+ UINT64 SenseAddr;
+ UINT32 SenseLen;
+ UINT32 Flags;
+ UINT8 Cdb[16];
+ UINT8 CdbLen;
+ UINT8 Lun[8];
+ UINT8 Tag;
+ UINT8 Bus;
+ UINT8 Target;
+ UINT8 VcpuHint;
+ UINT8 Unused[59];
+} PVSCSI_RING_REQ_DESC;
+#pragma pack ()
+
+//
+// Host adapter status/error codes
+//
+typedef enum {
+ PvScsiBtStatSuccess = 0x00, // CCB complete normally with no errors
+ PvScsiBtStatLinkedCommandCompleted = 0x0a,
+ PvScsiBtStatLinkedCommandCompletedWithFlag = 0x0b,
+ PvScsiBtStatDataUnderrun = 0x0c,
+ PvScsiBtStatSelTimeout = 0x11, // SCSI selection timeout
+ PvScsiBtStatDatarun = 0x12, // Data overrun/underrun
+ PvScsiBtStatBusFree = 0x13, // Unexpected bus free
+ PvScsiBtStatInvPhase = 0x14, //
+ // Invalid bus phase or sequence requested
+ // by target
+ //
+ PvScsiBtStatLunMismatch = 0x17, //
+ // Linked CCB has different LUN from first
+ // CCB
+ //
+ PvScsiBtStatSensFailed = 0x1b, // Auto request sense failed
+ PvScsiBtStatTagReject = 0x1c, //
+ // SCSI II tagged queueing message rejected
+ // by target
+ //
+ PvScsiBtStatBadMsg = 0x1d, //
+ // Unsupported message received by the host
+ // adapter
+ //
+ PvScsiBtStatHaHardware = 0x20, // Host adapter hardware failed
+ PvScsiBtStatNoResponse = 0x21, //
+ // Target did not respond to SCSI ATN sent
+ // a SCSI RST
+ //
+ PvScsiBtStatSentRst = 0x22, // Host adapter asserted a SCSI RST
+ PvScsiBtStatRecvRst = 0x23, // Other SCSI devices asserted a SCSI RST
+ PvScsiBtStatDisconnect = 0x24, //
+ // Target device reconnected improperly
+ // (w/o tag)
+ //
+ PvScsiBtStatBusReset = 0x25, // Host adapter issued BUS device reset
+ PvScsiBtStatAbortQueue = 0x26, // Abort queue generated
+ PvScsiBtStatHaSoftware = 0x27, // Host adapter software error
+ PvScsiBtStatHaTimeout = 0x30, // Host adapter hardware timeout error
+ PvScsiBtStatScsiParity = 0x34, // SCSI parity error detected
+} PVSCSI_HOST_BUS_ADAPTER_STATUS;
+
+#pragma pack (1)
+typedef struct {
+ UINT64 Context;
+ UINT64 DataLen;
+ UINT32 SenseLen;
+ UINT16 HostStatus;
+ UINT16 ScsiStatus;
+ UINT32 Pad[2];
+} PVSCSI_RING_CMP_DESC;
+#pragma pack ()
+
#endif // __PVSCSI_H_
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (10 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 11/17] OvmfPkg/PvScsiDxe: Define device interface structures and constants Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-30 15:19 ` [edk2-devel] " Laszlo Ersek
2020-03-28 20:00 ` [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Liran Alon
` (6 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
The following commits will complete the implementation of
device initialization.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 114 +++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 531bed4e5ab7..cf75884350ee 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -30,6 +30,107 @@
// Ext SCSI Pass Thru utilities
//
+/**
+ Writes a 32-bit value into BAR0 using MMIO
+**/
+STATIC
+EFI_STATUS
+PvScsiMmioWrite32 (
+ IN CONST PVSCSI_DEV *Dev,
+ IN UINT64 Offset,
+ IN UINT32 Value
+ )
+{
+ return Dev->PciIo->Mem.Write (
+ Dev->PciIo,
+ EfiPciIoWidthUint32,
+ PCI_BAR_IDX0,
+ Offset,
+ 1, // Count
+ &Value
+ );
+}
+
+/**
+ Writes multiple words of data into BAR0 using MMIO
+**/
+STATIC
+EFI_STATUS
+PvScsiMmioWrite32Multiple (
+ IN CONST PVSCSI_DEV *Dev,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN UINT32 *Words
+ )
+{
+ return Dev->PciIo->Mem.Write (
+ Dev->PciIo,
+ EfiPciIoWidthFifoUint32,
+ PCI_BAR_IDX0,
+ Offset,
+ Count,
+ Words
+ );
+}
+
+/**
+ Send a PVSCSI command to device.
+
+ @param[in] Dev The pvscsi host device.
+ @param[in] Cmd The command to send to device.
+ @param[in] OPTIONAL DescWords An optional command descriptor (If command
+ have a descriptor). The descriptor is
+ provided as an array of UINT32 words and
+ is must be 32-bit aligned.
+ @param[in] DescWordsCount The number of words in command descriptor.
+ Caller must specify here 0 if DescWords
+ is not supplied (It is optional). In that
+ case, DescWords is ignored.
+
+ @return Status codes returned by Dev->PciIo->Mem.Write().
+
+**/
+STATIC
+EFI_STATUS
+PvScsiWriteCmdDesc (
+ IN CONST PVSCSI_DEV *Dev,
+ IN UINT32 Cmd,
+ IN UINT32 *DescWords OPTIONAL,
+ IN UINTN DescWordsCount
+ )
+{
+ EFI_STATUS Status;
+
+ if (DescWordsCount > PVSCSI_MAX_CMD_DATA_WORDS) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetCommand, Cmd);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (DescWordsCount > 0) {
+ return PvScsiMmioWrite32Multiple (
+ Dev,
+ PvScsiRegOffsetCommandData,
+ DescWordsCount,
+ DescWords
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PvScsiResetAdapter (
+ IN CONST PVSCSI_DEV *Dev
+ )
+{
+ return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0);
+}
+
/**
Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
@@ -357,6 +458,14 @@ PvScsiInit (
return Status;
}
+ //
+ // Reset adapter
+ //
+ Status = PvScsiResetAdapter (Dev);
+ if (EFI_ERROR (Status)) {
+ goto RestorePciAttributes;
+ }
+
//
// Populate the exported interface's attributes
//
@@ -387,6 +496,11 @@ PvScsiInit (
Dev->PassThruMode.IoAlign = 0;
return EFI_SUCCESS;
+
+RestorePciAttributes:
+ PvScsiRestorePciAttributes (Dev);
+
+ return Status;
}
STATIC
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init
2020-03-28 20:00 ` [PATCH v3 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init Liran Alon
@ 2020-03-30 15:19 ` Laszlo Ersek
0 siblings, 0 replies; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 15:19 UTC (permalink / raw)
To: devel, liran.alon
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/28/20 21:00, Liran Alon wrote:
> The following commits will complete the implementation of
> device initialization.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Liran Alon <liran.alon@oracle.com>
> ---
> OvmfPkg/PvScsiDxe/PvScsi.c | 114 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
Thanks for the updates in this patch, my R-b stands.
Laszlo
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
> index 531bed4e5ab7..cf75884350ee 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.c
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.c
> @@ -30,6 +30,107 @@
> // Ext SCSI Pass Thru utilities
> //
>
> +/**
> + Writes a 32-bit value into BAR0 using MMIO
> +**/
> +STATIC
> +EFI_STATUS
> +PvScsiMmioWrite32 (
> + IN CONST PVSCSI_DEV *Dev,
> + IN UINT64 Offset,
> + IN UINT32 Value
> + )
> +{
> + return Dev->PciIo->Mem.Write (
> + Dev->PciIo,
> + EfiPciIoWidthUint32,
> + PCI_BAR_IDX0,
> + Offset,
> + 1, // Count
> + &Value
> + );
> +}
> +
> +/**
> + Writes multiple words of data into BAR0 using MMIO
> +**/
> +STATIC
> +EFI_STATUS
> +PvScsiMmioWrite32Multiple (
> + IN CONST PVSCSI_DEV *Dev,
> + IN UINT64 Offset,
> + IN UINTN Count,
> + IN UINT32 *Words
> + )
> +{
> + return Dev->PciIo->Mem.Write (
> + Dev->PciIo,
> + EfiPciIoWidthFifoUint32,
> + PCI_BAR_IDX0,
> + Offset,
> + Count,
> + Words
> + );
> +}
> +
> +/**
> + Send a PVSCSI command to device.
> +
> + @param[in] Dev The pvscsi host device.
> + @param[in] Cmd The command to send to device.
> + @param[in] OPTIONAL DescWords An optional command descriptor (If command
> + have a descriptor). The descriptor is
> + provided as an array of UINT32 words and
> + is must be 32-bit aligned.
> + @param[in] DescWordsCount The number of words in command descriptor.
> + Caller must specify here 0 if DescWords
> + is not supplied (It is optional). In that
> + case, DescWords is ignored.
> +
> + @return Status codes returned by Dev->PciIo->Mem.Write().
> +
> +**/
> +STATIC
> +EFI_STATUS
> +PvScsiWriteCmdDesc (
> + IN CONST PVSCSI_DEV *Dev,
> + IN UINT32 Cmd,
> + IN UINT32 *DescWords OPTIONAL,
> + IN UINTN DescWordsCount
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (DescWordsCount > PVSCSI_MAX_CMD_DATA_WORDS) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetCommand, Cmd);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + if (DescWordsCount > 0) {
> + return PvScsiMmioWrite32Multiple (
> + Dev,
> + PvScsiRegOffsetCommandData,
> + DescWordsCount,
> + DescWords
> + );
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +PvScsiResetAdapter (
> + IN CONST PVSCSI_DEV *Dev
> + )
> +{
> + return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0);
> +}
> +
> /**
> Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
> EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
> @@ -357,6 +458,14 @@ PvScsiInit (
> return Status;
> }
>
> + //
> + // Reset adapter
> + //
> + Status = PvScsiResetAdapter (Dev);
> + if (EFI_ERROR (Status)) {
> + goto RestorePciAttributes;
> + }
> +
> //
> // Populate the exported interface's attributes
> //
> @@ -387,6 +496,11 @@ PvScsiInit (
> Dev->PassThruMode.IoAlign = 0;
>
> return EFI_SUCCESS;
> +
> +RestorePciAttributes:
> + PvScsiRestorePciAttributes (Dev);
> +
> + return Status;
> }
>
> STATIC
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (11 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-30 15:54 ` [edk2-devel] " Laszlo Ersek
2020-03-28 20:00 ` [PATCH v3 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer Liran Alon
` (5 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
These rings are shared memory buffers between host and device in which
a cyclic buffer is managed to send request descriptors from host to
device and receive completion descriptors from device to host.
Note that because device may be constrained by IOMMU or guest may be run
under AMD SEV, we make sure to map these rings to device by using
PciIo->Map().
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 219 ++++++++++++++++++++++++++++++++
OvmfPkg/PvScsiDxe/PvScsi.h | 17 +++
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 1 +
3 files changed, 237 insertions(+)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index cf75884350ee..c7d367e83a2d 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -11,11 +11,13 @@
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/PvScsi.h>
+#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
#include <Uefi/UefiSpec.h>
#include "PvScsi.h"
@@ -436,6 +438,207 @@ PvScsiRestorePciAttributes (
);
}
+STATIC
+EFI_STATUS
+PvScsiAllocateSharedPages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ OUT PVSCSI_DMA_DESC *DmaDesc
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumberOfBytes;
+
+ Status = Dev->PciIo->AllocateBuffer (
+ Dev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ Pages,
+ HostAddress,
+ EFI_PCI_ATTRIBUTE_MEMORY_CACHED
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
+ Status = Dev->PciIo->Map (
+ Dev->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ *HostAddress,
+ &NumberOfBytes,
+ &DmaDesc->DeviceAddress,
+ &DmaDesc->Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBuffer;
+ }
+
+ if (NumberOfBytes != EFI_PAGES_TO_SIZE (Pages)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Unmap;
+ }
+
+ return EFI_SUCCESS;
+
+Unmap:
+ Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
+
+FreeBuffer:
+ Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, *HostAddress);
+
+ return Status;
+}
+
+STATIC
+VOID
+PvScsiFreeSharedPages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ IN VOID *HostAddress,
+ IN PVSCSI_DMA_DESC *DmaDesc
+ )
+{
+ Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
+ Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, HostAddress);
+}
+
+STATIC
+EFI_STATUS
+PvScsiInitRings (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+ union {
+ PVSCSI_CMD_DESC_SETUP_RINGS Cmd;
+ UINT32 Uint32;
+ } AlignedCmd;
+ PVSCSI_CMD_DESC_SETUP_RINGS *Cmd;
+
+ Cmd = &AlignedCmd.Cmd;
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingState,
+ &Dev->RingDesc.RingStateDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ZeroMem (Dev->RingDesc.RingState, EFI_PAGE_SIZE);
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingReqs,
+ &Dev->RingDesc.RingReqsDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeRingState;
+ }
+ ZeroMem (Dev->RingDesc.RingReqs, EFI_PAGE_SIZE);
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingCmps,
+ &Dev->RingDesc.RingCmpsDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeRingReqs;
+ }
+ ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE);
+
+ ZeroMem (Cmd, sizeof (*Cmd));
+ Cmd->ReqRingNumPages = 1;
+ Cmd->CmpRingNumPages = 1;
+ Cmd->RingsStatePPN = RShiftU64 (
+ Dev->RingDesc.RingStateDmaDesc.DeviceAddress,
+ EFI_PAGE_SHIFT
+ );
+ Cmd->ReqRingPPNs[0] = RShiftU64 (
+ Dev->RingDesc.RingReqsDmaDesc.DeviceAddress,
+ EFI_PAGE_SHIFT
+ );
+ Cmd->CmpRingPPNs[0] = RShiftU64 (
+ Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress,
+ EFI_PAGE_SHIFT
+ );
+
+ STATIC_ASSERT (
+ sizeof (*Cmd) % sizeof (UINT32) == 0,
+ "Cmd must be multiple of 32-bit words"
+ );
+ Status = PvScsiWriteCmdDesc (
+ Dev,
+ PvScsiCmdSetupRings,
+ (UINT32 *)Cmd,
+ sizeof (*Cmd) / sizeof (UINT32)
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeRingCmps;
+ }
+
+ return EFI_SUCCESS;
+
+FreeRingCmps:
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingCmps,
+ &Dev->RingDesc.RingCmpsDmaDesc
+ );
+
+FreeRingReqs:
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingReqs,
+ &Dev->RingDesc.RingReqsDmaDesc
+ );
+
+FreeRingState:
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingState,
+ &Dev->RingDesc.RingStateDmaDesc
+ );
+
+ return Status;
+}
+
+STATIC
+VOID
+PvScsiFreeRings (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingCmps,
+ &Dev->RingDesc.RingCmpsDmaDesc
+ );
+
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingReqs,
+ &Dev->RingDesc.RingReqsDmaDesc
+ );
+
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ Dev->RingDesc.RingState,
+ &Dev->RingDesc.RingStateDmaDesc
+ );
+}
+
STATIC
EFI_STATUS
PvScsiInit (
@@ -466,6 +669,14 @@ PvScsiInit (
goto RestorePciAttributes;
}
+ //
+ // Init PVSCSI rings
+ //
+ Status = PvScsiInitRings (Dev);
+ if (EFI_ERROR (Status)) {
+ goto RestorePciAttributes;
+ }
+
//
// Populate the exported interface's attributes
//
@@ -509,6 +720,14 @@ PvScsiUninit (
IN OUT PVSCSI_DEV *Dev
)
{
+ //
+ // Reset device to stop device usage of the rings.
+ // This is required to safely free the rings.
+ //
+ PvScsiResetAdapter (Dev);
+
+ PvScsiFreeRings (Dev);
+
PvScsiRestorePciAttributes (Dev);
}
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index 5f611dbbc98c..6d23b6e1eccf 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -15,12 +15,29 @@
#include <Library/DebugLib.h>
#include <Protocol/ScsiPassThruExt.h>
+typedef struct {
+ EFI_PHYSICAL_ADDRESS DeviceAddress;
+ VOID *Mapping;
+} PVSCSI_DMA_DESC;
+
+typedef struct {
+ PVSCSI_RINGS_STATE *RingState;
+ PVSCSI_DMA_DESC RingStateDmaDesc;
+
+ PVSCSI_RING_REQ_DESC *RingReqs;
+ PVSCSI_DMA_DESC RingReqsDmaDesc;
+
+ PVSCSI_RING_CMP_DESC *RingCmps;
+ PVSCSI_DMA_DESC RingCmpsDmaDesc;
+} PVSCSI_RING_DESC;
+
#define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')
typedef struct {
UINT32 Signature;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
+ PVSCSI_RING_DESC RingDesc;
UINT8 MaxTarget;
UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index fcffc90d46c8..6200533698fc 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -26,6 +26,7 @@
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
+ BaseLib
BaseMemoryLib
DebugLib
MemoryAllocationLib
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings
2020-03-28 20:00 ` [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Liran Alon
@ 2020-03-30 15:54 ` Laszlo Ersek
2020-03-30 17:24 ` Liran Alon
0 siblings, 1 reply; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 15:54 UTC (permalink / raw)
To: devel, liran.alon
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/28/20 21:00, Liran Alon wrote:
> These rings are shared memory buffers between host and device in which
> a cyclic buffer is managed to send request descriptors from host to
> device and receive completion descriptors from device to host.
>
> Note that because device may be constrained by IOMMU or guest may be run
> under AMD SEV, we make sure to map these rings to device by using
> PciIo->Map().
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
> Signed-off-by: Liran Alon <liran.alon@oracle.com>
> ---
> OvmfPkg/PvScsiDxe/PvScsi.c | 219 ++++++++++++++++++++++++++++++++
> OvmfPkg/PvScsiDxe/PvScsi.h | 17 +++
> OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 1 +
> 3 files changed, 237 insertions(+)
>
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
> index cf75884350ee..c7d367e83a2d 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.c
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.c
> @@ -11,11 +11,13 @@
>
> #include <IndustryStandard/Pci.h>
> #include <IndustryStandard/PvScsi.h>
> +#include <Library/BaseLib.h>
> #include <Library/BaseMemoryLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/UefiBootServicesTableLib.h>
> #include <Library/UefiLib.h>
> #include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
> #include <Uefi/UefiSpec.h>
>
> #include "PvScsi.h"
> @@ -436,6 +438,207 @@ PvScsiRestorePciAttributes (
> );
> }
>
> +STATIC
> +EFI_STATUS
> +PvScsiAllocateSharedPages (
> + IN PVSCSI_DEV *Dev,
> + IN UINTN Pages,
> + OUT VOID **HostAddress,
> + OUT PVSCSI_DMA_DESC *DmaDesc
> + )
> +{
> + EFI_STATUS Status;
> + UINTN NumberOfBytes;
> +
> + Status = Dev->PciIo->AllocateBuffer (
> + Dev->PciIo,
> + AllocateAnyPages,
> + EfiBootServicesData,
> + Pages,
> + HostAddress,
> + EFI_PCI_ATTRIBUTE_MEMORY_CACHED
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
> + Status = Dev->PciIo->Map (
> + Dev->PciIo,
> + EfiPciIoOperationBusMasterCommonBuffer,
> + *HostAddress,
> + &NumberOfBytes,
> + &DmaDesc->DeviceAddress,
> + &DmaDesc->Mapping
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeBuffer;
> + }
> +
> + if (NumberOfBytes != EFI_PAGES_TO_SIZE (Pages)) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Unmap;
> + }
> +
> + return EFI_SUCCESS;
> +
> +Unmap:
> + Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
> +
> +FreeBuffer:
> + Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, *HostAddress);
> +
> + return Status;
> +}
> +
> +STATIC
> +VOID
> +PvScsiFreeSharedPages (
> + IN PVSCSI_DEV *Dev,
> + IN UINTN Pages,
> + IN VOID *HostAddress,
> + IN PVSCSI_DMA_DESC *DmaDesc
> + )
> +{
> + Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
> + Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, HostAddress);
> +}
> +
> +STATIC
> +EFI_STATUS
> +PvScsiInitRings (
> + IN OUT PVSCSI_DEV *Dev
> + )
> +{
> + EFI_STATUS Status;
> + union {
> + PVSCSI_CMD_DESC_SETUP_RINGS Cmd;
> + UINT32 Uint32;
> + } AlignedCmd;
> + PVSCSI_CMD_DESC_SETUP_RINGS *Cmd;
> +
> + Cmd = &AlignedCmd.Cmd;
> +
> + Status = PvScsiAllocateSharedPages (
> + Dev,
> + 1,
> + (VOID **)&Dev->RingDesc.RingState,
> + &Dev->RingDesc.RingStateDmaDesc
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + ZeroMem (Dev->RingDesc.RingState, EFI_PAGE_SIZE);
> +
> + Status = PvScsiAllocateSharedPages (
> + Dev,
> + 1,
> + (VOID **)&Dev->RingDesc.RingReqs,
> + &Dev->RingDesc.RingReqsDmaDesc
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeRingState;
> + }
> + ZeroMem (Dev->RingDesc.RingReqs, EFI_PAGE_SIZE);
> +
> + Status = PvScsiAllocateSharedPages (
> + Dev,
> + 1,
> + (VOID **)&Dev->RingDesc.RingCmps,
> + &Dev->RingDesc.RingCmpsDmaDesc
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeRingReqs;
> + }
> + ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE);
> +
> + ZeroMem (Cmd, sizeof (*Cmd));
> + Cmd->ReqRingNumPages = 1;
> + Cmd->CmpRingNumPages = 1;
> + Cmd->RingsStatePPN = RShiftU64 (
> + Dev->RingDesc.RingStateDmaDesc.DeviceAddress,
> + EFI_PAGE_SHIFT
> + );
> + Cmd->ReqRingPPNs[0] = RShiftU64 (
> + Dev->RingDesc.RingReqsDmaDesc.DeviceAddress,
> + EFI_PAGE_SHIFT
> + );
> + Cmd->CmpRingPPNs[0] = RShiftU64 (
> + Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress,
> + EFI_PAGE_SHIFT
> + );
> +
> + STATIC_ASSERT (
> + sizeof (*Cmd) % sizeof (UINT32) == 0,
> + "Cmd must be multiple of 32-bit words"
> + );
> + Status = PvScsiWriteCmdDesc (
> + Dev,
> + PvScsiCmdSetupRings,
> + (UINT32 *)Cmd,
> + sizeof (*Cmd) / sizeof (UINT32)
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeRingCmps;
> + }
> +
> + return EFI_SUCCESS;
> +
> +FreeRingCmps:
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingCmps,
> + &Dev->RingDesc.RingCmpsDmaDesc
> + );
> +
> +FreeRingReqs:
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingReqs,
> + &Dev->RingDesc.RingReqsDmaDesc
> + );
> +
> +FreeRingState:
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingState,
> + &Dev->RingDesc.RingStateDmaDesc
> + );
> +
> + return Status;
> +}
> +
> +STATIC
> +VOID
> +PvScsiFreeRings (
> + IN OUT PVSCSI_DEV *Dev
> + )
> +{
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingCmps,
> + &Dev->RingDesc.RingCmpsDmaDesc
> + );
> +
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingReqs,
> + &Dev->RingDesc.RingReqsDmaDesc
> + );
> +
> + PvScsiFreeSharedPages (
> + Dev,
> + 1,
> + Dev->RingDesc.RingState,
> + &Dev->RingDesc.RingStateDmaDesc
> + );
> +}
> +
> STATIC
> EFI_STATUS
> PvScsiInit (
> @@ -466,6 +669,14 @@ PvScsiInit (
> goto RestorePciAttributes;
> }
>
> + //
> + // Init PVSCSI rings
> + //
> + Status = PvScsiInitRings (Dev);
> + if (EFI_ERROR (Status)) {
> + goto RestorePciAttributes;
> + }
> +
> //
> // Populate the exported interface's attributes
> //
> @@ -509,6 +720,14 @@ PvScsiUninit (
> IN OUT PVSCSI_DEV *Dev
> )
> {
> + //
> + // Reset device to stop device usage of the rings.
> + // This is required to safely free the rings.
> + //
> + PvScsiResetAdapter (Dev);
If I understand correctly (at the end of the series):
in order to save one of the (ultimately) two reset calls in
PvScsiUninit(), namely
- one for releasing the DMA buf
- and the other (internal to PvScsiFreeRings()) for releasing the rings,
you unnested the latter reset call from PvScsiFreeRings(), and added it
manually to the error path of PvScsiInit().
To me, that's more brittle and more difficult to reason about than what
I proposed, because now PvScsiFreeRings() does not completely undo
PvScsiInitRings(). I specifically requested that we please not try to
save on the two (seemingly) redundant reset calls in PvScsiUninit() --
see the paragraph containing "bad idea" here:
http://mid.mail-archive.com/45e5950c-ec82-c24b-4c38-2912402747b2@redhat.com
https://edk2.groups.io/g/devel/message/56425
(Note: we could be tempted to somehow "centralize" all of these
Reset operations into a single spot. Bad idea. We are revoking the
device's access rights to different resources, so the revocation
operations will show up in different spots. It's a mere circumstance
that the revocations all happen to be Reset operations.)
I might be paranoid of course -- I just feel that maybe-superfluous
reset operations on error paths are much better than silently
corrupted guest memory and/or disk contents.
You reacted to that message of mine, but not this paragraph specifically
(it was snipped from your followup) -- so I thought you were OK with it.
I'm a bit disappointed that you disagreed with my request *silently*.
To summarize: technically, your solution is correct; from a code hygiene
and resource ownership question, I'm convinced it is wrong.
But, I'll live with it.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(Also, you didn't set up the "diff.orderFile" knob the way I requested
in point (8):
http://mid.mail-archive.com/0739202a-9b8a-759d-5809-2f2df69e9352@redhat.com
https://edk2.groups.io/g/devel/message/56420
and so the header file changes are again at the end of the patch...
Another thing I'll have to live with, I guess.)
Laszlo
> +
> + PvScsiFreeRings (Dev);
> +
> PvScsiRestorePciAttributes (Dev);
> }
>
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
> index 5f611dbbc98c..6d23b6e1eccf 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.h
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.h
> @@ -15,12 +15,29 @@
> #include <Library/DebugLib.h>
> #include <Protocol/ScsiPassThruExt.h>
>
> +typedef struct {
> + EFI_PHYSICAL_ADDRESS DeviceAddress;
> + VOID *Mapping;
> +} PVSCSI_DMA_DESC;
> +
> +typedef struct {
> + PVSCSI_RINGS_STATE *RingState;
> + PVSCSI_DMA_DESC RingStateDmaDesc;
> +
> + PVSCSI_RING_REQ_DESC *RingReqs;
> + PVSCSI_DMA_DESC RingReqsDmaDesc;
> +
> + PVSCSI_RING_CMP_DESC *RingCmps;
> + PVSCSI_DMA_DESC RingCmpsDmaDesc;
> +} PVSCSI_RING_DESC;
> +
> #define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')
>
> typedef struct {
> UINT32 Signature;
> EFI_PCI_IO_PROTOCOL *PciIo;
> UINT64 OriginalPciAttributes;
> + PVSCSI_RING_DESC RingDesc;
> UINT8 MaxTarget;
> UINT8 MaxLun;
> EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
> diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
> index fcffc90d46c8..6200533698fc 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
> +++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
> @@ -26,6 +26,7 @@
> OvmfPkg/OvmfPkg.dec
>
> [LibraryClasses]
> + BaseLib
> BaseMemoryLib
> DebugLib
> MemoryAllocationLib
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings
2020-03-30 15:54 ` [edk2-devel] " Laszlo Ersek
@ 2020-03-30 17:24 ` Liran Alon
2020-03-30 20:46 ` Laszlo Ersek
0 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-30 17:24 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 30/03/2020 18:54, Laszlo Ersek wrote:
> On 03/28/20 21:00, Liran Alon wrote:
>> STATIC
>> EFI_STATUS
>> PvScsiInit (
>> @@ -466,6 +669,14 @@ PvScsiInit (
>> goto RestorePciAttributes;
>> }
>>
>> + //
>> + // Init PVSCSI rings
>> + //
>> + Status = PvScsiInitRings (Dev);
>> + if (EFI_ERROR (Status)) {
>> + goto RestorePciAttributes;
>> + }
>> +
>> //
>> // Populate the exported interface's attributes
>> //
>> @@ -509,6 +720,14 @@ PvScsiUninit (
>> IN OUT PVSCSI_DEV *Dev
>> )
>> {
>> + //
>> + // Reset device to stop device usage of the rings.
>> + // This is required to safely free the rings.
>> + //
>> + PvScsiResetAdapter (Dev);
> If I understand correctly (at the end of the series):
>
> in order to save one of the (ultimately) two reset calls in
> PvScsiUninit(), namely
> - one for releasing the DMA buf
> - and the other (internal to PvScsiFreeRings()) for releasing the rings,
> you unnested the latter reset call from PvScsiFreeRings(), and added it
> manually to the error path of PvScsiInit().
Right.
>
> To me, that's more brittle and more difficult to reason about than what
> I proposed, because now PvScsiFreeRings() does not completely undo
> PvScsiInitRings().
Hmm right. Because PvScsiInitRings() also setup the ring to the device
with a command. Haven't thought about it.
> I specifically requested that we please not try to
> save on the two (seemingly) redundant reset calls in PvScsiUninit() --
> see the paragraph containing "bad idea" here:
>
> https://urldefense.com/v3/__http://mid.mail-archive.com/45e5950c-ec82-c24b-4c38-2912402747b2@redhat.com__;!!GqivPVa7Brio!MtQ2Nlgza8eW9tXH6x5jj0EZQbLphEJgXBmIFjEur-nxyjxDufyi4uk-Fn-EyPU$
> https://urldefense.com/v3/__https://edk2.groups.io/g/devel/message/56425__;!!GqivPVa7Brio!MtQ2Nlgza8eW9tXH6x5jj0EZQbLphEJgXBmIFjEur-nxyjxDufyi4uk-4bfLR8U$
>
> (Note: we could be tempted to somehow "centralize" all of these
> Reset operations into a single spot. Bad idea. We are revoking the
> device's access rights to different resources, so the revocation
> operations will show up in different spots. It's a mere circumstance
> that the revocations all happen to be Reset operations.)
>
> I might be paranoid of course -- I just feel that maybe-superfluous
> reset operations on error paths are much better than silently
> corrupted guest memory and/or disk contents.
>
> You reacted to that message of mine, but not this paragraph specifically
> (it was snipped from your followup) -- so I thought you were OK with it.
> I'm a bit disappointed that you disagreed with my request *silently*.
Oh now I got what you meant! I misinterpreted it. Not silently ignored
it of course!
I can change this in a v4 patch-series if you would like that. Sorry for
the misunderstanding.
I do agree with your statement that PvScsiFreeRings() is not completely
an undo of PvScsiInitRings().
And maybe for making code a little bit easier to reason about, it's
preferred to just do one additional unnecessary device reset.
>
> To summarize: technically, your solution is correct; from a code hygiene
> and resource ownership question, I'm convinced it is wrong.
I agree.
>
> But, I'll live with it.
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
I can send a v4 patch-series just changing that if you would like.
Or submit a patch to change it after it will be merged.
Or that you will change it when applying. Or leave it as is.
I don't have any objection to any of the above.
>
> (Also, you didn't set up the "diff.orderFile" knob the way I requested
> in point (8):
I actually did set it up in my ~/.gitconfig. It seems that it doesn't
work from some reason...
>
> https://urldefense.com/v3/__http://mid.mail-archive.com/0739202a-9b8a-759d-5809-2f2df69e9352@redhat.com__;!!GqivPVa7Brio!MtQ2Nlgza8eW9tXH6x5jj0EZQbLphEJgXBmIFjEur-nxyjxDufyi4uk-bs34O4s$
> https://urldefense.com/v3/__https://edk2.groups.io/g/devel/message/56420__;!!GqivPVa7Brio!MtQ2Nlgza8eW9tXH6x5jj0EZQbLphEJgXBmIFjEur-nxyjxDufyi4uk-msgEmGo$
>
> and so the header file changes are again at the end of the patch...
> Another thing I'll have to live with, I guess.)
>
> Laszlo
Thanks for the understanding,
-Liran
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings
2020-03-30 17:24 ` Liran Alon
@ 2020-03-30 20:46 ` Laszlo Ersek
0 siblings, 0 replies; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 20:46 UTC (permalink / raw)
To: Liran Alon, devel
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/30/20 19:24, Liran Alon wrote:
>
> On 30/03/2020 18:54, Laszlo Ersek wrote:
>> On 03/28/20 21:00, Liran Alon wrote:
>>> @@ -509,6 +720,14 @@ PvScsiUninit (
>>> IN OUT PVSCSI_DEV *Dev
>>> )
>>> {
>>> + //
>>> + // Reset device to stop device usage of the rings.
>>> + // This is required to safely free the rings.
>>> + //
>>> + PvScsiResetAdapter (Dev);
>> If I understand correctly (at the end of the series):
>>
>> in order to save one of the (ultimately) two reset calls in
>> PvScsiUninit(), namely
>> - one for releasing the DMA buf
>> - and the other (internal to PvScsiFreeRings()) for releasing the
>> rings, you unnested the latter reset call from PvScsiFreeRings(), and
>> added it manually to the error path of PvScsiInit().
> Right.
>> To me, that's more brittle and more difficult to reason about than
>> what I proposed, because now PvScsiFreeRings() does not completely
>> undo PvScsiInitRings().
> Hmm right. Because PvScsiInitRings() also setup the ring to the device
> with a command. Haven't thought about it.
>> I specifically requested that we please not try to save on the two
>> (seemingly) redundant reset calls in PvScsiUninit() -- see the
>> paragraph containing "bad idea" here:
>>
>> [...]
>>
>> (Note: we could be tempted to somehow "centralize" all of these
>> Reset operations into a single spot. Bad idea. We are revoking
>> the device's access rights to different resources, so the
>> revocation operations will show up in different spots. It's a
>> mere circumstance that the revocations all happen to be Reset
>> operations.)
>>
>> I might be paranoid of course -- I just feel that
>> maybe-superfluous reset operations on error paths are much
>> better than silently corrupted guest memory and/or disk
>> contents.
>>
>> You reacted to that message of mine, but not this paragraph
>> specifically (it was snipped from your followup) -- so I thought you
>> were OK with it. I'm a bit disappointed that you disagreed with my
>> request *silently*.
> Oh now I got what you meant! I misinterpreted it. Not silently ignored
> it of course!
> I can change this in a v4 patch-series if you would like that. Sorry
> for the misunderstanding.
>
> I do agree with your statement that PvScsiFreeRings() is not
> completely an undo of PvScsiInitRings().
> And maybe for making code a little bit easier to reason about, it's
> preferred to just do one additional unnecessary device reset.
>> To summarize: technically, your solution is correct; from a code
>> hygiene and resource ownership question, I'm convinced it is wrong.
> I agree.
>> But, I'll live with it.
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> I can send a v4 patch-series just changing that if you would like.
> Or submit a patch to change it after it will be merged.
> Or that you will change it when applying. Or leave it as is.
>
> I don't have any objection to any of the above.
OK. That's a relief to me, thank you! And I apologize for insinuating
that you deliberately & silently ignored said feedback from me. I tend
to be pedantic about email (it's not natural for me to think that
someone simply missed a comment) -- sorry about that!
Given that I've already merged v3 -- can you please post a followup
patch? Something like:
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
> index 0a66c98421a9..3066b83b96fc 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.c
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.c
> @@ -1093,6 +1093,12 @@ PvScsiFreeRings (
> IN OUT PVSCSI_DEV *Dev
> )
> {
> + //
> + // Reset device to stop device usage of the rings.
> + // This is required to safely free the rings.
> + //
> + PvScsiResetAdapter (Dev);
> +
> PvScsiFreeSharedPages (
> Dev,
> 1,
> @@ -1199,12 +1205,6 @@ PvScsiInit (
> return EFI_SUCCESS;
>
> FreeRings:
> - //
> - // Reset device to stop device usage of the rings.
> - // This is required to safely free the rings.
> - //
> - PvScsiResetAdapter (Dev);
> -
> PvScsiFreeRings (Dev);
>
> RestorePciAttributes:
> @@ -1220,12 +1220,8 @@ PvScsiUninit (
> )
> {
> //
> - // Reset device to:
> - // - Make device stop processing all requests.
> - // - Stop device usage of the rings.
> - //
> - // This is required to safely free the DMA communication buffer
> - // and the rings.
> + // Reset device to make device stop processing all requests.
> + // This is required to safely free the DMA communication buffer.
> //
> PvScsiResetAdapter (Dev);
Thank you!
Laszlo
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (12 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-30 16:06 ` [edk2-devel] " Laszlo Ersek
2020-03-28 20:00 ` [PATCH v3 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response Liran Alon
` (4 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
In case device is constrained by IOMMU or guest is running under AMD SEV,
input/output buffers provided to device (DataBuffer and SenseData) needs
to be explicitly mapped to device by PciIo->Map().
To avoid the overhead of mapping/unmapping the DataBuffer and SenseData
to the device for every SCSI requst (and to simplify code), introduce a
single DMA communication buffer that will be mapped to device on
initialization. When a SCSI request needs to be sent to device, the
DataBuffer and SenseData will be copied from/to the DMA communication
buffer as required. This will be done by the following commits.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 60 ++++++++++++++++++++++++++++++--------
OvmfPkg/PvScsiDxe/PvScsi.h | 20 +++++++++++++
2 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index c7d367e83a2d..6e350bb2d6e0 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -677,6 +677,19 @@ PvScsiInit (
goto RestorePciAttributes;
}
+ //
+ // Allocate DMA communication buffer
+ //
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
+ (VOID **)&Dev->DmaBuf,
+ &Dev->DmaBufDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeRings;
+ }
+
//
// Populate the exported interface's attributes
//
@@ -708,18 +721,7 @@ PvScsiInit (
return EFI_SUCCESS;
-RestorePciAttributes:
- PvScsiRestorePciAttributes (Dev);
-
- return Status;
-}
-
-STATIC
-VOID
-PvScsiUninit (
- IN OUT PVSCSI_DEV *Dev
- )
-{
+FreeRings:
//
// Reset device to stop device usage of the rings.
// This is required to safely free the rings.
@@ -728,6 +730,40 @@ PvScsiUninit (
PvScsiFreeRings (Dev);
+RestorePciAttributes:
+ PvScsiRestorePciAttributes (Dev);
+
+ return Status;
+}
+
+STATIC
+VOID
+PvScsiUninit (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ //
+ // Reset device to:
+ // - Make device stop processing all requests.
+ // - Stop device usage of the rings.
+ //
+ // This is required to safely free the DMA communication buffer
+ // and the rings.
+ //
+ PvScsiResetAdapter (Dev);
+
+ //
+ // Free DMA communication buffer
+ //
+ PvScsiFreeSharedPages (
+ Dev,
+ EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
+ Dev->DmaBuf,
+ &Dev->DmaBufDmaDesc
+ );
+
+ PvScsiFreeRings (Dev);
+
PvScsiRestorePciAttributes (Dev);
}
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index 6d23b6e1eccf..fff12146dc75 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -31,6 +31,21 @@ typedef struct {
PVSCSI_DMA_DESC RingCmpsDmaDesc;
} PVSCSI_RING_DESC;
+typedef struct {
+ //
+ // As EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.SenseDataLength is defined
+ // as UINT8, defining here SenseData size to MAX_UINT8 will guarantee it
+ // cannot overflow when passed to device.
+ //
+ UINT8 SenseData[MAX_UINT8];
+ //
+ // This size of the data is arbitrarily chosen.
+ // It seems to be sufficient for all I/O requests sent through
+ // EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() for common boot scenarios.
+ //
+ UINT8 Data[0x2000];
+} PVSCSI_DMA_BUFFER;
+
#define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S')
typedef struct {
@@ -38,6 +53,8 @@ typedef struct {
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
PVSCSI_RING_DESC RingDesc;
+ PVSCSI_DMA_BUFFER *DmaBuf;
+ PVSCSI_DMA_DESC DmaBufDmaDesc;
UINT8 MaxTarget;
UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
@@ -47,4 +64,7 @@ typedef struct {
#define PVSCSI_FROM_PASS_THRU(PassThruPointer) \
CR (PassThruPointer, PVSCSI_DEV, PassThru, PVSCSI_SIG)
+#define PVSCSI_DMA_BUF_DEV_ADDR(Dev, MemberName) \
+ (Dev->DmaBufDmaDesc.DeviceAddress + OFFSET_OF(PVSCSI_DMA_BUFFER, MemberName))
+
#endif // __PVSCSI_DXE_H_
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer
2020-03-28 20:00 ` [PATCH v3 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer Liran Alon
@ 2020-03-30 16:06 ` Laszlo Ersek
0 siblings, 0 replies; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 16:06 UTC (permalink / raw)
To: devel, liran.alon
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/28/20 21:00, Liran Alon wrote:
> In case device is constrained by IOMMU or guest is running under AMD SEV,
> input/output buffers provided to device (DataBuffer and SenseData) needs
> to be explicitly mapped to device by PciIo->Map().
>
> To avoid the overhead of mapping/unmapping the DataBuffer and SenseData
> to the device for every SCSI requst (and to simplify code), introduce a
> single DMA communication buffer that will be mapped to device on
> initialization. When a SCSI request needs to be sent to device, the
> DataBuffer and SenseData will be copied from/to the DMA communication
> buffer as required. This will be done by the following commits.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
> Signed-off-by: Liran Alon <liran.alon@oracle.com>
> ---
> OvmfPkg/PvScsiDxe/PvScsi.c | 60 ++++++++++++++++++++++++++++++--------
> OvmfPkg/PvScsiDxe/PvScsi.h | 20 +++++++++++++
> 2 files changed, 68 insertions(+), 12 deletions(-)
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (13 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-30 16:22 ` [edk2-devel] " Laszlo Ersek
2020-03-28 20:00 ` [PATCH v3 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices() Liran Alon
` (3 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Implement EXT_SCSI_PASS_THRU.PassThru().
Machines should be able to boot after this commit.
Tested with Ubuntu 16.04 guest.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/OvmfPkg.dec | 6 +
OvmfPkg/PvScsiDxe/PvScsi.c | 456 +++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 1 +
OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 5 +-
4 files changed, 465 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index a04aee5c2cd4..ff49ec0e9e6a 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -130,6 +130,12 @@
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit|64|UINT8|0x36
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit|0|UINT8|0x37
+ ## After PvScsiDxe sends a SCSI request to the device, it waits for
+ # the request completion in a polling loop.
+ # This constant defines how many micro-seconds to wait between each
+ # polling loop iteration.
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiWaitForCmpStallInUsecs|5|UINT32|0x38
+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index 6e350bb2d6e0..da3535c75220 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -32,6 +32,27 @@
// Ext SCSI Pass Thru utilities
//
+/**
+ Reads a 32-bit value into BAR0 using MMIO
+**/
+STATIC
+EFI_STATUS
+PvScsiMmioRead32 (
+ IN CONST PVSCSI_DEV *Dev,
+ IN UINT64 Offset,
+ OUT UINT32 *Value
+ )
+{
+ return Dev->PciIo->Mem.Read (
+ Dev->PciIo,
+ EfiPciIoWidthUint32,
+ PCI_BAR_IDX0,
+ Offset,
+ 1, // Count
+ Value
+ );
+}
+
/**
Writes a 32-bit value into BAR0 using MMIO
**/
@@ -133,6 +154,383 @@ PvScsiResetAdapter (
return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0);
}
+/**
+ Returns if PVSCSI request ring is full
+**/
+STATIC
+BOOLEAN
+PvScsiIsReqRingFull (
+ IN CONST PVSCSI_DEV *Dev
+ )
+{
+ PVSCSI_RINGS_STATE *RingsState;
+ UINT32 ReqNumEntries;
+
+ RingsState = Dev->RingDesc.RingState;
+ ReqNumEntries = 1U << RingsState->ReqNumEntriesLog2;
+ return (RingsState->ReqProdIdx - RingsState->CmpConsIdx) >= ReqNumEntries;
+}
+
+/**
+ Returns pointer to current request descriptor to produce
+**/
+STATIC
+PVSCSI_RING_REQ_DESC *
+PvScsiGetCurrentRequest (
+ IN CONST PVSCSI_DEV *Dev
+ )
+{
+ PVSCSI_RINGS_STATE *RingState;
+ UINT32 ReqNumEntries;
+
+ RingState = Dev->RingDesc.RingState;
+ ReqNumEntries = 1U << RingState->ReqNumEntriesLog2;
+ return Dev->RingDesc.RingReqs +
+ (RingState->ReqProdIdx & (ReqNumEntries - 1));
+}
+
+/**
+ Returns pointer to current completion descriptor to consume
+**/
+STATIC
+PVSCSI_RING_CMP_DESC *
+PvScsiGetCurrentResponse (
+ IN CONST PVSCSI_DEV *Dev
+ )
+{
+ PVSCSI_RINGS_STATE *RingState;
+ UINT32 CmpNumEntries;
+
+ RingState = Dev->RingDesc.RingState;
+ CmpNumEntries = 1U << RingState->CmpNumEntriesLog2;
+ return Dev->RingDesc.RingCmps +
+ (RingState->CmpConsIdx & (CmpNumEntries - 1));
+}
+
+/**
+ Wait for device to signal completion of submitted requests
+**/
+STATIC
+EFI_STATUS
+PvScsiWaitForRequestCompletion (
+ IN CONST PVSCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+ UINT32 IntrStatus;
+
+ //
+ // Note: We don't yet support Timeout according to
+ // EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.Timeout.
+ //
+ // This is consistent with some other Scsi PassThru drivers
+ // such as VirtioScsi.
+ //
+ for (;;) {
+ Status = PvScsiMmioRead32 (Dev, PvScsiRegOffsetIntrStatus, &IntrStatus);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // PVSCSI_INTR_CMPL_MASK is set if device completed submitted requests
+ //
+ if ((IntrStatus & PVSCSI_INTR_CMPL_MASK) != 0) {
+ break;
+ }
+
+ gBS->Stall (Dev->WaitForCmpStallInUsecs);
+ }
+
+ //
+ // Acknowledge PVSCSI_INTR_CMPL_MASK in device interrupt-status register
+ //
+ return PvScsiMmioWrite32 (
+ Dev,
+ PvScsiRegOffsetIntrStatus,
+ PVSCSI_INTR_CMPL_MASK
+ );
+}
+
+/**
+ Create a fake host adapter error
+**/
+STATIC
+EFI_STATUS
+ReportHostAdapterError (
+ OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
+ )
+{
+ Packet->InTransferLength = 0;
+ Packet->OutTransferLength = 0;
+ Packet->SenseDataLength = 0;
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
+ Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Create a fake host adapter overrun error
+**/
+STATIC
+EFI_STATUS
+ReportHostAdapterOverrunError (
+ OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
+ )
+{
+ Packet->SenseDataLength = 0;
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
+ Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
+ return EFI_BAD_BUFFER_SIZE;
+}
+
+/**
+ Populate a PVSCSI request descriptor from the Extended SCSI Pass Thru
+ Protocol packet.
+**/
+STATIC
+EFI_STATUS
+PopulateRequest (
+ IN CONST PVSCSI_DEV *Dev,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+ OUT PVSCSI_RING_REQ_DESC *Request
+ )
+{
+ UINT8 TargetValue;
+
+ //
+ // We only use first byte of target identifer
+ //
+ TargetValue = *Target;
+
+ //
+ // Check for unsupported requests
+ //
+ if (
+ //
+ // Bidirectional transfer was requested
+ //
+ (Packet->InTransferLength > 0 && Packet->OutTransferLength > 0) ||
+ (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
+ //
+ // Command Descriptor Block bigger than this constant should be considered
+ // out-of-band. We currently don't support these CDBs.
+ //
+ (Packet->CdbLength > PVSCSI_CDB_MAX_SIZE)
+ ) {
+
+ //
+ // This error code doesn't require updates to the Packet output fields
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check for invalid parameters
+ //
+ if (
+ //
+ // Addressed invalid device
+ //
+ (TargetValue > Dev->MaxTarget) || (Lun > Dev->MaxLun) ||
+ //
+ // Invalid direction (there doesn't seem to be a macro for the "no data
+ // transferred" "direction", eg. for TEST UNIT READY)
+ //
+ (Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
+ //
+ // Trying to receive, but destination pointer is NULL, or contradicting
+ // transfer direction
+ //
+ ((Packet->InTransferLength > 0) &&
+ ((Packet->InDataBuffer == NULL) ||
+ (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE)
+ )
+ ) ||
+ //
+ // Trying to send, but source pointer is NULL, or contradicting
+ // transfer direction
+ //
+ ((Packet->OutTransferLength > 0) &&
+ ((Packet->OutDataBuffer == NULL) ||
+ (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ)
+ )
+ )
+ ) {
+
+ //
+ // This error code doesn't require updates to the Packet output fields
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for input/output buffer too large for DMA communication buffer
+ //
+ if (Packet->InTransferLength > sizeof (Dev->DmaBuf->Data)) {
+ Packet->InTransferLength = sizeof (Dev->DmaBuf->Data);
+ return ReportHostAdapterOverrunError (Packet);
+ }
+ if (Packet->OutTransferLength > sizeof (Dev->DmaBuf->Data)) {
+ Packet->OutTransferLength = sizeof (Dev->DmaBuf->Data);
+ return ReportHostAdapterOverrunError (Packet);
+ }
+
+ //
+ // Encode PVSCSI request
+ //
+ ZeroMem (Request, sizeof (*Request));
+
+ Request->Bus = 0;
+ Request->Target = TargetValue;
+ //
+ // This cast is safe as PVSCSI_DEV.MaxLun is defined as UINT8
+ //
+ Request->Lun[1] = (UINT8)Lun;
+ Request->SenseLen = Packet->SenseDataLength;
+ //
+ // DMA communication buffer SenseData overflow is not possible
+ // due to Packet->SenseDataLength defined as UINT8
+ //
+ Request->SenseAddr = PVSCSI_DMA_BUF_DEV_ADDR (Dev, SenseData);
+ Request->CdbLen = Packet->CdbLength;
+ CopyMem (Request->Cdb, Packet->Cdb, Packet->CdbLength);
+ Request->VcpuHint = 0;
+ Request->Tag = PVSCSI_SIMPLE_QUEUE_TAG;
+ if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+ Request->Flags = PVSCSI_FLAG_CMD_DIR_TOHOST;
+ Request->DataLen = Packet->InTransferLength;
+ } else {
+ Request->Flags = PVSCSI_FLAG_CMD_DIR_TODEVICE;
+ Request->DataLen = Packet->OutTransferLength;
+ CopyMem (
+ Dev->DmaBuf->Data,
+ Packet->OutDataBuffer,
+ Packet->OutTransferLength
+ );
+ }
+ Request->DataAddr = PVSCSI_DMA_BUF_DEV_ADDR (Dev, Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Handle the PVSCSI device response:
+ - Copy returned data from DMA communication buffer.
+ - Update fields in Extended SCSI Pass Thru Protocol packet as required.
+ - Translate response code to EFI status code and host adapter status.
+**/
+STATIC
+EFI_STATUS
+HandleResponse (
+ IN PVSCSI_DEV *Dev,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+ IN CONST PVSCSI_RING_CMP_DESC *Response
+ )
+{
+ //
+ // Fix SenseDataLength to amount of data returned
+ //
+ if (Packet->SenseDataLength > Response->SenseLen) {
+ Packet->SenseDataLength = (UINT8)Response->SenseLen;
+ }
+ //
+ // Copy sense data from DMA communication buffer
+ //
+ CopyMem (
+ Packet->SenseData,
+ Dev->DmaBuf->SenseData,
+ Packet->SenseDataLength
+ );
+
+ //
+ // Copy device output from DMA communication buffer
+ //
+ if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+ CopyMem (Packet->InDataBuffer, Dev->DmaBuf->Data, Packet->InTransferLength);
+ }
+
+ //
+ // Report target status
+ //
+ Packet->TargetStatus = Response->ScsiStatus;
+
+ //
+ // Host adapter status and function return value depend on
+ // device response's host status
+ //
+ switch (Response->HostStatus) {
+ case PvScsiBtStatSuccess:
+ case PvScsiBtStatLinkedCommandCompleted:
+ case PvScsiBtStatLinkedCommandCompletedWithFlag:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
+ return EFI_SUCCESS;
+
+ case PvScsiBtStatDataUnderrun:
+ //
+ // Report transferred amount in underrun
+ //
+ if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+ Packet->InTransferLength = (UINT32)Response->DataLen;
+ } else {
+ Packet->OutTransferLength = (UINT32)Response->DataLen;
+ }
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
+ return EFI_SUCCESS;
+
+ case PvScsiBtStatDatarun:
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
+ return EFI_SUCCESS;
+
+ case PvScsiBtStatSelTimeout:
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;
+ return EFI_TIMEOUT;
+
+ case PvScsiBtStatBusFree:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE;
+ break;
+
+ case PvScsiBtStatInvPhase:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR;
+ break;
+
+ case PvScsiBtStatSensFailed:
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED;
+ break;
+
+ case PvScsiBtStatTagReject:
+ case PvScsiBtStatBadMsg:
+ Packet->HostAdapterStatus =
+ EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT;
+ break;
+
+ case PvScsiBtStatBusReset:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET;
+ break;
+
+ case PvScsiBtStatHaTimeout:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;
+ return EFI_TIMEOUT;
+
+ case PvScsiBtStatScsiParity:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR;
+ break;
+
+ default:
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
+ break;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
/**
Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
@@ -168,7 +566,62 @@ PvScsiPassThru (
IN EFI_EVENT Event OPTIONAL
)
{
- return EFI_UNSUPPORTED;
+ PVSCSI_DEV *Dev;
+ EFI_STATUS Status;
+ PVSCSI_RING_REQ_DESC *Request;
+ PVSCSI_RING_CMP_DESC *Response;
+
+ Dev = PVSCSI_FROM_PASS_THRU (This);
+
+ if (PvScsiIsReqRingFull (Dev)) {
+ return EFI_NOT_READY;
+ }
+
+ Request = PvScsiGetCurrentRequest (Dev);
+
+ Status = PopulateRequest (Dev, Target, Lun, Packet, Request);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Writes to Request must be globally visible before making request
+ // available to device
+ //
+ MemoryFence ();
+ Dev->RingDesc.RingState->ReqProdIdx++;
+
+ Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetKickRwIo, 0);
+ if (EFI_ERROR (Status)) {
+ //
+ // If kicking the host fails, we must fake a host adapter error.
+ // EFI_NOT_READY would save us the effort, but it would also suggest that
+ // the caller retry.
+ //
+ return ReportHostAdapterError (Packet);
+ }
+
+ Status = PvScsiWaitForRequestCompletion (Dev);
+ if (EFI_ERROR (Status)) {
+ //
+ // If waiting for request completion fails, we must fake a host adapter
+ // error. EFI_NOT_READY would save us the effort, but it would also suggest
+ // that the caller retry.
+ //
+ return ReportHostAdapterError (Packet);
+ }
+
+ Response = PvScsiGetCurrentResponse (Dev);
+ Status = HandleResponse (Dev, Packet, Response);
+
+ //
+ // Reads from response must complete before releasing completion entry
+ // to device
+ //
+ MemoryFence ();
+ Dev->RingDesc.RingState->CmpConsIdx++;
+
+ return Status;
}
STATIC
@@ -652,6 +1105,7 @@ PvScsiInit (
//
Dev->MaxTarget = PcdGet8 (PcdPvScsiMaxTargetLimit);
Dev->MaxLun = PcdGet8 (PcdPvScsiMaxLunLimit);
+ Dev->WaitForCmpStallInUsecs = PcdGet32 (PcdPvScsiWaitForCmpStallInUsecs);
//
// Set PCI Attributes
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index fff12146dc75..02feac734743 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -57,6 +57,7 @@ typedef struct {
PVSCSI_DMA_DESC DmaBufDmaDesc;
UINT8 MaxTarget;
UINT8 MaxLun;
+ UINTN WaitForCmpStallInUsecs;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
} PVSCSI_DEV;
diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
index 6200533698fc..284035fb10d4 100644
--- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
+++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf
@@ -39,5 +39,6 @@
gEfiPciIoProtocolGuid ## TO_START
[Pcd]
- gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit ## CONSUMES
- gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiWaitForCmpStallInUsecs ## CONSUMES
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v3 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices()
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (14 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response Liran Alon
@ 2020-03-28 20:00 ` Liran Alon
2020-03-30 16:23 ` [edk2-devel] " Laszlo Ersek
2020-03-28 20:01 ` [PATCH v3 17/17] OvmfPkg/PvScsiDxe: Enable device 64-bit DMA addresses Liran Alon
` (2 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:00 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
This causes the device to forget about the request/completion rings.
We allocated said rings in EfiBootServicesData type memory, and code
executing after ExitBootServices() is permitted to overwrite it.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 43 +++++++++++++++++++++++++++++++++++++-
OvmfPkg/PvScsiDxe/PvScsi.h | 1 +
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index da3535c75220..d7f0d3c8790c 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -1221,6 +1221,31 @@ PvScsiUninit (
PvScsiRestorePciAttributes (Dev);
}
+/**
+ Event notification called by ExitBootServices()
+**/
+STATIC
+VOID
+EFIAPI
+PvScsiExitBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ PVSCSI_DEV *Dev;
+
+ Dev = Context;
+ DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
+
+ //
+ // Reset the device to stop device usage of the rings.
+ //
+ // We allocated said rings in EfiBootServicesData type memory, and code
+ // executing after ExitBootServices() is permitted to overwrite it.
+ //
+ PvScsiResetAdapter (Dev);
+}
+
//
// Driver Binding
//
@@ -1314,6 +1339,17 @@ PvScsiDriverBindingStart (
goto ClosePciIo;
}
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ &PvScsiExitBoot,
+ Dev,
+ &Dev->ExitBoot
+ );
+ if (EFI_ERROR (Status)) {
+ goto UninitDev;
+ }
+
//
// Setup complete, attempt to export the driver instance's PassThru interface
//
@@ -1325,11 +1361,14 @@ PvScsiDriverBindingStart (
&Dev->PassThru
);
if (EFI_ERROR (Status)) {
- goto UninitDev;
+ goto CloseExitBoot;
}
return EFI_SUCCESS;
+CloseExitBoot:
+ gBS->CloseEvent (Dev->ExitBoot);
+
UninitDev:
PvScsiUninit (Dev);
@@ -1384,6 +1423,8 @@ PvScsiDriverBindingStop (
return Status;
}
+ gBS->CloseEvent (Dev->ExitBoot);
+
PvScsiUninit (Dev);
gBS->CloseProtocol (
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
index 02feac734743..544359ebc05c 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.h
+++ b/OvmfPkg/PvScsiDxe/PvScsi.h
@@ -51,6 +51,7 @@ typedef struct {
typedef struct {
UINT32 Signature;
EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_EVENT ExitBoot;
UINT64 OriginalPciAttributes;
PVSCSI_RING_DESC RingDesc;
PVSCSI_DMA_BUFFER *DmaBuf;
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices()
2020-03-28 20:00 ` [PATCH v3 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices() Liran Alon
@ 2020-03-30 16:23 ` Laszlo Ersek
0 siblings, 0 replies; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 16:23 UTC (permalink / raw)
To: devel, liran.alon
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/28/20 21:00, Liran Alon wrote:
> This causes the device to forget about the request/completion rings.
> We allocated said rings in EfiBootServicesData type memory, and code
> executing after ExitBootServices() is permitted to overwrite it.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Liran Alon <liran.alon@oracle.com>
> ---
> OvmfPkg/PvScsiDxe/PvScsi.c | 43 +++++++++++++++++++++++++++++++++++++-
> OvmfPkg/PvScsiDxe/PvScsi.h | 1 +
> 2 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
> index da3535c75220..d7f0d3c8790c 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.c
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.c
> @@ -1221,6 +1221,31 @@ PvScsiUninit (
> PvScsiRestorePciAttributes (Dev);
> }
>
> +/**
> + Event notification called by ExitBootServices()
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +PvScsiExitBoot (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + PVSCSI_DEV *Dev;
> +
> + Dev = Context;
> + DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
> +
> + //
> + // Reset the device to stop device usage of the rings.
> + //
> + // We allocated said rings in EfiBootServicesData type memory, and code
> + // executing after ExitBootServices() is permitted to overwrite it.
> + //
> + PvScsiResetAdapter (Dev);
> +}
> +
My R-b stands.
Thanks
Laszlo
> //
> // Driver Binding
> //
> @@ -1314,6 +1339,17 @@ PvScsiDriverBindingStart (
> goto ClosePciIo;
> }
>
> + Status = gBS->CreateEvent (
> + EVT_SIGNAL_EXIT_BOOT_SERVICES,
> + TPL_CALLBACK,
> + &PvScsiExitBoot,
> + Dev,
> + &Dev->ExitBoot
> + );
> + if (EFI_ERROR (Status)) {
> + goto UninitDev;
> + }
> +
> //
> // Setup complete, attempt to export the driver instance's PassThru interface
> //
> @@ -1325,11 +1361,14 @@ PvScsiDriverBindingStart (
> &Dev->PassThru
> );
> if (EFI_ERROR (Status)) {
> - goto UninitDev;
> + goto CloseExitBoot;
> }
>
> return EFI_SUCCESS;
>
> +CloseExitBoot:
> + gBS->CloseEvent (Dev->ExitBoot);
> +
> UninitDev:
> PvScsiUninit (Dev);
>
> @@ -1384,6 +1423,8 @@ PvScsiDriverBindingStop (
> return Status;
> }
>
> + gBS->CloseEvent (Dev->ExitBoot);
> +
> PvScsiUninit (Dev);
>
> gBS->CloseProtocol (
> diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h
> index 02feac734743..544359ebc05c 100644
> --- a/OvmfPkg/PvScsiDxe/PvScsi.h
> +++ b/OvmfPkg/PvScsiDxe/PvScsi.h
> @@ -51,6 +51,7 @@ typedef struct {
> typedef struct {
> UINT32 Signature;
> EFI_PCI_IO_PROTOCOL *PciIo;
> + EFI_EVENT ExitBoot;
> UINT64 OriginalPciAttributes;
> PVSCSI_RING_DESC RingDesc;
> PVSCSI_DMA_BUFFER *DmaBuf;
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v3 17/17] OvmfPkg/PvScsiDxe: Enable device 64-bit DMA addresses
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (15 preceding siblings ...)
2020-03-28 20:00 ` [PATCH v3 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices() Liran Alon
@ 2020-03-28 20:01 ` Liran Alon
2020-03-29 9:29 ` [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Nikita Leshenko
2020-03-30 16:53 ` [edk2-devel] " Laszlo Ersek
18 siblings, 0 replies; 27+ messages in thread
From: Liran Alon @ 2020-03-28 20:01 UTC (permalink / raw)
To: devel, lersek
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel,
Liran Alon
Enable PCI dual-address cycle attribute to signal device
supports 64-bit DMA addresses.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index d7f0d3c8790c..0a66c98421a9 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -874,6 +874,29 @@ PvScsiSetPciAttributes (
return Status;
}
+ //
+ // Signal device supports 64-bit DMA addresses
+ //
+ Status = Dev->PciIo->Attributes (
+ Dev->PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Warn user that device will only be using 32-bit DMA addresses.
+ //
+ // Note that this does not prevent the device/driver from working
+ // and therefore we only warn and continue as usual.
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: failed to enable 64-bit DMA addresses\n",
+ __FUNCTION__
+ ));
+ }
+
return EFI_SUCCESS;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (16 preceding siblings ...)
2020-03-28 20:01 ` [PATCH v3 17/17] OvmfPkg/PvScsiDxe: Enable device 64-bit DMA addresses Liran Alon
@ 2020-03-29 9:29 ` Nikita Leshenko
2020-03-30 16:53 ` [edk2-devel] " Laszlo Ersek
18 siblings, 0 replies; 27+ messages in thread
From: Nikita Leshenko @ 2020-03-29 9:29 UTC (permalink / raw)
To: Liran Alon; +Cc: devel, lersek, aaron.young, jordan.l.justen, ard.biesheuvel
> On 28 Mar 2020, at 23:00, Liran Alon <liran.alon@oracle.com> wrote:
>
> Hi,
>
> This series adds driver support for VMware PVSCSI controller.
>
> This controller is supported by VMware and QEMU. This work is part of
> the more general agenda of enhancing OVMF boot device support to have
> feature parity with SeaBIOS (Which supports booting from VMware PVSCSI).
>
> I pushed a copy of these (v3) patches to https://github.com/nikital/edk2/tree/pvscsi6
> The v2 patches can be found at https://github.com/nikital/edk2/tree/pvscsi5
> The v1 patches can be found at https://github.com/nikital/edk2/tree/pvscsi4
>
> Regards,
> -Liran
>
> v2->v3:
> * Add function documentation to PvScsiWriteCmdDesc with “@param” to explain DescWords alignment requirement. [Laszlo]
> * Also set Packet’s HostAdapterStatus and TargetStatus when returning EFI_BAD_BUFFER_SIZE from PassThru() method. [Liran]
> * Add comments explaining why DMA communication buffer fields sizes are defined as they are. [Laszlo]
> * Remove unnecessary (UINT64) casts from EFI_PHYSICAL_ADDRESS expressions. [Laszlo]
> * Changed HandleResponse() to always copy SenseData based on Response->SenseLen. Not only if ScsiStatus equal to CHECK. [Liran]
> * Changed HandleResponse() to update Packet TransferLength only on underrun. [Liran]
> * Changed PassThru() to return EFI_STATUS_SUCCESS on device return overrun/underrun. [Laszlo & Liran]
> * Removed unnecessary PvScsiAllocatePages(), PvScsiFreePages(), PvScsiMapBuffer() and PvScsiUnmapBuffer() utility functions. [Laszlo]
> * Changed PvScsiInitRings() to align PVSCSI_CMD_DESC_SETUP_RINGS command to UINT32 before using it with EfiPciIoWidthFifoUint32. [Laszlo]
> * Removed PciIoOperation parameter from PvScsiAllocateSharedPages(). [Laszlo
> * Added STATIC_ASSERT() to verify PVSCSI_CMD_DESC_SETUP_RINGS is of size multiple of UINT32 words [Laszlo].
> * Added reset device before either freeing PVSCSI rings or DMA communication buffer. [Laszlo]
> * Removed unnecessary cast to (VOID **) in call to PvScsiFreeSharedPages() in PvScsiUninit(). [Laszlo]
> * Added #include <Library/BaseLib.h> and BaseLib to PvScsiDxe.inf because of RShiftU64() usage. [Laszlo]
>
> v1->v2:
> * Removed Nikita’s Reviewed-By tags. [Laszlo]
> * Renamed PvScsi.inf to PvScsiDxe.inf and fixed references from all DSC files. [Laszlo]
> * Changed “!ifdef $(PVSCSI_ENABLE)” in DSC files to “!if $(PVSCSI_ENABLE) == TRUE”. [Laszlo]
> * Fix Identation in various places. [Laszlo]
> * Added “#include <Uefi/UefiSpec.h>” for EFI_SYSTEM_TABLE. [Laszlo]
> * Fix various typos. [Laszlo]
> * Made “STATIC” on same line of object delcerations. [Laszlo]
> * Added Laszlo’s Reviewed-by tags on some patches. [Laszlo]
> * Added missing spaces before “(“ on various function calls. [Laszlo]
> * Added PvScsi.h header file to INF [Sources] section. [Laszlo]
> * Changed [Protocols] section in INF file to be lexicographically sorted. [Laszlo]
> * Changed [PCDs] section in INF file to be lexigraphically sorted. [Laszlo]
> * Fixed function comments blocks to be “/** **/” instead of “//” style. [Laszlo]
> * Changed PvScsiGetTargetLun() to ZeroMem() all target bytes except first one. [Laszlo]
> * Replaced “IOSpace” with “MMIO-Space” in comments. [Laszlo]
> * Changed enums to match EDK2 coding convention. [Laszlo]
> * Use PCI_BAR_IDX0 instead of hard-coded 0. [Laszlo]
> * Use EFI_PAGES_TO_SIZE() instead of manually multiplying with EFI_PAGE_SIZE. [Laszlo]
> * Use RShiftU64() to shift UINT64 vars. [Laszlo]
> * Changed ReqNumEntries var to UINT32 and shift to use “1U <<” instead of “1 <<”. [Laszlo]
> * Changed condition on flag (In PvScsiWaitForRequestCompletion()) to be a boolean expression. [Laszlo]
> * Replaced “FakeHostAdapterError” label with a utility function. [Laszlo]
> * Added debug message to PvScsiExitBoot() to assist debugging. [Laszlo]
> * Fixed resource management to make each function either completely succeed or completely fail and free all resources. [Laszlo]
> * Changed PvScsiWriteCmdDesc() to use EfiPciIoWidthFifoUint32. [Laszlo]
> * Changed PvScsiWriteCmdDesc() prototype to make clear it descriptor must be an array of words. [Laszlo]
>
The entire series looks good to me:
Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller
2020-03-28 20:00 [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Liran Alon
` (17 preceding siblings ...)
2020-03-29 9:29 ` [PATCH v3 00/17] OvmfPkg: Support booting from VMware PVSCSI controller Nikita Leshenko
@ 2020-03-30 16:53 ` Laszlo Ersek
18 siblings, 0 replies; 27+ messages in thread
From: Laszlo Ersek @ 2020-03-30 16:53 UTC (permalink / raw)
To: devel, liran.alon
Cc: nikita.leshchenko, aaron.young, jordan.l.justen, ard.biesheuvel
On 03/28/20 21:00, Liran Alon wrote:
> Hi,
>
> This series adds driver support for VMware PVSCSI controller.
>
> This controller is supported by VMware and QEMU. This work is part of
> the more general agenda of enhancing OVMF boot device support to have
> feature parity with SeaBIOS (Which supports booting from VMware PVSCSI).
>
> I pushed a copy of these (v3) patches to https://github.com/nikital/edk2/tree/pvscsi6
> The v2 patches can be found at https://github.com/nikital/edk2/tree/pvscsi5
> The v1 patches can be found at https://github.com/nikital/edk2/tree/pvscsi4
Merged in commit range 6c1fb56802d5..f34c7645bd87, via
<https://github.com/tianocore/edk2/pull/474>.
Thanks for the contribution!
Laszlo
> v2->v3:
> * Add function documentation to PvScsiWriteCmdDesc with “@param” to explain DescWords alignment requirement. [Laszlo]
> * Also set Packet’s HostAdapterStatus and TargetStatus when returning EFI_BAD_BUFFER_SIZE from PassThru() method. [Liran]
> * Add comments explaining why DMA communication buffer fields sizes are defined as they are. [Laszlo]
> * Remove unnecessary (UINT64) casts from EFI_PHYSICAL_ADDRESS expressions. [Laszlo]
> * Changed HandleResponse() to always copy SenseData based on Response->SenseLen. Not only if ScsiStatus equal to CHECK. [Liran]
> * Changed HandleResponse() to update Packet TransferLength only on underrun. [Liran]
> * Changed PassThru() to return EFI_STATUS_SUCCESS on device return overrun/underrun. [Laszlo & Liran]
> * Removed unnecessary PvScsiAllocatePages(), PvScsiFreePages(), PvScsiMapBuffer() and PvScsiUnmapBuffer() utility functions. [Laszlo]
> * Changed PvScsiInitRings() to align PVSCSI_CMD_DESC_SETUP_RINGS command to UINT32 before using it with EfiPciIoWidthFifoUint32. [Laszlo]
> * Removed PciIoOperation parameter from PvScsiAllocateSharedPages(). [Laszlo
> * Added STATIC_ASSERT() to verify PVSCSI_CMD_DESC_SETUP_RINGS is of size multiple of UINT32 words [Laszlo].
> * Added reset device before either freeing PVSCSI rings or DMA communication buffer. [Laszlo]
> * Removed unnecessary cast to (VOID **) in call to PvScsiFreeSharedPages() in PvScsiUninit(). [Laszlo]
> * Added #include <Library/BaseLib.h> and BaseLib to PvScsiDxe.inf because of RShiftU64() usage. [Laszlo]
>
> v1->v2:
> * Removed Nikita’s Reviewed-By tags. [Laszlo]
> * Renamed PvScsi.inf to PvScsiDxe.inf and fixed references from all DSC files. [Laszlo]
> * Changed “!ifdef $(PVSCSI_ENABLE)” in DSC files to “!if $(PVSCSI_ENABLE) == TRUE”. [Laszlo]
> * Fix Identation in various places. [Laszlo]
> * Added “#include <Uefi/UefiSpec.h>” for EFI_SYSTEM_TABLE. [Laszlo]
> * Fix various typos. [Laszlo]
> * Made “STATIC” on same line of object delcerations. [Laszlo]
> * Added Laszlo’s Reviewed-by tags on some patches. [Laszlo]
> * Added missing spaces before “(“ on various function calls. [Laszlo]
> * Added PvScsi.h header file to INF [Sources] section. [Laszlo]
> * Changed [Protocols] section in INF file to be lexicographically sorted. [Laszlo]
> * Changed [PCDs] section in INF file to be lexigraphically sorted. [Laszlo]
> * Fixed function comments blocks to be “/** **/” instead of “//” style. [Laszlo]
> * Changed PvScsiGetTargetLun() to ZeroMem() all target bytes except first one. [Laszlo]
> * Replaced “IOSpace” with “MMIO-Space” in comments. [Laszlo]
> * Changed enums to match EDK2 coding convention. [Laszlo]
> * Use PCI_BAR_IDX0 instead of hard-coded 0. [Laszlo]
> * Use EFI_PAGES_TO_SIZE() instead of manually multiplying with EFI_PAGE_SIZE. [Laszlo]
> * Use RShiftU64() to shift UINT64 vars. [Laszlo]
> * Changed ReqNumEntries var to UINT32 and shift to use “1U <<” instead of “1 <<”. [Laszlo]
> * Changed condition on flag (In PvScsiWaitForRequestCompletion()) to be a boolean expression. [Laszlo]
> * Replaced “FakeHostAdapterError” label with a utility function. [Laszlo]
> * Added debug message to PvScsiExitBoot() to assist debugging. [Laszlo]
> * Fixed resource management to make each function either completely succeed or completely fail and free all resources. [Laszlo]
> * Changed PvScsiWriteCmdDesc() to use EfiPciIoWidthFifoUint32. [Laszlo]
> * Changed PvScsiWriteCmdDesc() prototype to make clear it descriptor must be an array of words. [Laszlo]
>
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread