PlatformConfig.c 3.9 KB

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