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 mAhciStorageSecurityPpiListTemplate
= {
20 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
21 &gEdkiiPeiStorageSecurityCommandPpiGuid
,
25 EFI_PEI_NOTIFY_DESCRIPTOR mAhciEndOfPeiNotifyListTemplate
= {
26 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
27 &gEfiEndOfPeiSignalPpiGuid
,
33 Free the DMA resources allocated by an ATA AHCI controller.
35 @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA data
41 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
44 EFI_AHCI_REGISTERS
*AhciRegisters
;
46 ASSERT (Private
!= NULL
);
48 AhciRegisters
= &Private
->AhciRegisters
;
50 if (AhciRegisters
->AhciRFisMap
!= NULL
) {
52 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxRFisSize
),
53 AhciRegisters
->AhciRFis
,
54 AhciRegisters
->AhciRFisMap
58 if (AhciRegisters
->AhciCmdListMap
!= NULL
) {
60 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdListSize
),
61 AhciRegisters
->AhciCmdList
,
62 AhciRegisters
->AhciCmdListMap
66 if (AhciRegisters
->AhciCmdTableMap
!= NULL
) {
68 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdTableSize
),
69 AhciRegisters
->AhciCmdTable
,
70 AhciRegisters
->AhciCmdTableMap
77 One notified function to cleanup the allocated DMA buffers at EndOfPei.
79 @param[in] PeiServices Pointer to PEI Services Table.
80 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
81 event that caused this function to execute.
82 @param[in] Ppi Pointer to the PPI data associated with this function.
84 @retval EFI_SUCCESS The function completes successfully
90 IN EFI_PEI_SERVICES
**PeiServices
,
91 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
95 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
97 Private
= GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
98 AhciFreeDmaResource (Private
);
104 Entry point of the PEIM.
106 @param[in] FileHandle Handle of the file being invoked.
107 @param[in] PeiServices Describes the list of possible PEI Services.
109 @retval EFI_SUCCESS PPI successfully installed.
115 IN EFI_PEI_FILE_HANDLE FileHandle
,
116 IN CONST EFI_PEI_SERVICES
**PeiServices
120 EFI_BOOT_MODE BootMode
;
121 EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
*AhciHcPpi
;
124 UINTN DevicePathLength
;
125 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
127 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
130 DEBUG ((DEBUG_INFO
, "%a: Enters.\n", __FUNCTION__
));
133 // Get the current boot mode.
135 Status
= PeiServicesGetBootMode (&BootMode
);
136 if (EFI_ERROR (Status
)) {
137 DEBUG ((DEBUG_ERROR
, "%a: Fail to get the current boot mode.\n", __FUNCTION__
));
142 // Locate the ATA AHCI host controller PPI.
144 Status
= PeiServicesLocatePpi (
145 &gEdkiiPeiAtaAhciHostControllerPpiGuid
,
150 if (EFI_ERROR (Status
)) {
151 DEBUG ((DEBUG_ERROR
, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__
));
152 return EFI_UNSUPPORTED
;
158 Status
= AhciHcPpi
->GetAhciHcMmioBar (
164 // When status is error, meant no controller is found.
166 if (EFI_ERROR (Status
)) {
170 Status
= AhciHcPpi
->GetAhciHcDevicePath (
176 if (EFI_ERROR (Status
)) {
178 DEBUG_ERROR
, "%a: Fail to allocate get the device path for Controller %d.\n",
179 __FUNCTION__
, Controller
185 // Check validity of the device path of the ATA AHCI controller.
187 Status
= AhciIsHcDevicePathValid (DevicePath
, DevicePathLength
);
188 if (EFI_ERROR (Status
)) {
190 DEBUG_ERROR
, "%a: The device path is invalid for Controller %d.\n",
191 __FUNCTION__
, Controller
198 // For S3 resume performance consideration, not all ports on an ATA AHCI
199 // controller will be enumerated/initialized. The driver consumes the
200 // content within S3StorageDeviceInitList LockBox to get the ports that
201 // will be enumerated/initialized during S3 resume.
203 if (BootMode
== BOOT_ON_S3_RESUME
) {
204 NumberOfPorts
= AhciS3GetEumeratePorts (DevicePath
, DevicePathLength
, &PortBitMap
);
205 if (NumberOfPorts
== 0) {
207 // No ports need to be enumerated for this controller.
213 PortBitMap
= MAX_UINT32
;
217 // Memory allocation for controller private data.
219 Private
= AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA
));
220 if (Private
== NULL
) {
222 DEBUG_ERROR
, "%a: Fail to allocate private data for Controller %d.\n",
223 __FUNCTION__
, Controller
225 return EFI_OUT_OF_RESOURCES
;
229 // Initialize controller private data.
231 Private
->Signature
= AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE
;
232 Private
->MmioBase
= MmioBase
;
233 Private
->DevicePathLength
= DevicePathLength
;
234 Private
->DevicePath
= DevicePath
;
235 Private
->PortBitMap
= PortBitMap
;
236 InitializeListHead (&Private
->DeviceList
);
238 Status
= AhciModeInitialization (Private
);
239 if (EFI_ERROR (Status
)) {
242 "%a: Controller initialization fail for Controller %d with Status - %r.\n",
251 Private
->AtaPassThruMode
.Attributes
= EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
|
252 EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
;
253 Private
->AtaPassThruMode
.IoAlign
= sizeof (UINTN
);
254 Private
->AtaPassThruPpi
.Revision
= EDKII_PEI_ATA_PASS_THRU_PPI_REVISION
;
255 Private
->AtaPassThruPpi
.Mode
= &Private
->AtaPassThruMode
;
256 Private
->AtaPassThruPpi
.PassThru
= AhciAtaPassThruPassThru
;
257 Private
->AtaPassThruPpi
.GetNextPort
= AhciAtaPassThruGetNextPort
;
258 Private
->AtaPassThruPpi
.GetNextDevice
= AhciAtaPassThruGetNextDevice
;
259 Private
->AtaPassThruPpi
.GetDevicePath
= AhciAtaPassThruGetDevicePath
;
261 &Private
->AtaPassThruPpiList
,
262 &mAhciAtaPassThruPpiListTemplate
,
263 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
265 Private
->AtaPassThruPpiList
.Ppi
= &Private
->AtaPassThruPpi
;
266 PeiServicesInstallPpi (&Private
->AtaPassThruPpiList
);
268 if (Private
->TrustComputingDevices
!= 0) {
271 "%a: Security Security Command PPI will be produced for Controller %d.\n",
272 __FUNCTION__
, Controller
274 Private
->StorageSecurityPpi
.Revision
= EDKII_STORAGE_SECURITY_PPI_REVISION
;
275 Private
->StorageSecurityPpi
.GetNumberofDevices
= AhciStorageSecurityGetDeviceNo
;
276 Private
->StorageSecurityPpi
.GetDevicePath
= AhciStorageSecurityGetDevicePath
;
277 Private
->StorageSecurityPpi
.ReceiveData
= AhciStorageSecurityReceiveData
;
278 Private
->StorageSecurityPpi
.SendData
= AhciStorageSecuritySendData
;
280 &Private
->StorageSecurityPpiList
,
281 &mAhciStorageSecurityPpiListTemplate
,
282 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
284 Private
->StorageSecurityPpiList
.Ppi
= &Private
->StorageSecurityPpi
;
285 PeiServicesInstallPpi (&Private
->StorageSecurityPpiList
);
289 &Private
->EndOfPeiNotifyList
,
290 &mAhciEndOfPeiNotifyListTemplate
,
291 sizeof (EFI_PEI_NOTIFY_DESCRIPTOR
)
293 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
296 DEBUG_INFO
, "%a: Controller %d has been successfully initialized.\n",
297 __FUNCTION__
, Controller