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
,
44 Free the DMA resources allocated by an ATA AHCI controller.
46 @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA data
52 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
55 EFI_AHCI_REGISTERS
*AhciRegisters
;
57 ASSERT (Private
!= NULL
);
59 AhciRegisters
= &Private
->AhciRegisters
;
61 if (AhciRegisters
->AhciRFisMap
!= NULL
) {
63 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxRFisSize
),
64 AhciRegisters
->AhciRFis
,
65 AhciRegisters
->AhciRFisMap
69 if (AhciRegisters
->AhciCmdListMap
!= NULL
) {
71 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdListSize
),
72 AhciRegisters
->AhciCmdList
,
73 AhciRegisters
->AhciCmdListMap
77 if (AhciRegisters
->AhciCmdTableMap
!= NULL
) {
79 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdTableSize
),
80 AhciRegisters
->AhciCmdTable
,
81 AhciRegisters
->AhciCmdTableMap
87 One notified function to cleanup the allocated DMA buffers at EndOfPei.
89 @param[in] PeiServices Pointer to PEI Services Table.
90 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
91 event that caused this function to execute.
92 @param[in] Ppi Pointer to the PPI data associated with this function.
94 @retval EFI_SUCCESS The function completes successfully
100 IN EFI_PEI_SERVICES
**PeiServices
,
101 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
105 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
107 Private
= GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
108 AhciFreeDmaResource (Private
);
114 Entry point of the PEIM.
116 @param[in] FileHandle Handle of the file being invoked.
117 @param[in] PeiServices Describes the list of possible PEI Services.
119 @retval EFI_SUCCESS PPI successfully installed.
125 IN EFI_PEI_FILE_HANDLE FileHandle
,
126 IN CONST EFI_PEI_SERVICES
**PeiServices
130 EFI_BOOT_MODE BootMode
;
131 EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
*AhciHcPpi
;
134 UINTN DevicePathLength
;
135 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
137 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
140 DEBUG ((DEBUG_INFO
, "%a: Enters.\n", __FUNCTION__
));
143 // Get the current boot mode.
145 Status
= PeiServicesGetBootMode (&BootMode
);
146 if (EFI_ERROR (Status
)) {
147 DEBUG ((DEBUG_ERROR
, "%a: Fail to get the current boot mode.\n", __FUNCTION__
));
152 // Locate the ATA AHCI host controller PPI.
154 Status
= PeiServicesLocatePpi (
155 &gEdkiiPeiAtaAhciHostControllerPpiGuid
,
160 if (EFI_ERROR (Status
)) {
161 DEBUG ((DEBUG_ERROR
, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__
));
162 return EFI_UNSUPPORTED
;
168 Status
= AhciHcPpi
->GetAhciHcMmioBar (
174 // When status is error, meant no controller is found.
176 if (EFI_ERROR (Status
)) {
180 Status
= AhciHcPpi
->GetAhciHcDevicePath (
186 if (EFI_ERROR (Status
)) {
189 "%a: Fail to allocate get the device path for Controller %d.\n",
197 // Check validity of the device path of the ATA AHCI controller.
199 Status
= AhciIsHcDevicePathValid (DevicePath
, DevicePathLength
);
200 if (EFI_ERROR (Status
)) {
203 "%a: The device path is invalid for Controller %d.\n",
212 // For S3 resume performance consideration, not all ports on an ATA AHCI
213 // controller will be enumerated/initialized. The driver consumes the
214 // content within S3StorageDeviceInitList LockBox to get the ports that
215 // will be enumerated/initialized during S3 resume.
217 if (BootMode
== BOOT_ON_S3_RESUME
) {
218 NumberOfPorts
= AhciS3GetEumeratePorts (DevicePath
, DevicePathLength
, &PortBitMap
);
219 if (NumberOfPorts
== 0) {
221 // No ports need to be enumerated for this controller.
227 PortBitMap
= MAX_UINT32
;
231 // Memory allocation for controller private data.
233 Private
= AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA
));
234 if (Private
== NULL
) {
237 "%a: Fail to allocate private data for Controller %d.\n",
241 return EFI_OUT_OF_RESOURCES
;
245 // Initialize controller private data.
247 Private
->Signature
= AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE
;
248 Private
->MmioBase
= MmioBase
;
249 Private
->DevicePathLength
= DevicePathLength
;
250 Private
->DevicePath
= DevicePath
;
251 Private
->PortBitMap
= PortBitMap
;
252 InitializeListHead (&Private
->DeviceList
);
254 Status
= AhciModeInitialization (Private
);
255 if (EFI_ERROR (Status
)) {
258 "%a: Controller initialization fail for Controller %d with Status - %r.\n",
267 Private
->AtaPassThruMode
.Attributes
= EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
|
268 EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
;
269 Private
->AtaPassThruMode
.IoAlign
= sizeof (UINTN
);
270 Private
->AtaPassThruPpi
.Revision
= EDKII_PEI_ATA_PASS_THRU_PPI_REVISION
;
271 Private
->AtaPassThruPpi
.Mode
= &Private
->AtaPassThruMode
;
272 Private
->AtaPassThruPpi
.PassThru
= AhciAtaPassThruPassThru
;
273 Private
->AtaPassThruPpi
.GetNextPort
= AhciAtaPassThruGetNextPort
;
274 Private
->AtaPassThruPpi
.GetNextDevice
= AhciAtaPassThruGetNextDevice
;
275 Private
->AtaPassThruPpi
.GetDevicePath
= AhciAtaPassThruGetDevicePath
;
277 &Private
->AtaPassThruPpiList
,
278 &mAhciAtaPassThruPpiListTemplate
,
279 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
281 Private
->AtaPassThruPpiList
.Ppi
= &Private
->AtaPassThruPpi
;
282 PeiServicesInstallPpi (&Private
->AtaPassThruPpiList
);
284 Private
->BlkIoPpi
.GetNumberOfBlockDevices
= AhciBlockIoGetDeviceNo
;
285 Private
->BlkIoPpi
.GetBlockDeviceMediaInfo
= AhciBlockIoGetMediaInfo
;
286 Private
->BlkIoPpi
.ReadBlocks
= AhciBlockIoReadBlocks
;
288 &Private
->BlkIoPpiList
,
289 &mAhciBlkIoPpiListTemplate
,
290 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
292 Private
->BlkIoPpiList
.Ppi
= &Private
->BlkIoPpi
;
293 PeiServicesInstallPpi (&Private
->BlkIoPpiList
);
295 Private
->BlkIo2Ppi
.Revision
= EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION
;
296 Private
->BlkIo2Ppi
.GetNumberOfBlockDevices
= AhciBlockIoGetDeviceNo2
;
297 Private
->BlkIo2Ppi
.GetBlockDeviceMediaInfo
= AhciBlockIoGetMediaInfo2
;
298 Private
->BlkIo2Ppi
.ReadBlocks
= AhciBlockIoReadBlocks2
;
300 &Private
->BlkIo2PpiList
,
301 &mAhciBlkIo2PpiListTemplate
,
302 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
304 Private
->BlkIo2PpiList
.Ppi
= &Private
->BlkIo2Ppi
;
305 PeiServicesInstallPpi (&Private
->BlkIo2PpiList
);
307 if (Private
->TrustComputingDevices
!= 0) {
310 "%a: Security Security Command PPI will be produced for Controller %d.\n",
314 Private
->StorageSecurityPpi
.Revision
= EDKII_STORAGE_SECURITY_PPI_REVISION
;
315 Private
->StorageSecurityPpi
.GetNumberofDevices
= AhciStorageSecurityGetDeviceNo
;
316 Private
->StorageSecurityPpi
.GetDevicePath
= AhciStorageSecurityGetDevicePath
;
317 Private
->StorageSecurityPpi
.ReceiveData
= AhciStorageSecurityReceiveData
;
318 Private
->StorageSecurityPpi
.SendData
= AhciStorageSecuritySendData
;
320 &Private
->StorageSecurityPpiList
,
321 &mAhciStorageSecurityPpiListTemplate
,
322 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
324 Private
->StorageSecurityPpiList
.Ppi
= &Private
->StorageSecurityPpi
;
325 PeiServicesInstallPpi (&Private
->StorageSecurityPpiList
);
329 &Private
->EndOfPeiNotifyList
,
330 &mAhciEndOfPeiNotifyListTemplate
,
331 sizeof (EFI_PEI_NOTIFY_DESCRIPTOR
)
333 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
337 "%a: Controller %d has been successfully initialized.\n",