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.
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
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.
17 #include "HiiDatabase.h"
19 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE ConfigAccessProtocolInstanceTempate
= {
20 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_SIGNATURE
,
25 }, //ConfigAccessProtocol
26 NULL
, //FrameworkFormCallbackProtocol
27 {NULL
, NULL
} //ConfigAccessStorageListHead
30 EFI_HII_PACKAGE_HEADER
*
32 IN CONST EFI_HII_PACKAGES
*Packages
35 TIANO_AUTOGEN_PACKAGES_HEADER
**TianoAutogenPackageHdrArray
;
36 EFI_HII_PACKAGE_HEADER
*IfrPackage
;
39 ASSERT (Packages
!= NULL
);
43 TianoAutogenPackageHdrArray
= (TIANO_AUTOGEN_PACKAGES_HEADER
**) (((UINT8
*) &Packages
->GuidId
) + sizeof (Packages
->GuidId
));
44 for (Index
= 0; Index
< Packages
->NumberOfPackages
; Index
++) {
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
52 switch (TianoAutogenPackageHdrArray
[Index
]->PackageHeader
.Type
) {
53 case EFI_HII_PACKAGE_FORM
:
54 return &TianoAutogenPackageHdrArray
[Index
]->PackageHeader
;
57 case EFI_HII_PACKAGE_STRINGS
:
58 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
62 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.
64 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
65 case EFI_HII_PACKAGE_FONTS
:
66 case EFI_HII_PACKAGE_IMAGES
:
73 return (EFI_HII_PACKAGE_HEADER
*) NULL
;
78 IN CONST EFI_HII_PACKAGE_HEADER
*FormSetPackage
,
79 OUT LIST_ENTRY
*BufferStorageListHead
86 EFI_IFR_VARSTORE
*VarStoreOpCode
;
87 HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
;
89 OpCodeOffset
= sizeof (EFI_HII_PACKAGE_HEADER
);
90 while (OpCodeOffset
< FormSetPackage
->Length
) {
91 OpCodeData
= (UINT8
*) FormSetPackage
+ OpCodeOffset
;
93 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
94 OpCodeOffset
+= OpCodeLength
;
95 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
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
;
103 CopyMem (&BufferStorageKey
->Guid
, &VarStoreOpCode
->Guid
, sizeof (EFI_GUID
));
105 BufferStorageKey
->Name
= AllocateZeroPool (AsciiStrSize (VarStoreOpCode
->Name
) * 2);
106 AsciiStrToUnicodeStr (VarStoreOpCode
->Name
, BufferStorageKey
->Name
);
108 BufferStorageKey
->VarStoreId
= VarStoreOpCode
->VarStoreId
;
110 BufferStorageKey
->Size
= VarStoreOpCode
->Size
;
111 BufferStorageKey
->Signature
= HII_TRHUNK_BUFFER_STORAGE_KEY_SIGNATURE
;
113 InsertTailList (BufferStorageListHead
, &BufferStorageKey
->List
);
121 InstallDefaultUefiConfigAccessProtocol (
122 IN CONST EFI_HII_PACKAGES
*Packages
,
123 OUT EFI_HANDLE
*Handle
,
124 IN OUT HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*MapEntry
127 EFI_HII_PACKAGE_HEADER
*FormSetPackage
;
129 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE
*ConfigAccessInstance
;
131 Status
= HiiLibCreateHiiDriverHandle (Handle
);
132 ConfigAccessInstance
= AllocateCopyPool (
133 sizeof (HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE
),
134 &ConfigAccessProtocolInstanceTempate
136 InitializeListHead (&ConfigAccessInstance
->ConfigAccessBufferStorageListHead
);
139 // We assume there is only one formset package in each Forms Package
141 FormSetPackage
= GetIfrFormSet (Packages
);
142 Status
= GetBufferStorage (FormSetPackage
, &ConfigAccessInstance
->ConfigAccessBufferStorageListHead
);
143 if (EFI_ERROR (Status
)) {
144 FreePool (ConfigAccessInstance
);
149 Status
= gBS
->InstallMultipleProtocolInterfaces (
151 &gEfiHiiConfigAccessProtocolGuid
,
152 &ConfigAccessInstance
->ConfigAccessProtocol
,
155 ASSERT_EFI_ERROR (Status
);
156 if (EFI_ERROR (Status
)) {
157 FreePool (ConfigAccessInstance
);
165 RouteConfigToFrameworkFormCallBack (
166 IN HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
,
167 IN EFI_FORM_CALLBACK_PROTOCOL
*FrameworkFormCallBack
,
173 BOOLEAN ResetRequired
;
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
,
188 ExtractConfigFromFrameworkFormCallBack (
189 IN HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
,
190 IN EFI_FORM_CALLBACK_PROTOCOL
*FrameworkFormCallBack
,
200 Status
= FrameworkFormCallBack
->NvRead (
201 FrameworkFormCallBack
,
202 BufferStorageKey
->Name
,
203 &BufferStorageKey
->Guid
,
208 if (Status
== EFI_BUFFER_TOO_SMALL
) {
209 if (BufferStorageKey
->Size
!= *DataSize
) {
211 return EFI_INVALID_PARAMETER
;
214 *Data
= AllocateZeroPool (*DataSize
);
216 return EFI_OUT_OF_RESOURCES
;
219 FrameworkFormCallBack
->NvRead (
220 FrameworkFormCallBack
,
221 BufferStorageKey
->Name
,
222 &BufferStorageKey
->Guid
,
233 RouteConfigToUefiVariable (
234 IN HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
,
239 return gRT
->SetVariable (
240 BufferStorageKey
->Name
,
241 &BufferStorageKey
->Guid
,
242 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
249 ExtractConfigFromUefiVariable (
250 IN HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
,
259 Status
= gRT
->GetVariable (
260 BufferStorageKey
->Name
,
261 &BufferStorageKey
->Guid
,
266 if (Status
== EFI_BUFFER_TOO_SMALL
) {
268 if (BufferStorageKey
->Size
!= *DataSize
) {
270 return EFI_INVALID_PARAMETER
;
273 *Data
= AllocateZeroPool (*DataSize
);
275 return EFI_OUT_OF_RESOURCES
;
278 Status
= gRT
->GetVariable (
279 BufferStorageKey
->Name
,
280 &BufferStorageKey
->Guid
,
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
301 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE
*ConfigaAccessInstance
;
302 LIST_ENTRY
*ListEntry
;
303 HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
;
308 ConfigaAccessInstance
= HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This
);
310 ListEntry
= GetFirstNode (&ConfigaAccessInstance
->ConfigAccessBufferStorageListHead
);
311 if (ListEntry
== NULL
) {
313 return EFI_INVALID_PARAMETER
;
316 BufferStorageKey
= HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry
);
318 if (ConfigaAccessInstance
->FrameworkFormCallbackProtocol
== NULL
||
319 ConfigaAccessInstance
->FrameworkFormCallbackProtocol
->NvRead
== NULL
) {
320 Status
= ExtractConfigFromUefiVariable (
326 Status
= ExtractConfigFromFrameworkFormCallBack (
328 ConfigaAccessInstance
->FrameworkFormCallbackProtocol
,
334 if (!EFI_ERROR (Status
)) {
335 Status
= mHiiConfigRoutingProtocol
->BlockToConfig (
336 mHiiConfigRoutingProtocol
,
353 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
354 IN CONST EFI_STRING Configuration
,
355 OUT EFI_STRING
*Progress
359 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE
*ConfigaAccessInstance
;
360 LIST_ENTRY
*ListEntry
;
361 HII_TRHUNK_BUFFER_STORAGE_KEY
*BufferStorageKey
;
364 UINTN LastModifiedByteIndex
;
367 ConfigaAccessInstance
= HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This
);
369 ListEntry
= GetFirstNode (&ConfigaAccessInstance
->ConfigAccessBufferStorageListHead
);
370 if (ListEntry
== NULL
) {
372 return EFI_INVALID_PARAMETER
;
375 BufferStorageKey
= HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry
);
377 Data
= AllocateZeroPool (BufferStorageKey
->Size
);
379 return EFI_OUT_OF_RESOURCES
;
381 Status
= mHiiConfigRoutingProtocol
->ConfigToBlock (
382 mHiiConfigRoutingProtocol
,
385 &LastModifiedByteIndex
,
389 if (EFI_ERROR (Status
)) {
393 DataSize
= BufferStorageKey
->Size
;
394 if (ConfigaAccessInstance
->FrameworkFormCallbackProtocol
== NULL
||
395 ConfigaAccessInstance
->FrameworkFormCallbackProtocol
->NvRead
== NULL
) {
396 Status
= RouteConfigToUefiVariable (
402 Status
= RouteConfigToFrameworkFormCallBack (
404 ConfigaAccessInstance
->FrameworkFormCallbackProtocol
,
418 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
419 IN EFI_BROWSER_ACTION Action
,
420 IN EFI_QUESTION_ID QuestionId
,
422 IN EFI_IFR_TYPE_VALUE
*Value
,
423 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
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
;
434 ASSERT (This
!= NULL
);
435 ASSERT (Value
!= NULL
);
436 ASSERT (ActionRequest
!= NULL
);
438 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
440 ConfigaAccessInstance
= HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This
);
442 FrameworkFormCallbackProtocol
= ConfigaAccessInstance
->FrameworkFormCallbackProtocol
;
443 if (FrameworkFormCallbackProtocol
== NULL
) {
444 return EFI_UNSUPPORTED
;
446 Callback
= FrameworkFormCallbackProtocol
->Callback
;
449 FrameworkFormCallbackProtocol
,
456 // Callback require browser to perform action
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
) {
463 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
466 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
469 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
472 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;