From: Laszlo Ersek <lersek@redhat.com>
To: edk2-devel-01 <edk2-devel@lists.01.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>,
Eric Dong <eric.dong@intel.com>, Star Zeng <star.zeng@intel.com>
Subject: [PATCH 4/4] MdeModulePkg/AtaAtapiPassThru: unmap common buffers at ExitBootServices()
Date: Sun, 3 Sep 2017 21:54:49 +0200 [thread overview]
Message-ID: <20170903195449.30261-5-lersek@redhat.com> (raw)
In-Reply-To: <20170903195449.30261-1-lersek@redhat.com>
The AtaAtapiPassThru() driver maps three system memory regions for Bus
Master Common Buffer operation on the following call path, if the
controller being bound has PCI_CLASS_MASS_STORAGE_SATADPA class code:
AtaAtapiPassThruStart()
EnumerateAttachedDevice()
AhciModeInitialization()
AhciCreateTransferDescriptor()
The regions are unmapped when the controller is unbound, in
AtaAtapiPassThruStop().
The common buffers should also be de-programmed when we exit the boot
services and the OS gains ownership of the system memory. Introduce an
ExitBootServices() notification function that
- resets the controller so that it forgets the device addresses for the
common buffers,
- unmaps the common buffers so that device-to-RAM address translations (in
a potential IOMMU or another translator) are torn down.
ExitBootServices() notification functions must not alter the UEFI memory
map, thus call only PciIo->Unmap(), and not PciIo->FreeBuffer(). (Unlike
AtaAtapiPassThruStop() does.)
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h | 18 ++++++
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h | 5 ++
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c | 67 +++++++++++++++++++-
3 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h
index 809bcc307fc4..d085597fbdfe 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h
@@ -367,5 +367,23 @@ AhciStopCommand (
IN UINT64 Timeout
);
+/**
+ Do AHCI HBA reset.
+
+ @param PciIo The PCI IO protocol instance.
+ @param Timeout The timeout value of reset, uses 100ns as a unit.
+
+ @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware
+ reset.
+ @retval EFI_TIMEOUT The reset operation is time out.
+ @retval EFI_SUCCESS AHCI controller is reset successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+AhciReset (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT64 Timeout
+ );
#endif
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
index 4f327dc30b60..e51c66f392d2 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
@@ -120,6 +120,11 @@ typedef struct {
//
EFI_EVENT TimerEvent;
LIST_ENTRY NonBlockingTaskList;
+
+ //
+ // For resetting AHCI and unmapping CommonBuffer DMA at ExitBootServices().
+ //
+ EFI_EVENT ExitBootEvent;
} ATA_ATAPI_PASS_THRU_INSTANCE;
//
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
index 795443ef74f6..6972349b2b8f 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
@@ -103,7 +103,8 @@ ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
{ // NonBlocking TaskList
NULL,
NULL
- }
+ },
+ NULL, // ExitBootEvent
};
ATAPI_DEVICE_PATH mAtapiDevicePathTemplate = {
@@ -477,6 +478,50 @@ InitializeAtaAtapiPassThru (
return Status;
}
+/**
+ If operating in AHCI mode, then reset the HBA and unmap CommonBuffer Bus
+ Master DMA when exiting the boot services.
+
+ @param[in] Event Event for which this notification function is being
+ called.
+ @param[in] Context Pointer to the ATA_ATAPI_PASS_THRU_INSTANCE that
+ represents the HBA.
+**/
+VOID
+EFIAPI
+AtaPassThruExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_AHCI_REGISTERS *AhciRegisters;
+
+ Instance = Context;
+
+ if (Instance->Mode == EfiAtaAhciMode) {
+ PciIo = Instance->PciIo;
+ AhciRegisters = &Instance->AhciRegisters;
+ //
+ // De-program common buffer references from the HBA by resetting the HBA.
+ //
+ AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT);
+ //
+ // Unmap long-lived common buffers.
+ //
+ if (AhciRegisters->AhciRFis != NULL) {
+ PciIo->Unmap (PciIo, AhciRegisters->MapRFis);
+ }
+ if (AhciRegisters->AhciCmdList != NULL) {
+ PciIo->Unmap (PciIo, AhciRegisters->MapCmdList);
+ }
+ if (AhciRegisters->AhciCommandTable != NULL) {
+ PciIo->Unmap (PciIo, AhciRegisters->MapCommandTable);
+ }
+ }
+}
+
/**
Tests to see if this driver supports a given controller. If a child device is provided,
it further tests to see if this driver supports creating a handle for the specified child device.
@@ -755,6 +800,17 @@ AtaAtapiPassThruStart (
InitializeListHead(&Instance->DeviceList);
InitializeListHead(&Instance->NonBlockingTaskList);
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ AtaPassThruExitBootServices,
+ Instance,
+ &Instance->ExitBootEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
Instance->TimerEvent = NULL;
Status = gBS->CreateEvent (
@@ -808,6 +864,10 @@ ErrorExit:
gBS->CloseEvent (Instance->TimerEvent);
}
+ if ((Instance != NULL) && (Instance->ExitBootEvent != NULL)) {
+ gBS->CloseEvent (Instance->ExitBootEvent);
+ }
+
//
// Remove all inserted ATA devices.
//
@@ -912,6 +972,11 @@ AtaAtapiPassThruStop (
//
DestroyDeviceInfoList (Instance);
+ if (Instance->ExitBootEvent != NULL) {
+ gBS->CloseEvent (Instance->ExitBootEvent);
+ Instance->ExitBootEvent = NULL;
+ }
+
//
// If the current working mode is AHCI mode, then pre-allocated resource
// for AHCI initialization should be released.
--
2.14.1.3.gb7cf6e02401b
next prev parent reply other threads:[~2017-09-03 19:52 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-03 19:54 [PATCH 0/4] MdeModulePkg: some PCI HC drivers: unmap common buffers at ExitBootServices() Laszlo Ersek
2017-09-03 19:54 ` [PATCH 1/4] MdeModulePkg/UhciDxe: unmap BM common buffers when exiting boot services Laszlo Ersek
2017-09-03 19:54 ` [PATCH 2/4] MdeModulePkg/EhciDxe: " Laszlo Ersek
2017-09-03 19:54 ` [PATCH 3/4] MdeModulePkg/XhciDxe: " Laszlo Ersek
2017-09-03 19:54 ` Laszlo Ersek [this message]
2017-09-04 10:36 ` [PATCH 0/4] MdeModulePkg: some PCI HC drivers: unmap common buffers at ExitBootServices() Zeng, Star
2017-09-04 21:19 ` Laszlo Ersek
2017-09-05 2:18 ` Yao, Jiewen
2017-09-05 9:15 ` Laszlo Ersek
2017-09-05 13:44 ` Yao, Jiewen
2017-09-05 17:57 ` Laszlo Ersek
2017-09-06 4:37 ` Yao, Jiewen
2017-09-06 12:14 ` Laszlo Ersek
2017-09-06 15:39 ` Brijesh Singh
2017-09-07 4:46 ` Yao, Jiewen
2017-09-07 11:46 ` Laszlo Ersek
2017-09-07 14:40 ` Brijesh Singh
2017-09-07 14:48 ` Yao, Jiewen
2017-09-07 16:40 ` Laszlo Ersek
2017-09-07 4:34 ` Yao, Jiewen
2017-09-07 12:11 ` 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=20170903195449.30261-5-lersek@redhat.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