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