]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Ata/AhciPei/AhciPeiS3.c
MdeModulePkg/AhciPei: Add AHCI mode ATA device support in PEI
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AhciPei / AhciPeiS3.c
CommitLineData
87bc3f19
HW
1/** @file\r
2 The AhciPei driver is used to manage ATA hard disk device working under AHCI\r
3 mode at PEI phase.\r
4\r
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
6\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions\r
9 of the BSD License which accompanies this distribution. The\r
10 full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "AhciPei.h"\r
19\r
20#include <Guid/S3StorageDeviceInitList.h>\r
21\r
22#include <Library/LockBoxLib.h>\r
23\r
24/**\r
25 Collect the ports that need to be enumerated on a controller for S3 phase.\r
26\r
27 @param[in] HcDevicePath Device path of the controller.\r
28 @param[in] HcDevicePathLength Length of the device path specified by\r
29 HcDevicePath.\r
30 @param[out] PortBitMap Bitmap that indicates the ports that need\r
31 to be enumerated on the controller.\r
32\r
33 @retval The number of ports that need to be enumerated.\r
34\r
35**/\r
36UINT8\r
37AhciS3GetEumeratePorts (\r
38 IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath,\r
39 IN UINTN HcDevicePathLength,\r
40 OUT UINT32 *PortBitMap\r
41 )\r
42{\r
43 EFI_STATUS Status;\r
44 UINT8 DummyData;\r
45 UINTN S3InitDevicesLength;\r
46 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;\r
47 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
48 UINTN DevicePathInstLength;\r
49 BOOLEAN EntireEnd;\r
50 SATA_DEVICE_PATH *SataDeviceNode;\r
51\r
52 *PortBitMap = 0;\r
53\r
54 //\r
55 // From the LockBox, get the list of device paths for devices need to be\r
56 // initialized in S3.\r
57 //\r
58 S3InitDevices = NULL;\r
59 S3InitDevicesLength = sizeof (DummyData);\r
60 EntireEnd = FALSE;\r
61 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, &DummyData, &S3InitDevicesLength);\r
62 if (Status != EFI_BUFFER_TOO_SMALL) {\r
63 return 0;\r
64 } else {\r
65 S3InitDevices = AllocatePool (S3InitDevicesLength);\r
66 if (S3InitDevices == NULL) {\r
67 return 0;\r
68 }\r
69\r
70 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, S3InitDevices, &S3InitDevicesLength);\r
71 if (EFI_ERROR (Status)) {\r
72 return 0;\r
73 }\r
74 }\r
75\r
76 if (S3InitDevices == NULL) {\r
77 return 0;\r
78 }\r
79\r
80 //\r
81 // Only enumerate the ports that exist in the device list.\r
82 //\r
83 do {\r
84 //\r
85 // Fetch the size of current device path instance.\r
86 //\r
87 Status = GetDevicePathInstanceSize (\r
88 S3InitDevices,\r
89 &DevicePathInstLength,\r
90 &EntireEnd\r
91 );\r
92 if (EFI_ERROR (Status)) {\r
93 break;\r
94 }\r
95\r
96 DevicePathInst = S3InitDevices;\r
97 S3InitDevices = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN) S3InitDevices + DevicePathInstLength);\r
98\r
99 if (HcDevicePathLength >= DevicePathInstLength) {\r
100 continue;\r
101 }\r
102\r
103 //\r
104 // Compare the device paths to determine if the device is managed by this\r
105 // controller.\r
106 //\r
107 if (CompareMem (\r
108 DevicePathInst,\r
109 HcDevicePath,\r
110 HcDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)\r
111 ) == 0) {\r
112 //\r
113 // Get the port number.\r
114 //\r
115 while (DevicePathInst->Type != END_DEVICE_PATH_TYPE) {\r
116 if ((DevicePathInst->Type == MESSAGING_DEVICE_PATH) &&\r
117 (DevicePathInst->SubType == MSG_SATA_DP)) {\r
118 SataDeviceNode = (SATA_DEVICE_PATH *) DevicePathInst;\r
119 //\r
120 // For now, the driver only support upto AHCI_MAX_PORTS ports and\r
121 // devices directly connected to a HBA.\r
122 //\r
123 if ((SataDeviceNode->HBAPortNumber >= AHCI_MAX_PORTS) ||\r
124 (SataDeviceNode->PortMultiplierPortNumber != 0xFFFF)) {\r
125 break;\r
126 }\r
127 *PortBitMap |= (UINT32)BIT0 << SataDeviceNode->HBAPortNumber;\r
128 break;\r
129 }\r
130 DevicePathInst = NextDevicePathNode (DevicePathInst);\r
131 }\r
132 }\r
133 } while (!EntireEnd);\r
134\r
135 //\r
136 // Return the number of ports need to be enumerated on this controller.\r
137 //\r
138 return AhciGetNumberOfPortsFromMap (*PortBitMap);\r
139}\r