tbutils.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbutils - Table manipulation utilities
  4.  *              $Revision: 42 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "actables.h"
  26. #include "acinterp.h"
  27. #define _COMPONENT          ACPI_TABLES
  28.  MODULE_NAME         ("tbutils")
  29. /*******************************************************************************
  30.  *
  31.  * FUNCTION:    Acpi_tb_handle_to_object
  32.  *
  33.  * PARAMETERS:  Table_id            - Id for which the function is searching
  34.  *              Table_desc          - Pointer to return the matching table
  35.  *                                      descriptor.
  36.  *
  37.  * RETURN:      Search the tables to find one with a matching Table_id and
  38.  *              return a pointer to that table descriptor.
  39.  *
  40.  ******************************************************************************/
  41. acpi_status
  42. acpi_tb_handle_to_object (
  43. u16                     table_id,
  44. acpi_table_desc         **table_desc)
  45. {
  46. u32                     i;
  47. acpi_table_desc         *list_head;
  48. PROC_NAME ("Tb_handle_to_object");
  49. for (i = 0; i < ACPI_TABLE_MAX; i++) {
  50. list_head = &acpi_gbl_acpi_tables[i];
  51. do {
  52. if (list_head->table_id == table_id) {
  53. *table_desc = list_head;
  54. return (AE_OK);
  55. }
  56. list_head = list_head->next;
  57. } while (list_head != &acpi_gbl_acpi_tables[i]);
  58. }
  59. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table_id=%X does not existn", table_id));
  60. return (AE_BAD_PARAMETER);
  61. }
  62. /*******************************************************************************
  63.  *
  64.  * FUNCTION:    Acpi_tb_system_table_pointer
  65.  *
  66.  * PARAMETERS:  *Where              - Pointer to be examined
  67.  *
  68.  * RETURN:      TRUE if Where is within the AML stream (in one of the ACPI
  69.  *              system tables such as the DSDT or an SSDT.)
  70.  *              FALSE otherwise
  71.  *
  72.  ******************************************************************************/
  73. u8
  74. acpi_tb_system_table_pointer (
  75. void                    *where)
  76. {
  77. u32                     i;
  78. acpi_table_desc         *table_desc;
  79. acpi_table_header       *table;
  80. /* No function trace, called too often! */
  81. /* Ignore null pointer */
  82. if (!where) {
  83. return (FALSE);
  84. }
  85. /* Check for a pointer within the DSDT */
  86. if ((acpi_gbl_DSDT) &&
  87. (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) {
  88. return (TRUE);
  89. }
  90. /* Check each of the loaded SSDTs (if any)*/
  91. table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
  92. for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
  93. table = table_desc->pointer;
  94. if (IS_IN_ACPI_TABLE (where, table)) {
  95. return (TRUE);
  96. }
  97. table_desc = table_desc->next;
  98. }
  99. /* Check each of the loaded PSDTs (if any)*/
  100. table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
  101. for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
  102. table = table_desc->pointer;
  103. if (IS_IN_ACPI_TABLE (where, table)) {
  104. return (TRUE);
  105. }
  106. table_desc = table_desc->next;
  107. }
  108. /* Pointer does not point into any system table */
  109. return (FALSE);
  110. }
  111. /*******************************************************************************
  112.  *
  113.  * FUNCTION:    Acpi_tb_validate_table_header
  114.  *
  115.  * PARAMETERS:  Table_header        - Logical pointer to the table
  116.  *
  117.  * RETURN:      Status
  118.  *
  119.  * DESCRIPTION: Check an ACPI table header for validity
  120.  *
  121.  * NOTE:  Table pointers are validated as follows:
  122.  *          1) Table pointer must point to valid physical memory
  123.  *          2) Signature must be 4 ASCII chars, even if we don't recognize the
  124.  *             name
  125.  *          3) Table must be readable for length specified in the header
  126.  *          4) Table checksum must be valid (with the exception of the FACS
  127.  *              which has no checksum for some odd reason)
  128.  *
  129.  ******************************************************************************/
  130. acpi_status
  131. acpi_tb_validate_table_header (
  132. acpi_table_header       *table_header)
  133. {
  134. acpi_name               signature;
  135. PROC_NAME ("Tb_validate_table_header");
  136. /* Verify that this is a valid address */
  137. if (!acpi_os_readable (table_header, sizeof (acpi_table_header))) {
  138. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  139. "Cannot read table header at %pn", table_header));
  140. return (AE_BAD_ADDRESS);
  141. }
  142. /* Ensure that the signature is 4 ASCII characters */
  143. MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature);
  144. if (!acpi_ut_valid_acpi_name (signature)) {
  145. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  146. "Table signature at %p [%p] has invalid charactersn",
  147. table_header, &signature));
  148. REPORT_WARNING (("Invalid table signature %4.4s foundn", (char*)&signature));
  149. DUMP_BUFFER (table_header, sizeof (acpi_table_header));
  150. return (AE_BAD_SIGNATURE);
  151. }
  152. /* Validate the table length */
  153. if (table_header->length < sizeof (acpi_table_header)) {
  154. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  155. "Invalid length in table header %p name %4.4sn",
  156. table_header, (char*)&signature));
  157. REPORT_WARNING (("Invalid table header length foundn"));
  158. DUMP_BUFFER (table_header, sizeof (acpi_table_header));
  159. return (AE_BAD_HEADER);
  160. }
  161. return (AE_OK);
  162. }
  163. /*******************************************************************************
  164.  *
  165.  * FUNCTION:    Acpi_tb_map_acpi_table
  166.  *
  167.  * PARAMETERS:  Physical_address        - Physical address of table to map
  168.  *              *Size                   - Size of the table.  If zero, the size
  169.  *                                        from the table header is used.
  170.  *                                        Actual size is returned here.
  171.  *              **Logical_address       - Logical address of mapped table
  172.  *
  173.  * RETURN:      Logical address of the mapped table.
  174.  *
  175.  * DESCRIPTION: Maps the physical address of table into a logical address
  176.  *
  177.  ******************************************************************************/
  178. acpi_status
  179. acpi_tb_map_acpi_table (
  180. ACPI_PHYSICAL_ADDRESS   physical_address,
  181. u32                     *size,
  182. acpi_table_header       **logical_address)
  183. {
  184. acpi_table_header       *table;
  185. u32                     table_size = *size;
  186. acpi_status             status = AE_OK;
  187. PROC_NAME ("Tb_map_acpi_table");
  188. /* If size is zero, look at the table header to get the actual size */
  189. if ((*size) == 0) {
  190. /* Get the table header so we can extract the table length */
  191. status = acpi_os_map_memory (physical_address, sizeof (acpi_table_header),
  192.   (void **) &table);
  193. if (ACPI_FAILURE (status)) {
  194. return (status);
  195. }
  196. /* Extract the full table length before we delete the mapping */
  197. table_size = table->length;
  198. /*
  199.  * Validate the header and delete the mapping.
  200.  * We will create a mapping for the full table below.
  201.  */
  202. status = acpi_tb_validate_table_header (table);
  203. /* Always unmap the memory for the header */
  204. acpi_os_unmap_memory (table, sizeof (acpi_table_header));
  205. /* Exit if header invalid */
  206. if (ACPI_FAILURE (status)) {
  207. return (status);
  208. }
  209. }
  210. /* Map the physical memory for the correct length */
  211. status = acpi_os_map_memory (physical_address, table_size, (void **) &table);
  212. if (ACPI_FAILURE (status)) {
  213. return (status);
  214. }
  215. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  216. "Mapped memory for ACPI table, length=%d(%X) at %pn",
  217. table_size, table_size, table));
  218. *size = table_size;
  219. *logical_address = table;
  220. return (status);
  221. }
  222. /*******************************************************************************
  223.  *
  224.  * FUNCTION:    Acpi_tb_verify_table_checksum
  225.  *
  226.  * PARAMETERS:  *Table_header           - ACPI table to verify
  227.  *
  228.  * RETURN:      8 bit checksum of table
  229.  *
  230.  * DESCRIPTION: Does an 8 bit checksum of table and returns status.  A correct
  231.  *              table should have a checksum of 0.
  232.  *
  233.  ******************************************************************************/
  234. acpi_status
  235. acpi_tb_verify_table_checksum (
  236. acpi_table_header       *table_header)
  237. {
  238. u8                      checksum;
  239. acpi_status             status = AE_OK;
  240. FUNCTION_TRACE ("Tb_verify_table_checksum");
  241. /* Compute the checksum on the table */
  242. checksum = acpi_tb_checksum (table_header, table_header->length);
  243. /* Return the appropriate exception */
  244. if (checksum) {
  245. REPORT_WARNING (("Invalid checksum (%X) in table %4.4sn",
  246. checksum, (char*)&table_header->signature));
  247. status = AE_BAD_CHECKSUM;
  248. }
  249. return_ACPI_STATUS (status);
  250. }
  251. /*******************************************************************************
  252.  *
  253.  * FUNCTION:    Acpi_tb_checksum
  254.  *
  255.  * PARAMETERS:  Buffer              - Buffer to checksum
  256.  *              Length              - Size of the buffer
  257.  *
  258.  * RETURNS      8 bit checksum of buffer
  259.  *
  260.  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
  261.  *
  262.  ******************************************************************************/
  263. u8
  264. acpi_tb_checksum (
  265. void                    *buffer,
  266. u32                     length)
  267. {
  268. u8                      *limit;
  269. u8                      *rover;
  270. u8                      sum = 0;
  271. if (buffer && length) {
  272. /*  Buffer and Length are valid   */
  273. limit = (u8 *) buffer + length;
  274. for (rover = buffer; rover < limit; rover++) {
  275. sum = (u8) (sum + *rover);
  276. }
  277. }
  278. return (sum);
  279. }