From: "Nikita Leshenko" <nikita.leshchenko@oracle.com>
To: devel@edk2.groups.io
Cc: liran.alon@oracle.com, aaron.young@oracle.com,
jordan.l.justen@intel.com, lersek@redhat.com,
ard.biesheuvel@linaro.org,
Nikita Leshenko <nikita.leshchenko@oracle.com>
Subject: [PATCH v2 11/13] OvmfPkg/MptScsiDxe: Initialize hardware
Date: Wed, 26 Feb 2020 18:41:49 +0200 [thread overview]
Message-ID: <20200226164151.125182-12-nikita.leshchenko@oracle.com> (raw)
In-Reply-To: <20200226164151.125182-1-nikita.leshchenko@oracle.com>
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.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2390
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
Reviewed-by: Aaron Young <aaron.young@oracle.com>
Reviewed-by: Liran Alon <liran.alon@oracle.com>
---
.../Include/IndustryStandard/FusionMptScsi.h | 115 ++++++++++++
OvmfPkg/MptScsiDxe/MptScsi.c | 168 ++++++++++++++++++
2 files changed, 283 insertions(+)
diff --git a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h b/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
index 3b911bdb5b..20f535a2c8 100644
--- a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
+++ b/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
@@ -22,3 +22,118 @@
#define LSI_53C1030_PCI_DEVICE_ID 0x0030
#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_REPLY 0x08
+
+#define MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST 0x00
+#define MPT_MESSAGE_HDR_FUNCTION_IOC_INIT 0x02
+
+#define MPT_SG_ENTRY_TYPE_SIMPLE 0x01
+
+#define MPT_IOC_WHOINIT_ROM_BIOS 0x02
+
+//
+// Device structures
+//
+
+typedef struct {
+#pragma pack (1)
+ struct {
+ UINT8 WhoInit;
+ UINT8 Reserved1;
+ UINT8 ChainOffset;
+ UINT8 Function;
+ UINT8 Flags;
+ UINT8 MaxDevices;
+ UINT8 MaxBuses;
+ UINT8 MessageFlags;
+ UINT32 MessageContext;
+ UINT16 ReplyFrameSize;
+ UINT16 Reserved2;
+ UINT32 HostMfaHighAddr;
+ UINT32 SenseBufferHighAddr;
+ } Data;
+#pragma pack ()
+ UINT64 Uint64; // 8 byte alignment required by HW
+} MPT_IO_CONTROLLER_INIT_REQUEST;
+#pragma pack (1)
+typedef struct {
+ UINT8 WhoInit;
+ UINT8 Reserved1;
+ UINT8 MessageLength;
+ UINT8 Function;
+ UINT8 Flags;
+ UINT8 MaxDevices;
+ UINT8 MaxBuses;
+ UINT8 MessageFlags;
+ UINT32 MessageContext;
+ UINT16 Reserved2;
+ UINT16 IOCStatus;
+ UINT32 IOCLogInfo;
+} MPT_IO_CONTROLLER_INIT_REPLY;
+typedef struct {
+ UINT8 TargetID;
+ UINT8 Bus;
+ UINT8 ChainOffset;
+ UINT8 Function;
+ UINT8 CDBLength;
+ UINT8 SenseBufferLength;
+ UINT8 Reserved;
+ UINT8 MessageFlags;
+ UINT32 MessageContext;
+ UINT8 LUN[8];
+ UINT32 Control;
+ UINT8 CDB[16];
+ UINT32 DataLength;
+ UINT32 SenseBufferLowAddress;
+} MPT_SCSI_IO_REQUEST;
+typedef struct {
+ UINT32 Length: 24;
+ UINT32 EndOfList: 1;
+ UINT32 Is64BitAddress: 1;
+ UINT32 BufferContainsData: 1;
+ UINT32 LocalAddress: 1;
+ UINT32 ElementType: 2;
+ UINT32 EndOfBuffer: 1;
+ UINT32 LastElement: 1;
+ UINT64 DataBufferAddress;
+} MPT_SG_ENTRY_SIMPLE;
+#pragma pack ()
+typedef struct {
+#pragma pack (1)
+ struct {
+ UINT8 TargetID;
+ UINT8 Bus;
+ UINT8 MessageLength;
+ UINT8 Function;
+ UINT8 CDBLength;
+ UINT8 SenseBufferLength;
+ UINT8 Reserved;
+ UINT8 MessageFlags;
+ UINT32 MessageContext;
+ UINT8 SCSIStatus;
+ UINT8 SCSIState;
+ UINT16 IOCStatus;
+ UINT32 IOCLogInfo;
+ UINT32 TransferCount;
+ UINT32 SenseCount;
+ UINT32 ResponseInfo;
+ } Data;
+#pragma pack ()
+ UINT64 Uint64; // 8 byte alignment required by HW
+} MPT_SCSI_IO_ERROR_REPLY;
diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
index f5f774e431..4cb35046c4 100644
--- a/OvmfPkg/MptScsiDxe/MptScsi.c
+++ b/OvmfPkg/MptScsiDxe/MptScsi.c
@@ -47,6 +47,167 @@ 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,
+ &Data
+ );
+}
+
+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,
+ (((UINT32)DoorbellFunc) << 24) | (DoorbellArg << 16)
+ );
+}
+
+STATIC
+EFI_STATUS
+MptScsiReset (
+ IN MPT_SCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Reset hardware
+ //
+ Status = MptDoorbell (Dev, MPT_DOORBELL_RESET, 0);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Mask interrupts
+ //
+ Status = Out32 (Dev, MPT_REG_IMASK, MPT_IMASK_DOORBELL|MPT_IMASK_REPLY);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Clear interrupt status
+ //
+ Status = Out32 (Dev, MPT_REG_ISTATUS, 0);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MptScsiInit (
+ IN MPT_SCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+ MPT_IO_CONTROLLER_INIT_REQUEST Req;
+ MPT_IO_CONTROLLER_INIT_REPLY Reply;
+ UINT8 *ReplyBytes;
+ UINT32 Reply32;
+
+ Status = MptScsiReset (Dev);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ZeroMem (&Req, sizeof (Req));
+ ZeroMem (&Reply, sizeof (Reply));
+ Req.Data.WhoInit = MPT_IOC_WHOINIT_ROM_BIOS;
+ Req.Data.Function = MPT_MESSAGE_HDR_FUNCTION_IOC_INIT;
+ Req.Data.MaxDevices = 1;
+ Req.Data.MaxBuses = 1;
+ Req.Data.ReplyFrameSize = sizeof (MPT_SCSI_IO_ERROR_REPLY);
+
+ //
+ // Send controller init through doorbell
+ //
+ Status = MptDoorbell (
+ Dev,
+ MPT_DOORBELL_HANDSHAKE,
+ sizeof (Req) / sizeof (UINT32)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = Dev->PciIo->Io.Write (
+ Dev->PciIo,
+ EfiPciIoWidthFifoUint32,
+ 0,
+ MPT_REG_DOORBELL,
+ sizeof (Req) / sizeof (UINT32),
+ &Req
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Read reply through doorbell
+ // Each 32bit read produces 16bit of data
+ //
+ ReplyBytes = (UINT8 *)&Reply;
+ while (ReplyBytes != (UINT8 *)(&Reply + 1)) {
+ Status = In32 (Dev, MPT_REG_DOORBELL, &Reply32);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ CopyMem (ReplyBytes, &Reply32, sizeof (UINT16));
+ ReplyBytes += sizeof (UINT16);
+ }
+
+ //
+ // Clear interrupts generated by doorbell reply
+ //
+ Status = Out32 (Dev, MPT_REG_ISTATUS, 0);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
//
// Ext SCSI Pass Thru
//
@@ -311,6 +472,11 @@ MptScsiControllerStart (
}
PciAttributesChanged = TRUE;
+ Status = MptScsiInit (Dev);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
//
// Host adapter channel, doesn't exist
//
@@ -398,6 +564,8 @@ MptScsiControllerStop (
&Dev->PassThru
);
+ MptScsiReset (Dev);
+
Dev->PciIo->Attributes (
Dev->PciIo,
EfiPciIoAttributeOperationEnable,
--
2.20.1
next prev parent reply other threads:[~2020-02-26 16:40 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-26 16:41 [PATCH v2 00/13] OvmfPkg: Support booting from Fusion-MPT SCSI controllers Nikita Leshenko
2020-02-26 16:41 ` [PATCH v2 01/13] OvmfPkg/MptScsiDxe: Create empty driver Nikita Leshenko
2020-02-28 8:12 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 02/13] OvmfPkg/MptScsiDxe: Install DriverBinding Protocol Nikita Leshenko
2020-02-28 8:16 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 03/13] OvmfPkg/MptScsiDxe: Report name of driver Nikita Leshenko
2020-02-28 8:17 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 04/13] OvmfPkg/MptScsiDxe: Probe PCI devices and look for MptScsi Nikita Leshenko
2020-02-28 8:26 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 05/13] OvmfPkg/MptScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Nikita Leshenko
2020-02-28 8:35 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 06/13] OvmfPkg/MptScsiDxe: Report one Target and one LUN Nikita Leshenko
2020-02-28 8:41 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 07/13] OvmfPkg/MptScsiDxe: Build DevicePath for discovered devices Nikita Leshenko
2020-02-28 9:03 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 08/13] OvmfPkg/MptScsiDxe: Implement GetTargetLun Nikita Leshenko
2020-02-28 9:16 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 09/13] OvmfPkg/MptScsiDxe: Open PciIo protocol for later use Nikita Leshenko
2020-02-28 9:50 ` Laszlo Ersek
2020-02-28 9:53 ` Laszlo Ersek
2020-02-26 16:41 ` [PATCH v2 10/13] OvmfPkg/MptScsiDxe: Set and restore PCI attributes Nikita Leshenko
2020-02-26 16:41 ` Nikita Leshenko [this message]
2020-02-26 16:41 ` [PATCH v2 12/13] OvmfPkg/MptScsiDxe: Implement the PassThru method Nikita Leshenko
2020-02-26 16:41 ` [PATCH v2 13/13] OvmfPkg/MptScsiDxe: Report multiple targets Nikita Leshenko
2020-02-27 9:52 ` [edk2-devel] [PATCH v2 00/13] OvmfPkg: Support booting from Fusion-MPT SCSI controllers Laszlo Ersek
2020-02-28 7:51 ` Laszlo Ersek
2020-02-28 8:06 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200226164151.125182-12-nikita.leshchenko@oracle.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox