| /** @file | |
| Utility functions for serializing (persistently storing) and deserializing | |
| OVMF's platform configuration. | |
| Copyright (C) 2014, Red Hat, Inc. | |
| This program and the accompanying materials are licensed and made available | |
| under the terms and conditions of the BSD License which accompanies this | |
| distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT | |
| WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/MemoryAllocationLib.h> | |
| #include <Library/UefiLib.h> | |
| #include <Library/UefiRuntimeServicesTableLib.h> | |
| #include <Guid/OvmfPlatformConfig.h> | |
| #include "PlatformConfig.h" | |
| // | |
| // Name of the UEFI variable that we use for persistent storage. | |
| // | |
| STATIC CHAR16 mVariableName[] = L"PlatformConfig"; | |
| /** | |
| Serialize and persistently save platform configuration. | |
| @param[in] PlatformConfig The platform configuration to serialize and save. | |
| @return Status codes returned by gRT->SetVariable(). | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PlatformConfigSave ( | |
| IN PLATFORM_CONFIG *PlatformConfig | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| // | |
| // We could implement any kind of translation here, as part of serialization. | |
| // For example, we could expose the platform configuration in separate | |
| // variables with human-readable contents, allowing other tools to access | |
| // them more easily. For now, just save a binary dump. | |
| // | |
| Status = gRT->SetVariable (mVariableName, &gOvmfPlatformConfigGuid, | |
| EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | | |
| EFI_VARIABLE_RUNTIME_ACCESS, | |
| sizeof *PlatformConfig, PlatformConfig); | |
| return Status; | |
| } | |
| /** | |
| Load and deserialize platform configuration. | |
| When the function fails, output parameters are indeterminate. | |
| @param[out] PlatformConfig The platform configuration to receive the | |
| loaded data. | |
| @param[out] OptionalElements This bitmap describes the presence of optional | |
| configuration elements that have been loaded. | |
| PLATFORM_CONFIG_F_DOWNGRADE means that some | |
| unknown elements, present in the wire format, | |
| have been ignored. | |
| @retval EFI_SUCCESS Loading & deserialization successful. | |
| @return Error codes returned by GetVariable2(). | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PlatformConfigLoad ( | |
| OUT PLATFORM_CONFIG *PlatformConfig, | |
| OUT UINT64 *OptionalElements | |
| ) | |
| { | |
| VOID *Data; | |
| UINTN DataSize; | |
| EFI_STATUS Status; | |
| // | |
| // Any translation done in PlatformConfigSave() would have to be mirrored | |
| // here. For now, just load the binary dump. | |
| // | |
| // Versioning of the binary wire format is implemented based on size | |
| // (only incremental changes, ie. new fields), and on GUID. | |
| // (Incompatible changes require a GUID change.) | |
| // | |
| Status = GetVariable2 (mVariableName, &gOvmfPlatformConfigGuid, &Data, | |
| &DataSize); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| *OptionalElements = 0; | |
| if (DataSize > sizeof *PlatformConfig) { | |
| // | |
| // Handle firmware downgrade -- keep only leading part. | |
| // | |
| CopyMem (PlatformConfig, Data, sizeof *PlatformConfig); | |
| *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE; | |
| } else { | |
| CopyMem (PlatformConfig, Data, DataSize); | |
| // | |
| // Handle firmware upgrade -- zero out missing fields. | |
| // | |
| ZeroMem ((UINT8 *)PlatformConfig + DataSize, | |
| sizeof *PlatformConfig - DataSize); | |
| } | |
| // | |
| // Based on DataSize, report the optional features that we recognize. | |
| // | |
| if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) + | |
| sizeof PlatformConfig->VerticalResolution)) { | |
| *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION; | |
| } | |
| FreePool (Data); | |
| return EFI_SUCCESS; | |
| } |