]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Ata/AhciPei/AhciPeiS3.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[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
9d510e61 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
87bc3f19
HW
8\r
9**/\r
10\r
11#include "AhciPei.h"\r
12\r
13#include <Guid/S3StorageDeviceInitList.h>\r
14\r
15#include <Library/LockBoxLib.h>\r
16\r
17/**\r
18 Collect the ports that need to be enumerated on a controller for S3 phase.\r
19\r
20 @param[in] HcDevicePath Device path of the controller.\r
21 @param[in] HcDevicePathLength Length of the device path specified by\r
22 HcDevicePath.\r
23 @param[out] PortBitMap Bitmap that indicates the ports that need\r
24 to be enumerated on the controller.\r
25\r
26 @retval The number of ports that need to be enumerated.\r
27\r
28**/\r
29UINT8\r
30AhciS3GetEumeratePorts (\r
31 IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath,\r
32 IN UINTN HcDevicePathLength,\r
33 OUT UINT32 *PortBitMap\r
34 )\r
35{\r
36 EFI_STATUS Status;\r
37 UINT8 DummyData;\r
38 UINTN S3InitDevicesLength;\r
39 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;\r
40 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
41 UINTN DevicePathInstLength;\r
42 BOOLEAN EntireEnd;\r
43 SATA_DEVICE_PATH *SataDeviceNode;\r
44\r
45 *PortBitMap = 0;\r
46\r
47 //\r
48 // From the LockBox, get the list of device paths for devices need to be\r
49 // initialized in S3.\r
50 //\r
51 S3InitDevices = NULL;\r
52 S3InitDevicesLength = sizeof (DummyData);\r
53 EntireEnd = FALSE;\r
54 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, &DummyData, &S3InitDevicesLength);\r
55 if (Status != EFI_BUFFER_TOO_SMALL) {\r
56 return 0;\r
57 } else {\r
58 S3InitDevices = AllocatePool (S3InitDevicesLength);\r
59 if (S3InitDevices == NULL) {\r
60 return 0;\r
61 }\r
62\r
63 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, S3InitDevices, &S3InitDevicesLength);\r
64 if (EFI_ERROR (Status)) {\r
65 return 0;\r
66 }\r
67 }\r
68\r
69 if (S3InitDevices == NULL) {\r
70 return 0;\r
71 }\r
72\r
73 //\r
74 // Only enumerate the ports that exist in the device list.\r
75 //\r
76 do {\r
77 //\r
78 // Fetch the size of current device path instance.\r
79 //\r
80 Status = GetDevicePathInstanceSize (\r
81 S3InitDevices,\r
82 &DevicePathInstLength,\r
83 &EntireEnd\r
84 );\r
85 if (EFI_ERROR (Status)) {\r
86 break;\r
87 }\r
88\r
89 DevicePathInst = S3InitDevices;\r
90 S3InitDevices = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN) S3InitDevices + DevicePathInstLength);\r
91\r
92 if (HcDevicePathLength >= DevicePathInstLength) {\r
93 continue;\r
94 }\r
95\r
96 //\r
97 // Compare the device paths to determine if the device is managed by this\r
98 // controller.\r
99 //\r
100 if (CompareMem (\r
101 DevicePathInst,\r
102 HcDevicePath,\r
103 HcDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)\r
104 ) == 0) {\r
105 //\r
106 // Get the port number.\r
107 //\r
108 while (DevicePathInst->Type != END_DEVICE_PATH_TYPE) {\r
109 if ((DevicePathInst->Type == MESSAGING_DEVICE_PATH) &&\r
110 (DevicePathInst->SubType == MSG_SATA_DP)) {\r
111 SataDeviceNode = (SATA_DEVICE_PATH *) DevicePathInst;\r
112 //\r
113 // For now, the driver only support upto AHCI_MAX_PORTS ports and\r
114 // devices directly connected to a HBA.\r
115 //\r
116 if ((SataDeviceNode->HBAPortNumber >= AHCI_MAX_PORTS) ||\r
117 (SataDeviceNode->PortMultiplierPortNumber != 0xFFFF)) {\r
118 break;\r
119 }\r
120 *PortBitMap |= (UINT32)BIT0 << SataDeviceNode->HBAPortNumber;\r
121 break;\r
122 }\r
123 DevicePathInst = NextDevicePathNode (DevicePathInst);\r
124 }\r
125 }\r
126 } while (!EntireEnd);\r
127\r
128 //\r
129 // Return the number of ports need to be enumerated on this controller.\r
130 //\r
131 return AhciGetNumberOfPortsFromMap (*PortBitMap);\r
132}\r