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