mirror of https://github.com/acidanthera/audk.git
132 lines
4.1 KiB
C
132 lines
4.1 KiB
C
|
/** @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;
|
||
|
}
|