Date
1 - 2 of 2
Device path for the HII Form drivers
Konstantin Aladyshev
Hello!
Why form storage does not work if HII resources were published without
a DevicePath?
I'm trying to create a minimal example of a checkbox form:
```
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(FORMSET_TITLE),
help = STRING_TOKEN(FORMSET_HELP),
efivarstore UINT8,
attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
name = MyVar,
guid = FORMSET_GUID;
form
formid = 1,
title = STRING_TOKEN(FORMID1_TITLE);
checkbox
varid = MyVar,
prompt = STRING_TOKEN(CHECKBOX_PROMPT),
help = STRING_TOKEN(CHECKBOX_HELP),
endcheckbox;
endform;
endformset;
```
Initially I've tried this code:
```
EFI_STATUS Status;
EFI_GUID Guid = FORMSET_GUID;
UINTN BufferSize;
UINT8 EfiVarstore;
BufferSize = sizeof(UINT8);
Status = gRT->GetVariable(
L"HIIFormCheckboxEfiVarstore",
&Guid,
NULL,
&BufferSize,
&EfiVarstore);
if (EFI_ERROR(Status)) {
ZeroMem(&EfiVarstore, sizeof(EfiVarstore));
Status = gRT->SetVariable(
L"HIIFormCheckboxEfiVarstore",
&Guid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(EfiVarstore),
&EfiVarstore);
}
mHiiHandle = HiiAddPackages(
&gEfiCallerIdGuid,
NULL,
HIIFormCheckboxStrings,
FormBin,
NULL
);
```
With this code form successfully loads but fails to save any data.
I've tried to debug OVMF code and have found out that the RouteConfig
call fails because the DevicePath is not present in the ConfigResp
string:
https://github.com/tianocore/edk2/blob/7c0ad2c33810ead45b7919f8f8d0e282dae52e71/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c#L5486
So I've added:
```
HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
FORMSET_GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8) (END_DEVICE_PATH_LENGTH),
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
...
Status = gBS->InstallProtocolInterface (
&mDriverHandle,
&gEfiDevicePathProtocolGuid,
EFI_NATIVE_INTERFACE,
&mHiiVendorDevicePath
);
...
mHiiHandle = HiiAddPackages(
&gEfiCallerIdGuid,
mDriverHandle,
HIIFormCheckboxStrings,
FormBin,
NULL
);
```
And now the storage works successfully.
But I still don't understand, why is the DevicePath mandatory?
efivarstore has GUID and name for the UEFI variable, and their values
are present in the ConfigResp string. Why do we need something more
for the system to work?
Best regards,
Konstantin Aladyshev
Why form storage does not work if HII resources were published without
a DevicePath?
I'm trying to create a minimal example of a checkbox form:
```
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(FORMSET_TITLE),
help = STRING_TOKEN(FORMSET_HELP),
efivarstore UINT8,
attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
name = MyVar,
guid = FORMSET_GUID;
form
formid = 1,
title = STRING_TOKEN(FORMID1_TITLE);
checkbox
varid = MyVar,
prompt = STRING_TOKEN(CHECKBOX_PROMPT),
help = STRING_TOKEN(CHECKBOX_HELP),
endcheckbox;
endform;
endformset;
```
Initially I've tried this code:
```
EFI_STATUS Status;
EFI_GUID Guid = FORMSET_GUID;
UINTN BufferSize;
UINT8 EfiVarstore;
BufferSize = sizeof(UINT8);
Status = gRT->GetVariable(
L"HIIFormCheckboxEfiVarstore",
&Guid,
NULL,
&BufferSize,
&EfiVarstore);
if (EFI_ERROR(Status)) {
ZeroMem(&EfiVarstore, sizeof(EfiVarstore));
Status = gRT->SetVariable(
L"HIIFormCheckboxEfiVarstore",
&Guid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof(EfiVarstore),
&EfiVarstore);
}
mHiiHandle = HiiAddPackages(
&gEfiCallerIdGuid,
NULL,
HIIFormCheckboxStrings,
FormBin,
NULL
);
```
With this code form successfully loads but fails to save any data.
I've tried to debug OVMF code and have found out that the RouteConfig
call fails because the DevicePath is not present in the ConfigResp
string:
https://github.com/tianocore/edk2/blob/7c0ad2c33810ead45b7919f8f8d0e282dae52e71/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c#L5486
So I've added:
```
HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
FORMSET_GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8) (END_DEVICE_PATH_LENGTH),
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
...
Status = gBS->InstallProtocolInterface (
&mDriverHandle,
&gEfiDevicePathProtocolGuid,
EFI_NATIVE_INTERFACE,
&mHiiVendorDevicePath
);
...
mHiiHandle = HiiAddPackages(
&gEfiCallerIdGuid,
mDriverHandle,
HIIFormCheckboxStrings,
FormBin,
NULL
);
```
And now the storage works successfully.
But I still don't understand, why is the DevicePath mandatory?
efivarstore has GUID and name for the UEFI variable, and their values
are present in the ConfigResp string. Why do we need something more
for the system to work?
Best regards,
Konstantin Aladyshev
Tomas Pilar (tpilar)
I've tried to debug OVMF code and have found out that the RouteConfigI think this implementation guards against the possibility that you might have two similar devices that install the same third-party driver. Now the two drivers will install two HII forms with the same GUID so the RouteConfig has to distinguish between then somehow.
call fails because the DevicePath is not present in the ConfigResp
string:
https://github.com/tianocore/edk2/blob/7c0ad2c33810ead45b7919f8f8d0e282dae52e71/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c#L5486
Cheers,
Tom