2 Capsule Runtime Drivers produces two UEFI capsule runtime services.
3 (UpdateCapsule, QueryCapsuleCapabilities)
5 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "CapsuleService.h"
19 Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
20 consumption, the firmware may process the capsule immediately. If the payload should persist
21 across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
22 be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
23 part of the reset process.
25 @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
26 being passed into update capsule.
27 @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
29 @param ScatterGatherList Physical pointer to a set of
30 EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
31 location in physical memory of a set of capsules.
33 @retval EFI_SUCCESS Valid capsule was passed. If
34 CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
35 capsule has been successfully processed by the firmware.
36 @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error.
37 @retval EFI_INVALID_PARAMETER CapsuleCount is Zero, or CapsuleImage is not valid.
38 For across reset capsule image, ScatterGatherList is NULL.
39 @retval EFI_UNSUPPORTED CapsuleImage is not recognized by the firmware.
45 IN EFI_CAPSULE_HEADER
**CapsuleHeaderArray
,
46 IN UINTN CapsuleCount
,
47 IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
52 EFI_CAPSULE_HEADER
*CapsuleHeader
;
55 // Capsule Count can't be less than one.
57 if (CapsuleCount
< 1) {
58 return EFI_INVALID_PARAMETER
;
63 for (ArrayNumber
= 0; ArrayNumber
< CapsuleCount
; ArrayNumber
++) {
65 // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
66 // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
68 CapsuleHeader
= CapsuleHeaderArray
[ArrayNumber
];
69 if ((CapsuleHeader
->Flags
& (CAPSULE_FLAGS_PERSIST_ACROSS_RESET
| CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
) {
70 return EFI_INVALID_PARAMETER
;
73 // Check Capsule image without populate flag by firmware support capsule function
75 if (((CapsuleHeader
->Flags
& CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
) == 0) &&
76 (SupportCapsuleImage (CapsuleHeader
) != EFI_SUCCESS
)) {
77 return EFI_UNSUPPORTED
;
82 // Assume that capsules have the same flags on reseting or not.
84 CapsuleHeader
= CapsuleHeaderArray
[0];
87 // Process across reset capsule image.
89 if ((CapsuleHeader
->Flags
& CAPSULE_FLAGS_PERSIST_ACROSS_RESET
) != 0) {
91 // Check if the platform supports update capsule across a system reset
93 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest
)) {
94 return EFI_UNSUPPORTED
;
97 // ScatterGatherList is only referenced if the capsules are defined to persist across
100 if (ScatterGatherList
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
) {
101 return EFI_INVALID_PARAMETER
;
104 // ScatterGatherList is only referenced if the capsules are defined to persist across
105 // system reset. Set its value into NV storage to let pre-boot driver to pick it up
106 // after coming through a system reset.
108 Status
= EfiSetVariable (
109 EFI_CAPSULE_VARIABLE_NAME
,
110 &gEfiCapsuleVendorGuid
,
111 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
113 (VOID
*) &ScatterGatherList
115 if (Status
!= EFI_SUCCESS
) {
119 // Successfully set the capsule image address into EFI variable.
126 // Process the non-reset capsule image.
128 if (EfiAtRuntime ()) {
130 // Runtime mode doesn't support the non-reset capsule image.
132 return EFI_UNSUPPORTED
;
136 // Here should be in the boot-time for non-reset capsule image
137 // Platform specific update for the non-reset capsule image.
139 for (ArrayNumber
= 0; ArrayNumber
< CapsuleCount
; ArrayNumber
++) {
140 Status
= ProcessCapsuleImage (CapsuleHeaderArray
[ArrayNumber
]);
141 if (EFI_ERROR (Status
)) {
150 Returns if the capsule can be supported via UpdateCapsule().
152 @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
153 being passed into update capsule.
154 @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
156 @param MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can
157 support as an argument to UpdateCapsule() via
158 CapsuleHeaderArray and ScatterGatherList.
159 @param ResetType Returns the type of reset required for the capsule update.
161 @retval EFI_SUCCESS Valid answer returned.
162 @retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and
163 MaximumCapsuleSize and ResetType are undefined.
164 @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL, or ResetTyep is NULL,
165 Or CapsuleCount is Zero, or CapsuleImage is not valid.
170 QueryCapsuleCapabilities (
171 IN EFI_CAPSULE_HEADER
**CapsuleHeaderArray
,
172 IN UINTN CapsuleCount
,
173 OUT UINT64
*MaxiumCapsuleSize
,
174 OUT EFI_RESET_TYPE
*ResetType
178 EFI_CAPSULE_HEADER
*CapsuleHeader
;
181 // Capsule Count can't be less than one.
183 if (CapsuleCount
< 1) {
184 return EFI_INVALID_PARAMETER
;
188 // Check whether input paramter is valid
190 if ((MaxiumCapsuleSize
== NULL
) ||(ResetType
== NULL
)) {
191 return EFI_INVALID_PARAMETER
;
194 CapsuleHeader
= NULL
;
196 for (ArrayNumber
= 0; ArrayNumber
< CapsuleCount
; ArrayNumber
++) {
197 CapsuleHeader
= CapsuleHeaderArray
[ArrayNumber
];
199 // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
200 // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
202 if ((CapsuleHeader
->Flags
& (CAPSULE_FLAGS_PERSIST_ACROSS_RESET
| CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
) {
203 return EFI_INVALID_PARAMETER
;
206 // Check Capsule image without populate flag is supported by firmware
208 if (((CapsuleHeader
->Flags
& CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
) == 0) &&
209 (SupportCapsuleImage (CapsuleHeader
) != EFI_SUCCESS
)) {
210 return EFI_UNSUPPORTED
;
215 // Assume that capsules have the same flags on reseting or not.
217 CapsuleHeader
= CapsuleHeaderArray
[0];
218 if ((CapsuleHeader
->Flags
& CAPSULE_FLAGS_PERSIST_ACROSS_RESET
) != 0) {
220 //Check if the platform supports update capsule across a system reset
222 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest
)) {
223 return EFI_UNSUPPORTED
;
225 *ResetType
= EfiResetWarm
;
226 *MaxiumCapsuleSize
= FixedPcdGet32(PcdMaxSizePopulateCapsule
);
229 // For non-reset capsule image.
231 *ResetType
= EfiResetCold
;
232 *MaxiumCapsuleSize
= FixedPcdGet32(PcdMaxSizeNonPopulateCapsule
);
240 This code is to install UEFI capsule runtime service.
242 @param ImageHandle The firmware allocated handle for the EFI image.
243 @param SystemTable A pointer to the EFI System Table.
245 @retval EFI_SUCCESS UEFI Capsule Runtime Services are installed successfully.
250 CapsuleServiceInitialize (
251 IN EFI_HANDLE ImageHandle
,
252 IN EFI_SYSTEM_TABLE
*SystemTable
256 EFI_HANDLE NewHandle
;
259 // Install capsule runtime services into UEFI runtime service tables.
261 SystemTable
->RuntimeServices
->UpdateCapsule
= UpdateCapsule
;
262 SystemTable
->RuntimeServices
->QueryCapsuleCapabilities
= QueryCapsuleCapabilities
;
265 // Install the Capsule Architectural Protocol on a new handle
266 // to signify the capsule runtime services are ready.
270 Status
= gBS
->InstallMultipleProtocolInterfaces (
272 &gEfiCapsuleArchProtocolGuid
,
276 ASSERT_EFI_ERROR (Status
);