acpitabs.c 3.6 KB

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