CloudHvAcpi.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /** @file
  2. Install Acpi tables for Cloud Hypervisor
  3. Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Library/BaseLib.h>
  7. #include <Library/MemoryAllocationLib.h>
  8. #include <IndustryStandard/Acpi63.h>
  9. #include <Protocol/AcpiTable.h>
  10. #include <Library/UefiBootServicesTableLib.h>
  11. #include <Library/UefiDriverEntryPoint.h>
  12. #include <Library/DebugLib.h>
  13. /**
  14. Find Acpi table Protocol and return it
  15. @return AcpiTable Protocol, which is used to handle Acpi Table, on SUCCESS or NULL on FAILURE.
  16. **/
  17. STATIC
  18. EFI_ACPI_TABLE_PROTOCOL *
  19. FindAcpiTableProtocol (
  20. VOID
  21. )
  22. {
  23. EFI_STATUS Status;
  24. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  25. Status = gBS->LocateProtocol (
  26. &gEfiAcpiTableProtocolGuid,
  27. NULL,
  28. (VOID **)&AcpiTable
  29. );
  30. ASSERT_EFI_ERROR (Status);
  31. return AcpiTable;
  32. }
  33. /** Install Acpi tables for Cloud Hypervisor
  34. @param [in] AcpiProtocol Acpi Protocol which is used to install Acpi tables
  35. @return EFI_SUCCESS The table was successfully inserted.
  36. @return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL
  37. and the size field embedded in the ACPI table pointed
  38. by AcpiTablePtr or DsdtPtr are not in sync.
  39. @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
  40. @return EFI_NOT_FOUND DSDT table not found.
  41. **/
  42. EFI_STATUS
  43. EFIAPI
  44. InstallCloudHvAcpiTables (
  45. IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
  46. )
  47. {
  48. UINTN InstalledKey;
  49. UINTN TableSize;
  50. UINTN AcpiTableLength;
  51. UINT64 RsdpPtr;
  52. UINT64 XsdtPtr;
  53. UINT64 TableOffset;
  54. UINT64 AcpiTablePtr;
  55. UINT64 *DsdtPtr;
  56. EFI_STATUS Status;
  57. if (AcpiProtocol == NULL) {
  58. return EFI_INVALID_PARAMETER;
  59. }
  60. RsdpPtr = PcdGet64 (PcdCloudHvAcpiRsdpBaseAddress);
  61. XsdtPtr = ((EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER *)RsdpPtr)->XsdtAddress;
  62. AcpiTableLength = ((EFI_ACPI_COMMON_HEADER *)XsdtPtr)->Length;
  63. TableOffset = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  64. DsdtPtr = NULL;
  65. while (TableOffset < AcpiTableLength) {
  66. AcpiTablePtr = *(UINT64 *)(XsdtPtr + TableOffset);
  67. TableSize = ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Length;
  68. //
  69. // Install ACPI tables from XSDT
  70. //
  71. Status = AcpiProtocol->InstallAcpiTable (
  72. AcpiProtocol,
  73. (VOID *)AcpiTablePtr,
  74. TableSize,
  75. &InstalledKey
  76. );
  77. if (EFI_ERROR (Status)) {
  78. return Status;
  79. }
  80. //
  81. // Get DSDT from FADT
  82. //
  83. if ((DsdtPtr == NULL) &&
  84. (EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE ==
  85. ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Signature))
  86. {
  87. DsdtPtr = (UINT64 *)((EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *)AcpiTablePtr)->XDsdt;
  88. }
  89. TableOffset += sizeof (UINT64);
  90. } // while
  91. if (DsdtPtr == NULL) {
  92. DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));
  93. return EFI_NOT_FOUND;
  94. }
  95. //
  96. // Install DSDT table
  97. //
  98. TableSize = ((EFI_ACPI_COMMON_HEADER *)DsdtPtr)->Length;
  99. Status = AcpiProtocol->InstallAcpiTable (
  100. AcpiProtocol,
  101. DsdtPtr,
  102. TableSize,
  103. &InstalledKey
  104. );
  105. return Status;
  106. }
  107. /** Entry point for Cloud Hypervisor Platform Dxe
  108. @param [in] ImageHandle Handle for this image.
  109. @param [in] SystemTable Pointer to the EFI system table.
  110. @return EFI_SUCCESS The table was successfully inserted.
  111. @return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL
  112. and the size field embedded in the ACPI table pointed to
  113. by AcpiTablePtr or DsdtPtr are not in sync.
  114. @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
  115. @return EFI_NOT_FOUND DSDT table not found
  116. **/
  117. EFI_STATUS
  118. EFIAPI
  119. CloudHvAcpiPlatformEntryPoint (
  120. IN EFI_HANDLE ImageHandle,
  121. IN EFI_SYSTEM_TABLE *SystemTable
  122. )
  123. {
  124. EFI_STATUS Status;
  125. Status = InstallCloudHvAcpiTables (FindAcpiTableProtocol ());
  126. if (EFI_ERROR (Status)) {
  127. DEBUG ((
  128. DEBUG_ERROR,
  129. "%a: Fail to install Acpi table: %r\n",
  130. __FUNCTION__,
  131. Status
  132. ));
  133. CpuDeadLoop ();
  134. }
  135. return EFI_SUCCESS;
  136. }