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