summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/SataControllerDxe
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2015-09-22 11:18:27 +0000
committerlersek <lersek@Edk2>2015-09-22 11:18:27 +0000
commitbcab71413407e61c144994925556725dd65eede9 (patch)
treefdaddb050777c4abf6ab2a0d0975727f7225eea8 /OvmfPkg/SataControllerDxe
parent379b17965f0fc3fcf542c606ad628856c2504a2e (diff)
downloadedk2-bcab71413407e61c144994925556725dd65eede9.tar.gz
edk2-bcab71413407e61c144994925556725dd65eede9.tar.bz2
edk2-bcab71413407e61c144994925556725dd65eede9.zip
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 <agraf@suse.de> Cc: Reza Jelveh <reza.jelveh@tuhh.de> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Hannes Reinecke <hare@suse.de> Cc: Gabriel L. Somlo <somlo@cmu.edu> Cc: Feng Tian <feng.tian@intel.com> Suggested-by: Feng Tian <feng.tian@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Feng Tian <feng.tian@intel.com> Tested-by: Gabriel Somlo <somlo@cmu.edu> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18528 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/SataControllerDxe')
-rw-r--r--OvmfPkg/SataControllerDxe/SataController.c33
-rw-r--r--OvmfPkg/SataControllerDxe/SataController.h5
2 files changed, 37 insertions, 1 deletions
diff --git a/OvmfPkg/SataControllerDxe/SataController.c b/OvmfPkg/SataControllerDxe/SataController.c
index 5e7e23b261..ba21717cad 100644
--- a/OvmfPkg/SataControllerDxe/SataController.c
+++ b/OvmfPkg/SataControllerDxe/SataController.c
@@ -390,6 +390,7 @@ SataControllerStart (
{
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 @@ SataControllerStart (
}
//
+ // 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 @@ SataControllerStart (
//
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 @@ FreeDisqualifiedModes:
FreeSataPrivateData:
FreePool (SataPrivateData);
+RestorePciAttributes:
+ PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSet,
+ OriginalPciAttributes, NULL);
+
ClosePciIo:
gBS->CloseProtocol (
Controller,
@@ -595,6 +616,16 @@ SataControllerStop (
}
//
+ // Restore original PCI attributes
+ //
+ SataPrivateData->PciIo->Attributes (
+ SataPrivateData->PciIo,
+ EfiPciIoAttributeOperationSet,
+ SataPrivateData->OriginalPciAttributes,
+ NULL
+ );
+
+ //
// Close protocols opened by Sata Controller driver
//
return gBS->CloseProtocol (
diff --git a/OvmfPkg/SataControllerDxe/SataController.h b/OvmfPkg/SataControllerDxe/SataController.h
index a6c6c168df..e5b719e76d 100644
--- a/OvmfPkg/SataControllerDxe/SataController.h
+++ b/OvmfPkg/SataControllerDxe/SataController.h
@@ -86,6 +86,11 @@ typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
EFI_PCI_IO_PROTOCOL *PciIo;
//
+ // Original PCI attributes
+ //
+ UINT64 OriginalPciAttributes;
+
+ //
// The number of devices that are supported by this channel
//
UINT8 DeviceCount;