]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Capsule/RuntimeDxe/CapsuleService.c
1. Remove #ifdef _MSC_EXTENSION_ from all source files
[mirror_edk2.git] / EdkModulePkg / Universal / Capsule / RuntimeDxe / CapsuleService.c
CommitLineData
045f4521 1/*++\r
2\r
e5f461a8 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
045f4521 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
24\r
25STATIC EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;\r
26\r
27\r
28EFI_STATUS\r
29EFIAPI\r
30UpdateCapsule (\r
31 IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
32 IN UINTN CapsuleCount,\r
33 IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL\r
34 )\r
35/*++\r
36\r
37Routine Description:\r
38\r
39 This code finds whether the capsules need reset to update, if not, update immediately.\r
40\r
41Arguments:\r
42\r
43 CapsuleHeaderArray A array of pointers to capsule headers passed in\r
44 CapsuleCount The number of capsule\r
45 ScatterGatherList Physical address of datablock list points to capsule\r
e5f461a8 46\r
045f4521 47Returns:\r
48\r
49 EFI STATUS\r
50 EFI_SUCCESS Valid capsule was passed.If CAPSULE_FLAG_PERSIT_ACROSS_RESET is\r
51 not set, the capsule has been successfully processed by the firmware.\r
52 If it set, the ScattlerGatherList is successfully to be set.\r
53 EFI_INVALID_PARAMETER CapsuleCount is less than 1,CapsuleGuid is not supported.\r
e5f461a8 54 EFI_DEVICE_ERROR Failed to SetVariable or AllocatePool or ProcessFirmwareVolume.\r
55\r
045f4521 56--*/\r
57{\r
58 UINTN CapsuleSize;\r
59 UINTN ArrayNumber;\r
60 VOID *BufferPtr;\r
61 EFI_STATUS Status;\r
62 EFI_HANDLE FvHandle;\r
63 UEFI_CAPSULE_HEADER *CapsuleHeader;\r
64\r
65 if (CapsuleCount < 1) {\r
66 return EFI_INVALID_PARAMETER;\r
67 }\r
68\r
69 BufferPtr = NULL;\r
70 CapsuleHeader = NULL;\r
71\r
72 //\r
73 //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
74 //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.\r
75 //\r
76 for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
77 CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
d73196f3 78 if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
e5f461a8 79 return EFI_INVALID_PARAMETER;\r
045f4521 80 }\r
81 if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &mEfiCapsuleHeaderGuid)) {\r
d73196f3 82 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
045f4521 83 return EFI_UNSUPPORTED;\r
e5f461a8 84 }\r
85 }\r
045f4521 86 }\r
87\r
88 //\r
e5f461a8 89 //Assume that capsules have the same flags on reseting or not.\r
045f4521 90 //\r
91 CapsuleHeader = CapsuleHeaderArray[0];\r
92\r
93 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
94 //\r
95 //Check if the platform supports update capsule across a system reset\r
96 //\r
97 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest)) {\r
98 return EFI_UNSUPPORTED;\r
99 }\r
e5f461a8 100\r
045f4521 101 if (ScatterGatherList == 0) {\r
102 return EFI_INVALID_PARAMETER;\r
103 } else {\r
104 Status = EfiSetVariable (\r
e5f461a8 105 EFI_CAPSULE_VARIABLE_NAME,\r
106 &gEfiCapsuleVendorGuid,\r
107 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
108 sizeof (UINTN),\r
109 (VOID *) &ScatterGatherList\r
045f4521 110 );\r
e5f461a8 111 if (Status != EFI_SUCCESS) {\r
045f4521 112 return EFI_DEVICE_ERROR;\r
113 }\r
114 }\r
115 return EFI_SUCCESS;\r
116 }\r
e5f461a8 117\r
045f4521 118 //\r
119 //The rest occurs in the condition of non-reset mode\r
120 //\r
e5f461a8 121 if (EfiAtRuntime ()) {\r
045f4521 122 return EFI_INVALID_PARAMETER;\r
123 }\r
124\r
125 //\r
126 //Here should be in the boot-time\r
127 //\r
128 for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {\r
129 CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
130 CapsuleSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
e5f461a8 131\r
132 BufferPtr = AllocatePool (CapsuleSize);\r
133 if (BufferPtr == NULL) {\r
134 return EFI_DEVICE_ERROR;\r
045f4521 135 }\r
e5f461a8 136\r
137 CopyMem (BufferPtr, (UINT8*)CapsuleHeader+ CapsuleHeader->HeaderSize, CapsuleSize);\r
045f4521 138\r
139 //\r
e5f461a8 140 //Call DXE service ProcessFirmwareVolume to process immediatelly\r
045f4521 141 //\r
142 Status = gDS->ProcessFirmwareVolume (BufferPtr, CapsuleSize, &FvHandle);\r
143 if (Status != EFI_SUCCESS) {\r
e5f461a8 144 FreePool (BufferPtr);\r
045f4521 145 return EFI_DEVICE_ERROR;\r
146 }\r
147 gDS->Dispatch ();\r
e5f461a8 148 FreePool (BufferPtr);\r
045f4521 149 }\r
045f4521 150\r
e5f461a8 151 return EFI_SUCCESS;\r
045f4521 152}\r
153\r
154\r
e5f461a8 155\r
045f4521 156EFI_STATUS\r
157EFIAPI\r
158QueryCapsuleCapabilities (\r
159 IN UEFI_CAPSULE_HEADER **CapsuleHeaderArray,\r
160 IN UINTN CapsuleCount,\r
161 OUT UINT64 *MaxiumCapsuleSize,\r
162 OUT EFI_RESET_TYPE *ResetType\r
163 )\r
164/*++\r
165\r
166Routine Description:\r
167\r
168 This code is to query about capsule capability.\r
169\r
170Arguments:\r
171\r
172 CapsuleHeaderArray A array of pointers to capsule headers passed in\r
173 CapsuleCount The number of capsule\r
174 MaxiumCapsuleSize Max capsule size is supported\r
175 ResetType Reset type the capsule indicates, if reset is not needed,return EfiResetCold.\r
176 If reset is needed, return EfiResetWarm.\r
177\r
178Returns:\r
179\r
180 EFI STATUS\r
181 EFI_SUCCESS Valid answer returned\r
182 EFI_INVALID_PARAMETER MaxiumCapsuleSize is NULL,ResetType is NULL.CapsuleCount is less than 1,CapsuleGuid is not supported.\r
183 EFI_UNSUPPORTED The capsule type is not supported.\r
184\r
185--*/\r
186{\r
187 UINTN ArrayNumber;\r
188 UEFI_CAPSULE_HEADER *CapsuleHeader;\r
189\r
190 if (CapsuleCount < 1) {\r
191 return EFI_INVALID_PARAMETER;\r
192 }\r
193\r
194 if ((MaxiumCapsuleSize == NULL) ||(ResetType == NULL)) {\r
195 return EFI_INVALID_PARAMETER;\r
e5f461a8 196 }\r
045f4521 197\r
198 CapsuleHeader = NULL;\r
e5f461a8 199\r
045f4521 200 //\r
201 //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
202 //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.\r
203 //\r
204 for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
205 CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
d73196f3 206 if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
e5f461a8 207 return EFI_INVALID_PARAMETER;\r
045f4521 208 }\r
209 if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &mEfiCapsuleHeaderGuid)) {\r
d73196f3 210 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
045f4521 211 return EFI_UNSUPPORTED;\r
212 }\r
e5f461a8 213 }\r
045f4521 214 }\r
215\r
216 //\r
e5f461a8 217 //Assume that capsules have the same flags on reseting or not.\r
045f4521 218 //\r
e5f461a8 219 CapsuleHeader = CapsuleHeaderArray[0];\r
045f4521 220 if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
221 //\r
222 //Check if the platform supports update capsule across a system reset\r
223 //\r
224 if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest)) {\r
225 return EFI_UNSUPPORTED;\r
226 }\r
227 *ResetType = EfiResetWarm;\r
e5f461a8 228 *MaxiumCapsuleSize = FixedPcdGet32(PcdMaxSizePopulateCapsule);\r
045f4521 229 } else {\r
230 *ResetType = EfiResetCold;\r
231 *MaxiumCapsuleSize = FixedPcdGet32(PcdMaxSizeNonPopulateCapsule);\r
e5f461a8 232 }\r
045f4521 233 return EFI_SUCCESS;\r
e5f461a8 234}\r
045f4521 235\r