FeatureControl.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /** @file
  2. Install a callback when necessary for setting the Feature Control MSR on all
  3. processors.
  4. Copyright (C) 2016, 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/DebugLib.h>
  9. #include <Library/PeiServicesLib.h>
  10. #include <Ppi/MpServices.h>
  11. #include <Register/Intel/Msr/Core2Msr.h>
  12. #include "Platform.h"
  13. //
  14. // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
  15. //
  16. STATIC UINT64 mFeatureControlValue = 0x00000005;
  17. /**
  18. Write the Feature Control MSR on an Application Processor or the Boot
  19. Processor.
  20. All APs execute this function in parallel. The BSP executes the function
  21. separately.
  22. @param[in,out] WorkSpace Pointer to the input/output argument workspace
  23. shared by all processors.
  24. **/
  25. STATIC
  26. VOID
  27. EFIAPI
  28. WriteFeatureControl (
  29. IN OUT VOID *WorkSpace
  30. )
  31. {
  32. AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
  33. }
  34. /**
  35. Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
  36. @param[in] PeiServices Indirect reference to the PEI Services Table.
  37. @param[in] NotifyDescriptor Address of the notification descriptor data
  38. structure.
  39. @param[in] Ppi Address of the PPI that was installed.
  40. @return Status of the notification. The status code returned from this
  41. function is ignored.
  42. **/
  43. STATIC
  44. EFI_STATUS
  45. EFIAPI
  46. OnMpServicesAvailable (
  47. IN EFI_PEI_SERVICES **PeiServices,
  48. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  49. IN VOID *Ppi
  50. )
  51. {
  52. EFI_PEI_MP_SERVICES_PPI *MpServices;
  53. EFI_STATUS Status;
  54. DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
  55. //
  56. // Write the MSR on all the APs in parallel.
  57. //
  58. MpServices = Ppi;
  59. Status = MpServices->StartupAllAPs (
  60. (CONST EFI_PEI_SERVICES **)PeiServices,
  61. MpServices,
  62. WriteFeatureControl, // Procedure
  63. FALSE, // SingleThread
  64. 0, // TimeoutInMicroSeconds: inf.
  65. NULL // ProcedureArgument
  66. );
  67. if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
  68. DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
  69. return Status;
  70. }
  71. //
  72. // Now write the MSR on the BSP too.
  73. //
  74. WriteFeatureControl (NULL);
  75. return EFI_SUCCESS;
  76. }
  77. //
  78. // Notification object for registering the callback, for when
  79. // EFI_PEI_MP_SERVICES_PPI becomes available.
  80. //
  81. STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
  82. EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
  83. EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  84. &gEfiPeiMpServicesPpiGuid, // Guid
  85. OnMpServicesAvailable // Notify
  86. };
  87. VOID
  88. InstallFeatureControlCallback (
  89. VOID
  90. )
  91. {
  92. EFI_STATUS Status;
  93. Status = PeiServicesNotifyPpi (&mMpServicesNotify);
  94. if (EFI_ERROR (Status)) {
  95. DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
  96. __FUNCTION__, Status));
  97. }
  98. }