AcpiGnvsInit.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /** @file
  2. Acpi Gnvs Init Library.
  3. Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Uefi.h>
  7. #include <Library/IoLib.h>
  8. #include <Library/PciLib.h>
  9. #include <Library/DebugLib.h>
  10. #include <Library/BaseMemoryLib.h>
  11. #include <Library/UefiLib.h>
  12. #include <Library/UefiBootServicesTableLib.h>
  13. #include <PchAccess.h>
  14. #include <Protocol/GlobalNvsArea.h>
  15. #include <Protocol/MpService.h>
  16. #include <Protocol/SaGlobalNvsArea.h>
  17. /**
  18. A protocol callback which updates MMIO Base and Length in SA GNVS area
  19. @param[in] Event - The triggered event.
  20. @param[in] Context - Context for this event.
  21. **/
  22. VOID
  23. EFIAPI
  24. UpdateSaGnvsForMmioResourceBaseLength (
  25. IN EFI_EVENT Event,
  26. IN VOID *Context
  27. )
  28. {
  29. EFI_STATUS Status;
  30. SYSTEM_AGENT_GLOBAL_NVS_AREA_PROTOCOL *SaGlobalNvsAreaProtocol;
  31. Status = gBS->LocateProtocol (&gSaGlobalNvsAreaProtocolGuid, NULL, (VOID **) &SaGlobalNvsAreaProtocol);
  32. if (Status != EFI_SUCCESS) {
  33. return;
  34. }
  35. gBS->CloseEvent (Event);
  36. //
  37. // Configure MMIO Base/Length. This logic is only valid for platforms that use PciHostBridgeLibSimple.
  38. //
  39. DEBUG ((DEBUG_INFO, "[BoardAcpiDxe] Update SA GNVS Area.\n"));
  40. SaGlobalNvsAreaProtocol->Area->Mmio32Base = PcdGet32 (PcdPciReservedMemBase);
  41. if (PcdGet32 (PcdPciReservedMemLimit) != 0) {
  42. SaGlobalNvsAreaProtocol->Area->Mmio32Length = PcdGet32 (PcdPciReservedMemLimit) - PcdGet32 (PcdPciReservedMemBase) + 1;
  43. } else {
  44. SaGlobalNvsAreaProtocol->Area->Mmio32Length = ((UINT32) PcdGet64 (PcdPciExpressBaseAddress)) - PcdGet32 (PcdPciReservedMemBase);
  45. }
  46. if (PcdGet64 (PcdPciReservedMemAbove4GBLimit) > PcdGet64 (PcdPciReservedMemAbove4GBBase)) {
  47. SaGlobalNvsAreaProtocol->Area->Mmio64Base = PcdGet64 (PcdPciReservedMemAbove4GBBase);
  48. SaGlobalNvsAreaProtocol->Area->Mmio64Length = PcdGet64 (PcdPciReservedMemAbove4GBLimit) - PcdGet64 (PcdPciReservedMemAbove4GBBase) + 1;
  49. }
  50. }
  51. /**
  52. @brief
  53. Global NVS initialize.
  54. @param[in] GlobalNvs - Pointer of Global NVS area
  55. @retval EFI_SUCCESS - Allocate Global NVS completed.
  56. @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
  57. **/
  58. EFI_STATUS
  59. EFIAPI
  60. AcpiGnvsInit (
  61. IN OUT VOID **GlobalNvs
  62. )
  63. {
  64. UINTN Pages;
  65. EFI_PHYSICAL_ADDRESS Address;
  66. EFI_STATUS Status;
  67. EFI_GLOBAL_NVS_AREA_PROTOCOL *GNVS;
  68. EFI_MP_SERVICES_PROTOCOL *MpService;
  69. UINTN NumberOfCPUs;
  70. UINTN NumberOfEnabledCPUs;
  71. VOID *SaGlobalNvsRegistration;
  72. Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
  73. Address = 0xffffffff; // allocate address below 4G.
  74. Status = gBS->AllocatePages (
  75. AllocateMaxAddress,
  76. EfiACPIMemoryNVS,
  77. Pages,
  78. &Address
  79. );
  80. ASSERT_EFI_ERROR (Status);
  81. if (EFI_ERROR(Status)) {
  82. return Status;
  83. }
  84. //
  85. // Locate the MP services protocol
  86. // Find the MP Protocol. This is an MP platform, so MP protocol must be there.
  87. //
  88. Status = gBS->LocateProtocol (
  89. &gEfiMpServiceProtocolGuid,
  90. NULL,
  91. (VOID **) &MpService
  92. );
  93. ASSERT_EFI_ERROR (Status);
  94. //
  95. // Determine the number of processors
  96. //
  97. MpService->GetNumberOfProcessors (
  98. MpService,
  99. &NumberOfCPUs,
  100. &NumberOfEnabledCPUs
  101. );
  102. *GlobalNvs = (VOID *) (UINTN) Address;
  103. SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
  104. //
  105. // GNVS default value init here...
  106. //
  107. GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
  108. GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
  109. //
  110. // Miscellaneous
  111. //
  112. GNVS->Area->PL1LimitCS = 0;
  113. GNVS->Area->PL1LimitCSValue = 4500;
  114. //
  115. // Update SA GNVS with MMIO Base/Length
  116. //
  117. EfiCreateProtocolNotifyEvent (
  118. &gSaGlobalNvsAreaProtocolGuid,
  119. TPL_CALLBACK,
  120. UpdateSaGnvsForMmioResourceBaseLength,
  121. NULL,
  122. &SaGlobalNvsRegistration
  123. );
  124. return EFI_SUCCESS;
  125. }