2 The AhciPei driver is used to manage ATA hard disk device working under AHCI
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
13 EFI_PEI_PPI_DESCRIPTOR mAhciAtaPassThruPpiListTemplate
= {
14 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
15 &gEdkiiPeiAtaPassThruPpiGuid
,
19 EFI_PEI_PPI_DESCRIPTOR mAhciBlkIoPpiListTemplate
= {
20 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
21 &gEfiPeiVirtualBlockIoPpiGuid
,
25 EFI_PEI_PPI_DESCRIPTOR mAhciBlkIo2PpiListTemplate
= {
26 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
27 &gEfiPeiVirtualBlockIo2PpiGuid
,
31 EFI_PEI_PPI_DESCRIPTOR mAhciStorageSecurityPpiListTemplate
= {
32 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
33 &gEdkiiPeiStorageSecurityCommandPpiGuid
,
37 EFI_PEI_NOTIFY_DESCRIPTOR mAhciEndOfPeiNotifyListTemplate
= {
38 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
39 &gEfiEndOfPeiSignalPpiGuid
,
45 Free the DMA resources allocated by an ATA AHCI controller.
47 @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA data
53 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
56 EFI_AHCI_REGISTERS
*AhciRegisters
;
58 ASSERT (Private
!= NULL
);
60 AhciRegisters
= &Private
->AhciRegisters
;
62 if (AhciRegisters
->AhciRFisMap
!= NULL
) {
64 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxRFisSize
),
65 AhciRegisters
->AhciRFis
,
66 AhciRegisters
->AhciRFisMap
70 if (AhciRegisters
->AhciCmdListMap
!= NULL
) {
72 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdListSize
),
73 AhciRegisters
->AhciCmdList
,
74 AhciRegisters
->AhciCmdListMap
78 if (AhciRegisters
->AhciCmdTableMap
!= NULL
) {
80 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdTableSize
),
81 AhciRegisters
->AhciCmdTable
,
82 AhciRegisters
->AhciCmdTableMap
89 One notified function to cleanup the allocated DMA buffers at EndOfPei.
91 @param[in] PeiServices Pointer to PEI Services Table.
92 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
93 event that caused this function to execute.
94 @param[in] Ppi Pointer to the PPI data associated with this function.
96 @retval EFI_SUCCESS The function completes successfully
102 IN EFI_PEI_SERVICES
**PeiServices
,
103 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
107 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
109 Private
= GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
110 AhciFreeDmaResource (Private
);
116 Entry point of the PEIM.
118 @param[in] FileHandle Handle of the file being invoked.
119 @param[in] PeiServices Describes the list of possible PEI Services.
121 @retval EFI_SUCCESS PPI successfully installed.
127 IN EFI_PEI_FILE_HANDLE FileHandle
,
128 IN CONST EFI_PEI_SERVICES
**PeiServices
132 EFI_BOOT_MODE BootMode
;
133 EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
*AhciHcPpi
;
136 UINTN DevicePathLength
;
137 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
139 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
142 DEBUG ((DEBUG_INFO
, "%a: Enters.\n", __FUNCTION__
));
145 // Get the current boot mode.
147 Status
= PeiServicesGetBootMode (&BootMode
);
148 if (EFI_ERROR (Status
)) {
149 DEBUG ((DEBUG_ERROR
, "%a: Fail to get the current boot mode.\n", __FUNCTION__
));
154 // Locate the ATA AHCI host controller PPI.
156 Status
= PeiServicesLocatePpi (
157 &gEdkiiPeiAtaAhciHostControllerPpiGuid
,
162 if (EFI_ERROR (Status
)) {
163 DEBUG ((DEBUG_ERROR
, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__
));
164 return EFI_UNSUPPORTED
;
170 Status
= AhciHcPpi
->GetAhciHcMmioBar (
176 // When status is error, meant no controller is found.
178 if (EFI_ERROR (Status
)) {
182 Status
= AhciHcPpi
->GetAhciHcDevicePath (
188 if (EFI_ERROR (Status
)) {
190 DEBUG_ERROR
, "%a: Fail to allocate get the device path for Controller %d.\n",
191 __FUNCTION__
, Controller
197 // Check validity of the device path of the ATA AHCI controller.
199 Status
= AhciIsHcDevicePathValid (DevicePath
, DevicePathLength
);
200 if (EFI_ERROR (Status
)) {
202 DEBUG_ERROR
, "%a: The device path is invalid for Controller %d.\n",
203 __FUNCTION__
, Controller
210 // For S3 resume performance consideration, not all ports on an ATA AHCI
211 // controller will be enumerated/initialized. The driver consumes the
212 // content within S3StorageDeviceInitList LockBox to get the ports that
213 // will be enumerated/initialized during S3 resume.
215 if (BootMode
== BOOT_ON_S3_RESUME
) {
216 NumberOfPorts
= AhciS3GetEumeratePorts (DevicePath
, DevicePathLength
, &PortBitMap
);
217 if (NumberOfPorts
== 0) {
219 // No ports need to be enumerated for this controller.
225 PortBitMap
= MAX_UINT32
;
229 // Memory allocation for controller private data.
231 Private
= AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA
));
232 if (Private
== NULL
) {
234 DEBUG_ERROR
, "%a: Fail to allocate private data for Controller %d.\n",
235 __FUNCTION__
, Controller
237 return EFI_OUT_OF_RESOURCES
;
241 // Initialize controller private data.
243 Private
->Signature
= AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE
;
244 Private
->MmioBase
= MmioBase
;
245 Private
->DevicePathLength
= DevicePathLength
;
246 Private
->DevicePath
= DevicePath
;
247 Private
->PortBitMap
= PortBitMap
;
248 InitializeListHead (&Private
->DeviceList
);
250 Status
= AhciModeInitialization (Private
);
251 if (EFI_ERROR (Status
)) {
254 "%a: Controller initialization fail for Controller %d with Status - %r.\n",
263 Private
->AtaPassThruMode
.Attributes
= EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
|
264 EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
;
265 Private
->AtaPassThruMode
.IoAlign
= sizeof (UINTN
);
266 Private
->AtaPassThruPpi
.Revision
= EDKII_PEI_ATA_PASS_THRU_PPI_REVISION
;
267 Private
->AtaPassThruPpi
.Mode
= &Private
->AtaPassThruMode
;
268 Private
->AtaPassThruPpi
.PassThru
= AhciAtaPassThruPassThru
;
269 Private
->AtaPassThruPpi
.GetNextPort
= AhciAtaPassThruGetNextPort
;
270 Private
->AtaPassThruPpi
.GetNextDevice
= AhciAtaPassThruGetNextDevice
;
271 Private
->AtaPassThruPpi
.GetDevicePath
= AhciAtaPassThruGetDevicePath
;
273 &Private
->AtaPassThruPpiList
,
274 &mAhciAtaPassThruPpiListTemplate
,
275 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
277 Private
->AtaPassThruPpiList
.Ppi
= &Private
->AtaPassThruPpi
;
278 PeiServicesInstallPpi (&Private
->AtaPassThruPpiList
);
280 Private
->BlkIoPpi
.GetNumberOfBlockDevices
= AhciBlockIoGetDeviceNo
;
281 Private
->BlkIoPpi
.GetBlockDeviceMediaInfo
= AhciBlockIoGetMediaInfo
;
282 Private
->BlkIoPpi
.ReadBlocks
= AhciBlockIoReadBlocks
;
284 &Private
->BlkIoPpiList
,
285 &mAhciBlkIoPpiListTemplate
,
286 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
288 Private
->BlkIoPpiList
.Ppi
= &Private
->BlkIoPpi
;
289 PeiServicesInstallPpi (&Private
->BlkIoPpiList
);
291 Private
->BlkIo2Ppi
.Revision
= EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION
;
292 Private
->BlkIo2Ppi
.GetNumberOfBlockDevices
= AhciBlockIoGetDeviceNo2
;
293 Private
->BlkIo2Ppi
.GetBlockDeviceMediaInfo
= AhciBlockIoGetMediaInfo2
;
294 Private
->BlkIo2Ppi
.ReadBlocks
= AhciBlockIoReadBlocks2
;
296 &Private
->BlkIo2PpiList
,
297 &mAhciBlkIo2PpiListTemplate
,
298 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
300 Private
->BlkIo2PpiList
.Ppi
= &Private
->BlkIo2Ppi
;
301 PeiServicesInstallPpi (&Private
->BlkIo2PpiList
);
303 if (Private
->TrustComputingDevices
!= 0) {
306 "%a: Security Security Command PPI will be produced for Controller %d.\n",
307 __FUNCTION__
, Controller
309 Private
->StorageSecurityPpi
.Revision
= EDKII_STORAGE_SECURITY_PPI_REVISION
;
310 Private
->StorageSecurityPpi
.GetNumberofDevices
= AhciStorageSecurityGetDeviceNo
;
311 Private
->StorageSecurityPpi
.GetDevicePath
= AhciStorageSecurityGetDevicePath
;
312 Private
->StorageSecurityPpi
.ReceiveData
= AhciStorageSecurityReceiveData
;
313 Private
->StorageSecurityPpi
.SendData
= AhciStorageSecuritySendData
;
315 &Private
->StorageSecurityPpiList
,
316 &mAhciStorageSecurityPpiListTemplate
,
317 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
319 Private
->StorageSecurityPpiList
.Ppi
= &Private
->StorageSecurityPpi
;
320 PeiServicesInstallPpi (&Private
->StorageSecurityPpiList
);
324 &Private
->EndOfPeiNotifyList
,
325 &mAhciEndOfPeiNotifyListTemplate
,
326 sizeof (EFI_PEI_NOTIFY_DESCRIPTOR
)
328 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
331 DEBUG_INFO
, "%a: Controller %d has been successfully initialized.\n",
332 __FUNCTION__
, Controller