• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Utility functions for serializing (persistently storing) and deserializing
4   OVMF's platform configuration.
5 
6   Copyright (C) 2014, Red Hat, Inc.
7 
8   This program and the accompanying materials are licensed and made available
9   under the terms and conditions of the BSD License which accompanies this
10   distribution. The full text of the license may be found at
11   http://opensource.org/licenses/bsd-license.php
12 
13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
14   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 
16 **/
17 
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiLib.h>
22 #include <Library/UefiRuntimeServicesTableLib.h>
23 #include <Guid/OvmfPlatformConfig.h>
24 
25 #include "PlatformConfig.h"
26 
27 //
28 // Name of the UEFI variable that we use for persistent storage.
29 //
30 STATIC CHAR16 mVariableName[] = L"PlatformConfig";
31 
32 
33 /**
34   Serialize and persistently save platform configuration.
35 
36   @param[in] PlatformConfig  The platform configuration to serialize and save.
37 
38   @return  Status codes returned by gRT->SetVariable().
39 **/
40 EFI_STATUS
41 EFIAPI
PlatformConfigSave(IN PLATFORM_CONFIG * PlatformConfig)42 PlatformConfigSave (
43   IN PLATFORM_CONFIG *PlatformConfig
44   )
45 {
46   EFI_STATUS Status;
47 
48   //
49   // We could implement any kind of translation here, as part of serialization.
50   // For example, we could expose the platform configuration in separate
51   // variables with human-readable contents, allowing other tools to access
52   // them more easily. For now, just save a binary dump.
53   //
54   Status = gRT->SetVariable (mVariableName, &gOvmfPlatformConfigGuid,
55                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
56                     EFI_VARIABLE_RUNTIME_ACCESS,
57                   sizeof *PlatformConfig, PlatformConfig);
58   return Status;
59 }
60 
61 
62 /**
63   Load and deserialize platform configuration.
64 
65   When the function fails, output parameters are indeterminate.
66 
67   @param[out] PlatformConfig    The platform configuration to receive the
68                                 loaded data.
69 
70   @param[out] OptionalElements  This bitmap describes the presence of optional
71                                 configuration elements that have been loaded.
72                                 PLATFORM_CONFIG_F_DOWNGRADE means that some
73                                 unknown elements, present in the wire format,
74                                 have been ignored.
75 
76   @retval  EFI_SUCCESS         Loading & deserialization successful.
77   @return                      Error codes returned by GetVariable2().
78 **/
79 EFI_STATUS
80 EFIAPI
PlatformConfigLoad(OUT PLATFORM_CONFIG * PlatformConfig,OUT UINT64 * OptionalElements)81 PlatformConfigLoad (
82   OUT PLATFORM_CONFIG *PlatformConfig,
83   OUT UINT64          *OptionalElements
84   )
85 {
86   VOID       *Data;
87   UINTN      DataSize;
88   EFI_STATUS Status;
89 
90   //
91   // Any translation done in PlatformConfigSave() would have to be mirrored
92   // here. For now, just load the binary dump.
93   //
94   // Versioning of the binary wire format is implemented based on size
95   // (only incremental changes, ie. new fields), and on GUID.
96   // (Incompatible changes require a GUID change.)
97   //
98   Status = GetVariable2 (mVariableName, &gOvmfPlatformConfigGuid, &Data,
99              &DataSize);
100   if (EFI_ERROR (Status)) {
101     return Status;
102   }
103 
104   *OptionalElements = 0;
105   if (DataSize > sizeof *PlatformConfig) {
106     //
107     // Handle firmware downgrade -- keep only leading part.
108     //
109     CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
110     *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
111   } else {
112     CopyMem (PlatformConfig, Data, DataSize);
113 
114     //
115     // Handle firmware upgrade -- zero out missing fields.
116     //
117     ZeroMem ((UINT8 *)PlatformConfig + DataSize,
118       sizeof *PlatformConfig - DataSize);
119   }
120 
121   //
122   // Based on DataSize, report the optional features that we recognize.
123   //
124   if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
125                    sizeof PlatformConfig->VerticalResolution)) {
126     *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
127   }
128 
129   FreePool (Data);
130   return EFI_SUCCESS;
131 }
132