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

Join discuss@edk2.groups.io to automatically receive all group messages.