mirror of https://github.com/acidanthera/audk.git
136 lines
3.9 KiB
C
136 lines
3.9 KiB
C
/** @file
|
|
|
|
Utility functions for serializing (persistently storing) and deserializing
|
|
OVMF's platform configuration.
|
|
|
|
Copyright (C) 2014, Red Hat, Inc.
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#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.
|
|
//
|
|
CHAR16 mVariableName[] = L"PlatformConfig";
|
|
CHAR16 mHiiFormName[] = L"MainFormState";
|
|
|
|
/**
|
|
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;
|
|
}
|