]>
Commit | Line | Data |
---|---|---|
6c496642 WX |
1 | /** @file\r |
2 | Provides FMP capsule dependency check services when updating the firmware\r | |
3 | image of a FMP device.\r | |
4 | \r | |
e4e27351 | 5 | Copyright (c) Microsoft Corporation.<BR>\r |
6c496642 WX |
6 | Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r |
7 | \r | |
8 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
9 | \r | |
10 | **/\r | |
11 | #include <PiDxe.h>\r | |
12 | #include <Library/BaseLib.h>\r | |
13 | #include <Library/BaseMemoryLib.h>\r | |
14 | #include <Library/DebugLib.h>\r | |
15 | #include <Library/FmpDependencyLib.h>\r | |
16 | #include <Library/FmpDependencyCheckLib.h>\r | |
17 | #include <Library/MemoryAllocationLib.h>\r | |
18 | #include <Library/UefiLib.h>\r | |
19 | #include <Library/UefiBootServicesTableLib.h>\r | |
207414cb MK |
20 | #include <Guid/SystemResourceTable.h>\r |
21 | #include <LastAttemptStatus.h>\r | |
22 | #include <FmpLastAttemptStatus.h>\r | |
6c496642 WX |
23 | \r |
24 | /**\r | |
25 | Check dependency for firmware update.\r | |
26 | \r | |
27 | @param[in] ImageTypeId Image Type Id.\r | |
28 | @param[in] Version New version.\r | |
29 | @param[in] Dependencies Fmp dependency.\r | |
30 | @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.\r | |
207414cb MK |
31 | @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the\r |
32 | last attempt status to report back to the caller.\r | |
33 | This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS\r | |
34 | if an error code is not set.\r | |
6c496642 WX |
35 | \r |
36 | @retval TRUE Dependencies are satisfied.\r | |
37 | @retval FALSE Dependencies are unsatisfied or dependency check fails.\r | |
38 | \r | |
39 | **/\r | |
40 | BOOLEAN\r | |
41 | EFIAPI\r | |
42 | CheckFmpDependency (\r | |
43 | IN EFI_GUID ImageTypeId,\r | |
44 | IN UINT32 Version,\r | |
9c721071 | 45 | IN EFI_FIRMWARE_IMAGE_DEP *Dependencies OPTIONAL,\r |
207414cb MK |
46 | IN UINT32 DependenciesSize,\r |
47 | OUT UINT32 *LastAttemptStatus OPTIONAL\r | |
6c496642 WX |
48 | )\r |
49 | {\r | |
50 | EFI_STATUS Status;\r | |
51 | EFI_HANDLE *HandleBuffer;\r | |
52 | UINTN Index;\r | |
53 | EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r | |
54 | UINTN ImageInfoSize;\r | |
207414cb | 55 | UINT32 LocalLastAttemptStatus;\r |
6c496642 WX |
56 | UINT32 *DescriptorVer;\r |
57 | UINT8 FmpImageInfoCount;\r | |
58 | UINTN *DescriptorSize;\r | |
59 | UINT32 PackageVersion;\r | |
60 | CHAR16 *PackageVersionName;\r | |
61 | UINTN NumberOfFmpInstance;\r | |
62 | EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf;\r | |
63 | FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions;\r | |
64 | UINTN FmpVersionsCount;\r | |
65 | BOOLEAN IsSatisfied;\r | |
66 | \r | |
45ce0a67 MK |
67 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r |
68 | FmpImageInfoBuf = NULL;\r | |
69 | DescriptorVer = NULL;\r | |
70 | DescriptorSize = NULL;\r | |
71 | NumberOfFmpInstance = 0;\r | |
72 | FmpVersions = NULL;\r | |
73 | FmpVersionsCount = 0;\r | |
74 | IsSatisfied = TRUE;\r | |
75 | PackageVersionName = NULL;\r | |
6c496642 WX |
76 | \r |
77 | //\r | |
78 | // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.\r | |
79 | //\r | |
80 | Status = gBS->LocateHandleBuffer (\r | |
45ce0a67 MK |
81 | ByProtocol,\r |
82 | &gEfiFirmwareManagementProtocolGuid,\r | |
83 | NULL,\r | |
84 | &NumberOfFmpInstance,\r | |
85 | &HandleBuffer\r | |
86 | );\r | |
6c496642 WX |
87 | if (EFI_ERROR (Status)) {\r |
88 | DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));\r | |
45ce0a67 | 89 | IsSatisfied = FALSE;\r |
207414cb | 90 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND;\r |
6c496642 WX |
91 | goto cleanup;\r |
92 | }\r | |
93 | \r | |
45ce0a67 | 94 | FmpImageInfoBuf = AllocateZeroPool (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);\r |
6c496642 | 95 | if (FmpImageInfoBuf == NULL) {\r |
45ce0a67 | 96 | IsSatisfied = FALSE;\r |
207414cb | 97 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED;\r |
6c496642 WX |
98 | goto cleanup;\r |
99 | }\r | |
100 | \r | |
45ce0a67 | 101 | DescriptorVer = AllocateZeroPool (sizeof (UINT32) * NumberOfFmpInstance);\r |
6c496642 | 102 | if (DescriptorVer == NULL ) {\r |
45ce0a67 | 103 | IsSatisfied = FALSE;\r |
207414cb | 104 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED;\r |
6c496642 WX |
105 | goto cleanup;\r |
106 | }\r | |
107 | \r | |
45ce0a67 | 108 | DescriptorSize = AllocateZeroPool (sizeof (UINTN) * NumberOfFmpInstance);\r |
6c496642 | 109 | if (DescriptorSize == NULL ) {\r |
45ce0a67 | 110 | IsSatisfied = FALSE;\r |
207414cb | 111 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED;\r |
6c496642 WX |
112 | goto cleanup;\r |
113 | }\r | |
114 | \r | |
45ce0a67 | 115 | FmpVersions = AllocateZeroPool (sizeof (FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);\r |
6c496642 | 116 | if (FmpVersions == NULL) {\r |
45ce0a67 | 117 | IsSatisfied = FALSE;\r |
207414cb | 118 | LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED;\r |
6c496642 WX |
119 | goto cleanup;\r |
120 | }\r | |
121 | \r | |
45ce0a67 | 122 | for (Index = 0; Index < NumberOfFmpInstance; Index++) {\r |
6c496642 WX |
123 | Status = gBS->HandleProtocol (\r |
124 | HandleBuffer[Index],\r | |
125 | &gEfiFirmwareManagementProtocolGuid,\r | |
45ce0a67 | 126 | (VOID **)&Fmp\r |
6c496642 | 127 | );\r |
45ce0a67 | 128 | if (EFI_ERROR (Status)) {\r |
6c496642 WX |
129 | continue;\r |
130 | }\r | |
131 | \r | |
132 | ImageInfoSize = 0;\r | |
45ce0a67 MK |
133 | Status = Fmp->GetImageInfo (\r |
134 | Fmp,\r | |
135 | &ImageInfoSize,\r | |
136 | NULL,\r | |
137 | NULL,\r | |
138 | NULL,\r | |
139 | NULL,\r | |
140 | NULL,\r | |
141 | NULL\r | |
142 | );\r | |
6c496642 WX |
143 | if (Status != EFI_BUFFER_TOO_SMALL) {\r |
144 | continue;\r | |
145 | }\r | |
146 | \r | |
147 | FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);\r | |
148 | if (FmpImageInfoBuf[Index] == NULL) {\r | |
149 | continue;\r | |
150 | }\r | |
151 | \r | |
152 | Status = Fmp->GetImageInfo (\r | |
153 | Fmp,\r | |
154 | &ImageInfoSize, // ImageInfoSize\r | |
155 | FmpImageInfoBuf[Index], // ImageInfo\r | |
156 | &DescriptorVer[Index], // DescriptorVersion\r | |
157 | &FmpImageInfoCount, // DescriptorCount\r | |
158 | &DescriptorSize[Index], // DescriptorSize\r | |
159 | &PackageVersion, // PackageVersion\r | |
160 | &PackageVersionName // PackageVersionName\r | |
161 | );\r | |
45ce0a67 | 162 | if (EFI_ERROR (Status)) {\r |
6c496642 WX |
163 | FreePool (FmpImageInfoBuf[Index]);\r |
164 | FmpImageInfoBuf[Index] = NULL;\r | |
165 | continue;\r | |
166 | }\r | |
167 | \r | |
168 | if (PackageVersionName != NULL) {\r | |
169 | FreePool (PackageVersionName);\r | |
170 | PackageVersionName = NULL;\r | |
171 | }\r | |
172 | \r | |
173 | CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId);\r | |
174 | FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version;\r | |
45ce0a67 | 175 | FmpVersionsCount++;\r |
6c496642 WX |
176 | }\r |
177 | \r | |
178 | //\r | |
179 | // Evaluate firmware image's depex, against the version of other Fmp instances.\r | |
180 | //\r | |
181 | if (Dependencies != NULL) {\r | |
207414cb | 182 | IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount, &LocalLastAttemptStatus);\r |
6c496642 WX |
183 | }\r |
184 | \r | |
185 | if (!IsSatisfied) {\r | |
186 | DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId));\r | |
187 | goto cleanup;\r | |
188 | }\r | |
189 | \r | |
190 | cleanup:\r | |
191 | if (FmpImageInfoBuf != NULL) {\r | |
45ce0a67 | 192 | for (Index = 0; Index < NumberOfFmpInstance; Index++) {\r |
6c496642 WX |
193 | if (FmpImageInfoBuf[Index] != NULL) {\r |
194 | FreePool (FmpImageInfoBuf[Index]);\r | |
195 | }\r | |
196 | }\r | |
45ce0a67 | 197 | \r |
6c496642 WX |
198 | FreePool (FmpImageInfoBuf);\r |
199 | }\r | |
200 | \r | |
201 | if (DescriptorVer != NULL) {\r | |
202 | FreePool (DescriptorVer);\r | |
203 | }\r | |
204 | \r | |
205 | if (DescriptorSize != NULL) {\r | |
206 | FreePool (DescriptorSize);\r | |
207 | }\r | |
208 | \r | |
209 | if (FmpVersions != NULL) {\r | |
210 | FreePool (FmpVersions);\r | |
211 | }\r | |
212 | \r | |
207414cb MK |
213 | if (LastAttemptStatus != NULL) {\r |
214 | *LastAttemptStatus = LocalLastAttemptStatus;\r | |
215 | }\r | |
216 | \r | |
6c496642 WX |
217 | return IsSatisfied;\r |
218 | }\r |