acpitabs.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*++
  2. Copyright (c) 2016 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. acpitabs.c
  9. Abstract:
  10. This module implements support for getting ACPI tables from the EFI system
  11. table.
  12. Author:
  13. Chris Stevens 3-May-2016
  14. Environment:
  15. Firmware
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "ueficore.h"
  21. #include <minoca/fw/acpitabs.h>
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. //
  29. // ----------------------------------------------- Internal Function Prototypes
  30. //
  31. PRSDP
  32. EfipGetRsdp (
  33. VOID
  34. );
  35. //
  36. // -------------------------------------------------------------------- Globals
  37. //
  38. //
  39. // ------------------------------------------------------------------ Functions
  40. //
  41. EFIAPI
  42. VOID *
  43. EfiGetAcpiTable (
  44. UINT32 Signature,
  45. VOID *PreviousTable
  46. )
  47. /*++
  48. Routine Description:
  49. This routine attempts to find an ACPI description table with the given
  50. signature. This routine does not validate the checksum of the table.
  51. Arguments:
  52. Signature - Supplies the signature of the desired table.
  53. PreviousTable - Supplies an optional pointer to the table to start the
  54. search from.
  55. Return Value:
  56. Returns a pointer to the beginning of the header to the table if the table
  57. was found, or NULL if the table could not be located.
  58. --*/
  59. {
  60. PRSDP Rsdp;
  61. PRSDT Rsdt;
  62. UINTN RsdtIndex;
  63. PULONG RsdtTableEntry;
  64. PDESCRIPTION_HEADER Table;
  65. UINTN TableCount;
  66. UINTN TableIndex;
  67. Rsdp = EfipGetRsdp();
  68. if (Rsdp == NULL) {
  69. return NULL;
  70. }
  71. Rsdt = (PRSDT)(Rsdp->RsdtAddress);
  72. if (Rsdt == NULL) {
  73. return NULL;
  74. }
  75. TableCount = (Rsdt->Header.Length - sizeof(DESCRIPTION_HEADER)) /
  76. sizeof(UINT32);
  77. RsdtTableEntry = (PULONG)&(Rsdt->Entries);
  78. //
  79. // Search the list of pointers, but do it backwards. This runs on the
  80. // assumption that if there are two tables in the firmware, the later one
  81. // is the better one.
  82. //
  83. for (TableIndex = 0; TableIndex < TableCount; TableIndex += 1) {
  84. RsdtIndex = TableCount - TableIndex - 1;
  85. Table = (PDESCRIPTION_HEADER)(UINTN)(RsdtTableEntry[RsdtIndex]);
  86. if (Table == NULL) {
  87. continue;
  88. }
  89. if (PreviousTable != NULL) {
  90. if (Table == PreviousTable) {
  91. PreviousTable = NULL;
  92. }
  93. continue;
  94. }
  95. if (Table->Signature == Signature) {
  96. return Table;
  97. }
  98. }
  99. return NULL;
  100. }
  101. //
  102. // --------------------------------------------------------- Internal Functions
  103. //
  104. PRSDP
  105. EfipGetRsdp (
  106. VOID
  107. )
  108. /*++
  109. Routine Description:
  110. This routine attempts to find the RSDP in the EFI system table.
  111. Arguments:
  112. None.
  113. Return Value:
  114. Returns a pointer to the RSDP on success.
  115. NULL on failure.
  116. --*/
  117. {
  118. BOOLEAN Match;
  119. EFI_CONFIGURATION_TABLE *Table;
  120. UINTN TableCount;
  121. UINTN TableIndex;
  122. TableCount = EfiSystemTable->NumberOfTableEntries;
  123. for (TableIndex = 0; TableIndex < TableCount; TableIndex += 1) {
  124. Table = &(EfiSystemTable->ConfigurationTable[TableIndex]);
  125. Match = EfiCoreCompareGuids(&(Table->VendorGuid), &EfiAcpiTableGuid);
  126. if (Match != FALSE) {
  127. return Table->VendorTable;
  128. }
  129. Match = EfiCoreCompareGuids(&(Table->VendorGuid), &EfiAcpiTable1Guid);
  130. if (Match != FALSE) {
  131. return Table->VendorTable;
  132. }
  133. }
  134. return NULL;
  135. }