]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AhciPei / AhciPei.c
1 /** @file
2 The AhciPei driver is used to manage ATA hard disk device working under AHCI
3 mode at PEI phase.
4
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "AhciPei.h"
12
13 EFI_PEI_PPI_DESCRIPTOR mAhciAtaPassThruPpiListTemplate = {
14 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
15 &gEdkiiPeiAtaPassThruPpiGuid,
16 NULL
17 };
18
19 EFI_PEI_PPI_DESCRIPTOR mAhciBlkIoPpiListTemplate = {
20 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
21 &gEfiPeiVirtualBlockIoPpiGuid,
22 NULL
23 };
24
25 EFI_PEI_PPI_DESCRIPTOR mAhciBlkIo2PpiListTemplate = {
26 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
27 &gEfiPeiVirtualBlockIo2PpiGuid,
28 NULL
29 };
30
31 EFI_PEI_PPI_DESCRIPTOR mAhciStorageSecurityPpiListTemplate = {
32 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
33 &gEdkiiPeiStorageSecurityCommandPpiGuid,
34 NULL
35 };
36
37 EFI_PEI_NOTIFY_DESCRIPTOR mAhciEndOfPeiNotifyListTemplate = {
38 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
39 &gEfiEndOfPeiSignalPpiGuid,
40 AhciPeimEndOfPei
41 };
42
43 /**
44 Free the DMA resources allocated by an ATA AHCI controller.
45
46 @param[in] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA data
47 structure.
48
49 **/
50 VOID
51 AhciFreeDmaResource (
52 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private
53 )
54 {
55 EFI_AHCI_REGISTERS *AhciRegisters;
56
57 ASSERT (Private != NULL);
58
59 AhciRegisters = &Private->AhciRegisters;
60
61 if (AhciRegisters->AhciRFisMap != NULL) {
62 IoMmuFreeBuffer (
63 EFI_SIZE_TO_PAGES (AhciRegisters->MaxRFisSize),
64 AhciRegisters->AhciRFis,
65 AhciRegisters->AhciRFisMap
66 );
67 }
68
69 if (AhciRegisters->AhciCmdListMap != NULL) {
70 IoMmuFreeBuffer (
71 EFI_SIZE_TO_PAGES (AhciRegisters->MaxCmdListSize),
72 AhciRegisters->AhciCmdList,
73 AhciRegisters->AhciCmdListMap
74 );
75 }
76
77 if (AhciRegisters->AhciCmdTableMap != NULL) {
78 IoMmuFreeBuffer (
79 EFI_SIZE_TO_PAGES (AhciRegisters->MaxCmdTableSize),
80 AhciRegisters->AhciCmdTable,
81 AhciRegisters->AhciCmdTableMap
82 );
83 }
84 }
85
86 /**
87 One notified function to cleanup the allocated DMA buffers at EndOfPei.
88
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.
93
94 @retval EFI_SUCCESS The function completes successfully
95
96 **/
97 EFI_STATUS
98 EFIAPI
99 AhciPeimEndOfPei (
100 IN EFI_PEI_SERVICES **PeiServices,
101 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
102 IN VOID *Ppi
103 )
104 {
105 PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private;
106
107 Private = GET_AHCI_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor);
108 AhciFreeDmaResource (Private);
109
110 return EFI_SUCCESS;
111 }
112
113 /**
114 Entry point of the PEIM.
115
116 @param[in] FileHandle Handle of the file being invoked.
117 @param[in] PeiServices Describes the list of possible PEI Services.
118
119 @retval EFI_SUCCESS PPI successfully installed.
120
121 **/
122 EFI_STATUS
123 EFIAPI
124 AtaAhciPeimEntry (
125 IN EFI_PEI_FILE_HANDLE FileHandle,
126 IN CONST EFI_PEI_SERVICES **PeiServices
127 )
128 {
129 EFI_STATUS Status;
130 EFI_BOOT_MODE BootMode;
131 EDKII_ATA_AHCI_HOST_CONTROLLER_PPI *AhciHcPpi;
132 UINT8 Controller;
133 UINTN MmioBase;
134 UINTN DevicePathLength;
135 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
136 UINT32 PortBitMap;
137 PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private;
138 UINT8 NumberOfPorts;
139
140 DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
141
142 //
143 // Get the current boot mode.
144 //
145 Status = PeiServicesGetBootMode (&BootMode);
146 if (EFI_ERROR (Status)) {
147 DEBUG ((DEBUG_ERROR, "%a: Fail to get the current boot mode.\n", __FUNCTION__));
148 return Status;
149 }
150
151 //
152 // Locate the ATA AHCI host controller PPI.
153 //
154 Status = PeiServicesLocatePpi (
155 &gEdkiiPeiAtaAhciHostControllerPpiGuid,
156 0,
157 NULL,
158 (VOID **)&AhciHcPpi
159 );
160 if (EFI_ERROR (Status)) {
161 DEBUG ((DEBUG_ERROR, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__));
162 return EFI_UNSUPPORTED;
163 }
164
165 Controller = 0;
166 MmioBase = 0;
167 while (TRUE) {
168 Status = AhciHcPpi->GetAhciHcMmioBar (
169 AhciHcPpi,
170 Controller,
171 &MmioBase
172 );
173 //
174 // When status is error, meant no controller is found.
175 //
176 if (EFI_ERROR (Status)) {
177 break;
178 }
179
180 Status = AhciHcPpi->GetAhciHcDevicePath (
181 AhciHcPpi,
182 Controller,
183 &DevicePathLength,
184 &DevicePath
185 );
186 if (EFI_ERROR (Status)) {
187 DEBUG ((
188 DEBUG_ERROR,
189 "%a: Fail to allocate get the device path for Controller %d.\n",
190 __FUNCTION__,
191 Controller
192 ));
193 return Status;
194 }
195
196 //
197 // Check validity of the device path of the ATA AHCI controller.
198 //
199 Status = AhciIsHcDevicePathValid (DevicePath, DevicePathLength);
200 if (EFI_ERROR (Status)) {
201 DEBUG ((
202 DEBUG_ERROR,
203 "%a: The device path is invalid for Controller %d.\n",
204 __FUNCTION__,
205 Controller
206 ));
207 Controller++;
208 continue;
209 }
210
211 //
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.
216 //
217 if (BootMode == BOOT_ON_S3_RESUME) {
218 NumberOfPorts = AhciS3GetEumeratePorts (DevicePath, DevicePathLength, &PortBitMap);
219 if (NumberOfPorts == 0) {
220 //
221 // No ports need to be enumerated for this controller.
222 //
223 Controller++;
224 continue;
225 }
226 } else {
227 PortBitMap = MAX_UINT32;
228 }
229
230 //
231 // Memory allocation for controller private data.
232 //
233 Private = AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA));
234 if (Private == NULL) {
235 DEBUG ((
236 DEBUG_ERROR,
237 "%a: Fail to allocate private data for Controller %d.\n",
238 __FUNCTION__,
239 Controller
240 ));
241 return EFI_OUT_OF_RESOURCES;
242 }
243
244 //
245 // Initialize controller private data.
246 //
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);
253
254 Status = AhciModeInitialization (Private);
255 if (EFI_ERROR (Status)) {
256 DEBUG ((
257 DEBUG_ERROR,
258 "%a: Controller initialization fail for Controller %d with Status - %r.\n",
259 __FUNCTION__,
260 Controller,
261 Status
262 ));
263 Controller++;
264 continue;
265 }
266
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;
276 CopyMem (
277 &Private->AtaPassThruPpiList,
278 &mAhciAtaPassThruPpiListTemplate,
279 sizeof (EFI_PEI_PPI_DESCRIPTOR)
280 );
281 Private->AtaPassThruPpiList.Ppi = &Private->AtaPassThruPpi;
282 PeiServicesInstallPpi (&Private->AtaPassThruPpiList);
283
284 Private->BlkIoPpi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo;
285 Private->BlkIoPpi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo;
286 Private->BlkIoPpi.ReadBlocks = AhciBlockIoReadBlocks;
287 CopyMem (
288 &Private->BlkIoPpiList,
289 &mAhciBlkIoPpiListTemplate,
290 sizeof (EFI_PEI_PPI_DESCRIPTOR)
291 );
292 Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
293 PeiServicesInstallPpi (&Private->BlkIoPpiList);
294
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;
299 CopyMem (
300 &Private->BlkIo2PpiList,
301 &mAhciBlkIo2PpiListTemplate,
302 sizeof (EFI_PEI_PPI_DESCRIPTOR)
303 );
304 Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
305 PeiServicesInstallPpi (&Private->BlkIo2PpiList);
306
307 if (Private->TrustComputingDevices != 0) {
308 DEBUG ((
309 DEBUG_INFO,
310 "%a: Security Security Command PPI will be produced for Controller %d.\n",
311 __FUNCTION__,
312 Controller
313 ));
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;
319 CopyMem (
320 &Private->StorageSecurityPpiList,
321 &mAhciStorageSecurityPpiListTemplate,
322 sizeof (EFI_PEI_PPI_DESCRIPTOR)
323 );
324 Private->StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;
325 PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
326 }
327
328 CopyMem (
329 &Private->EndOfPeiNotifyList,
330 &mAhciEndOfPeiNotifyListTemplate,
331 sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
332 );
333 PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
334
335 DEBUG ((
336 DEBUG_INFO,
337 "%a: Controller %d has been successfully initialized.\n",
338 __FUNCTION__,
339 Controller
340 ));
341 Controller++;
342 }
343
344 return EFI_SUCCESS;
345 }