From: "Liran Alon" <liran.alon@oracle.com>
To: devel@edk2.groups.io, lersek@redhat.com
Cc: nikita.leshchenko@oracle.com, aaron.young@oracle.com,
jordan.l.justen@intel.com, ard.biesheuvel@linaro.org,
Liran Alon <liran.alon@oracle.com>
Subject: [PATCH 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings
Date: Mon, 16 Mar 2020 17:01:09 +0200 [thread overview]
Message-ID: <20200316150113.104630-14-liran.alon@oracle.com> (raw)
In-Reply-To: <20200316150113.104630-1-liran.alon@oracle.com>
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
Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
OvmfPkg/PvScsiDxe/PvScsi.c | 235 +++++++++++++++++++++++++++++++++++++
OvmfPkg/PvScsiDxe/PvScsi.h | 17 +++
2 files changed, 252 insertions(+)
diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c
index fb2407d2adb2..c3f5d38f3d30 100644
--- a/OvmfPkg/PvScsiDxe/PvScsi.c
+++ b/OvmfPkg/PvScsiDxe/PvScsi.c
@@ -16,6 +16,7 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
#include "PvScsi.h"
@@ -396,6 +397,209 @@ PvScsiSetPCIAttributes (
return EFI_SUCCESS;
}
+STATIC
+EFI_STATUS
+PvScsiAllocatePages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ IN OUT VOID **HostAddress
+ )
+{
+ return Dev->PciIo->AllocateBuffer (
+ Dev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ Pages,
+ HostAddress,
+ EFI_PCI_ATTRIBUTE_MEMORY_CACHED
+ );
+}
+
+STATIC
+VOID
+PvScsiFreePages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ Dev->PciIo->FreeBuffer (
+ Dev->PciIo,
+ Pages,
+ HostAddress
+ );
+}
+
+STATIC
+EFI_STATUS
+PvScsiMapBuffer (
+ IN PVSCSI_DEV *Dev,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation,
+ IN VOID *HostAddress,
+ IN UINTN NumberOfBytes,
+ OUT PVSCSI_DMA_DESC *DmaDesc
+ )
+{
+ EFI_STATUS Status;
+ UINTN BytesMapped;
+
+ BytesMapped = NumberOfBytes;
+ Status = Dev->PciIo->Map (
+ Dev->PciIo,
+ PciIoOperation,
+ HostAddress,
+ &BytesMapped,
+ &DmaDesc->DeviceAddress,
+ &DmaDesc->Mapping
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (BytesMapped != NumberOfBytes) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Unmap;
+ }
+
+ return EFI_SUCCESS;
+
+Unmap:
+ Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
+ DmaDesc->Mapping = NULL;
+
+ return Status;
+}
+
+STATIC
+VOID
+PvScsiUnmapBuffer (
+ IN PVSCSI_DEV *Dev,
+ IN OUT PVSCSI_DMA_DESC *DmaDesc)
+{
+ Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
+}
+
+STATIC
+EFI_STATUS
+PvScsiAllocateSharedPages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation,
+ OUT VOID **HostAddress,
+ OUT PVSCSI_DMA_DESC *DmaDesc
+ )
+{
+ EFI_STATUS Status;
+
+ *HostAddress = NULL;
+ DmaDesc->Mapping = NULL;
+
+ Status = PvScsiAllocatePages (Dev, Pages, HostAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PvScsiMapBuffer (
+ Dev,
+ PciIoOperation,
+ *HostAddress,
+ Pages * EFI_PAGE_SIZE,
+ DmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreePages;
+ }
+
+ return EFI_SUCCESS;
+
+FreePages:
+ PvScsiFreePages (Dev, Pages, *HostAddress);
+ *HostAddress = NULL;
+
+ return Status;
+}
+
+STATIC
+VOID
+PvScsiFreeSharedPages (
+ IN PVSCSI_DEV *Dev,
+ IN UINTN Pages,
+ IN OUT VOID **HostAddress,
+ IN OUT PVSCSI_DMA_DESC *DmaDesc
+ )
+{
+ if (*HostAddress) {
+ if (DmaDesc->Mapping) {
+ PvScsiUnmapBuffer (Dev, DmaDesc);
+ DmaDesc->Mapping = NULL;
+ }
+
+ PvScsiFreePages (Dev, Pages, *HostAddress);
+ *HostAddress = NULL;
+ }
+}
+
+STATIC
+EFI_STATUS
+PvScsiInitRings (
+ IN OUT PVSCSI_DEV *Dev
+ )
+{
+ EFI_STATUS Status;
+ PVSCSI_CMD_DESC_SETUP_RINGS Cmd;
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID **)&Dev->RingDesc.RingState,
+ &Dev->RingDesc.RingStateDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ZeroMem (Dev->RingDesc.RingState, EFI_PAGE_SIZE);
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID **)&Dev->RingDesc.RingReqs,
+ &Dev->RingDesc.RingReqsDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ZeroMem (Dev->RingDesc.RingReqs, EFI_PAGE_SIZE);
+
+ Status = PvScsiAllocateSharedPages (
+ Dev,
+ 1,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID **)&Dev->RingDesc.RingCmps,
+ &Dev->RingDesc.RingCmpsDmaDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE);
+
+ ZeroMem (&Cmd, sizeof Cmd);
+ Cmd.ReqRingNumPages = 1;
+ Cmd.CmpRingNumPages = 1;
+ Cmd.RingsStatePPN =
+ ((UINT64) Dev->RingDesc.RingStateDmaDesc.DeviceAddress) >>
+ EFI_PAGE_SHIFT;
+ Cmd.ReqRingPPNs[0] =
+ ((UINT64) Dev->RingDesc.RingReqsDmaDesc.DeviceAddress) >>
+ EFI_PAGE_SHIFT;
+ Cmd.CmpRingPPNs[0] =
+ ((UINT64) Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress) >>
+ EFI_PAGE_SHIFT;
+
+ return PvScsiWriteCmdDesc(Dev, PVSCSI_CMD_SETUP_RINGS, &Cmd, sizeof Cmd);
+}
+
STATIC
EFI_STATUS
PvScsiInit (
@@ -425,6 +629,15 @@ PvScsiInit (
if (EFI_ERROR (Status)) {
return Status;
}
+
+ //
+ // Init PVSCSI rings
+ //
+ Status = PvScsiInitRings (Dev);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
//
// Populate the exported interface's attributes
//
@@ -463,6 +676,28 @@ PvScsiUninit (
IN OUT PVSCSI_DEV *Dev
)
{
+ //
+ // Free PVSCSI rings
+ //
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingCmps,
+ &Dev->RingDesc.RingCmpsDmaDesc
+ );
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingReqs,
+ &Dev->RingDesc.RingReqsDmaDesc
+ );
+ PvScsiFreeSharedPages (
+ Dev,
+ 1,
+ (VOID **)&Dev->RingDesc.RingState,
+ &Dev->RingDesc.RingStateDmaDesc
+ );
+
//
// Restore PCI Attributes
//
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;
--
2.20.1
next prev parent reply other threads:[~2020-03-16 15:02 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-16 15:00 [PATCH 00/17]: OvmfPkg: Support booting from VMware PVSCSI controller liran.alon
2020-03-16 15:00 ` [PATCH 01/17] OvmfPkg/PvScsiDxe: Create empty driver Liran Alon
2020-03-24 11:15 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:00 ` [PATCH 02/17] OvmfPkg/PvScsiDxe: Install DriverBinding protocol Liran Alon
2020-03-24 11:23 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:00 ` [PATCH 03/17] OvmfPkg/PvScsiDxe: Report name of driver Liran Alon
2020-03-24 11:29 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 04/17] OvmfPkg/PvScsiDxe: Probe PCI devices and look for PvScsi Liran Alon
2020-03-24 11:41 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 05/17] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Liran Alon
2020-03-24 12:27 ` [edk2-devel] " Laszlo Ersek
2020-03-24 12:47 ` Laszlo Ersek
2020-03-16 15:01 ` [PATCH 06/17] OvmfPkg/PvScsiDxe: Report the number of targets and LUNs Liran Alon
2020-03-24 13:12 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 07/17] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath Liran Alon
2020-03-24 13:36 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 08/17] OvmfPkg/PvScsiDxe: Open PciIo protocol for later use Liran Alon
2020-03-24 13:47 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 09/17] OvmfPkg/PvScsiDxe: Backup/Restore PCI attributes on Init/UnInit Liran Alon
2020-03-24 15:14 ` [edk2-devel] " Laszlo Ersek
2020-03-24 15:35 ` Liran Alon
2020-03-25 1:48 ` Laszlo Ersek
2020-03-25 10:32 ` Liran Alon
2020-03-16 15:01 ` [PATCH 10/17] OvmfPkg/PvScsiDxe: Enable IOSpace & Bus-Mastering in PCI attributes Liran Alon
2020-03-24 15:22 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 11/17] OvmfPkg/PvScsiDxe: Define device interface structures and constants Liran Alon
2020-03-24 15:35 ` [edk2-devel] " Laszlo Ersek
2020-03-24 16:34 ` Laszlo Ersek
2020-03-16 15:01 ` [PATCH 12/17] OvmfPkg/PvScsiDxe: Reset adapter on init Liran Alon
2020-03-24 16:00 ` [edk2-devel] " Laszlo Ersek
2020-03-25 1:11 ` Liran Alon
2020-03-25 16:31 ` Laszlo Ersek
2020-03-25 16:40 ` Liran Alon
2020-03-25 17:13 ` Liran Alon
2020-03-27 12:55 ` Laszlo Ersek
2020-03-16 15:01 ` Liran Alon [this message]
2020-03-24 16:11 ` [edk2-devel] [PATCH 13/17] OvmfPkg/PvScsiDxe: Setup requests and completions rings Laszlo Ersek
2020-03-16 15:01 ` [PATCH 14/17] OvmfPkg/PvScsiDxe: Introduce DMA communication buffer Liran Alon
2020-03-24 16:13 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 15/17] OvmfPkg/PvScsiDxe: Support sending SCSI request and receive response Liran Alon
2020-03-24 16:43 ` [edk2-devel] " Laszlo Ersek
2020-03-25 1:17 ` Liran Alon
2020-03-16 15:01 ` [PATCH 16/17] OvmfPkg/PvScsiDxe: Reset device on ExitBootServices() Liran Alon
2020-03-24 17:04 ` [edk2-devel] " Laszlo Ersek
2020-03-16 15:01 ` [PATCH 17/17] OvmfPkg/PvScsiDxe: Enable device 64-bit DMA addresses Liran Alon
2020-03-24 15:26 ` [edk2-devel] " Laszlo Ersek
2020-03-23 16:33 ` [edk2-devel] [PATCH 00/17]: OvmfPkg: Support booting from VMware PVSCSI controller 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=20200316150113.104630-14-liran.alon@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