patch-2.4.0-test3 linux/drivers/acpi/tables/tbutils.c
Next file: linux/drivers/acpi/tables/tbxface.c
Previous file: linux/drivers/acpi/tables/tbtable.c
Back to the patch index
Back to the overall index
- Lines: 353
- Date:
Wed Jul 5 11:23:13 2000
- Orig file:
v2.4.0-test2/linux/drivers/acpi/tables/tbutils.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/tables/tbutils.c linux/drivers/acpi/tables/tbutils.c
@@ -0,0 +1,352 @@
+
+/******************************************************************************
+ *
+ * Module Name: tbutils - Table manipulation utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"
+#include "tables.h"
+#include "interp.h"
+
+
+#define _COMPONENT TABLE_MANAGER
+ MODULE_NAME ("tbutils");
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_system_table_pointer
+ *
+ * PARAMETERS: *Where - Pointer to be examined
+ *
+ * RETURN: TRUE if Where is within the AML stream (in one of the ACPI
+ * system tables such as the DSDT or an SSDT.)
+ * FALSE otherwise
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_handle_to_object (
+ u16 table_id,
+ ACPI_TABLE_DESC **table_desc)
+{
+ u32 i;
+ ACPI_TABLE_DESC *list_head;
+
+
+ for (i = 0; i < ACPI_TABLE_MAX; i++) {
+ list_head = &acpi_gbl_acpi_tables[i];
+ do
+ {
+ if (list_head->table_id == table_id) {
+ *table_desc = list_head;
+ return AE_OK;
+ }
+
+ list_head = list_head->next;
+
+ } while (list_head != &acpi_gbl_acpi_tables[i]);
+ }
+
+
+ return AE_BAD_PARAMETER;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_system_table_pointer
+ *
+ * PARAMETERS: *Where - Pointer to be examined
+ *
+ * RETURN: TRUE if Where is within the AML stream (in one of the ACPI
+ * system tables such as the DSDT or an SSDT.)
+ * FALSE otherwise
+ *
+ ******************************************************************************/
+
+u8
+acpi_tb_system_table_pointer (
+ void *where)
+{
+ u32 i;
+ ACPI_TABLE_DESC *table_desc;
+ ACPI_TABLE_HEADER *table;
+
+
+ /* No function trace, called too often! */
+
+
+ /* Ignore null pointer */
+
+ if (!where) {
+ return (FALSE);
+ }
+
+
+ /* Check for a pointer within the DSDT */
+
+ if (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT)) {
+ return (TRUE);
+ }
+
+
+ /* Check each of the loaded SSDTs (if any)*/
+
+ table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
+
+ for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
+ table = table_desc->pointer;
+
+ if (IS_IN_ACPI_TABLE (where, table)) {
+ return (TRUE);
+ }
+
+ table_desc = table_desc->next;
+ }
+
+
+ /* Check each of the loaded PSDTs (if any)*/
+
+ table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
+
+ for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
+ table = table_desc->pointer;
+
+ if (IS_IN_ACPI_TABLE (where, table)) {
+ return (TRUE);
+ }
+
+ table_desc = table_desc->next;
+ }
+
+
+ /* Pointer does not point into any system table */
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_validate_table_header
+ *
+ * PARAMETERS: Table_header - Logical pointer to the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check an ACPI table header for validity
+ *
+ * NOTE: Table pointers are validated as follows:
+ * 1) Table pointer must point to valid physical memory
+ * 2) Signature must be 4 ASCII chars, even if we don't recognize the
+ * name
+ * 3) Table must be readable for length specified in the header
+ * 4) Table checksum must be valid (with the exception of the FACS
+ * which has no checksum for some odd reason)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_validate_table_header (
+ ACPI_TABLE_HEADER *table_header)
+{
+ ACPI_NAME signature;
+
+
+ /* Verify that this is a valid address */
+
+ if (!acpi_os_readable (table_header, sizeof (ACPI_TABLE_HEADER))) {
+ return AE_BAD_ADDRESS;
+ }
+
+
+ /* Ensure that the signature is 4 ASCII characters */
+
+ MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature);
+ if (!acpi_cm_valid_acpi_name (signature)) {
+ REPORT_WARNING ("Invalid table signature found");
+ return AE_BAD_SIGNATURE;
+ }
+
+
+ /* Validate the table length */
+
+ if (table_header->length < sizeof (ACPI_TABLE_HEADER)) {
+ REPORT_WARNING ("Invalid table header length found");
+ return AE_BAD_HEADER;
+ }
+
+ return AE_OK;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_map_acpi_table
+ *
+ * PARAMETERS: Physical_address - Physical address of table to map
+ * *Size - Size of the table. If zero, the size
+ * from the table header is used.
+ * Actual size is returned here.
+ * **Logical_address - Logical address of mapped table
+ *
+ * RETURN: Logical address of the mapped table.
+ *
+ * DESCRIPTION: Maps the physical address of table into a logical address
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_map_acpi_table (
+ void *physical_address,
+ u32 *size,
+ void **logical_address)
+{
+ ACPI_TABLE_HEADER *table;
+ u32 table_size = *size;
+ ACPI_STATUS status = AE_OK;
+
+
+ /* If size is zero, look at the table header to get the actual size */
+
+ if ((*size) == 0) {
+ /* Get the table header so we can extract the table length */
+
+ status = acpi_os_map_memory (physical_address, sizeof (ACPI_TABLE_HEADER),
+ (void **) &table);
+ if (ACPI_FAILURE (status)) {
+ return status;
+ }
+
+ /* Extract the full table length before we delete the mapping */
+
+ table_size = table->length;
+
+ /*
+ * Validate the header and delete the mapping.
+ * We will create a mapping for the full table below.
+ */
+
+ status = acpi_tb_validate_table_header (table);
+
+ /* Always unmap the memory for the header */
+
+ acpi_os_unmap_memory (table, sizeof (ACPI_TABLE_HEADER));
+
+ /* Exit if header invalid */
+
+ if (ACPI_FAILURE (status)) {
+ return status;
+ }
+ }
+
+
+ /* Map the physical memory for the correct length */
+
+ status = acpi_os_map_memory (physical_address, table_size, (void **) &table);
+ if (ACPI_FAILURE (status)) {
+ return status;
+ }
+
+ *size = table_size;
+ *logical_address = table;
+
+ return status;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_verify_table_checksum
+ *
+ * PARAMETERS: *Table_header - ACPI table to verify
+ *
+ * RETURN: 8 bit checksum of table
+ *
+ * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct
+ * table should have a checksum of 0.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_tb_verify_table_checksum (
+ ACPI_TABLE_HEADER *table_header)
+{
+ u8 check_sum;
+ ACPI_STATUS status = AE_OK;
+
+
+ /* Compute the checksum on the table */
+
+ check_sum = acpi_tb_checksum (table_header, table_header->length);
+
+ /* Return the appropriate exception */
+
+ if (check_sum) {
+ REPORT_ERROR ("Invalid ACPI table checksum");
+ status = AE_BAD_CHECKSUM;
+ }
+
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_tb_checksum
+ *
+ * PARAMETERS: Buffer - Buffer to checksum
+ * Length - Size of the buffer
+ *
+ * RETURNS 8 bit checksum of buffer
+ *
+ * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
+ *
+ ******************************************************************************/
+
+u8
+acpi_tb_checksum (
+ void *buffer,
+ u32 length)
+{
+ u8 *limit;
+ u8 *rover;
+ u8 sum = 0;
+
+
+ if (buffer && length) {
+ /* Buffer and Length are valid */
+
+ limit = (u8 *) buffer + length;
+
+ for (rover = buffer; rover < limit; rover++) {
+ sum = (u8) (sum + *rover);
+ }
+ }
+
+ return sum;
+}
+
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)