PlatformConfig.c 3.9 KB

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