patch-2.4.0-test3 linux/drivers/acpi/interpreter/amutils.c
Next file: linux/drivers/acpi/interpreter/amxface.c
Previous file: linux/drivers/acpi/interpreter/amsystem.c
Back to the patch index
Back to the overall index
- Lines: 523
- Date:
Wed Jul 5 11:23:12 2000
- Orig file:
v2.4.0-test2/linux/drivers/acpi/interpreter/amutils.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/interpreter/amutils.c linux/drivers/acpi/interpreter/amutils.c
@@ -0,0 +1,522 @@
+
+/******************************************************************************
+ *
+ * Module Name: amutils - interpreter/scanner 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 "parser.h"
+#include "interp.h"
+#include "amlcode.h"
+#include "namesp.h"
+#include "events.h"
+
+#define _COMPONENT INTERPRETER
+ MODULE_NAME ("amutils");
+
+
+typedef struct internal_search_st
+{
+ ACPI_OBJECT_INTERNAL *dest_obj;
+ u32 index;
+ ACPI_OBJECT_INTERNAL *source_obj;
+
+} INTERNAL_PKG_SEARCH_INFO;
+
+
+/* Used to traverse nested packages when copying*/
+
+INTERNAL_PKG_SEARCH_INFO copy_level[MAX_PACKAGE_DEPTH];
+
+
+static char hex[] =
+ {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_enter_interpreter
+ *
+ * PARAMETERS: None
+ *
+ * DESCRIPTION: Enter the interpreter execution region
+ *
+ ******************************************************************************/
+
+void
+acpi_aml_enter_interpreter (void)
+{
+
+ acpi_cm_acquire_mutex (ACPI_MTX_EXECUTE);
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_exit_interpreter
+ *
+ * PARAMETERS: None
+ *
+ * DESCRIPTION: Exit the interpreter execution region
+ *
+ * Cases where the interpreter is unlocked:
+ * 1) Completion of the execution of a control method
+ * 2) Method blocked on a Sleep() AML opcode
+ * 3) Method blocked on an Acquire() AML opcode
+ * 4) Method blocked on a Wait() AML opcode
+ * 5) Method blocked to acquire the global lock
+ * 6) Method blocked to execute a serialized control method that is
+ * already executing
+ * 7) About to invoke a user-installed opregion handler
+ *
+ ******************************************************************************/
+
+void
+acpi_aml_exit_interpreter (void)
+{
+
+ acpi_cm_release_mutex (ACPI_MTX_EXECUTE);
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_validate_object_type
+ *
+ * PARAMETERS: Type Object type to validate
+ *
+ * DESCRIPTION: Determine if a type is a valid ACPI object type
+ *
+ ******************************************************************************/
+
+u8
+acpi_aml_validate_object_type (
+ ACPI_OBJECT_TYPE type)
+{
+
+ if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) ||
+ (type > INTERNAL_TYPE_MAX))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_append_operand_diag
+ *
+ * PARAMETERS: *File_name - Name of source file
+ * Line_num - Line Number in file
+ * Op_code - Op_code being executed
+ * Num_operands - Number of operands Prep_stack tried to check
+ *
+ * DESCRIPTION: Print diagnostic information about operands.
+ * This function is intended to be called after Prep_stack
+ * has returned S_ERROR.
+ *
+ ******************************************************************************/
+
+void
+acpi_aml_append_operand_diag (
+ char *file_name,
+ s32 line_num,
+ u16 op_code,
+ ACPI_OBJECT_INTERNAL **operands,
+ s32 num_operands)
+{
+
+ /*
+ * This function outputs debug information only
+ */
+
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_buf_seq
+ *
+ * RETURN: The next buffer descriptor sequence number
+ *
+ * DESCRIPTION: Provide a unique sequence number for each Buffer descriptor
+ * allocated during the interpreter's existence. These numbers
+ * are used to relate Field_unit descriptors to the Buffers
+ * within which the fields are defined.
+ *
+ * Just increment the global counter and return it.
+ *
+ ******************************************************************************/
+
+u32
+acpi_aml_buf_seq (void)
+{
+
+ return ++acpi_gbl_buf_seq;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_acquire_global_lock
+ *
+ * PARAMETERS: Rule - Lock rule: Always_lock, Never_lock
+ *
+ * RETURN: TRUE/FALSE indicating whether the lock was actually acquired
+ *
+ * DESCRIPTION: Obtain the global lock and keep track of this fact via two
+ * methods. A global variable keeps the state of the lock, and
+ * the state is returned to the caller.
+ *
+ ******************************************************************************/
+
+u8
+acpi_aml_acquire_global_lock (
+ u32 rule)
+{
+ u8 locked = FALSE;
+ ACPI_STATUS status;
+
+
+ /* Only attempt lock if the Rule says so */
+
+ if (rule == (u32) GLOCK_ALWAYS_LOCK) {
+ /* OK to get the lock */
+
+ status = acpi_ev_acquire_global_lock ();
+
+ if (ACPI_SUCCESS (status)) {
+ acpi_gbl_global_lock_set = TRUE;
+ locked = TRUE;
+ }
+ }
+
+ return (locked);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_release_global_lock
+ *
+ * PARAMETERS: Locked_by_me - Return value from corresponding call to
+ * Acquire_global_lock.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release the global lock if it is locked.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_release_global_lock (
+ u8 locked_by_me)
+{
+
+
+ /* Only attempt unlock if the caller locked it */
+
+ if (locked_by_me) {
+ /* Double check against the global flag */
+
+ if (acpi_gbl_global_lock_set) {
+ /* OK, now release the lock */
+
+ acpi_ev_release_global_lock ();
+ acpi_gbl_global_lock_set = FALSE;
+ }
+
+ }
+
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_digits_needed
+ *
+ * PARAMETERS: val - Value to be represented
+ * base - Base of representation
+ *
+ * RETURN: the number of digits needed to represent val in base
+ *
+ ******************************************************************************/
+
+s32
+acpi_aml_digits_needed (
+ s32 val,
+ s32 base)
+{
+ s32 num_digits = 0;
+
+
+ if (base < 1) {
+ /* impossible base */
+
+ REPORT_ERROR ("Aml_digits_needed: Impossible base");
+ }
+
+ else {
+ for (num_digits = 1 + (val < 0) ; val /= base ; ++num_digits) { ; }
+ }
+
+ return (num_digits);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: ntohl
+ *
+ * PARAMETERS: Value - Value to be converted
+ *
+ * RETURN: Convert a 32-bit value to big-endian (swap the bytes)
+ *
+ ******************************************************************************/
+
+u32
+_ntohl (
+ u32 value)
+{
+ union
+ {
+ u32 value;
+ char bytes[4];
+ } out;
+
+ union
+ {
+ u32 value;
+ char bytes[4];
+ } in;
+
+
+ in.value = value;
+
+ out.bytes[0] = in.bytes[3];
+ out.bytes[1] = in.bytes[2];
+ out.bytes[2] = in.bytes[1];
+ out.bytes[3] = in.bytes[0];
+
+ return out.value;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_eisa_id_to_string
+ *
+ * PARAMETERS: Numeric_id - EISA ID to be converted
+ * Out_string - Where to put the converted string (8 bytes)
+ *
+ * RETURN: Convert a numeric EISA ID to string representation
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_eisa_id_to_string (
+ u32 numeric_id,
+ char *out_string)
+{
+ u32 id;
+
+ /* swap to big-endian to get contiguous bits */
+
+ id = _ntohl (numeric_id);
+
+ out_string[0] = (char) ('@' + ((id >> 26) & 0x1f));
+ out_string[1] = (char) ('@' + ((id >> 21) & 0x1f));
+ out_string[2] = (char) ('@' + ((id >> 16) & 0x1f));
+ out_string[3] = hex[(id >> 12) & 0xf];
+ out_string[4] = hex[(id >> 8) & 0xf];
+ out_string[5] = hex[(id >> 4) & 0xf];
+ out_string[6] = hex[id & 0xf];
+ out_string[7] = 0;
+
+ return AE_OK;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_build_copy_internal_package_object
+ *
+ * PARAMETERS: *Source_obj - Pointer to the source package object
+ * *Dest_obj - Where the internal object is returned
+ *
+ * RETURN: Status - the status of the call
+ *
+ * DESCRIPTION: This function is called to copy an internal package object
+ * into another internal package object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_build_copy_internal_package_object (
+ ACPI_OBJECT_INTERNAL *source_obj,
+ ACPI_OBJECT_INTERNAL *dest_obj)
+{
+ u32 current_depth = 0;
+ ACPI_STATUS status = AE_OK;
+ u32 length = 0;
+ u32 this_index;
+ u32 object_space = 0;
+ ACPI_OBJECT_INTERNAL *this_dest_obj;
+ ACPI_OBJECT_INTERNAL *this_source_obj;
+ INTERNAL_PKG_SEARCH_INFO *level_ptr;
+
+
+ /*
+ * Initialize the working variables
+ */
+
+ MEMSET ((void *) copy_level, 0, sizeof(copy_level));
+
+ copy_level[0].dest_obj = dest_obj;
+ copy_level[0].source_obj = source_obj;
+ level_ptr = ©_level[0];
+ current_depth = 0;
+
+ dest_obj->common.type = source_obj->common.type;
+ dest_obj->package.count = source_obj->package.count;
+
+
+ /*
+ * Build an array of ACPI_OBJECTS in the buffer
+ * and move the free space past it
+ */
+
+ dest_obj->package.elements = acpi_cm_callocate (
+ (dest_obj->package.count + 1) *
+ sizeof (void *));
+ if (!dest_obj->package.elements) {
+ /* Package vector allocation failure */
+
+ REPORT_ERROR ("Aml_build_copy_internal_package_object: Package vector allocation failure");
+ return (AE_NO_MEMORY);
+ }
+
+ dest_obj->package.next_element = dest_obj->package.elements;
+
+
+ while (1) {
+ this_index = level_ptr->index;
+ this_dest_obj = (ACPI_OBJECT_INTERNAL *) level_ptr->dest_obj->package.elements[this_index];
+ this_source_obj = (ACPI_OBJECT_INTERNAL *) level_ptr->source_obj->package.elements[this_index];
+
+ if (IS_THIS_OBJECT_TYPE (this_source_obj, ACPI_TYPE_PACKAGE)) {
+ /*
+ * If this object is a package then we go one deeper
+ */
+ if (current_depth >= MAX_PACKAGE_DEPTH-1) {
+ /*
+ * Too many nested levels of packages for us to handle
+ */
+ return (AE_LIMIT);
+ }
+
+ /*
+ * Build the package object
+ */
+ this_dest_obj = acpi_cm_create_internal_object (ACPI_TYPE_PACKAGE);
+ level_ptr->dest_obj->package.elements[this_index] = this_dest_obj;
+
+
+ this_dest_obj->common.type = ACPI_TYPE_PACKAGE;
+ this_dest_obj->package.count = this_dest_obj->package.count;
+
+ /*
+ * Save space for the array of objects (Package elements)
+ * update the buffer length counter
+ */
+ object_space = this_dest_obj->package.count *
+ sizeof (ACPI_OBJECT_INTERNAL);
+ length += object_space;
+ current_depth++;
+ level_ptr = ©_level[current_depth];
+ level_ptr->dest_obj = this_dest_obj;
+ level_ptr->source_obj = this_source_obj;
+ level_ptr->index = 0;
+
+ } /* if object is a package */
+
+ else {
+
+ this_dest_obj = acpi_cm_create_internal_object (
+ this_source_obj->common.type);
+ level_ptr->dest_obj->package.elements[this_index] = this_dest_obj;
+
+ status = acpi_aml_store_object_to_object(this_source_obj, this_dest_obj);
+
+ if (status != AE_OK) {
+ /*
+ * Failure get out
+ */
+ return (status);
+ }
+
+ length +=object_space;
+
+ level_ptr->index++;
+ while (level_ptr->index >= level_ptr->dest_obj->package.count) {
+ /*
+ * We've handled all of the objects at this level, This means
+ * that we have just completed a package. That package may
+ * have contained one or more packages itself
+ */
+ if (current_depth == 0) {
+ /*
+ * We have handled all of the objects in the top level
+ * package just add the length of the package objects
+ * and exit
+ */
+ return (AE_OK);
+ }
+
+ /*
+ * Go back up a level and move the index past the just
+ * completed package object.
+ */
+ current_depth--;
+ level_ptr = ©_level[current_depth];
+ level_ptr->index++;
+ }
+ } /* else object is NOT a package */
+ } /* while (1) */
+
+
+ /*
+ * We'll never get here, but the compiler whines about return value
+ */
+ return (AE_OK);
+}
+
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)