]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
Add the check- in missed file
[mirror_edk2.git] / MdeModulePkg / Universal / CapsuleRuntimeDxe / CapsuleService.c
CommitLineData
74fea867 1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 CapsuleService.c\r
15\r
16Abstract:\r
17\r
18 Capsule Runtime Service.\r
19\r
20--*/\r
21\r
22#include "CapsuleService.h"\r
23\r
24EFI_STATUS\r
25EFIAPI\r
26UpdateCapsule (\r
27 IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
28 IN UINTN CapsuleCount,\r
29 IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34\r
35 This code finds whether the capsules need reset to update, if not, update immediately.\r
36\r
37Arguments:\r
38\r
39 CapsuleHeaderArray A array of pointers to capsule headers passed in\r
40 CapsuleCount The number of capsule\r
41 ScatterGatherList Physical address of datablock list points to capsule\r
42\r
43Returns:\r
44\r
45 EFI STATUS\r
46 EFI_SUCCESS Valid capsule was passed.If CAPSULE_FLAG_PERSIT_ACROSS_RESET is\r
47 not set, the capsule has been successfully processed by the firmware.\r
48 If it set, the ScattlerGatherList is successfully to be set.\r
49 EFI_INVALID_PARAMETER CapsuleCount is less than 1,CapsuleGuid is not supported.\r
6ee65722 50 EFI_DEVICE_ERROR Failed to SetVariable or ProcessFirmwareVolume.\r
74fea867 51\r
52--*/\r
53{\r
74fea867 54 UINTN ArrayNumber;\r
74fea867 55 EFI_STATUS Status;\r
74fea867 56 EFI_CAPSULE_HEADER *CapsuleHeader;\r
57\r
58 if (CapsuleCount < 1) {\r
59 return EFI_INVALID_PARAMETER;\r
60 }\r
61\r
74fea867 62 CapsuleHeader = NULL;\r
63\r
64 for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
d12f75fe
LG
65 //\r
66 // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have\r
67 // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.\r
68 //\r
74fea867 69 CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
70 if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
71 return EFI_INVALID_PARAMETER;\r
72 }\r
d12f75fe 73 //\r
6ee65722
LG
74 // Check Capsule image without populate flag by firmware support capsule function \r
75 //\r
76 if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
77 (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
78 return EFI_UNSUPPORTED;\r
79 }\r
74fea867 80 }\r
81\r
d12f75fe 82 //\r
6ee65722 83 // Assume that capsules have the same flags on reseting or not.\r
74fea867 84 //\r
85 CapsuleHeader = CapsuleHeaderArray[0];\r
86\r
87 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
88 //\r
6ee65722 89 // Check if the platform supports update capsule across a system reset\r
74fea867 90 //\r
91 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest)) {\r
92 return EFI_UNSUPPORTED;\r
93 }\r
d12f75fe
LG
94 //\r
95 // ScatterGatherList is only referenced if the capsules are defined to persist across\r
96 // system reset. \r
97 //\r
98 if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) NULL) {\r
74fea867 99 return EFI_INVALID_PARAMETER;\r
100 } else {\r
d12f75fe
LG
101 //\r
102 // ScatterGatherList is only referenced if the capsules are defined to persist across\r
103 // system reset. Set its value into NV storage to let pre-boot driver to pick it up \r
104 // after coming through a system reset.\r
105 //\r
74fea867 106 Status = EfiSetVariable (\r
107 EFI_CAPSULE_VARIABLE_NAME,\r
108 &gEfiCapsuleVendorGuid,\r
109 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
110 sizeof (UINTN),\r
111 (VOID *) &ScatterGatherList\r
112 );\r
113 if (Status != EFI_SUCCESS) {\r
d12f75fe 114 return Status;\r
74fea867 115 }\r
6ee65722
LG
116 //\r
117 // Successfully set the capsule image address into variable.\r
118 //\r
119 return EFI_SUCCESS;\r
74fea867 120 }\r
74fea867 121 }\r
122\r
123 //\r
d12f75fe 124 // The rest occurs in the condition of non-reset mode\r
6ee65722 125 // Now Runtime mode doesn't support the non-reset capsule image.\r
74fea867 126 //\r
127 if (EfiAtRuntime ()) {\r
128 return EFI_INVALID_PARAMETER;\r
129 }\r
130\r
131 //\r
d12f75fe 132 // Here should be in the boot-time for non-reset capsule image\r
6ee65722 133 // Default process to Update Capsule image into Flash.\r
74fea867 134 //\r
135 for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {\r
6ee65722
LG
136 Status = ProcessCapsuleImage (CapsuleHeaderArray[ArrayNumber]);\r
137 if (EFI_ERROR (Status)) {\r
d12f75fe 138 return Status;\r
74fea867 139 }\r
74fea867 140 }\r
141\r
142 return EFI_SUCCESS;\r
143}\r
144\r
145\r
146\r
147EFI_STATUS\r
148EFIAPI\r
149QueryCapsuleCapabilities (\r
150 IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
151 IN UINTN CapsuleCount,\r
152 OUT UINT64 *MaxiumCapsuleSize,\r
153 OUT EFI_RESET_TYPE *ResetType\r
154 )\r
155/*++\r
156\r
157Routine Description:\r
158\r
159 This code is to query about capsule capability.\r
160\r
161Arguments:\r
162\r
163 CapsuleHeaderArray A array of pointers to capsule headers passed in\r
164 CapsuleCount The number of capsule\r
165 MaxiumCapsuleSize Max capsule size is supported\r
166 ResetType Reset type the capsule indicates, if reset is not needed,return EfiResetCold.\r
167 If reset is needed, return EfiResetWarm.\r
168\r
169Returns:\r
170\r
171 EFI STATUS\r
172 EFI_SUCCESS Valid answer returned\r
173 EFI_INVALID_PARAMETER MaxiumCapsuleSize is NULL,ResetType is NULL.CapsuleCount is less than 1,CapsuleGuid is not supported.\r
174 EFI_UNSUPPORTED The capsule type is not supported.\r
175\r
176--*/\r
177{\r
178 UINTN ArrayNumber;\r
179 EFI_CAPSULE_HEADER *CapsuleHeader;\r
180\r
181 if (CapsuleCount < 1) {\r
182 return EFI_INVALID_PARAMETER;\r
183 }\r
184\r
185 if ((MaxiumCapsuleSize == NULL) ||(ResetType == NULL)) {\r
186 return EFI_INVALID_PARAMETER;\r
187 }\r
188\r
189 CapsuleHeader = NULL;\r
190\r
191 for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
192 CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
d12f75fe
LG
193 //\r
194 // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have\r
195 // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.\r
196 //\r
74fea867 197 if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
198 return EFI_INVALID_PARAMETER;\r
199 }\r
d12f75fe 200 //\r
6ee65722
LG
201 // Check Capsule image without populate flag by firmware support capsule function \r
202 //\r
203 if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
204 (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
205 return EFI_UNSUPPORTED;\r
206 }\r
74fea867 207 }\r
208\r
209 //\r
210 //Assume that capsules have the same flags on reseting or not.\r
211 //\r
212 CapsuleHeader = CapsuleHeaderArray[0];\r
213 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
214 //\r
215 //Check if the platform supports update capsule across a system reset\r
216 //\r
217 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest)) {\r
218 return EFI_UNSUPPORTED;\r
219 }\r
220 *ResetType = EfiResetWarm;\r
221 *MaxiumCapsuleSize = FixedPcdGet32(PcdMaxSizePopulateCapsule);\r
222 } else {\r
223 *ResetType = EfiResetCold;\r
224 *MaxiumCapsuleSize = FixedPcdGet32(PcdMaxSizeNonPopulateCapsule);\r
225 }\r
226 return EFI_SUCCESS;\r
227}\r
228\r
229\r
230EFI_STATUS\r
231EFIAPI\r
232CapsuleServiceInitialize (\r
233 IN EFI_HANDLE ImageHandle,\r
234 IN EFI_SYSTEM_TABLE *SystemTable\r
235 )\r
236/*++\r
237\r
238Routine Description:\r
239\r
240 This code is capsule runtime service initialization.\r
241\r
242Arguments:\r
243\r
244 ImageHandle The image handle\r
245 SystemTable The system table.\r
246\r
247Returns:\r
248\r
249 EFI STATUS\r
250\r
251--*/\r
252{\r
253 EFI_STATUS Status;\r
254 EFI_HANDLE NewHandle;\r
255\r
256 SystemTable->RuntimeServices->UpdateCapsule = UpdateCapsule;\r
257 SystemTable->RuntimeServices->QueryCapsuleCapabilities = QueryCapsuleCapabilities;\r
258\r
259 //\r
260 // Now install the Capsule Architectural Protocol on a new handle\r
261 //\r
262 NewHandle = NULL;\r
263\r
264 Status = gBS->InstallMultipleProtocolInterfaces (\r
265 &NewHandle,\r
266 &gEfiCapsuleArchProtocolGuid,\r
267 NULL,\r
268 NULL\r
269 );\r
270 ASSERT_EFI_ERROR (Status);\r
271\r
272 return EFI_SUCCESS;\r
273}\r