[edk2] [PATCH 07/14] OvmfPkg/MptScsiDxe: Build DevicePath for discovered devices

2019-01-31 Thread Nikita Leshenko
Used to identify the individual disks in the hardware tree

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 8ce7986b1d..7f360158e7 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -133,8 +133,24 @@ MptScsiBuildDevicePath (
   IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
   )
 {
+  SCSI_DEVICE_PATH *ScsiDevicePath;
+
   DEBUG ((EFI_D_INFO, "MptScsiBuildDevicePath %d %d\n", *Target, Lun));
-  return EFI_UNSUPPORTED;
+
+  ScsiDevicePath = AllocateZeroPool (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  = *Target;
+  ScsiDevicePath->Lun  = (UINT16) Lun;
+
+  *DevicePath = >Header;
+  return EFI_SUCCESS;
 }
 
 STATIC
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 14/14] OvmfPkg/MptScsiDxe: Support packets with pointers above 4G

2019-01-31 Thread Nikita Leshenko
Users of this device might pass data pointers which are above 4G, in which case
we can't pass the pointers directly to the controller because the descriptors
contain 32-bit pointers.

Instead of failing the request, use below-4G memory to support the request.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 50 +++-
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 0b888a1c56..9e803735d2 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -160,6 +160,9 @@ typedef struct {
   UINT8   MaxTarget;
   MPT_SCSI_IO_ERROR_REPLY IoErrorReply;
   MPT_SCSI_REQUEST_WITH_SGIoRequest;
+
+  UINT8   SenseBuffer[MAX_UINT8];
+  UINT8   DataBuffer[0x2000];
 } MPT_SCSI_DEV;
 
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
@@ -323,6 +326,18 @@ MptScsiPopulateRequest (
 return EFI_INVALID_PARAMETER;
   }
 
+  // If the buffers are above 4G, make sure that we can buffer that data
+  if ((UINTN) Packet->InDataBuffer > MAX_UINT32 &&
+  Packet->InTransferLength > sizeof (Dev->DataBuffer)) {
+Packet->InTransferLength = sizeof (Dev->DataBuffer);
+return EFI_BAD_BUFFER_SIZE;
+  }
+  if ((UINTN) Packet->OutDataBuffer > MAX_UINT32 &&
+  Packet->OutTransferLength > sizeof (Dev->DataBuffer)) {
+Packet->OutTransferLength = sizeof (Dev->DataBuffer);
+return EFI_BAD_BUFFER_SIZE;
+  }
+
   if (Packet->InTransferLength > MPT_SG_ENTRY_SIMPLE_MAX_LENGTH) {
 Packet->InTransferLength = MPT_SG_ENTRY_SIMPLE_MAX_LENGTH;
 return EFI_BAD_BUFFER_SIZE;
@@ -343,8 +358,14 @@ MptScsiPopulateRequest (
   CopyMem (Request->Header.CDB, Packet->Cdb, Packet->CdbLength);
 
   Request->Header.SenseBufferLength = Packet->SenseDataLength;
-  ASSERT ((UINTN) Packet->SenseData <= MAX_UINT32);
-  Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) Packet->SenseData;
+  // If sense is above 4G, we can't pass it directly to controller
+  if ((UINTN) Packet->SenseData > MAX_UINT32) {
+// Zero because the controller doesn't report the resulting sense data size
+ZeroMem (>SenseBuffer, Packet->SenseDataLength);
+Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) >SenseBuffer;
+  } else {
+Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) Packet->SenseData;
+  }
 
   Request->Sg.EndOfList = 1;
   Request->Sg.EndOfBuffer = 1;
@@ -356,15 +377,24 @@ MptScsiPopulateRequest (
   case EFI_EXT_SCSI_DATA_DIRECTION_READ:
 Request->Header.DataLength = Packet->InTransferLength;
 Request->Sg.Length = Packet->InTransferLength;
-ASSERT ((UINTN) Packet->InDataBuffer <= MAX_UINT32);
-Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->InDataBuffer;
+// If buffer is above 4G, we can't pass it directly to controller
+if ((UINTN) Packet->InDataBuffer > MAX_UINT32) {
+  Request->Sg.DataBufferAddress = (UINT32)(UINTN) >DataBuffer;
+} else {
+  Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->InDataBuffer;
+}
 Request->Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ;
 break;
   case EFI_EXT_SCSI_DATA_DIRECTION_WRITE:
 Request->Header.DataLength = Packet->OutTransferLength;
 Request->Sg.Length = Packet->OutTransferLength;
-ASSERT ((UINTN) Packet->OutDataBuffer <= MAX_UINT32);
-Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->OutDataBuffer;
+// If buffer is above 4G, we can't pass it directly to controller
+if ((UINTN) Packet->OutDataBuffer > MAX_UINT32) {
+  CopyMem (>DataBuffer, Packet->OutDataBuffer, 
Packet->OutTransferLength);
+  Request->Sg.DataBufferAddress = (UINT32)(UINTN) >DataBuffer;
+} else {
+  Request->Sg.DataBufferAddress = (UINT32)(UINTN) Packet->OutDataBuffer;
+}
 Request->Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE;
 Request->Sg.BufferContainsData = 1;
 break;
@@ -451,6 +481,14 @@ MptScsiHandleReply (
   OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*Packet
   )
 {
+  if ((UINTN) Packet->SenseData > MAX_UINT32) {
+CopyMem (Packet->SenseData, >SenseBuffer, Packet->SenseDataLength);
+  }
+  if ((UINTN) Packet->InDataBuffer > MAX_UINT32 &&
+  Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
+CopyMem (Packet->InDataBuffer, >DataBuffer, Packet->InTransferLength);
+  }
+
   if (Reply == Request->Header.MessageContext) {
 // Everything is good
 Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 02/14] OvmfPkg/MptScsiDxe: Install DriverBinding Protocol

2019-01-31 Thread Nikita Leshenko
In order to probe and connect to the MptScsi device we need this
protocol. Currently it does nothing.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 65 ++-
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf |  1 +
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 73a693741d..4dcb1b1ae5 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -15,6 +15,62 @@
 
 **/
 
+#include 
+
+//
+// Driver Binding
+//
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiControllerSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL*This,
+  IN EFI_HANDLE ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath OPTIONAL
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiControllerStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL*This,
+  IN EFI_HANDLE ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath OPTIONAL
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiControllerStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL*This,
+  IN  EFI_HANDLEControllerHandle,
+  IN  UINTN NumberOfChildren,
+  IN  EFI_HANDLE*ChildHandleBuffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+// Higher versions will be used before lower, 0x10-0xffef is the version
+// range for IVH (Indie Hardware Vendors)
+#define MPT_SCSI_BINDING_VERSION 0x10
+STATIC
+EFI_DRIVER_BINDING_PROTOCOL gMptScsiDriverBinding = {
+  ,
+  ,
+  ,
+  MPT_SCSI_BINDING_VERSION,
+  NULL, // ImageHandle filled by EfiLibInstallDriverBindingComponentName2
+  NULL, // DriverBindingHandle filled by 
EfiLibInstallDriverBindingComponentName2
+};
+
 //
 // Entry Point
 //
@@ -26,5 +82,12 @@ MptScsiEntryPoint (
   IN EFI_SYSTEM_TABLE *SystemTable
   )
 {
-  return EFI_UNSUPPORTED;
+  return EfiLibInstallDriverBindingComponentName2 (
+ImageHandle,
+SystemTable,
+,
+ImageHandle, // The handle to install onto
+NULL, // TODO Component name
+NULL // TODO Component name
+);
 }
diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf 
b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
index c558d78034..8a780a661e 100644
--- a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
+++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
@@ -31,3 +31,4 @@
 
 [LibraryClasses]
   UefiDriverEntryPoint
+  UefiLib
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 10/14] OvmfPkg/MptScsiDxe: Set and restore PCI attributes

2019-01-31 Thread Nikita Leshenko
Enable the IO Space and Bus Mastering and restore the original values
when the device is stopped. This is a standard procedure in PCI
drivers.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 29816fb98c..92c190499e 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -43,6 +43,7 @@ typedef struct {
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
   EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
   EFI_PCI_IO_PROTOCOL *PciIo;
+  UINT64  OriginalPciAttributes;
 } MPT_SCSI_DEV;
 
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
@@ -269,6 +270,7 @@ MptScsiControllerStart (
   EFI_STATUS   Status;
   EFI_PHYSICAL_ADDRESS PhysicalAddress;
   MPT_SCSI_DEV *Dev;
+  BOOLEAN  PciAttributesChanged = FALSE;
 
   DEBUG ((EFI_D_INFO, "Starting MptScsi\n"));
 
@@ -307,6 +309,25 @@ MptScsiControllerStart (
 goto Done;
   }
 
+  Status = Dev->PciIo->Attributes (
+  Dev->PciIo,
+  EfiPciIoAttributeOperationGet, 0,
+  >OriginalPciAttributes);
+  if (EFI_ERROR (Status)) {
+goto Done;
+  }
+
+  // Enable I/O Space & Bus-Mastering
+  Status = Dev->PciIo->Attributes (
+  Dev->PciIo,
+  EfiPciIoAttributeOperationEnable,
+  EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,
+  NULL);
+  if (EFI_ERROR (Status)) {
+goto Done;
+  }
+  PciAttributesChanged = TRUE;
+
   Dev->PassThruMode.AdapterId = MAX_UINT32; // Host adapter channel, doesn't 
exist
   Dev->PassThruMode.Attributes =
 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
@@ -332,6 +353,13 @@ MptScsiControllerStart (
   DEBUG ((EFI_D_INFO, "MptScsi Installed\n"));
 Done:
   if (EFI_ERROR (Status)) {
+if (PciAttributesChanged) {
+  Dev->PciIo->Attributes (
+  Dev->PciIo,
+  EfiPciIoAttributeOperationEnable,
+  Dev->OriginalPciAttributes,
+  NULL);
+}
 if (Dev->PciIo) {
   gBS->CloseProtocol (
   ControllerHandle,
@@ -378,6 +406,13 @@ MptScsiControllerStop (
   ControllerHandle,
   ,
   >PassThru);
+
+  Dev->PciIo->Attributes (
+  Dev->PciIo,
+  EfiPciIoAttributeOperationEnable,
+  Dev->OriginalPciAttributes,
+  NULL);
+
   gBS->CloseProtocol (
   ControllerHandle,
   ,
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 05/14] OvmfPkg/MptScsiDxe: Install stubbed EXT_SCSI_PASS_THRU

2019-01-31 Thread Nikita Leshenko
Support dynamic insertion and removal of the protocol

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 204 +-
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf |   5 +-
 2 files changed, 205 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 57a17ca0cb..6b655d9fe8 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -16,10 +16,13 @@
 **/
 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 //
 // Device offsets and constants
@@ -30,6 +33,118 @@
 #define LSI_SAS1068_PCI_DEVICE_ID 0x0054
 #define LSI_SAS1068E_PCI_DEVICE_ID 0x0058
 
+//
+// Runtime Structures
+//
+
+#define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S')
+typedef struct {
+  UINT32  Signature;
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
+  EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
+} MPT_SCSI_DEV;
+
+#define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
+  CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE)
+
+//
+// Ext SCSI Pass Thru
+//
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiPassThru (
+  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
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiPassThru Direction %d In %d Out %d\n",
+  Packet->DataDirection,
+  Packet->InTransferLength, Packet->OutTransferLength));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiGetNextTargetLun (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL*This,
+  IN OUT UINT8  **Target,
+  IN OUT UINT64 *Lun
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiGetNextTargetLun %d %d\n", **Target, *Lun));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiGetNextTarget (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This,
+  IN OUT UINT8 **Target
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiGetNextTarget\n"));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiBuildDevicePath (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This,
+  IN UINT8 *Target,
+  IN UINT64Lun,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiBuildDevicePath %d %d\n", *Target, Lun));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiGetTargetLun (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This,
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
+  OUT UINT8**Target,
+  OUT UINT64   *Lun
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiGetTargetLun\n"));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiResetChannel (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiResetChannel\n"));
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+MptScsiResetTargetLun (
+  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *This,
+  IN UINT8 *Target,
+  IN UINT64Lun
+  )
+{
+  DEBUG ((EFI_D_INFO, "MptScsiResetTargetLun\n"));
+  return EFI_UNSUPPORTED;
+}
+
 //
 // Driver Binding
 //
@@ -94,8 +209,65 @@ MptScsiControllerStart (
   IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath OPTIONAL
   )
 {
-  DEBUG ((EFI_D_INFO, "Attempted to start MptScsi\n"));
-  return EFI_UNSUPPORTED;
+  EFI_STATUS   Status;
+  EFI_PHYSICAL_ADDRESS PhysicalAddress;
+  MPT_SCSI_DEV *Dev;
+
+  DEBUG ((EFI_D_INFO, "Starting MptScsi\n"));
+
+  //
+  // MPT_SCSI_DEV contains descriptors that are passed to the controller. The
+  // controller doesn't easily support addresses larger than 4GB, so we 
allocate
+  // the struct below 4GB. (Technically we can use HostMfaHighAddr and make 
sure
+  // all descriptors have the same high address but it's more complicated than
+  // just allocating below 4GB. Also, we allocate it only once per device so 
the
+  // overhead of allocating a whole page is minimal.)
+  //
+  PhysicalAddress = MAX_UINT32;
+  Status = gBS->AllocatePages (
+  AllocateMaxAddress,
+  EfiRuntimeServicesData,
+  EFI_SIZE_TO_PAGES (sizeof (*Dev)),
+  
+  );
+  if (EF

[edk2] [PATCH 04/14] OvmfPkg/MptScsiDxe: Probe PCI devices and look for MptScsi

2019-01-31 Thread Nikita Leshenko
The MptScsiControllerSupported function is called for every handle
that appears on the system and if the handle is the lsi53c1030
controller the function would return success. A successful return
value will attach our driver to the device.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 55 ++-
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf |  5 +++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 38cdda1abe..57a17ca0cb 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -15,7 +15,20 @@
 
 **/
 
+#include 
+#include 
 #include 
+#include 
+#include 
+
+//
+// Device offsets and constants
+//
+
+#define LSI_LOGIC_PCI_VENDOR_ID 0x1000
+#define LSI_53C1030_PCI_DEVICE_ID 0x0030
+#define LSI_SAS1068_PCI_DEVICE_ID 0x0054
+#define LSI_SAS1068E_PCI_DEVICE_ID 0x0058
 
 //
 // Driver Binding
@@ -30,7 +43,46 @@ MptScsiControllerSupported (
   IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath OPTIONAL
   )
 {
-  return EFI_UNSUPPORTED;
+  EFI_STATUS  Status;
+  EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+  PCI_TYPE00  Pci;
+
+  Status = gBS->OpenProtocol (
+  ControllerHandle,
+  ,
+  (VOID **) ,
+  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),
+  );
+  if (EFI_ERROR (Status)) {
+goto Done;
+  }
+
+  if (Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID
+  && (Pci.Hdr.DeviceId == LSI_53C1030_PCI_DEVICE_ID
+  || Pci.Hdr.DeviceId == LSI_SAS1068_PCI_DEVICE_ID
+  || Pci.Hdr.DeviceId == LSI_SAS1068E_PCI_DEVICE_ID)) {
+Status = EFI_SUCCESS;
+  } else {
+Status = EFI_UNSUPPORTED;
+  }
+
+Done:
+  gBS->CloseProtocol (
+  ControllerHandle,
+  ,
+  This->DriverBindingHandle,
+  ControllerHandle);
+  return Status;
 }
 
 STATIC
@@ -42,6 +94,7 @@ MptScsiControllerStart (
   IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath OPTIONAL
   )
 {
+  DEBUG ((EFI_D_INFO, "Attempted to start MptScsi\n"));
   return EFI_UNSUPPORTED;
 }
 
diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf 
b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
index 8a780a661e..3608cecaab 100644
--- a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
+++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
@@ -30,5 +30,10 @@
   OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
   UefiDriverEntryPoint
   UefiLib
+
+[Protocols]
+  gEfiPciIoProtocolGuid## TO_START
\ No newline at end of file
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 03/14] OvmfPkg/MptScsiDxe: Report name of driver

2019-01-31 Thread Nikita Leshenko
Install Component Name protocols to have a nice display name for the
driver in places such as UEFI shell.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 61 ++--
 1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 4dcb1b1ae5..38cdda1abe 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -71,6 +71,63 @@ EFI_DRIVER_BINDING_PROTOCOL gMptScsiDriverBinding = {
   NULL, // DriverBindingHandle filled by 
EfiLibInstallDriverBindingComponentName2
 };
 
+//
+// Component Name
+//
+
+STATIC
+EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
+  { "eng;en", L"LSI Fusion MPT SCSI Driver" },
+  { NULL, NULL   }
+};
+
+STATIC
+EFI_COMPONENT_NAME_PROTOCOL gComponentName;
+
+EFI_STATUS
+EFIAPI
+MptScsiGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8   *Language,
+  OUT CHAR16  **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+   Language,
+   This->SupportedLanguages,
+   mDriverNameTable,
+   DriverName,
+   (BOOLEAN) (This == ) // Iso639Language
+   );
+}
+
+EFI_STATUS
+EFIAPI
+MptScsiGetDeviceName (
+  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 gComponentName = {
+  ,
+  ,
+  "eng" // SupportedLanguages, ISO 639-2 language codes
+};
+
+STATIC
+EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) ,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) ,
+  "en" // SupportedLanguages, RFC 4646 language codes
+};
+
 //
 // Entry Point
 //
@@ -87,7 +144,7 @@ MptScsiEntryPoint (
 SystemTable,
 ,
 ImageHandle, // The handle to install onto
-NULL, // TODO Component name
-NULL // TODO Component name
+,
+
 );
 }
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 12/14] OvmfPkg/MptScsiDxe: Implement the PassThru method

2019-01-31 Thread Nikita Leshenko
Machines should be able to boot after this commit. Tested with different Linux
distributions (Ubuntu, CentOS) and different Windows versions (Windows 7,
Windows 10, Server 2016).

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 255 +-
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf |   3 +
 OvmfPkg/OvmfPkg.dec   |   2 +
 3 files changed, 256 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index fbabeb22ca..a7dab0f71a 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -54,9 +54,15 @@
 #define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT0x02
 
 #define MPT_SG_ENTRY_TYPE_SIMPLE 0x01
+#define MPT_SG_ENTRY_SIMPLE_MAX_LENGTH ((1 << 24) - 1)
 
 #define MPT_IOC_WHOINIT_ROM_BIOS 0x02
 
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE (0x01 << 24)
+#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ  (0x02 << 24)
+
+#define MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE 0x0043
+
 //
 // Runtime Structures
 //
@@ -110,6 +116,8 @@ typedef struct {
   UINT32Length: 24;
   UINT32EndOfList:  1;
   UINT32Is64BitAddress: 1;
+  // True when the buffer contains data to be transfered. Otherwise it's the
+  // destination buffer
   UINT32BufferContainsData: 1;
   UINT32LocalAddress:   1;
   UINT32ElementType:2;
@@ -136,6 +144,11 @@ typedef struct {
   UINT32ResponseInfo;
 } __attribute__((aligned(8), packed)) MPT_SCSI_IO_ERROR_REPLY; // Align 
required by HW
 
+typedef struct {
+  MPT_SCSI_IO_REQUEST Header;
+  MPT_SG_ENTRY_SIMPLE Sg;
+} __attribute__((aligned(8), packed)) MPT_SCSI_REQUEST_WITH_SG; // Align 
required by HW
+
 #define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S')
 typedef struct {
   UINT32  Signature;
@@ -143,6 +156,9 @@ typedef struct {
   EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
   EFI_PCI_IO_PROTOCOL *PciIo;
   UINT64  OriginalPciAttributes;
+  UINT32  StallPerPollUsec;
+  MPT_SCSI_IO_ERROR_REPLY IoErrorReply;
+  MPT_SCSI_REQUEST_WITH_SGIoRequest;
 } MPT_SCSI_DEV;
 
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
@@ -228,6 +244,8 @@ MptScsiInit (
 {
   EFI_STATUS Status;
 
+  Dev->StallPerPollUsec = PcdGet32 (PcdMptScsiStallPerPollUsec);
+
   Status = MptScsiReset (Dev);
   if (EFI_ERROR (Status)) {
 return Status;
@@ -273,6 +291,193 @@ MptScsiInit (
 return Status;
   }
 
+  // Put one free reply frame on the reply queue, the hardware may use it to
+  // report an error to us.
+  ASSERT ((UINTN) >IoErrorReply <= MAX_UINT32);
+  Status = Out32 (Dev, MPT_REG_REP_Q, (UINT32)(UINTN) >IoErrorReply);
+  if (EFI_ERROR (Status)) {
+return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MptScsiPopulateRequest (
+  IN UINT8  Target,
+  IN UINT64 Lun,
+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+  OUT MPT_SCSI_REQUEST_WITH_SG  *Request
+  )
+{
+  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||
+  Packet->CdbLength > sizeof (Request->Header.CDB)) {
+return EFI_UNSUPPORTED;
+  }
+
+  if (Target > 0 || Lun > 0) {
+return EFI_INVALID_PARAMETER;
+  }
+
+  if (Packet->InTransferLength > MPT_SG_ENTRY_SIMPLE_MAX_LENGTH) {
+Packet->InTransferLength = MPT_SG_ENTRY_SIMPLE_MAX_LENGTH;
+return EFI_BAD_BUFFER_SIZE;
+  }
+  if (Packet->OutTransferLength > MPT_SG_ENTRY_SIMPLE_MAX_LENGTH) {
+Packet->OutTransferLength = MPT_SG_ENTRY_SIMPLE_MAX_LENGTH;
+return EFI_BAD_BUFFER_SIZE;
+  }
+
+  ZeroMem (Request, sizeof (*Request));
+  Request->Header.TargetID = Target;
+  // It's 1 and not 0, for some reason...
+  Request->Header.LUN[1] = Lun;
+  Request->Header.Function = MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST;
+  Request->Header.MessageContext = 1; // Hardcoded, we handle one request at a 
time
+
+  Request->Header.CDBLength = Packet->CdbLength;
+  CopyMem (Request->Header.CDB, Packet->Cdb, Packet->CdbLength);
+
+  Request->Header.SenseBufferLength = Packet->SenseDataLength;
+  ASSERT ((UINTN) Packet->SenseData <= MAX_UINT32);
+  Request->Header.SenseBufferLowAddress = (UINT32)(UINTN) Packet->SenseData;
+
+  Request->Sg.EndOfList = 1;
+  Request->Sg.EndOfBuffer = 1;
+  Request->Sg.LastElement = 1;
+  Request->Sg.ElementType = MPT_SG_ENTRY_TYPE_SIMPLE;
+
+  switch (Packet->DataDirection)
+  {
+  case EFI_EXT_SCSI_DATA_DIRECTION_READ:
+Request->Header.DataLength = Packet->InTransferLength;
+Request->Sg.Length = Packet->InTransferLength;
+ASSERT ((UINTN) Pa

[edk2] [PATCH 13/14] OvmfPkg/MptScsiDxe: Report multiple targets

2019-01-31 Thread Nikita Leshenko
The controller supports up to 8 targets (Not reported by the
controller, but based on the implementation of the virtual device),
report them in GetNextTarget and GetNextTargetLun. The firmware will
then try to communicate with them and create a block device for each
one that responds.

Support for multiple LUNs will be implemented in another series.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 27 ---
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf |  1 +
 OvmfPkg/OvmfPkg.dec   |  3 +++
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index a7dab0f71a..0b888a1c56 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -157,6 +157,7 @@ typedef struct {
   EFI_PCI_IO_PROTOCOL *PciIo;
   UINT64  OriginalPciAttributes;
   UINT32  StallPerPollUsec;
+  UINT8   MaxTarget;
   MPT_SCSI_IO_ERROR_REPLY IoErrorReply;
   MPT_SCSI_REQUEST_WITH_SGIoRequest;
 } MPT_SCSI_DEV;
@@ -245,6 +246,7 @@ MptScsiInit (
   EFI_STATUS Status;
 
   Dev->StallPerPollUsec = PcdGet32 (PcdMptScsiStallPerPollUsec);
+  Dev->MaxTarget = PcdGet8 (PcdMptScsiMaxTargetLimit);
 
   Status = MptScsiReset (Dev);
   if (EFI_ERROR (Status)) {
@@ -254,7 +256,7 @@ MptScsiInit (
   MPT_IO_CONTROLLER_INIT_REQUEST Req = {
 .WhoInit = MPT_IOC_WHOINIT_ROM_BIOS,
 .Function = MPT_MESSAGE_HDR_FUNCTION_IOC_INIT,
-.MaxDevices = 1,
+.MaxDevices = Dev->MaxTarget + 1,
 .MaxBuses = 1,
 .ReplyFrameSize = sizeof (MPT_SCSI_IO_ERROR_REPLY),
   };
@@ -305,6 +307,7 @@ MptScsiInit (
 STATIC
 EFI_STATUS
 MptScsiPopulateRequest (
+  IN MPT_SCSI_DEV   *Dev,
   IN UINT8  Target,
   IN UINT64 Lun,
   IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
@@ -316,7 +319,7 @@ MptScsiPopulateRequest (
 return EFI_UNSUPPORTED;
   }
 
-  if (Target > 0 || Lun > 0) {
+  if (Target > Dev->MaxTarget || Lun > 0) {
 return EFI_INVALID_PARAMETER;
   }
 
@@ -504,7 +507,7 @@ MptScsiPassThru (
   // Packet->DataDirection,
   // Packet->InTransferLength, Packet->OutTransferLength));
 
-  Status = MptScsiPopulateRequest (*Target, Lun, Packet, >IoRequest);
+  Status = MptScsiPopulateRequest (Dev, *Target, Lun, Packet, >IoRequest);
   if (EFI_ERROR (Status)) {
 return Status;
   }
@@ -568,16 +571,22 @@ MptScsiGetNextTargetLun (
   IN OUT UINT64 *Lun
   )
 {
+  MPT_SCSI_DEV *Dev = MPT_SCSI_FROM_PASS_THRU (This);
+
   DEBUG ((EFI_D_INFO, "MptScsiGetNextTargetLun %d %d\n", **Target, *Lun));
 
-  // Currently support only target 0 LUN 0, so hardcode it
+  // Currently support only LUN 0, so hardcode it
   if (!IsTargetInitialized (*Target)) {
 **Target = 0;
 *Lun = 0;
-return EFI_SUCCESS;
+  } else if (**Target < Dev->MaxTarget) {
+**Target += 1;
+*Lun = 0;
   } else {
 return EFI_NOT_FOUND;
   }
+
+  return EFI_SUCCESS;
 }
 
 STATIC
@@ -588,15 +597,19 @@ MptScsiGetNextTarget (
   IN OUT UINT8 **Target
   )
 {
+  MPT_SCSI_DEV *Dev = MPT_SCSI_FROM_PASS_THRU (This);
+
   DEBUG ((EFI_D_INFO, "MptScsiGetNextTarget\n"));
 
-  // Currently support only target 0 LUN 0, so hardcode it
   if (!IsTargetInitialized (*Target)) {
 **Target = 0;
-return EFI_SUCCESS;
+  } else if (**Target < Dev->MaxTarget) {
+**Target += 1;
   } else {
 return EFI_NOT_FOUND;
   }
+
+  return EFI_SUCCESS;
 }
 
 STATIC
diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf 
b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
index 5875d6c94b..3b6717c204 100644
--- a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
+++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
@@ -43,3 +43,4 @@
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec ## CONSUMES
+  gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiMaxTargetLimit ## CONSUMES
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4ca98ff09f..3f088eca96 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -123,6 +123,9 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd|0x0|UINT32|0x1f
 
   gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec|5|UINT32|0x28
+  ## Set the *inclusive* number of targets that MptScsi exposes for scan
+  #  by ScsiBusDxe.
+  gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiMaxTargetLimit|7|UINT8|0x29
 
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 11/14] OvmfPkg/MptScsiDxe: Initialize hardware

2019-01-31 Thread Nikita Leshenko
Reset and send the IO controller initialization request. The reply is
read back to complete the doorbell function but it isn't useful to us
because it doesn't contain relevant data or status codes.

See "LSI53C1030 PCI-X to Dual Channel Ultra320 SCSI Multifunction
Controller" technical manual for more information.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 234 +++
 1 file changed, 234 insertions(+)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 92c190499e..fbabeb22ca 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -33,10 +33,109 @@
 #define LSI_SAS1068_PCI_DEVICE_ID 0x0054
 #define LSI_SAS1068E_PCI_DEVICE_ID 0x0058
 
+#define MPT_REG_DOORBELL  0x00
+#define MPT_REG_WRITE_SEQ 0x04
+#define MPT_REG_HOST_DIAG 0x08
+#define MPT_REG_TEST  0x0c
+#define MPT_REG_DIAG_DATA 0x10
+#define MPT_REG_DIAG_ADDR 0x14
+#define MPT_REG_ISTATUS   0x30
+#define MPT_REG_IMASK 0x34
+#define MPT_REG_REQ_Q 0x40
+#define MPT_REG_REP_Q 0x44
+
+#define MPT_DOORBELL_RESET 0x40
+#define MPT_DOORBELL_HANDSHAKE 0x42
+
+#define MPT_IMASK_DOORBELL 0x01
+#define MPT_IMASK_REPLY0x08
+
+#define MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST 0x00
+#define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT0x02
+
+#define MPT_SG_ENTRY_TYPE_SIMPLE 0x01
+
+#define MPT_IOC_WHOINIT_ROM_BIOS 0x02
+
 //
 // Runtime Structures
 //
 
+typedef struct {
+  UINT8 WhoInit;
+  UINT8 Reserved1;
+  UINT8 ChainOffset;
+  UINT8 Function;
+  UINT8 Flags;
+  UINT8 MaxDevices;
+  UINT8 MaxBuses;
+  UINT8 MessageFlags;
+  UINT32MessageContext;
+  UINT16ReplyFrameSize;
+  UINT16Reserved2;
+  UINT32HostMfaHighAddr;
+  UINT32SenseBufferHighAddr;
+} __attribute__((aligned(8), packed)) MPT_IO_CONTROLLER_INIT_REQUEST; // Align 
required by HW
+typedef struct {
+  UINT8 WhoInit;
+  UINT8 Reserved1;
+  UINT8 MessageLength;
+  UINT8 Function;
+  UINT8 Flags;
+  UINT8 MaxDevices;
+  UINT8 MaxBuses;
+  UINT8 MessageFlags;
+  UINT32MessageContext;
+  UINT16Reserved2;
+  UINT16IOCStatus;
+  UINT32IOCLogInfo;
+} __attribute__((packed)) MPT_IO_CONTROLLER_INIT_REPLY;
+typedef struct {
+  UINT8 TargetID;
+  UINT8 Bus;
+  UINT8 ChainOffset;
+  UINT8 Function;
+  UINT8 CDBLength;
+  UINT8 SenseBufferLength;
+  UINT8 Reserved;
+  UINT8 MessageFlags;
+  UINT32MessageContext;
+  UINT8 LUN[8];
+  UINT32Control;
+  UINT8 CDB[16];
+  UINT32DataLength;
+  UINT32SenseBufferLowAddress;
+} __attribute__((packed)) MPT_SCSI_IO_REQUEST;
+typedef struct {
+  UINT32Length: 24;
+  UINT32EndOfList:  1;
+  UINT32Is64BitAddress: 1;
+  UINT32BufferContainsData: 1;
+  UINT32LocalAddress:   1;
+  UINT32ElementType:2;
+  UINT32EndOfBuffer:1;
+  UINT32LastElement:1;
+  UINT64DataBufferAddress;
+} __attribute__((packed)) MPT_SG_ENTRY_SIMPLE;
+typedef struct {
+  UINT8 TargetID;
+  UINT8 Bus;
+  UINT8 MessageLength;
+  UINT8 Function;
+  UINT8 CDBLength;
+  UINT8 SenseBufferLength;
+  UINT8 Reserved;
+  UINT8 MessageFlags;
+  UINT32MessageContext;
+  UINT8 SCSIStatus;
+  UINT8 SCSIState;
+  UINT16IOCStatus;
+  UINT32IOCLogInfo;
+  UINT32TransferCount;
+  UINT32SenseCount;
+  UINT32ResponseInfo;
+} __attribute__((aligned(8), packed)) MPT_SCSI_IO_ERROR_REPLY; // Align 
required by HW
+
 #define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S')
 typedef struct {
   UINT32  Signature;
@@ -49,6 +148,134 @@ typedef struct {
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
   CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE)
 
+//
+// Hardware functions
+//
+
+STATIC
+EFI_STATUS
+Out32 (
+  IN MPT_SCSI_DEV   *Dev,
+  IN UINT32 Addr,
+  IN UINT32 Data
+  )
+{
+  return Dev->PciIo->Io.Write (
+  Dev->PciIo,
+  EfiPciIoWidthUint32,
+  0, // BAR0
+  Addr, 1, );
+}
+
+STATIC
+EFI_STATUS
+In32 (
+  IN  MPT_SCSI_DEV   *Dev,
+  IN  UINT32 Addr,
+  OUT UINT32 *Data
+  )
+{
+  return Dev->PciIo->Io.Read (
+  Dev->PciIo,
+  EfiPciIoWidthUint32,
+  0, // BAR0
+  Addr, 1, Data);
+}
+
+STATIC
+EFI_STATUS
+MptDoorbell (
+  IN MPT_SCSI_DEV   *Dev,
+  IN UINT8  DoorbellFunc,
+  IN UINT8  DoorbellArg
+  )
+{
+  return Out32 (Dev, MPT_REG_DOORBELL, (DoorbellFunc << 24) | (DoorbellArg << 
16));
+}
+
+STATIC
+EFI_STATUS
+MptScsiReset (
+  IN MPT_SCSI_DEV   *Dev
+  )
+{
+  EFI_STATUS Status;
+
+  // Res

[edk2] [PATCH 09/14] OvmfPkg/MptScsiDxe: Open PciIo protocol for later use

2019-01-31 Thread Nikita Leshenko
This will give us an exclusive access to the PciIo of this device
after it was started and until is will be stopped.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 719948a73d..29816fb98c 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -42,6 +42,7 @@ typedef struct {
   UINT32  Signature;
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
   EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
+  EFI_PCI_IO_PROTOCOL *PciIo;
 } MPT_SCSI_DEV;
 
 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
@@ -295,6 +296,17 @@ MptScsiControllerStart (
   ZeroMem (Dev, sizeof (*Dev));
   Dev->Signature = MPT_SCSI_DEV_SIGNATURE;
 
+  Status = gBS->OpenProtocol (
+  ControllerHandle,
+  ,
+  (VOID **) >PciIo,
+  This->DriverBindingHandle,
+  ControllerHandle,
+  EFI_OPEN_PROTOCOL_BY_DRIVER); // exclusive for us until 
stopped
+  if (EFI_ERROR (Status)) {
+goto Done;
+  }
+
   Dev->PassThruMode.AdapterId = MAX_UINT32; // Host adapter channel, doesn't 
exist
   Dev->PassThruMode.Attributes =
 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
@@ -320,6 +332,13 @@ MptScsiControllerStart (
   DEBUG ((EFI_D_INFO, "MptScsi Installed\n"));
 Done:
   if (EFI_ERROR (Status)) {
+if (Dev->PciIo) {
+  gBS->CloseProtocol (
+  ControllerHandle,
+  ,
+  This->DriverBindingHandle,
+  ControllerHandle);
+}
 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Dev, EFI_SIZE_TO_PAGES 
(sizeof (*Dev)));
   }
 
@@ -359,6 +378,11 @@ MptScsiControllerStop (
   ControllerHandle,
   ,
   >PassThru);
+  gBS->CloseProtocol (
+  ControllerHandle,
+  ,
+  This->DriverBindingHandle,
+  ControllerHandle);
 
   gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Dev, EFI_SIZE_TO_PAGES 
(sizeof (*Dev)));
 
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 01/14] OvmfPkg/MptScsiDxe: Create empty driver

2019-01-31 Thread Nikita Leshenko
In preparation for implementing LSI Fusion MPT SCSI devices, create a
basic scaffolding for a driver.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c  | 30 
 OvmfPkg/MptScsiDxe/MptScsiDxe.inf | 33 +++
 OvmfPkg/OvmfPkgIa32.dsc   |  1 +
 OvmfPkg/OvmfPkgIa32.fdf   |  1 +
 OvmfPkg/OvmfPkgIa32X64.dsc|  1 +
 OvmfPkg/OvmfPkgIa32X64.fdf|  1 +
 OvmfPkg/OvmfPkgX64.dsc|  1 +
 OvmfPkg/OvmfPkgX64.fdf|  1 +
 8 files changed, 69 insertions(+)
 create mode 100644 OvmfPkg/MptScsiDxe/MptScsi.c
 create mode 100644 OvmfPkg/MptScsiDxe/MptScsiDxe.inf

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
new file mode 100644
index 00..73a693741d
--- /dev/null
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -0,0 +1,30 @@
+/** @file
+
+  This driver produces Extended SCSI Pass Thru Protocol instances for
+  LSI Fusion MPT SCSI devices.
+
+  Copyright (C) 2018, Oracle and/or its affiliates. All rights reserved.
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// Entry Point
+//
+
+EFI_STATUS
+EFIAPI
+MptScsiEntryPoint (
+  IN EFI_HANDLE   ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf 
b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
new file mode 100644
index 00..c558d78034
--- /dev/null
+++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
@@ -0,0 +1,33 @@
+## @file
+# This driver produces Extended SCSI Pass Thru Protocol instances for
+# LSI Fusion MPT SCSI devices.
+#
+# Copyright (C) 2018, Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION= 0x00010005
+  BASE_NAME  = MptScsiDxe
+  FILE_GUID  = 2B3DB5DD-B315-4961-8454-0AFF3C811B19
+  MODULE_TYPE= UEFI_DRIVER
+  VERSION_STRING = 1.0
+  ENTRY_POINT= MptScsiEntryPoint
+
+[Sources]
+  MptScsi.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index aee19b75d7..52458859b6 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -708,6 +708,7 @@
   OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+  OvmfPkg/MptScsiDxe/MptScsiDxe.inf
   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 e013099136..73e36636e0 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -233,6 +233,7 @@ INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf
 INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
 INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
 INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+INF  OvmfPkg/MptScsiDxe/MptScsiDxe.inf
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   INF  
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 90cbd8e341..d8ea2addb2 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -717,6 +717,7 @@
   OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+  OvmfPkg/MptScsiDxe/MptScsiDxe.inf
   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 afaa334384..e22a223e7e 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -234,6 +234,7 @@ INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf
 INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
 INF  OvmfPkg/Xen

[edk2] [PATCH 06/14] OvmfPkg/MptScsiDxe: Report one Target and one LUN

2019-01-31 Thread Nikita Leshenko
Support for multiple targets will be implemented in a later commit in
this series.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 34 --
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 6b655d9fe8..8ce7986b1d 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -68,6 +68,21 @@ MptScsiPassThru (
   return EFI_UNSUPPORTED;
 }
 
+STATIC
+BOOLEAN
+IsTargetInitialized (
+  IN UINT8  *Target
+  )
+{
+  int i;
+  for (i = 0; i < TARGET_MAX_BYTES; ++i) {
+if (Target[i] != 0xFF) {
+  return TRUE;
+}
+  }
+  return FALSE;
+}
+
 STATIC
 EFI_STATUS
 EFIAPI
@@ -78,7 +93,15 @@ MptScsiGetNextTargetLun (
   )
 {
   DEBUG ((EFI_D_INFO, "MptScsiGetNextTargetLun %d %d\n", **Target, *Lun));
-  return EFI_UNSUPPORTED;
+
+  // Currently support only target 0 LUN 0, so hardcode it
+  if (!IsTargetInitialized (*Target)) {
+**Target = 0;
+*Lun = 0;
+return EFI_SUCCESS;
+  } else {
+return EFI_NOT_FOUND;
+  }
 }
 
 STATIC
@@ -90,7 +113,14 @@ MptScsiGetNextTarget (
   )
 {
   DEBUG ((EFI_D_INFO, "MptScsiGetNextTarget\n"));
-  return EFI_UNSUPPORTED;
+
+  // Currently support only target 0 LUN 0, so hardcode it
+  if (!IsTargetInitialized (*Target)) {
+**Target = 0;
+return EFI_SUCCESS;
+  } else {
+return EFI_NOT_FOUND;
+  }
 }
 
 STATIC
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH 08/14] OvmfPkg/MptScsiDxe: Implement GetTargetLun

2019-01-31 Thread Nikita Leshenko
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Aaron Young 
Reviewed-by: Liran Alon 
---
 OvmfPkg/MptScsiDxe/MptScsi.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index 7f360158e7..719948a73d 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -164,7 +164,17 @@ MptScsiGetTargetLun (
   )
 {
   DEBUG ((EFI_D_INFO, "MptScsiGetTargetLun\n"));
-  return EFI_UNSUPPORTED;
+
+  if (DevicePath->Type!= MESSAGING_DEVICE_PATH ||
+  DevicePath->SubType != MSG_SCSI_DP) {
+return EFI_UNSUPPORTED;
+  }
+
+  SCSI_DEVICE_PATH *ScsiDevicePath = (SCSI_DEVICE_PATH *) DevicePath;
+  **Target = ScsiDevicePath->Pun;
+  *Lun = ScsiDevicePath->Lun;
+
+  return EFI_SUCCESS;
 }
 
 STATIC
-- 
2.20.1

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] OvmfPkg: Support booting from Fusion-MPT SCSI controllers

2019-01-31 Thread Nikita Leshenko
This series adds driver support for:
- LSI53C1030
- SAS1068
- SAS1068E

These controllers are widely supported by QEMU, VirtualBox and VMWare. This work
is part of the more general agenda of enhancing OVMF boot device support to have
feature parity with SeaBIOS.

We have also developed support for PVSCSI which we will submit in a separate
patch series.

Thanks,
Nikita


___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] PciBusDxe: PCI-Express bug with dynamic PcdPciExpressBaseAddress

2018-09-16 Thread Nikita Leshenko



> On 13 Sep 2018, at 15:15, Laszlo Ersek  wrote:
> 
> On 09/13/18 14:27, Nikita Leshenko wrote:
>> 
>> Thanks for the detailed explanation. I guess we have no choice
>> but to copy BaseCachingPciExpressLib (renamed to
>> DxePciExpressLibCaching) from ArmVirt to OVMF as well.
> 
> Uhh, hold on for a minute :) , "no choice but" is a bit of a stretch.
> Where does OVMF enter the picture to begin with?
> 
> Between OvmfPkg and ArmVirtPkg, we have a sort-of rule that ArmVirtPkg
> is allowed to consume OvmfPkg content, but not vice versa. So, we could
> move (and rename) the lib instance from ArmVirtPkg to OvmfPkg, update
> the reference(s) in ArmVirtPkg accordingly, and then consume the lib
> instance in OvmfPkg as well... *if* there was any reason to consume the
> lib instance in OvmfPkg in the first place.
> 
> (Of course if, by "we", you meant an internal Oracle use case, then I'm
> not trying to pry. I took "we" as "upstream community". Emails are
> ambiguous! :) )

Yes, I originally meant in upstream community. But I agree with your
comments below, so yes we definitely have a choice :)

> 
> I suggest that you please file a bug for MdeModulePkg /
> BasePciExpressLib in the TianoCore Bugzilla, referencing this discussion from 
> the
> mailing list archive

Sure, I filed the bug at
https://bugzilla.tianocore.org/show_bug.cgi?id=1178

-Nikita

> <https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.01.org_pipermail_edk2-2Ddevel_2018-2DSeptember_029427.html=DwICaQ=RoP1YumCXCgaWHvlZYR8PZh8Bv7qIrMUB65eapI_JnE=JD7W0KpKqI3xo5AglC-aIVDRz_ysy5CrQRnZ9Jb7je0=kTbOaTuIdbwwl68uu5hSfrQkVeQGmOgSZZgr8guTIAc=dBONCYfrLeiUrFWuFes0jATimnx7m278xMXfzfQauqA=>,
> and request that (a) either the dynamic PCD use case be fixed, or (b)
> the code own up to the restriction and be explicit about FixedPCD, both
> in the INF file(s) and the C-language APIs.
> 
> Thanks!
> Laszlo

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] PciBusDxe: PCI-Express bug with dynamic PcdPciExpressBaseAddress

2018-09-13 Thread Nikita Leshenko



> On 11 Sep 2018, at 15:34, Laszlo Ersek  wrote:
> 
> "BasePciExpressLib" has the prefix "Base", meaning that it is supposed
> to be usable in all types of firmware modules, even in SEC and PEIMs --
> which may not have access to writeable memory except stack (i.e.
> writeable global variables). Therefore modifying the original lib
> instance so that it depend on writeable globals wouldn't have been right.
> 
> We could have attempted to add the new library instance under MdePkg,
> and not ArmVirtPkg, but that's just a (more difficult) special case of
> point (1).
> 
> (Obviously if you try to apply the nomenclature I describe above to
> "BaseCachingPciExpressLib" as well, you'll see that it doesn't match.
> And that's because, when I invented the name for that lib instance, in
> 2015, I didn't know about the naming rules myself. :) In reality the lib
> instance should be called "DxePciExpressLibCaching" -- with "Dxe" for
> prefix, and "Caching" for suffix.)

Thanks for the detailed explanation. I guess we have no choice
but to copy BaseCachingPciExpressLib (renamed to
DxePciExpressLibCaching) from ArmVirt to OVMF as well.

In order to prevent such bugs in the future, what do you think
about changing the PCD reference in BasePciExpressLib.inf (in
MdePkg) from [Pcd] to [FixedPcd]? This way a module that has a
dynamic PcdPciExpressBaseAddress will fail to link with the
default PCIE library. Is it practical to get such change into
MdePkg despite their strict change policy?

Nikita

> 
> Thanks
> Laszlo
> 

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] PciBusDxe: PCI-Express bug with dynamic PcdPciExpressBaseAddress

2018-09-06 Thread Nikita Leshenko
Hi,

We ran into a bug in EDK2 relating to PCI-Express in PciBusDxe. Here's the flow
of the bug:

1. PciBusDxe/PciEnumeratorSupport.c: Function BarExisted probes a BAR. It raises
   TPL to TPL_HIGH_LEVEL to avoid timer interrupts while probing the BAR and
   calls PciIo->Pci.Write.
2. BasePciExpressLib/PciExpressLib.c: The write reaches PciExpressWrite32, which
   calls GetPciExpressBaseAddress.
3. GetPciExpressBaseAddress retrieves the address from PcdPciExpressBaseAddress.
4. Reading the PCD calls DxePcdGet64 -> GetWorker ->
   EfiAcquireLock(), which is at TPL_NOTIFY level. This crashes
   the firmware because step 1 raised the TPL to TPL_HIGH_LEVEL.

This doesn't happen when PcdPciExpressBaseAddress is fixed at build (because
then the read is optimized to a static global variable), but when the PCD is
dynamic PCI-Express is broken.

Does anybody have a suggestion for fixing it?

Options we thought about:
- Change mPcdDatabaseLock.Tpl to TPL_HIGH_LEVEL
- Don't use a PCD for the base address, put it in a static global variable and
  create functions to set and retrieve it.

Thanks,
Nikita
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel