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 This program and the accompanying materials
8 are licensed and made available under the terms and conditions
9 of the BSD License which accompanies this distribution. The
10 full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 EFI_PEI_PPI_DESCRIPTOR mAhciAtaPassThruPpiListTemplate
= {
21 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
22 &gEdkiiPeiAtaPassThruPpiGuid
,
26 EFI_PEI_PPI_DESCRIPTOR mAhciStorageSecurityPpiListTemplate
= {
27 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
28 &gEdkiiPeiStorageSecurityCommandPpiGuid
,
32 EFI_PEI_NOTIFY_DESCRIPTOR mAhciEndOfPeiNotifyListTemplate
= {
33 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
34 &gEfiEndOfPeiSignalPpiGuid
,
40 Free the DMA resources allocated by an ATA AHCI controller.
42 @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA data
48 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
51 EFI_AHCI_REGISTERS
*AhciRegisters
;
53 ASSERT (Private
!= NULL
);
55 AhciRegisters
= &Private
->AhciRegisters
;
57 if (AhciRegisters
->AhciRFisMap
!= NULL
) {
59 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxRFisSize
),
60 AhciRegisters
->AhciRFis
,
61 AhciRegisters
->AhciRFisMap
65 if (AhciRegisters
->AhciCmdListMap
!= NULL
) {
67 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdListSize
),
68 AhciRegisters
->AhciCmdList
,
69 AhciRegisters
->AhciCmdListMap
73 if (AhciRegisters
->AhciCmdTableMap
!= NULL
) {
75 EFI_SIZE_TO_PAGES (AhciRegisters
->MaxCmdTableSize
),
76 AhciRegisters
->AhciCmdTable
,
77 AhciRegisters
->AhciCmdTableMap
84 One notified function to cleanup the allocated DMA buffers at EndOfPei.
86 @param[in] PeiServices Pointer to PEI Services Table.
87 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
88 event that caused this function to execute.
89 @param[in] Ppi Pointer to the PPI data associated with this function.
91 @retval EFI_SUCCESS The function completes successfully
97 IN EFI_PEI_SERVICES
**PeiServices
,
98 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
102 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
104 Private
= GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
105 AhciFreeDmaResource (Private
);
111 Entry point of the PEIM.
113 @param[in] FileHandle Handle of the file being invoked.
114 @param[in] PeiServices Describes the list of possible PEI Services.
116 @retval EFI_SUCCESS PPI successfully installed.
122 IN EFI_PEI_FILE_HANDLE FileHandle
,
123 IN CONST EFI_PEI_SERVICES
**PeiServices
127 EFI_BOOT_MODE BootMode
;
128 EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
*AhciHcPpi
;
131 UINTN DevicePathLength
;
132 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
134 PEI_AHCI_CONTROLLER_PRIVATE_DATA
*Private
;
137 DEBUG ((DEBUG_INFO
, "%a: Enters.\n", __FUNCTION__
));
140 // Get the current boot mode.
142 Status
= PeiServicesGetBootMode (&BootMode
);
143 if (EFI_ERROR (Status
)) {
144 DEBUG ((DEBUG_ERROR
, "%a: Fail to get the current boot mode.\n", __FUNCTION__
));
149 // Locate the ATA AHCI host controller PPI.
151 Status
= PeiServicesLocatePpi (
152 &gEdkiiPeiAtaAhciHostControllerPpiGuid
,
157 if (EFI_ERROR (Status
)) {
158 DEBUG ((DEBUG_ERROR
, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__
));
159 return EFI_UNSUPPORTED
;
165 Status
= AhciHcPpi
->GetAhciHcMmioBar (
171 // When status is error, meant no controller is found.
173 if (EFI_ERROR (Status
)) {
177 Status
= AhciHcPpi
->GetAhciHcDevicePath (
183 if (EFI_ERROR (Status
)) {
185 DEBUG_ERROR
, "%a: Fail to allocate get the device path for Controller %d.\n",
186 __FUNCTION__
, Controller
192 // Check validity of the device path of the ATA AHCI controller.
194 Status
= AhciIsHcDevicePathValid (DevicePath
, DevicePathLength
);
195 if (EFI_ERROR (Status
)) {
197 DEBUG_ERROR
, "%a: The device path is invalid for Controller %d.\n",
198 __FUNCTION__
, Controller
205 // For S3 resume performance consideration, not all ports on an ATA AHCI
206 // controller will be enumerated/initialized. The driver consumes the
207 // content within S3StorageDeviceInitList LockBox to get the ports that
208 // will be enumerated/initialized during S3 resume.
210 if (BootMode
== BOOT_ON_S3_RESUME
) {
211 NumberOfPorts
= AhciS3GetEumeratePorts (DevicePath
, DevicePathLength
, &PortBitMap
);
212 if (NumberOfPorts
== 0) {
214 // No ports need to be enumerated for this controller.
220 PortBitMap
= MAX_UINT32
;
224 // Memory allocation for controller private data.
226 Private
= AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA
));
227 if (Private
== NULL
) {
229 DEBUG_ERROR
, "%a: Fail to allocate private data for Controller %d.\n",
230 __FUNCTION__
, Controller
232 return EFI_OUT_OF_RESOURCES
;
236 // Initialize controller private data.
238 Private
->Signature
= AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE
;
239 Private
->MmioBase
= MmioBase
;
240 Private
->DevicePathLength
= DevicePathLength
;
241 Private
->DevicePath
= DevicePath
;
242 Private
->PortBitMap
= PortBitMap
;
243 InitializeListHead (&Private
->DeviceList
);
245 Status
= AhciModeInitialization (Private
);
246 if (EFI_ERROR (Status
)) {
249 "%a: Controller initialization fail for Controller %d with Status - %r.\n",
258 Private
->AtaPassThruMode
.Attributes
= EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
|
259 EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
;
260 Private
->AtaPassThruMode
.IoAlign
= sizeof (UINTN
);
261 Private
->AtaPassThruPpi
.Revision
= EDKII_PEI_ATA_PASS_THRU_PPI_REVISION
;
262 Private
->AtaPassThruPpi
.Mode
= &Private
->AtaPassThruMode
;
263 Private
->AtaPassThruPpi
.PassThru
= AhciAtaPassThruPassThru
;
264 Private
->AtaPassThruPpi
.GetNextPort
= AhciAtaPassThruGetNextPort
;
265 Private
->AtaPassThruPpi
.GetNextDevice
= AhciAtaPassThruGetNextDevice
;
266 Private
->AtaPassThruPpi
.GetDevicePath
= AhciAtaPassThruGetDevicePath
;
268 &Private
->AtaPassThruPpiList
,
269 &mAhciAtaPassThruPpiListTemplate
,
270 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
272 Private
->AtaPassThruPpiList
.Ppi
= &Private
->AtaPassThruPpi
;
273 PeiServicesInstallPpi (&Private
->AtaPassThruPpiList
);
275 if (Private
->TrustComputingDevices
!= 0) {
278 "%a: Security Security Command PPI will be produced for Controller %d.\n",
279 __FUNCTION__
, Controller
281 Private
->StorageSecurityPpi
.Revision
= EDKII_STORAGE_SECURITY_PPI_REVISION
;
282 Private
->StorageSecurityPpi
.GetNumberofDevices
= AhciStorageSecurityGetDeviceNo
;
283 Private
->StorageSecurityPpi
.GetDevicePath
= AhciStorageSecurityGetDevicePath
;
284 Private
->StorageSecurityPpi
.ReceiveData
= AhciStorageSecurityReceiveData
;
285 Private
->StorageSecurityPpi
.SendData
= AhciStorageSecuritySendData
;
287 &Private
->StorageSecurityPpiList
,
288 &mAhciStorageSecurityPpiListTemplate
,
289 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
291 Private
->StorageSecurityPpiList
.Ppi
= &Private
->StorageSecurityPpi
;
292 PeiServicesInstallPpi (&Private
->StorageSecurityPpiList
);
296 &Private
->EndOfPeiNotifyList
,
297 &mAhciEndOfPeiNotifyListTemplate
,
298 sizeof (EFI_PEI_NOTIFY_DESCRIPTOR
)
300 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
303 DEBUG_INFO
, "%a: Controller %d has been successfully initialized.\n",
304 __FUNCTION__
, Controller