Using UEFI runtime variables on Xavier AGX

I’m trying to set/modify some UEFI variables (specifically boot entries/ordering) at runtime after having already booted into Linux. However, this functionality isn’t working on the Xavier AGX, even though it does work on the Orin AGX (and presumably also on the Xavier NX).

I had found this document relating to the experimental version of the UEFI firmware, and it mentions that SetVariable() is not available on the Xavier AGX: https://developer.download.nvidia.com/embedded/L4T/UEFI_Readme_8.26.html
I was hoping this was just a limitation of the experimental UEFI firmware, but it looks like it’s still an issue with the Jetpack 5.0.2 GA release.

After digging into the code, it looks like FvbDxe (from edk2-nvidia/Silicon/NVIDIA/Drivers/FvbDxe) is used on the Xavier AGX, which sets RuntimeServicesSupport to PcdNoVariableRtProperties, unlike FvbNorFlashDxe which sets it to PcdVariableRtProperties. Moreover, in FvbDxe there are checks for EfiAtRuntime() which then exit with EFI_UNSUPPORTED.

I was wondering if there is something fundamental preventing the UEFI variable store from working at runtime on the Xavier AGX, or is it just an unimplemented feature? If the latter, is this on the roadmap to be fixed in the near future?

2 Likes

Our team will do the investigation and provide suggestions soon. Thanks

Has the team finished investigating?

@nathan100 I just did a very similar investigation with a similar output. One thing I tried is to install a runtime properties struct in the config table in my custom bootloader to “overrride” what’s set by the firmware, but this doesn’t seem to work, writing to efivarfs gives EINVAL (which, looking at efi_status_to_err, is probably that EFI_UNSUPPORTED).

One thing that confuses me is that the variables definitely live on the partition named uefi_varaibles (if I rename that partition, I brick the system), but the only references to this partition name is in FvbNorFlashDxe, so doesn’t it kind of have to be running that firmware image?

Or mabye it runs both of them somehow? I’m unclear on how these firmware binaries are loaded anyways.

Just as an experiment, I tried removing those EfiAtRuntime checks, which results in kernel panics, so not just a trivial omission :)