PlatformConfig.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /** @file
  2. Utility functions for serializing (persistently storing) and deserializing
  3. SIMICS QSP's platform configuration.
  4. Copyright (C) 2014, Red Hat, Inc.
  5. Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include <Library/BaseMemoryLib.h>
  9. #include <Library/DebugLib.h>
  10. #include <Library/MemoryAllocationLib.h>
  11. #include <Library/UefiLib.h>
  12. #include <Library/UefiRuntimeServicesTableLib.h>
  13. #include <Guid/SimicsBoardConfig.h>
  14. #include "PlatformConfig.h"
  15. //
  16. // Name of the UEFI variable that we use for persistent storage.
  17. //
  18. STATIC CHAR16 mVariableName[] = L"PlatformConfig";
  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 (mVariableName, &gSimicsBoardConfigGuid,
  38. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
  39. EFI_VARIABLE_RUNTIME_ACCESS,
  40. sizeof *PlatformConfig, PlatformConfig);
  41. return Status;
  42. }
  43. /**
  44. Load and deserialize platform configuration.
  45. When the function fails, output parameters are indeterminate.
  46. @param[out] PlatformConfig The platform configuration to receive the
  47. loaded data.
  48. @param[out] OptionalElements This bitmap describes the presence of optional
  49. configuration elements that have been loaded.
  50. PLATFORM_CONFIG_F_DOWNGRADE means that some
  51. unknown elements, present in the wire format,
  52. have been ignored.
  53. @retval EFI_SUCCESS Loading & deserialization successful.
  54. @return Error codes returned by GetVariable2().
  55. **/
  56. EFI_STATUS
  57. EFIAPI
  58. PlatformConfigLoad (
  59. OUT PLATFORM_CONFIG *PlatformConfig,
  60. OUT UINT64 *OptionalElements
  61. )
  62. {
  63. VOID *Data;
  64. UINTN DataSize;
  65. EFI_STATUS Status;
  66. //
  67. // Any translation done in PlatformConfigSave() would have to be mirrored
  68. // here. For now, just load the binary dump.
  69. //
  70. // Versioning of the binary wire format is implemented based on size
  71. // (only incremental changes, ie. new fields), and on GUID.
  72. // (Incompatible changes require a GUID change.)
  73. //
  74. Status = GetVariable2 (mVariableName, &gSimicsBoardConfigGuid, &Data,
  75. &DataSize);
  76. if (EFI_ERROR (Status)) {
  77. return Status;
  78. }
  79. *OptionalElements = 0;
  80. if (DataSize > sizeof *PlatformConfig) {
  81. //
  82. // Handle firmware downgrade -- keep only leading part.
  83. //
  84. CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
  85. *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
  86. } else {
  87. CopyMem (PlatformConfig, Data, DataSize);
  88. //
  89. // Handle firmware upgrade -- zero out missing fields.
  90. //
  91. ZeroMem ((UINT8 *)PlatformConfig + DataSize,
  92. sizeof *PlatformConfig - DataSize);
  93. }
  94. //
  95. // Based on DataSize, report the optional features that we recognize.
  96. //
  97. if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
  98. sizeof PlatformConfig->VerticalResolution)) {
  99. *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
  100. }
  101. FreePool (Data);
  102. return EFI_SUCCESS;
  103. }