]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c
Add ASL_FLAGS template for user reference.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / ConfigAccess.c
CommitLineData
ebbd2793 1/**@file\r
2 This file contains functions related to Config Access Protocols installed by\r
3 by HII Thunk Modules which is used to thunk UEFI Config Access Callback to \r
4 Framework HII Callback.\r
5 \r
6Copyright (c) 2008, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "HiiDatabase.h"\r
18\r
19HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE ConfigAccessProtocolInstanceTempate = {\r
20 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_SIGNATURE,\r
21 {\r
22 ThunkExtractConfig,\r
23 ThunkRouteConfig,\r
24 ThunkCallback\r
25 }, //ConfigAccessProtocol\r
26 NULL, //FrameworkFormCallbackProtocol\r
27 {NULL, NULL} //ConfigAccessStorageListHead\r
28};\r
29\r
30EFI_HII_PACKAGE_HEADER *\r
31GetIfrFormSet (\r
32 IN CONST EFI_HII_PACKAGES *Packages\r
33 )\r
34{\r
35 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
36 EFI_HII_PACKAGE_HEADER *IfrPackage;\r
37 UINTN Index;\r
38\r
39 ASSERT (Packages != NULL);\r
40\r
41 IfrPackage = NULL;\r
42\r
43 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
44 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
45 //\r
46 // BugBug: The current UEFI HII build tool generate a binary in the format defined in: \r
47 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
48 // this binary is with same package type. So the returned IfrPackNum and StringPackNum\r
49 // may not be the exact number of valid package number in the binary generated \r
50 // by HII Build tool.\r
51 //\r
52 switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
53 case EFI_HII_PACKAGE_FORM:\r
54 return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
55 break;\r
56\r
57 case EFI_HII_PACKAGE_STRINGS:\r
58 case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
59 break;\r
60\r
61 //\r
62 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
63 //\r
64 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
65 case EFI_HII_PACKAGE_FONTS:\r
66 case EFI_HII_PACKAGE_IMAGES:\r
67 default:\r
68 ASSERT (FALSE);\r
69 break;\r
70 }\r
71 }\r
72\r
73 return (EFI_HII_PACKAGE_HEADER *) NULL;\r
74}\r
75\r
76EFI_STATUS\r
77GetBufferStorage (\r
78 IN CONST EFI_HII_PACKAGE_HEADER *FormSetPackage,\r
79 OUT LIST_ENTRY *BufferStorageListHead\r
80 )\r
81{\r
82 UINTN OpCodeOffset;\r
83 UINTN OpCodeLength;\r
84 UINT8 *OpCodeData;\r
85 UINT8 Operand;\r
86 EFI_IFR_VARSTORE *VarStoreOpCode;\r
87 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
88\r
89 OpCodeOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
90 while (OpCodeOffset < FormSetPackage->Length) {\r
91 OpCodeData = (UINT8 *) FormSetPackage + OpCodeOffset;\r
92\r
93 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
94 OpCodeOffset += OpCodeLength;\r
95 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
96\r
97 if (Operand == EFI_IFR_VARSTORE_OP) {\r
98 VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData;\r
99 BufferStorageKey = AllocateZeroPool (sizeof (*BufferStorageKey));\r
100 if (BufferStorageKey == NULL) {\r
101 return EFI_OUT_OF_RESOURCES;\r
102 }\r
0915f6dc 103 CopyMem (&BufferStorageKey->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));\r
104 \r
ebbd2793 105 BufferStorageKey->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);\r
106 AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorageKey->Name);\r
107\r
108 BufferStorageKey->VarStoreId = VarStoreOpCode->VarStoreId;\r
109\r
110 BufferStorageKey->Size = VarStoreOpCode->Size;\r
111 BufferStorageKey->Signature = HII_TRHUNK_BUFFER_STORAGE_KEY_SIGNATURE;\r
112\r
113 InsertTailList (BufferStorageListHead, &BufferStorageKey->List);\r
114 }\r
115 }\r
116 return EFI_SUCCESS;\r
117}\r
118 \r
119\r
120EFI_STATUS\r
121InstallDefaultUefiConfigAccessProtocol (\r
122 IN CONST EFI_HII_PACKAGES *Packages,\r
ebbd2793 123 IN OUT HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry\r
124 )\r
125{\r
126 EFI_HII_PACKAGE_HEADER *FormSetPackage;\r
127 EFI_STATUS Status;\r
128 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessInstance;\r
129\r
63dd6a96 130 Status = HiiLibCreateHiiDriverHandle (&MapEntry->UefiHiiDriverHandle);\r
ebbd2793 131 ConfigAccessInstance = AllocateCopyPool (\r
132 sizeof (HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE), \r
133 &ConfigAccessProtocolInstanceTempate\r
134 );\r
135 InitializeListHead (&ConfigAccessInstance->ConfigAccessBufferStorageListHead);\r
136\r
137 //\r
138 // We assume there is only one formset package in each Forms Package\r
139 //\r
140 FormSetPackage = GetIfrFormSet (Packages);\r
141 Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->ConfigAccessBufferStorageListHead);\r
142 if (EFI_ERROR (Status)) {\r
143 FreePool (ConfigAccessInstance);\r
144 ASSERT (FALSE);\r
145 return Status;\r
146 }\r
147\r
148 Status = gBS->InstallMultipleProtocolInterfaces (\r
63dd6a96 149 &MapEntry->UefiHiiDriverHandle,\r
ebbd2793 150 &gEfiHiiConfigAccessProtocolGuid,\r
151 &ConfigAccessInstance->ConfigAccessProtocol,\r
152 NULL\r
153 );\r
154 ASSERT_EFI_ERROR (Status);\r
155 if (EFI_ERROR (Status)) {\r
156 FreePool (ConfigAccessInstance);\r
157 return Status;\r
158 }\r
159 \r
160 return EFI_SUCCESS;\r
161}\r
162\r
163EFI_STATUS\r
164RouteConfigToFrameworkFormCallBack (\r
165 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
166 IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,\r
167 IN VOID *Data,\r
168 IN UINTN DataSize\r
169 )\r
170{\r
171 EFI_STATUS Status;\r
172 BOOLEAN ResetRequired;\r
173\r
174 Status = FrameworkFormCallBack->NvWrite (\r
175 FrameworkFormCallBack, \r
176 BufferStorageKey->Name,\r
177 &BufferStorageKey->Guid,\r
178 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
179 DataSize,\r
180 Data,\r
181 &ResetRequired\r
182 );\r
183 return Status;\r
184}\r
185\r
186EFI_STATUS\r
187ExtractConfigFromFrameworkFormCallBack (\r
188 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
189 IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,\r
190 OUT VOID **Data,\r
191 OUT UINTN *DataSize\r
192 )\r
193{\r
194 EFI_STATUS Status;\r
195\r
196 *DataSize = 0;\r
197 *Data = NULL;\r
198 \r
199 Status = FrameworkFormCallBack->NvRead (\r
200 FrameworkFormCallBack, \r
201 BufferStorageKey->Name,\r
202 &BufferStorageKey->Guid,\r
203 NULL,\r
204 DataSize,\r
205 *Data\r
206 );\r
207 if (Status == EFI_BUFFER_TOO_SMALL) {\r
208 if (BufferStorageKey->Size != *DataSize) {\r
209 ASSERT (FALSE);\r
210 return EFI_INVALID_PARAMETER;\r
211 }\r
212\r
213 *Data = AllocateZeroPool (*DataSize);\r
214 if (Data == NULL) {\r
215 return EFI_OUT_OF_RESOURCES;\r
216 }\r
217\r
218 FrameworkFormCallBack->NvRead (\r
219 FrameworkFormCallBack, \r
220 BufferStorageKey->Name,\r
221 &BufferStorageKey->Guid,\r
222 NULL,\r
223 DataSize,\r
224 *Data\r
225 );\r
226 }\r
227\r
228 return Status;\r
229}\r
230\r
231EFI_STATUS\r
232RouteConfigToUefiVariable (\r
233 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
234 IN VOID *Data,\r
235 IN UINTN DataSize\r
236 )\r
237{\r
238 return gRT->SetVariable (\r
239 BufferStorageKey->Name,\r
240 &BufferStorageKey->Guid,\r
241 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
242 DataSize,\r
243 Data\r
244 );\r
245 \r
246}\r
247EFI_STATUS\r
248ExtractConfigFromUefiVariable (\r
249 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,\r
250 OUT VOID **Data,\r
251 OUT UINTN *DataSize\r
252 )\r
253{\r
254 EFI_STATUS Status;\r
255\r
256 *DataSize = 0;\r
257 *Data = NULL;\r
258 Status = gRT->GetVariable (\r
259 BufferStorageKey->Name,\r
260 &BufferStorageKey->Guid,\r
261 NULL,\r
262 DataSize,\r
263 *Data\r
264 );\r
265 if (Status == EFI_BUFFER_TOO_SMALL) {\r
266\r
267 if (BufferStorageKey->Size != *DataSize) {\r
268 ASSERT (FALSE);\r
269 return EFI_INVALID_PARAMETER;\r
270 }\r
271\r
272 *Data = AllocateZeroPool (*DataSize);\r
273 if (Data == NULL) {\r
274 return EFI_OUT_OF_RESOURCES;\r
275 }\r
276\r
277 Status = gRT->GetVariable (\r
278 BufferStorageKey->Name,\r
279 &BufferStorageKey->Guid,\r
280 NULL,\r
281 DataSize,\r
282 *Data\r
283 );\r
284 }\r
285\r
286 return Status;\r
287}\r
288\r
289\r
290EFI_STATUS\r
291EFIAPI\r
292ThunkExtractConfig (\r
293 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
294 IN CONST EFI_STRING Request,\r
295 OUT EFI_STRING *Progress,\r
296 OUT EFI_STRING *Results\r
297 )\r
298{\r
299 EFI_STATUS Status;\r
300 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
301 LIST_ENTRY *ListEntry;\r
302 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
303 VOID *Data;\r
304 UINTN DataSize;\r
305\r
306 Data = NULL;\r
307 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
308\r
309 ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);\r
310 if (ListEntry == NULL) {\r
311 ASSERT (FALSE);\r
312 return EFI_INVALID_PARAMETER;\r
313 }\r
314 \r
315 BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);\r
316\r
317 if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||\r
318 ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {\r
319 Status = ExtractConfigFromUefiVariable (\r
320 BufferStorageKey,\r
321 &Data,\r
322 &DataSize\r
323 );\r
324 } else {\r
325 Status = ExtractConfigFromFrameworkFormCallBack (\r
326 BufferStorageKey,\r
327 ConfigaAccessInstance->FrameworkFormCallbackProtocol,\r
328 &Data,\r
329 &DataSize\r
330 );\r
331 }\r
332 \r
333 if (!EFI_ERROR (Status)) {\r
59336178 334 Status = mHiiConfigRoutingProtocol->BlockToConfig (\r
335 mHiiConfigRoutingProtocol,\r
ebbd2793 336 Request,\r
337 Data,\r
338 DataSize,\r
339 Results,\r
340 Progress\r
341 );\r
342 }\r
343\r
344 SafeFreePool (Data);\r
345 return Status;\r
346}\r
347\r
348\r
349EFI_STATUS\r
350EFIAPI\r
351ThunkRouteConfig (\r
352 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
353 IN CONST EFI_STRING Configuration,\r
354 OUT EFI_STRING *Progress\r
355 )\r
356{\r
357 EFI_STATUS Status;\r
358 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
359 LIST_ENTRY *ListEntry;\r
360 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;\r
361 VOID *Data;\r
362 UINTN DataSize;\r
363 UINTN LastModifiedByteIndex;\r
364\r
365 Data = NULL;\r
366 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
367\r
368 ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);\r
369 if (ListEntry == NULL) {\r
370 ASSERT (FALSE);\r
371 return EFI_INVALID_PARAMETER;\r
372 }\r
373\r
374 BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);\r
375\r
376 Data = AllocateZeroPool (BufferStorageKey->Size);\r
377 if (Data == NULL) {\r
378 return EFI_OUT_OF_RESOURCES;\r
379 }\r
59336178 380 Status = mHiiConfigRoutingProtocol->ConfigToBlock (\r
381 mHiiConfigRoutingProtocol,\r
ebbd2793 382 Configuration,\r
383 Data,\r
384 &LastModifiedByteIndex,\r
385 Progress\r
386 );\r
387\r
388 if (EFI_ERROR (Status)) {\r
389 goto Done;\r
390 }\r
391\r
392 DataSize = BufferStorageKey->Size;\r
393 if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||\r
394 ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {\r
395 Status = RouteConfigToUefiVariable (\r
396 BufferStorageKey,\r
397 Data,\r
398 DataSize\r
399 );\r
400 } else {\r
401 Status = RouteConfigToFrameworkFormCallBack (\r
402 BufferStorageKey,\r
403 ConfigaAccessInstance->FrameworkFormCallbackProtocol,\r
404 Data,\r
405 DataSize\r
406 );\r
407 }\r
408\r
409Done: \r
410 SafeFreePool (Data);\r
411 return Status;\r
412}\r
413\r
414EFI_STATUS\r
415EFIAPI\r
416ThunkCallback (\r
417 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
418 IN EFI_BROWSER_ACTION Action,\r
419 IN EFI_QUESTION_ID QuestionId,\r
420 IN UINT8 Type,\r
421 IN EFI_IFR_TYPE_VALUE *Value,\r
422 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
423 )\r
424{\r
425 EFI_STATUS Status;\r
426 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;\r
427 EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallbackProtocol;\r
428 EFI_HII_CALLBACK_PACKET *Packet;\r
429 FRAMEWORK_EFI_IFR_DATA_ARRAY Data;\r
430 FRAMEWORK_EFI_IFR_DATA_ENTRY *DataEntry;\r
431 EFI_FORM_CALLBACK Callback; \r
432\r
433 ASSERT (This != NULL);\r
434 ASSERT (Value != NULL);\r
435 ASSERT (ActionRequest != NULL);\r
436\r
437 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
438\r
439 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);\r
440\r
441 FrameworkFormCallbackProtocol = ConfigaAccessInstance->FrameworkFormCallbackProtocol;\r
442 if (FrameworkFormCallbackProtocol == NULL) {\r
443 return EFI_UNSUPPORTED;\r
444 }\r
445 Callback = FrameworkFormCallbackProtocol->Callback;\r
446\r
447 Status = Callback (\r
448 FrameworkFormCallbackProtocol,\r
449 QuestionId,\r
450 &Data,\r
451 &Packet\r
452 );\r
453\r
454 //\r
455 // Callback require browser to perform action\r
456 //\r
457 if (Packet != NULL) {\r
458 if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) {\r
459 DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));\r
460 switch (DataEntry->Flags) {\r
461 case EXIT_REQUIRED:\r
462 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
463 break;\r
464 case SAVE_REQUIRED:\r
465 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
466 break;\r
467 case RESET_REQUIRED:\r
468 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
469 break;\r
470 default:\r
471 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
472 break; \r
473 }\r
474 }\r
475 }\r
476 \r
477 return Status;\r
478}\r
479\r