Revision: 18528
          http://sourceforge.net/p/edk2/code/18528
Author:   lersek
Date:     2015-09-22 11:18:27 +0000 (Tue, 22 Sep 2015)
Log Message:
-----------
OvmfPkg: SataControllerDxe: enable IO / mem access and DMA when binding

When we bind the SATA controller in SataControllerStart(), we read the NP
("Number of Ports") bitfield from the CAP ("HBA Capabilities") register of
the controller. (See the AHCI 1.3.1 spec.)

This register is memory mapped. If we'd like to access it, we must at
least enable memory space access for the device. In addition, Feng Tian
recommended enabling Bus Master DMA in
<http://thread.gmane.org/gmane.comp.bios.tianocore.devel/10545/focus=10659>.
We also enable IO space access for completeness.

Further, because we change the PCI attributes of the device with the above
when binding it, we must also restore its original PCI attributes when
unbinding it. See the Driver Writer's Guide for UEFI 2.3.1 v1.01, section
18.3 "PCI drivers" | 18.3.2 "Start() and Stop()".

(OvmfPkg's copy of SataControllerDxe differs from the same in DuetPkg
because Duet inherits a pre-configured SATA controller from the BIOS, as
explained by Feng. Technically, DuetPkg's SataControllerDxe could also
apply the technique seen in this patch.)

Cc: Alexander Graf <[email protected]>
Cc: Reza Jelveh <[email protected]>
Cc: Jordan Justen <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Gabriel L. Somlo <[email protected]>
Cc: Feng Tian <[email protected]>
Suggested-by: Feng Tian <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
Reviewed-by: Feng Tian <[email protected]>
Tested-by: Gabriel Somlo <[email protected]>
Reviewed-by: Jordan Justen <[email protected]>

Modified Paths:
--------------
    trunk/edk2/OvmfPkg/SataControllerDxe/SataController.c
    trunk/edk2/OvmfPkg/SataControllerDxe/SataController.h

Modified: trunk/edk2/OvmfPkg/SataControllerDxe/SataController.c
===================================================================
--- trunk/edk2/OvmfPkg/SataControllerDxe/SataController.c       2015-09-22 
11:18:22 UTC (rev 18527)
+++ trunk/edk2/OvmfPkg/SataControllerDxe/SataController.c       2015-09-22 
11:18:27 UTC (rev 18528)
@@ -390,6 +390,7 @@
 {
   EFI_STATUS                        Status;
   EFI_PCI_IO_PROTOCOL               *PciIo;
+  UINT64                            OriginalPciAttributes;
   PCI_TYPE00                        PciData;
   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
   UINT32                            Data32;
@@ -415,12 +416,27 @@
   }
 
   //
+  // Save original PCI attributes, and enable IO space access, memory space
+  // access, and Bus Master (DMA).
+  //
+  Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationGet, 0,
+                    &OriginalPciAttributes);
+  if (EFI_ERROR (Status)) {
+    goto ClosePciIo;
+  }
+  Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,
+                    EFI_PCI_DEVICE_ENABLE, NULL);
+  if (EFI_ERROR (Status)) {
+    goto ClosePciIo;
+  }
+
+  //
   // Allocate Sata Private Data structure
   //
   SataPrivateData = AllocateZeroPool (sizeof 
(EFI_SATA_CONTROLLER_PRIVATE_DATA));
   if (SataPrivateData == NULL) {
     Status = EFI_OUT_OF_RESOURCES;
-    goto ClosePciIo;
+    goto RestorePciAttributes;
   }
 
   //
@@ -428,6 +444,7 @@
   //
   SataPrivateData->Signature = SATA_CONTROLLER_SIGNATURE;
   SataPrivateData->PciIo = PciIo;
+  SataPrivateData->OriginalPciAttributes = OriginalPciAttributes;
   SataPrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
   SataPrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase;
   SataPrivateData->IdeInit.SubmitData = IdeInitSubmitData;
@@ -512,6 +529,10 @@
 FreeSataPrivateData:
   FreePool (SataPrivateData);
 
+RestorePciAttributes:
+  PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSet,
+           OriginalPciAttributes, NULL);
+
 ClosePciIo:
   gBS->CloseProtocol (
          Controller,
@@ -595,6 +616,16 @@
   }
 
   //
+  // Restore original PCI attributes
+  //
+  SataPrivateData->PciIo->Attributes (
+                            SataPrivateData->PciIo,
+                            EfiPciIoAttributeOperationSet,
+                            SataPrivateData->OriginalPciAttributes,
+                            NULL
+                            );
+
+  //
   // Close protocols opened by Sata Controller driver
   //
   return gBS->CloseProtocol (

Modified: trunk/edk2/OvmfPkg/SataControllerDxe/SataController.h
===================================================================
--- trunk/edk2/OvmfPkg/SataControllerDxe/SataController.h       2015-09-22 
11:18:22 UTC (rev 18527)
+++ trunk/edk2/OvmfPkg/SataControllerDxe/SataController.h       2015-09-22 
11:18:27 UTC (rev 18528)
@@ -86,6 +86,11 @@
   EFI_PCI_IO_PROTOCOL               *PciIo;
 
   //
+  // Original PCI attributes
+  //
+  UINT64                            OriginalPciAttributes;
+
+  //
   // The number of devices that are supported by this channel
   //
   UINT8                             DeviceCount;


------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to