diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:26:51 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 20:26:51 -0800 |
| commit | 980adcb2cbdd20c15fe63b4c2db12ca0051d8c7d (patch) | |
| tree | 696c33a1fd8c9d41812ebc2be369bbe2cd203565 /drivers/acpi/executer | |
| parent | 9ff086a3d48d6f6e24281e6edb6c804091eda3d1 (diff) | |
v2.4.13 -> v2.4.13.1
- Michael Warfield: computone serial driver update
- Alexander Viro: cdrom module race fixes
- David Miller: Acenic driver fix
- Andrew Grover: ACPI update
- Kai Germaschewski: ISDN update
- Tim Waugh: parport update
- David Woodhouse: JFFS garbage collect sleep
Diffstat (limited to 'drivers/acpi/executer')
| -rw-r--r-- | drivers/acpi/executer/exconfig.c | 72 | ||||
| -rw-r--r-- | drivers/acpi/executer/exconvrt.c | 12 | ||||
| -rw-r--r-- | drivers/acpi/executer/excreate.c | 472 | ||||
| -rw-r--r-- | drivers/acpi/executer/exdump.c | 61 | ||||
| -rw-r--r-- | drivers/acpi/executer/exdyadic.c | 874 | ||||
| -rw-r--r-- | drivers/acpi/executer/exfldio.c | 58 | ||||
| -rw-r--r-- | drivers/acpi/executer/exmisc.c | 563 | ||||
| -rw-r--r-- | drivers/acpi/executer/exmonad.c | 970 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg1.c | 878 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg2.c | 564 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg3.c | 235 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg6.c | 276 | ||||
| -rw-r--r-- | drivers/acpi/executer/exprep.c | 286 | ||||
| -rw-r--r-- | drivers/acpi/executer/exregion.c | 88 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresnte.c | 79 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresolv.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresop.c | 8 | ||||
| -rw-r--r-- | drivers/acpi/executer/exstore.c | 93 | ||||
| -rw-r--r-- | drivers/acpi/executer/exutils.c | 23 | ||||
| -rw-r--r-- | drivers/acpi/executer/exxface.c | 102 |
20 files changed, 2692 insertions, 3032 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 82bfd875ae31..2a29c61b511e 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 41 $ + * $Revision: 44 $ * *****************************************************************************/ @@ -51,10 +51,10 @@ * ****************************************************************************/ -static acpi_status -acpi_ex_load_table_op ( +acpi_status +acpi_ex_load_op ( acpi_operand_object *rgn_desc, - acpi_operand_object **ddb_handle) + acpi_operand_object *ddb_handle) { acpi_status status; acpi_operand_object *table_desc = NULL; @@ -65,7 +65,7 @@ acpi_ex_load_table_op ( u32 i; - FUNCTION_TRACE ("Ex_load_table"); + FUNCTION_TRACE ("Ex_load_op"); /* TBD: [Unhandled] Object can be either a field or an opregion */ @@ -117,7 +117,7 @@ acpi_ex_load_table_op ( acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", - table_header.signature)); + (char*)table_header.signature)); status = AE_BAD_SIGNATURE; goto cleanup; } @@ -165,7 +165,8 @@ acpi_ex_load_table_op ( table_desc->reference.opcode = AML_LOAD_OP; table_desc->reference.object = table_info.installed_desc; - *ddb_handle = table_desc; + /* TBD: store the tabledesc into the Ddb_handle target */ + /* Ddb_handle = Table_desc; */ return_ACPI_STATUS (status); @@ -175,7 +176,6 @@ cleanup: ACPI_MEM_FREE (table_desc); ACPI_MEM_FREE (table_ptr); return_ACPI_STATUS (status); - } @@ -191,7 +191,7 @@ cleanup: * ****************************************************************************/ -static acpi_status +acpi_status acpi_ex_unload_table ( acpi_operand_object *ddb_handle) { @@ -240,57 +240,3 @@ acpi_ex_unload_table ( return_ACPI_STATUS (status); } - -/***************************************************************************** - * - * FUNCTION: Acpi_ex_reconfiguration - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current state of the parse tree walk - * - * RETURN: Status - * - * DESCRIPTION: Reconfiguration opcodes such as LOAD and UNLOAD - * - ****************************************************************************/ - -acpi_status -acpi_ex_reconfiguration ( - u16 opcode, - acpi_walk_state *walk_state) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_status status; - - - FUNCTION_TRACE ("Ex_reconfiguration"); - -#define ddb_handle operand[0] -#define region_desc operand[1] - - - switch (opcode) { - - case AML_LOAD_OP: - - status = acpi_ex_load_table_op (region_desc, &ddb_handle); - break; - - - case AML_UNLOAD_OP: - - status = acpi_ex_unload_table (ddb_handle); - break; - - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "bad opcode=%X\n", opcode)); - status = AE_AML_BAD_OPCODE; - break; - } - - - return_ACPI_STATUS (status); -} - diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 92f6c117718e..7e72920679d5 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exconvrt - Object conversion routines - * $Revision: 22 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -230,7 +230,7 @@ acpi_ex_convert_to_buffer ( new_buf = ACPI_MEM_CALLOCATE (integer_size); if (!new_buf) { REPORT_ERROR - (("Ex_dyadic2_r/Concat_op: Buffer allocation failure\n")); + (("Ex_convert_to_buffer: Buffer allocation failure\n")); acpi_ut_remove_reference (ret_desc); return (AE_NO_MEMORY); } @@ -296,8 +296,9 @@ acpi_ex_convert_to_ascii ( u32 k = 0; u8 hex_digit; acpi_integer digit; - u8 leading_zero = TRUE; + u32 remainder; u32 length = sizeof (acpi_integer); + u8 leading_zero = TRUE; FUNCTION_ENTRY (); @@ -306,12 +307,13 @@ acpi_ex_convert_to_ascii ( switch (base) { case 10: + remainder = 0; for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0 ; i--) { /* Divide by nth factor of 10 */ digit = integer; for (j = 1; j < i; j++) { - digit = ACPI_DIVIDE (digit, 10); + acpi_ut_short_divide (&digit, 10, &digit, &remainder); } /* Create the decimal digit */ @@ -321,7 +323,7 @@ acpi_ex_convert_to_ascii ( } if (!leading_zero) { - string[k] = (u8) (ASCII_ZERO + ACPI_MODULO (digit, 10)); + string[k] = (u8) (ASCII_ZERO + remainder); k++; } } diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 64b5a5425c38..be5e9c4e431d 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 66 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -37,162 +37,6 @@ MODULE_NAME ("excreate") -/******************************************************************************* - * - * FUNCTION: Acpi_ex_create_buffer_field - * - * PARAMETERS: Opcode - The opcode to be executed - * Operands - List of operands for the opcode - * - * RETURN: Status - * - * DESCRIPTION: Execute Create_field operators: Create_bit_field_op, - * Create_byte_field_op, Create_word_field_op, Create_dWord_field_op, - * Create_field_op (which define fields in buffers) - * - * ALLOCATION: Deletes Create_field_op's count operand descriptor - * - * - * ACPI SPECIFICATION REFERENCES: - * Def_create_bit_field := Create_bit_field_op Src_buf Bit_idx Name_string - * Def_create_byte_field := Create_byte_field_op Src_buf Byte_idx Name_string - * Def_create_dWord_field := Create_dWord_field_op Src_buf Byte_idx Name_string - * Def_create_field := Create_field_op Src_buf Bit_idx Num_bits Name_string - * Def_create_word_field := Create_word_field_op Src_buf Byte_idx Name_string - * Bit_index := Term_arg=>Integer - * Byte_index := Term_arg=>Integer - * Num_bits := Term_arg=>Integer - * Source_buff := Term_arg=>Buffer - * - ******************************************************************************/ - -acpi_status -acpi_ex_create_buffer_field ( - u8 *aml_ptr, - u32 aml_length, - acpi_namespace_node *node, - acpi_walk_state *walk_state) -{ - acpi_status status; - acpi_operand_object *obj_desc; - acpi_operand_object *tmp_desc; - - - FUNCTION_TRACE ("Ex_create_buffer_field"); - - - /* Create the descriptor */ - - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD); - if (!obj_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - - /* - * Allocate a method object for this field unit - */ - obj_desc->buffer_field.extra = acpi_ut_create_internal_object ( - INTERNAL_TYPE_EXTRA); - if (!obj_desc->buffer_field.extra) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* - * Remember location in AML stream of the field unit - * opcode and operands -- since the buffer and index - * operands must be evaluated. - */ - obj_desc->buffer_field.extra->extra.pcode = aml_ptr; - obj_desc->buffer_field.extra->extra.pcode_length = aml_length; - obj_desc->buffer_field.node = node; - - - /* - * This operation is supposed to cause the destination Name to refer - * to the defined Buffer_field -- it must not store the constructed - * Buffer_field object (or its current value) in some location that the - * Name may already be pointing to. So, if the Name currently contains - * a reference which would cause Acpi_ex_store() to perform an indirect - * store rather than setting the value of the Name itself, clobber that - * reference before calling Acpi_ex_store(). - */ - - /* Type of Name's existing value */ - - switch (acpi_ns_get_type (node)) { - - case ACPI_TYPE_BUFFER_FIELD: - case INTERNAL_TYPE_ALIAS: - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: - - tmp_desc = acpi_ns_get_attached_object (node); - if (tmp_desc) { - /* - * There is an existing object here; delete it and zero out the - * object field within the Node - */ - DUMP_PATHNAME (node, - "Ex_create_buffer_field: Removing Current Reference", - ACPI_LV_BFIELD, _COMPONENT); - - DUMP_ENTRY (node, ACPI_LV_BFIELD); - DUMP_STACK_ENTRY (tmp_desc); - - acpi_ut_remove_reference (tmp_desc); - acpi_ns_attach_object ((acpi_namespace_node *) node, NULL, - ACPI_TYPE_ANY); - } - - /* Set the type to ANY (or the store below will fail) */ - - ((acpi_namespace_node *) node)->type = ACPI_TYPE_ANY; - - break; - - - default: - - break; - } - - - /* Store constructed field descriptor in result location */ - - status = acpi_ex_store (obj_desc, (acpi_operand_object *) node, - walk_state); - - /* - * If the field descriptor was not physically stored (or if a failure - * above), we must delete it - */ - if (obj_desc->common.reference_count <= 1) { - acpi_ut_remove_reference (obj_desc); - } - - - return_ACPI_STATUS (AE_OK); - - -cleanup: - - /* Delete region object and method subobject */ - - if (obj_desc) { - /* Remove deletes both objects! */ - - acpi_ut_remove_reference (obj_desc); - obj_desc = NULL; - } - - return_ACPI_STATUS (status); -} - - /***************************************************************************** * * FUNCTION: Acpi_ex_create_alias @@ -211,7 +55,6 @@ acpi_ex_create_alias ( acpi_walk_state *walk_state) { acpi_namespace_node *source_node; - acpi_namespace_node *alias_node; acpi_status status; @@ -220,29 +63,19 @@ acpi_ex_create_alias ( /* Get the source/alias operands (both namespace nodes) */ - source_node = (acpi_namespace_node *) walk_state->operands[walk_state->num_operands -1]; - walk_state->num_operands--; - - /* - * Don't pop it, it gets removed in the calling routine - */ - alias_node = acpi_ds_obj_stack_get_value (0, walk_state); + source_node = (acpi_namespace_node *) walk_state->operands[1]; - /* Add an additional reference to the object */ - acpi_ut_add_reference (source_node->object); + /* Attach the original source object to the new Alias Node */ - /* - * Attach the original source Node to the new Alias Node. - */ - status = acpi_ns_attach_object (alias_node, source_node->object, + status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], + source_node->object, source_node->type); - /* * The new alias assumes the type of the source, but it points - * to the same object. The reference count of the object has two - * additional references to prevent deletion out from under either the + * to the same object. The reference count of the object has an + * additional reference to prevent deletion out from under either the * source or the alias Node */ @@ -256,7 +89,7 @@ acpi_ex_create_alias ( * * FUNCTION: Acpi_ex_create_event * - * PARAMETERS: None + * PARAMETERS: Walk_state - Current state * * RETURN: Status * @@ -288,23 +121,20 @@ acpi_ex_create_event ( status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 1, &obj_desc->event.semaphore); if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); goto cleanup; } /* Attach object to the Node */ - status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state), + status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], obj_desc, (u8) ACPI_TYPE_EVENT); - if (ACPI_FAILURE (status)) { - acpi_os_delete_semaphore (obj_desc->event.semaphore); - acpi_ut_remove_reference (obj_desc); - goto cleanup; - } - cleanup: - + /* + * Remove local reference to the object (on error, will cause deletion + * of both object and semaphore if present.) + */ + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } @@ -313,13 +143,14 @@ cleanup: * * FUNCTION: Acpi_ex_create_mutex * - * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec) - * Operands - List of operands for the opcode + * PARAMETERS: Walk_state - Current state * * RETURN: Status * * DESCRIPTION: Create a new mutex object * + * Mutex (Name[0], Sync_level[1]) + * ****************************************************************************/ acpi_status @@ -327,19 +158,13 @@ acpi_ex_create_mutex ( acpi_walk_state *walk_state) { acpi_status status = AE_OK; - acpi_operand_object *sync_desc; acpi_operand_object *obj_desc; FUNCTION_TRACE_PTR ("Ex_create_mutex", WALK_OPERANDS); - /* Get the operand */ - - sync_desc = walk_state->operands[walk_state->num_operands -1]; - walk_state->num_operands--; - - /* Attempt to allocate a new object */ + /* Create the new mutex object */ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_MUTEX); if (!obj_desc) { @@ -351,29 +176,23 @@ acpi_ex_create_mutex ( status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore); if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); goto cleanup; } - obj_desc->mutex.sync_level = (u8) sync_desc->integer.value; + /* Init object and attach to NS node */ - /* Obj_desc was on the stack top, and the name is below it */ + obj_desc->mutex.sync_level = (u8) walk_state->operands[1]->integer.value; - status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state), + status = acpi_ns_attach_object ((acpi_namespace_node *) walk_state->operands[0], obj_desc, (u8) ACPI_TYPE_MUTEX); - if (ACPI_FAILURE (status)) { - acpi_os_delete_semaphore (obj_desc->mutex.semaphore); - acpi_ut_remove_reference (obj_desc); - goto cleanup; - } cleanup: - - /* Always delete the operand */ - - acpi_ut_remove_reference (sync_desc); - + /* + * Remove local reference to the object (on error, will cause deletion + * of both object and semaphore if present.) + */ + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } @@ -382,10 +201,10 @@ cleanup: * * FUNCTION: Acpi_ex_create_region * - * PARAMETERS: Aml_ptr - Pointer to the region declaration AML + * PARAMETERS: Aml_start - Pointer to the region declaration AML * Aml_length - Max length of the declaration AML * Operands - List of operands for the opcode - * Interpreter_mode - Load1/Load2/Execute + * Walk_state - Current state * * RETURN: Status * @@ -395,7 +214,7 @@ cleanup: acpi_status acpi_ex_create_region ( - u8 *aml_ptr, + u8 *aml_start, u32 aml_length, u8 region_space, acpi_walk_state *walk_state) @@ -408,6 +227,18 @@ acpi_ex_create_region ( FUNCTION_TRACE ("Ex_create_region"); + /* Get the Node from the object stack */ + + node = (acpi_namespace_node *) walk_state->operands[0]; + + /* + * If the region object is already attached to this node, + * just return + */ + if (node->object) { + return_ACPI_STATUS (AE_OK); + } + /* * Space ID must be one of the predefined IDs, or in the user-defined * range @@ -422,10 +253,6 @@ acpi_ex_create_region ( acpi_ut_get_region_name (region_space), region_space)); - /* Get the Node from the object stack */ - - node = (acpi_namespace_node *) acpi_ds_obj_stack_get_value (0, walk_state); - /* Create the region descriptor */ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION); @@ -434,9 +261,8 @@ acpi_ex_create_region ( goto cleanup; } - /* - * Allocate a method object for this region. - */ + /* Allocate a method object for this region */ + obj_desc->region.extra = acpi_ut_create_internal_object ( INTERNAL_TYPE_EXTRA); if (!obj_desc->region.extra) { @@ -448,23 +274,20 @@ acpi_ex_create_region ( * Remember location in AML stream of address & length * operands since they need to be evaluated at run time. */ - obj_desc->region.extra->extra.pcode = aml_ptr; - obj_desc->region.extra->extra.pcode_length = aml_length; + obj_desc->region.extra->extra.aml_start = aml_start; + obj_desc->region.extra->extra.aml_length = aml_length; /* Init the region from the operands */ - obj_desc->region.space_id = region_space; - obj_desc->region.address = 0; - obj_desc->region.length = 0; - + obj_desc->region.space_id = region_space; + obj_desc->region.address = 0; + obj_desc->region.length = 0; + obj_desc->region.node = node; /* Install the new region object in the parent Node */ - obj_desc->region.node = node; - status = acpi_ns_attach_object (node, obj_desc, (u8) ACPI_TYPE_REGION); - if (ACPI_FAILURE (status)) { goto cleanup; } @@ -474,7 +297,6 @@ acpi_ex_create_region ( * Namespace is NOT locked at this point. */ status = acpi_ev_initialize_region (obj_desc, FALSE); - if (ACPI_FAILURE (status)) { /* * If AE_NOT_EXIST is returned, it is not fatal @@ -488,17 +310,48 @@ acpi_ex_create_region ( cleanup: - if (ACPI_FAILURE (status)) { - /* Delete region object and method subobject */ + /* Remove local reference to the object */ - if (obj_desc) { - /* Remove deletes both objects! */ + acpi_ut_remove_reference (obj_desc); - acpi_ut_remove_reference (obj_desc); - obj_desc = NULL; - } + return_ACPI_STATUS (status); +} + + +/***************************************************************************** + * + * FUNCTION: Acpi_ex_create_table_region + * + * PARAMETERS: Walk_state - Current state + * + * RETURN: Status + * + * DESCRIPTION: Create a new Data_table_region object + * + ****************************************************************************/ + +acpi_status +acpi_ex_create_table_region ( + acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + + + FUNCTION_TRACE ("Ex_create_table_region"); + +/* + acpi_operand_object *Obj_desc; + Obj_desc = Acpi_ut_create_internal_object (ACPI_TYPE_REGION); + if (!Obj_desc) + { + Status = AE_NO_MEMORY; + goto Cleanup; } + +Cleanup: +*/ + return_ACPI_STATUS (status); } @@ -515,68 +368,46 @@ cleanup: * * DESCRIPTION: Create a new processor object and populate the fields * + * Processor (Name[0], Cpu_iD[1], Pblock_addr[2], Pblock_length[3]) + * ****************************************************************************/ acpi_status acpi_ex_create_processor ( - acpi_parse_object *op, - acpi_namespace_node *processor_node) + acpi_walk_state *walk_state) { - acpi_status status; - acpi_parse_object *arg; + acpi_operand_object **operand = &walk_state->operands[0]; acpi_operand_object *obj_desc; + acpi_status status; - FUNCTION_TRACE_PTR ("Ex_create_processor", op); + FUNCTION_TRACE_PTR ("Ex_create_processor", walk_state); + /* Create the processor object */ + obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PROCESSOR); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Install the new processor object in the parent Node */ - - status = acpi_ns_attach_object (processor_node, obj_desc, - (u8) ACPI_TYPE_PROCESSOR); - if (ACPI_FAILURE (status)) { - acpi_ut_delete_object_desc (obj_desc); - return_ACPI_STATUS (status); - } - - /* Get first arg and verify existence */ - - arg = op->value.arg; - if (!arg) { - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } - - /* First arg is the Processor ID */ - - obj_desc->processor.proc_id = (u8) arg->value.integer; - - /* Get second arg and verify existence */ - - arg = arg->next; - if (!arg) { - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } + /* + * Initialize the processor object from the operands + */ + obj_desc->processor.proc_id = (u8) operand[1]->integer.value; + obj_desc->processor.address = (ACPI_IO_ADDRESS) operand[2]->integer.value; + obj_desc->processor.length = (u8) operand[3]->integer.value; - /* Second arg is the PBlock Address */ + /* Install the processor object in the parent Node */ - obj_desc->processor.address = (ACPI_IO_ADDRESS) arg->value.integer; + status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], + obj_desc, (u8) ACPI_TYPE_PROCESSOR); - /* Get third arg and verify existence */ - arg = arg->next; - if (!arg) { - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } + /* Remove local reference to the object */ - /* Third arg is the PBlock Length */ - - obj_desc->processor.length = (u8) arg->value.integer; - return_ACPI_STATUS (AE_OK); + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); } @@ -592,58 +423,44 @@ acpi_ex_create_processor ( * * DESCRIPTION: Create a new Power_resource object and populate the fields * + * Power_resource (Name[0], System_level[1], Resource_order[2]) + * ****************************************************************************/ acpi_status acpi_ex_create_power_resource ( - acpi_parse_object *op, - acpi_namespace_node *power_node) + acpi_walk_state *walk_state) { + acpi_operand_object **operand = &walk_state->operands[0]; acpi_status status; - acpi_parse_object *arg; acpi_operand_object *obj_desc; - FUNCTION_TRACE_PTR ("Ex_create_power_resource", op); + FUNCTION_TRACE_PTR ("Ex_create_power_resource", walk_state); + + /* Create the power resource object */ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_POWER); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - /* Install the new power resource object in the parent Node */ - - status = acpi_ns_attach_object (power_node, obj_desc, - (u8) ACPI_TYPE_POWER); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS(status); - } - - - /* Get first arg and verify existence */ - - arg = op->value.arg; - if (!arg) { - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } - - /* First arg is the System_level */ + /* Initialize the power object from the operands */ - obj_desc->power_resource.system_level = (u8) arg->value.integer; + obj_desc->power_resource.system_level = (u8) operand[1]->integer.value; + obj_desc->power_resource.resource_order = (u16) operand[2]->integer.value; - /* Get second arg and check existence */ + /* Install the power resource object in the parent Node */ - arg = arg->next; - if (!arg) { - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } + status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], + obj_desc, (u8) ACPI_TYPE_POWER); - /* Second arg is the PBlock Address */ - obj_desc->power_resource.resource_order = (u16) arg->value.integer; + /* Remove local reference to the object */ - return_ACPI_STATUS (AE_OK); + acpi_ut_remove_reference (obj_desc); + return_ACPI_STATUS (status); } @@ -651,7 +468,7 @@ acpi_ex_create_power_resource ( * * FUNCTION: Acpi_ex_create_method * - * PARAMETERS: Aml_ptr - First byte of the method's AML + * PARAMETERS: Aml_start - First byte of the method's AML * Aml_length - AML byte count for this method * Method_flags - AML method flag byte * Method - Method Node @@ -664,16 +481,17 @@ acpi_ex_create_power_resource ( acpi_status acpi_ex_create_method ( - u8 *aml_ptr, + u8 *aml_start, u32 aml_length, - u32 method_flags, - acpi_namespace_node *method) + acpi_walk_state *walk_state) { + acpi_operand_object **operand = &walk_state->operands[0]; acpi_operand_object *obj_desc; acpi_status status; + u8 method_flags; - FUNCTION_TRACE_PTR ("Ex_create_method", method); + FUNCTION_TRACE_PTR ("Ex_create_method", walk_state); /* Create a new method object */ @@ -683,18 +501,17 @@ acpi_ex_create_method ( return_ACPI_STATUS (AE_NO_MEMORY); } - /* Get the method's AML pointer/length from the Op */ + /* Save the method's AML pointer and length */ - obj_desc->method.pcode = aml_ptr; - obj_desc->method.pcode_length = aml_length; + obj_desc->method.aml_start = aml_start; + obj_desc->method.aml_length = aml_length; - /* - * First argument is the Method Flags (contains parameter count for the - * method) - */ - obj_desc->method.method_flags = (u8) method_flags; - obj_desc->method.param_count = (u8) (method_flags & - METHOD_FLAGS_ARG_COUNT); + /* disassemble the method flags */ + + method_flags = (u8) operand[1]->integer.value; + + obj_desc->method.method_flags = method_flags; + obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT); /* * Get the concurrency count. If required, a semaphore will be @@ -715,11 +532,16 @@ acpi_ex_create_method ( /* Attach the new object to the method Node */ - status = acpi_ns_attach_object (method, obj_desc, (u8) ACPI_TYPE_METHOD); - if (ACPI_FAILURE (status)) { - acpi_ut_delete_object_desc (obj_desc); - } + status = acpi_ns_attach_object ((acpi_namespace_node *) operand[0], + obj_desc, (u8) ACPI_TYPE_METHOD); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + + /* Remove a reference to the operand */ + acpi_ut_remove_reference (operand[1]); return_ACPI_STATUS (status); } diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index ef8cdb833c75..9811ee89f6a7 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exdump - Interpreter debug output routines - * $Revision: 123 $ + * $Revision: 126 $ * *****************************************************************************/ @@ -46,12 +46,12 @@ * FUNCTION: Acpi_ex_show_hex_value * * PARAMETERS: Byte_count - Number of bytes to print (1, 2, or 4) - * *Aml_ptr - Address in AML stream of bytes to print + * *Aml_start - Address in AML stream of bytes to print * Interpreter_mode - Current running mode (load1/Load2/Exec) * Lead_space - # of spaces to print ahead of value * 0 => none ahead but one behind * - * DESCRIPTION: Print Byte_count byte(s) starting at Aml_ptr as a single + * DESCRIPTION: Print Byte_count byte(s) starting at Aml_start as a single * value, in hex. If Byte_count > 1 or the value printed is > 9, also * print in decimal. * @@ -60,7 +60,7 @@ void acpi_ex_show_hex_value ( u32 byte_count, - u8 *aml_ptr, + u8 *aml_start, u32 lead_space) { u32 value; /* Value retrieved from AML stream */ @@ -72,7 +72,7 @@ acpi_ex_show_hex_value ( FUNCTION_TRACE ("Ex_show_hex_value"); - if (!aml_ptr) { + if (!aml_start) { REPORT_ERROR (("Ex_show_hex_value: null pointer\n")); } @@ -80,9 +80,9 @@ acpi_ex_show_hex_value ( * AML numbers are always stored little-endian, * even if the processor is big-endian. */ - for (current_aml_ptr = aml_ptr + byte_count, + for (current_aml_ptr = aml_start + byte_count, value = 0; - current_aml_ptr > aml_ptr; ) { + current_aml_ptr > aml_start; ) { value = (value << 8) + (u32)* --current_aml_ptr; } @@ -96,14 +96,12 @@ acpi_ex_show_hex_value ( length += 3 + acpi_ex_digits_needed (value, 10); } - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "")); - for (length = lead_space; length; --length ) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " ")); } while (byte_count--) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, "%02x", *aml_ptr++)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, "%02x", *aml_start++)); if (byte_count) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " ")); @@ -111,7 +109,7 @@ acpi_ex_show_hex_value ( } if (show_decimal_value) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " [%ld]", value)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_LOAD, " [%d]", value)); } if (0 == lead_space) { @@ -163,12 +161,6 @@ acpi_ex_dump_operand ( return (AE_OK); } - if (acpi_tb_system_table_pointer (entry_desc)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%p is an AML pointer\n", - entry_desc)); - return (AE_OK); - } - if (!VALID_DESCRIPTOR_TYPE (entry_desc, ACPI_DESC_TYPE_INTERNAL)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%p Is not a local object \n", entry_desc)); DUMP_BUFFER (entry_desc, sizeof (acpi_operand_object)); @@ -236,8 +228,9 @@ acpi_ex_dump_operand ( if (ACPI_TYPE_INTEGER == entry_desc->common.type) { /* Value is a Number */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%ld]", - entry_desc->integer.value)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%8.8X%8.8x]", + HIDWORD(entry_desc->integer.value), + LODWORD(entry_desc->integer.value))); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); @@ -253,8 +246,9 @@ acpi_ex_dump_operand ( /* Value is a Number */ - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%ld]", - entry_desc->integer.value)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " value is [%8.8X%8.8x]", + HIDWORD(entry_desc->integer.value), + LODWORD(entry_desc->integer.value))); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); @@ -262,7 +256,7 @@ acpi_ex_dump_operand ( case AML_INT_NAMEPATH_OP: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference.Node->Name %x\n", + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Reference.Node->Name %X\n", entry_desc->reference.node->name)); break; @@ -297,8 +291,7 @@ acpi_ex_dump_operand ( ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "Buffer Contents: ")); for (buf = entry_desc->buffer.pointer; length--; ++buf) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - length ? " %02x" : " %02x", *buf)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " %02x", *buf)); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,"\n")); } @@ -371,8 +364,10 @@ acpi_ex_dump_operand ( ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n")); } else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " base %p Length %X\n", - entry_desc->region.address, entry_desc->region.length)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, " base %8.8X%8.8X Length %X\n", + HIDWORD(entry_desc->region.address), + LODWORD(entry_desc->region.address), + entry_desc->region.length)); } break; @@ -400,7 +395,7 @@ acpi_ex_dump_operand ( case INTERNAL_TYPE_REGION_FIELD: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "Region_field: bits=%X bitaccwidth=%X lock=%X update=%X at byte=%lX bit=%X of below:\n", + "Region_field: bits=%X bitaccwidth=%X lock=%X update=%X at byte=%X bit=%X of below:\n", entry_desc->field.bit_length, entry_desc->field.access_bit_width, entry_desc->field.lock_rule, entry_desc->field.update_rule, entry_desc->field.base_byte_offset, entry_desc->field.start_field_bit_offset)); @@ -417,7 +412,7 @@ acpi_ex_dump_operand ( case ACPI_TYPE_BUFFER_FIELD: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "Buffer_field: %X bits at byte %lX bit %X of \n", + "Buffer_field: %X bits at byte %X bit %X of \n", entry_desc->buffer_field.bit_length, entry_desc->buffer_field.base_byte_offset, entry_desc->buffer_field.start_field_bit_offset)); @@ -449,9 +444,9 @@ acpi_ex_dump_operand ( case ACPI_TYPE_METHOD: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, - "Method(%X) @ %p:%lX\n", + "Method(%X) @ %p:%X\n", entry_desc->method.param_count, - entry_desc->method.pcode, entry_desc->method.pcode_length)); + entry_desc->method.aml_start, entry_desc->method.aml_length)); break; @@ -608,7 +603,7 @@ acpi_ex_dump_node ( } - acpi_os_printf ("%20s : %4.4s\n", "Name", &node->name); + acpi_os_printf ("%20s : %4.4s\n", "Name", (char*)&node->name); acpi_os_printf ("%20s : %s\n", "Type", acpi_ut_get_type_name (node->type)); acpi_os_printf ("%20s : %X\n", "Flags", node->flags); acpi_os_printf ("%20s : %X\n", "Owner Id", node->owner_id); @@ -730,8 +725,8 @@ acpi_ex_dump_object_descriptor ( acpi_os_printf ("%20s : %X\n", "Param_count", obj_desc->method.param_count); acpi_os_printf ("%20s : %X\n", "Concurrency", obj_desc->method.concurrency); acpi_os_printf ("%20s : %p\n", "Semaphore", obj_desc->method.semaphore); - acpi_os_printf ("%20s : %X\n", "Pcode_length", obj_desc->method.pcode_length); - acpi_os_printf ("%20s : %X\n", "Pcode", obj_desc->method.pcode); + acpi_os_printf ("%20s : %X\n", "Aml_length", obj_desc->method.aml_length); + acpi_os_printf ("%20s : %X\n", "Aml_start", obj_desc->method.aml_start); break; diff --git a/drivers/acpi/executer/exdyadic.c b/drivers/acpi/executer/exdyadic.c deleted file mode 100644 index 17184e2c10fc..000000000000 --- a/drivers/acpi/executer/exdyadic.c +++ /dev/null @@ -1,874 +0,0 @@ -/****************************************************************************** - * - * Module Name: exdyadic - ACPI AML execution for dyadic (2-operand) operators - * $Revision: 88 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 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 "acparser.h" -#include "acnamesp.h" -#include "acinterp.h" -#include "acevents.h" -#include "amlcode.h" -#include "acdispat.h" - - -#define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exdyadic") - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_do_concatenate - * - * PARAMETERS: *Obj_desc - Object to be converted. Must be an - * Integer, Buffer, or String - * Walk_state - Current walk state - * - * RETURN: Status - * - * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. - * - ******************************************************************************/ - -acpi_status -acpi_ex_do_concatenate ( - acpi_operand_object *obj_desc, - acpi_operand_object *obj_desc2, - acpi_operand_object **actual_ret_desc, - acpi_walk_state *walk_state) -{ - acpi_status status; - u32 i; - acpi_integer this_integer; - acpi_operand_object *ret_desc; - NATIVE_CHAR *new_buf; - u32 integer_size = sizeof (acpi_integer); - - - FUNCTION_ENTRY (); - - - /* - * There are three cases to handle: - * 1) Two Integers concatenated to produce a buffer - * 2) Two Strings concatenated to produce a string - * 3) Two Buffers concatenated to produce a buffer - */ - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: - - /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ - - if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { - /* - * We are running a method that exists in a 32-bit ACPI table. - * Truncate the value to 32 bits by zeroing out the upper - * 32-bit field - */ - integer_size = sizeof (u32); - } - - /* Result of two integers is a buffer */ - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); - if (!ret_desc) { - return (AE_NO_MEMORY); - } - - /* Need enough space for two integers */ - - ret_desc->buffer.length = integer_size * 2; - new_buf = ACPI_MEM_CALLOCATE (ret_desc->buffer.length); - if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: Buffer allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } - - ret_desc->buffer.pointer = (u8 *) new_buf; - - /* Convert the first integer */ - - this_integer = obj_desc->integer.value; - for (i = 0; i < integer_size; i++) { - new_buf[i] = (u8) this_integer; - this_integer >>= 8; - } - - /* Convert the second integer */ - - this_integer = obj_desc2->integer.value; - for (; i < (integer_size * 2); i++) { - new_buf[i] = (u8) this_integer; - this_integer >>= 8; - } - - break; - - - case ACPI_TYPE_STRING: - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); - if (!ret_desc) { - return (AE_NO_MEMORY); - } - - /* Operand1 is string */ - - new_buf = ACPI_MEM_ALLOCATE (obj_desc->string.length + - obj_desc2->string.length + 1); - if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: String allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } - - STRCPY (new_buf, obj_desc->string.pointer); - STRCPY (new_buf + obj_desc->string.length, - obj_desc2->string.pointer); - - /* Point the return object to the new string */ - - ret_desc->string.pointer = new_buf; - ret_desc->string.length = obj_desc->string.length += - obj_desc2->string.length; - break; - - - case ACPI_TYPE_BUFFER: - - /* Operand1 is a buffer */ - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); - if (!ret_desc) { - return (AE_NO_MEMORY); - } - - new_buf = ACPI_MEM_ALLOCATE (obj_desc->buffer.length + - obj_desc2->buffer.length); - if (!new_buf) { - REPORT_ERROR - (("Ex_do_concatenate: Buffer allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } - - MEMCPY (new_buf, obj_desc->buffer.pointer, - obj_desc->buffer.length); - MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer, - obj_desc2->buffer.length); - - /* - * Point the return object to the new buffer - */ - - ret_desc->buffer.pointer = (u8 *) new_buf; - ret_desc->buffer.length = obj_desc->buffer.length + - obj_desc2->buffer.length; - break; - - default: - status = AE_AML_INTERNAL; - ret_desc = NULL; - } - - - *actual_ret_desc = ret_desc; - return (AE_OK); - - -cleanup: - - acpi_ut_remove_reference (ret_desc); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_dyadic1 - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 1 dyadic operator with numeric operands: - * Notify_op - * - * ALLOCATION: Deletes both operands - * - ******************************************************************************/ - -acpi_status -acpi_ex_dyadic1 ( - u16 opcode, - acpi_walk_state *walk_state) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_namespace_node *node; - acpi_status status = AE_OK; - - - FUNCTION_TRACE_PTR ("Ex_dyadic1", WALK_OPERANDS); - - - /* Examine the opcode */ - - switch (opcode) { - - /* Def_notify := Notify_op (0)Notify_object (1)Notify_value */ - - case AML_NOTIFY_OP: - - /* The Obj_desc is actually an Node */ - - node = (acpi_namespace_node *) operand[0]; - operand[0] = NULL; - - /* Object must be a device or thermal zone */ - - if (node && operand[1]) { - switch (node->type) { - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_THERMAL: - - /* - * Dispatch the notify to the appropriate handler - * NOTE: the request is queued for execution after this method - * completes. The notify handlers are NOT invoked synchronously - * from this thread -- because handlers may in turn run other - * control methods. - */ - status = acpi_ev_queue_notify_request (node, - (u32) operand[1]->integer.value); - break; - - default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type %X\n", - operand[0]->common.type)); - - status = AE_AML_OPERAND_TYPE; - break; - } - } - break; - - default: - - REPORT_ERROR (("Acpi_ex_dyadic1: Unknown dyadic opcode %X\n", opcode)); - status = AE_AML_BAD_OPCODE; - } - - - /* Always delete both operands */ - - acpi_ut_remove_reference (operand[1]); - acpi_ut_remove_reference (operand[0]); - - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_dyadic2_r - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * Return_desc - Where to store the return object - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and - * one or two result operands. - * - * ALLOCATION: Deletes one operand descriptor -- other remains on stack - * - ******************************************************************************/ - -acpi_status -acpi_ex_dyadic2_r ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_operand_object *ret_desc2 = NULL; - acpi_status status = AE_OK; - - - FUNCTION_TRACE_U32 ("Ex_dyadic2_r", opcode); - - - /* Create an internal return object if necessary */ - - switch (opcode) { - case AML_ADD_OP: - case AML_BIT_AND_OP: - case AML_BIT_NAND_OP: - case AML_BIT_OR_OP: - case AML_BIT_NOR_OP: - case AML_BIT_XOR_OP: - case AML_DIVIDE_OP: - case AML_MOD_OP: - case AML_MULTIPLY_OP: - case AML_SHIFT_LEFT_OP: - case AML_SHIFT_RIGHT_OP: - case AML_SUBTRACT_OP: - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - break; - } - - - /* - * Execute the opcode - */ - switch (opcode) { - - /* Def_add := Add_op Operand1 Operand2 Result */ - - case AML_ADD_OP: - - ret_desc->integer.value = operand[0]->integer.value + - operand[1]->integer.value; - break; - - - /* Def_and := And_op Operand1 Operand2 Result */ - - case AML_BIT_AND_OP: - - ret_desc->integer.value = operand[0]->integer.value & - operand[1]->integer.value; - break; - - - /* Def_nAnd := NAnd_op Operand1 Operand2 Result */ - - case AML_BIT_NAND_OP: - - ret_desc->integer.value = ~(operand[0]->integer.value & - operand[1]->integer.value); - break; - - - /* Def_or := Or_op Operand1 Operand2 Result */ - - case AML_BIT_OR_OP: - - ret_desc->integer.value = operand[0]->integer.value | - operand[1]->integer.value; - break; - - - /* Def_nOr := NOr_op Operand1 Operand2 Result */ - - case AML_BIT_NOR_OP: - - ret_desc->integer.value = ~(operand[0]->integer.value | - operand[1]->integer.value); - break; - - - /* Def_xOr := XOr_op Operand1 Operand2 Result */ - - case AML_BIT_XOR_OP: - - ret_desc->integer.value = operand[0]->integer.value ^ - operand[1]->integer.value; - break; - - - /* Def_divide := Divide_op Dividend Divisor Remainder Quotient */ - - case AML_DIVIDE_OP: - - if (!operand[1]->integer.value) { - REPORT_ERROR - (("Divide_op: Divide by zero\n")); - - status = AE_AML_DIVIDE_BY_ZERO; - goto cleanup; - } - - ret_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc2) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Remainder (modulo) */ - - ret_desc->integer.value = ACPI_MODULO (operand[0]->integer.value, - operand[1]->integer.value); - - /* Result (what we used to call the quotient) */ - - ret_desc2->integer.value = ACPI_DIVIDE (operand[0]->integer.value, - operand[1]->integer.value); - break; - - - /* Def_mod := Mod_op Dividend Divisor Remainder */ - - case AML_MOD_OP: /* ACPI 2.0 */ - - if (!operand[1]->integer.value) { - REPORT_ERROR - (("Mod_op: Divide by zero\n")); - - status = AE_AML_DIVIDE_BY_ZERO; - goto cleanup; - } - - /* Remainder (modulo) */ - - ret_desc->integer.value = ACPI_MODULO (operand[0]->integer.value, - operand[1]->integer.value); - break; - - - /* Def_multiply := Multiply_op Operand1 Operand2 Result */ - - case AML_MULTIPLY_OP: - - ret_desc->integer.value = operand[0]->integer.value * - operand[1]->integer.value; - break; - - - /* Def_shift_left := Shift_left_op Operand Shift_count Result */ - - case AML_SHIFT_LEFT_OP: - - ret_desc->integer.value = operand[0]->integer.value << - operand[1]->integer.value; - break; - - - /* Def_shift_right := Shift_right_op Operand Shift_count Result */ - - case AML_SHIFT_RIGHT_OP: - - ret_desc->integer.value = operand[0]->integer.value >> - operand[1]->integer.value; - break; - - - /* Def_subtract := Subtract_op Operand1 Operand2 Result */ - - case AML_SUBTRACT_OP: - - ret_desc->integer.value = operand[0]->integer.value - - operand[1]->integer.value; - break; - - - /* Def_concat := Concat_op Data1 Data2 Result */ - - case AML_CONCAT_OP: - - /* - * Convert the second operand if necessary. The first operand - * determines the type of the second operand, (See the Data Types - * section of the ACPI specification.) Both object types are - * guaranteed to be either Integer/String/Buffer by the operand - * resolution mechanism above. - */ - switch (operand[0]->common.type) { - case ACPI_TYPE_INTEGER: - status = acpi_ex_convert_to_integer (operand[1], &operand[1], walk_state); - break; - - case ACPI_TYPE_STRING: - status = acpi_ex_convert_to_string (operand[1], &operand[1], 16, ACPI_UINT32_MAX, walk_state); - break; - - case ACPI_TYPE_BUFFER: - status = acpi_ex_convert_to_buffer (operand[1], &operand[1], walk_state); - break; - - default: - status = AE_AML_INTERNAL; - } - - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - - /* - * Both operands are now known to be the same object type - * (Both are Integer, String, or Buffer), and we can now perform the - * concatenation. - */ - status = acpi_ex_do_concatenate (operand[0], operand[1], &ret_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - break; - - - /* Def_to_string := Buffer, Length, Result */ - - case AML_TO_STRING_OP: /* ACPI 2.0 */ - - status = acpi_ex_convert_to_string (operand[0], &ret_desc, 16, - (u32) operand[1]->integer.value, walk_state); - break; - - - /* Def_concat_res := Buffer, Buffer, Result */ - - case AML_CONCAT_RES_OP: /* ACPI 2.0 */ - - status = AE_NOT_IMPLEMENTED; - goto cleanup; - break; - - - default: - - REPORT_ERROR (("Acpi_ex_dyadic2_r: Unknown dyadic opcode %X\n", - opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - } - - - /* - * Store the result of the operation (which is now in Operand[0]) into - * the result descriptor, or the location pointed to by the result - * descriptor (Operand[2]). - */ - status = acpi_ex_store (ret_desc, operand[2], walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - if (AML_DIVIDE_OP == opcode) { - status = acpi_ex_store (ret_desc2, operand[3], walk_state); - - /* - * Since the remainder is not returned, remove a reference to - * the object we created earlier - */ - acpi_ut_remove_reference (ret_desc); - *return_desc = ret_desc2; - } - - else { - *return_desc = ret_desc; - } - - -cleanup: - - /* Always delete the operands */ - - acpi_ut_remove_reference (operand[0]); - acpi_ut_remove_reference (operand[1]); - - - /* Delete return object on error */ - - if (ACPI_FAILURE (status)) { - /* On failure, delete the result ops */ - - acpi_ut_remove_reference (operand[2]); - acpi_ut_remove_reference (operand[3]); - - if (ret_desc) { - /* And delete the internal return object */ - - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; - } - } - - /* Set the return object and exit */ - - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_dyadic2_s - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * Return_desc - Where to store the return object - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 2 dyadic synchronization operator - * - * ALLOCATION: Deletes one operand descriptor -- other remains on stack - * - ******************************************************************************/ - -acpi_status -acpi_ex_dyadic2_s ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_status status; - - - FUNCTION_TRACE_PTR ("Ex_dyadic2_s", WALK_OPERANDS); - - - /* Create the internal return object */ - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Default return value is FALSE, operation did not time out */ - - ret_desc->integer.value = 0; - - - /* Examine the opcode */ - - switch (opcode) { - - /* Def_acquire := Acquire_op Mutex_object Timeout */ - - case AML_ACQUIRE_OP: - - status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state); - break; - - - /* Def_wait := Wait_op Acpi_event_object Timeout */ - - case AML_WAIT_OP: - - status = acpi_ex_system_wait_event (operand[1], operand[0]); - break; - - - default: - - REPORT_ERROR (("Acpi_ex_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - } - - - /* - * Return a boolean indicating if operation timed out - * (TRUE) or not (FALSE) - */ - if (status == AE_TIME) { - ret_desc->integer.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */ - status = AE_OK; - } - - -cleanup: - - /* Delete params */ - - acpi_ut_remove_reference (operand[1]); - acpi_ut_remove_reference (operand[0]); - - /* Delete return object on error */ - - if (ACPI_FAILURE (status) && - (ret_desc)) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; - } - - - /* Set the return object and exit */ - - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_dyadic2 - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * Return_desc - Where to store the return object - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and - * no result operands - * - * ALLOCATION: Deletes one operand descriptor -- other remains on stack - * containing result value - * - ******************************************************************************/ - -acpi_status -acpi_ex_dyadic2 ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_status status = AE_OK; - u8 lboolean; - - - FUNCTION_TRACE_PTR ("Ex_dyadic2", WALK_OPERANDS); - - - /* Create the internal return object */ - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* - * Execute the Opcode - */ - lboolean = FALSE; - switch (opcode) { - - /* Def_lAnd := LAnd_op Operand1 Operand2 */ - - case AML_LAND_OP: - - lboolean = (u8) (operand[0]->integer.value && - operand[1]->integer.value); - break; - - - /* Def_lEqual := LEqual_op Operand1 Operand2 */ - - case AML_LEQUAL_OP: - - lboolean = (u8) (operand[0]->integer.value == - operand[1]->integer.value); - break; - - - /* Def_lGreater := LGreater_op Operand1 Operand2 */ - - case AML_LGREATER_OP: - - lboolean = (u8) (operand[0]->integer.value > - operand[1]->integer.value); - break; - - - /* Def_lLess := LLess_op Operand1 Operand2 */ - - case AML_LLESS_OP: - - lboolean = (u8) (operand[0]->integer.value < - operand[1]->integer.value); - break; - - - /* Def_lOr := LOr_op Operand1 Operand2 */ - - case AML_LOR_OP: - - lboolean = (u8) (operand[0]->integer.value || - operand[1]->integer.value); - break; - - - /* Def_copy := Source, Destination */ - - case AML_COPY_OP: /* ACPI 2.0 */ - - status = AE_NOT_IMPLEMENTED; - goto cleanup; - break; - - - default: - - REPORT_ERROR (("Acpi_ex_dyadic2: Unknown dyadic opcode %X\n", opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - break; - } - - - /* Set return value to logical TRUE (all ones) or FALSE (zero) */ - - if (lboolean) { - ret_desc->integer.value = ACPI_INTEGER_MAX; - } - else { - ret_desc->integer.value = 0; - } - - -cleanup: - - /* Always delete operands */ - - acpi_ut_remove_reference (operand[0]); - acpi_ut_remove_reference (operand[1]); - - - /* Delete return object on error */ - - if (ACPI_FAILURE (status) && - (ret_desc)) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; - } - - - /* Set the return object and exit */ - - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} - - diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 39df9a6ba9fd..ec09328d02ef 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: exfldio - Aml Field I/O - * $Revision: 64 $ + * $Revision: 66 $ * *****************************************************************************/ @@ -71,7 +71,6 @@ acpi_ex_setup_field ( return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } - /* * If the Region Address and Length have not been previously evaluated, * evaluate them now and save the results. @@ -84,7 +83,6 @@ acpi_ex_setup_field ( } } - /* * Validate the request. The entire request from the byte offset for a * length of one field datum (access width) must fit within the region. @@ -158,7 +156,6 @@ acpi_ex_read_field_datum ( *value = 0; - /* * Buffer_fields - Read from a Buffer * Other Fields - Read from a Operation Region. @@ -189,7 +186,6 @@ acpi_ex_read_field_datum ( return_ACPI_STATUS (status); } - /* * The physical address of this field datum is: * @@ -201,13 +197,12 @@ acpi_ex_read_field_datum ( address = rgn_desc->region.address + obj_desc->common_field.base_byte_offset + field_datum_byte_offset; - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Region %s(%X) width %X base:off %X:%X at %8.8lX%8.8lX\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Region %s(%X) width %X base:off %X:%X at %8.8X%8.8X\n", acpi_ut_get_region_name (rgn_desc->region.space_id), rgn_desc->region.space_id, obj_desc->common_field.access_bit_width, obj_desc->common_field.base_byte_offset, field_datum_byte_offset, HIDWORD(address), LODWORD(address))); - /* Invoke the appropriate Address_space/Op_region handler */ status = acpi_ev_address_space_dispatch (rgn_desc, ACPI_READ_ADR_SPACE, @@ -235,7 +230,7 @@ acpi_ex_read_field_datum ( } - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Returned value=%08lX \n", *value)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Returned value=%08X \n", *value)); return_ACPI_STATUS (status); } @@ -381,7 +376,6 @@ acpi_ex_extract_from_field ( byte_field_length, datum_count, obj_desc->common_field.access_bit_width, obj_desc->common_field.access_byte_width)); - /* * Clear the caller's buffer (the whole buffer length as given) * This is very important, especially in the cases where a byte is read, @@ -485,7 +479,6 @@ acpi_ex_extract_from_field ( } } - /* * Store the merged field datum in the caller's buffer, according to * the granularity of the field (size of each datum). @@ -501,7 +494,6 @@ acpi_ex_extract_from_field ( datum_offset++; } - return_ACPI_STATUS (AE_OK); } @@ -576,7 +568,7 @@ acpi_ex_write_field_datum ( field_datum_byte_offset; ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Store %X in Region %s(%X) at %8.8lX%8.8lX width %X\n", + "Store %X in Region %s(%X) at %8.8X%8.8X width %X\n", value, acpi_ut_get_region_name (rgn_desc->region.space_id), rgn_desc->region.space_id, HIDWORD(address), LODWORD(address), obj_desc->common_field.access_bit_width)); @@ -612,7 +604,7 @@ acpi_ex_write_field_datum ( } - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value written=%08lX \n", value)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value written=%08X \n", value)); return_ACPI_STATUS (status); } @@ -649,16 +641,13 @@ acpi_ex_write_field_datum_with_update_rule ( merged_value = field_value; - /* If the mask is all ones, we don't need to worry about the update rule */ if (mask != ACPI_UINT32_MAX) { /* Decode the update rule */ switch (obj_desc->common_field.update_rule) { - case UPDATE_PRESERVE: - /* * Check if update rule needs to be applied (not if mask is all * ones) The left shift drops the bits we want to ignore. @@ -772,7 +761,6 @@ acpi_ex_insert_into_field ( byte_field_length, datum_count, obj_desc->common_field.access_bit_width, obj_desc->common_field.access_byte_width)); - /* * Break the request into up to three parts (similar to an I/O request): * 1) non-aligned part at start @@ -868,31 +856,34 @@ acpi_ex_insert_into_field ( merged_datum = this_raw_datum; } - /* * Special handling for the last datum if the field does NOT end on * a datum boundary. Update Rule must be applied to the bits outside * the field. */ - if ((datum_offset == datum_count) && - obj_desc->common_field.end_field_valid_bits) { + if (datum_offset == datum_count) { /* - * Part3: - * This is the last datum and the field does not end on a datum boundary. - * Build the partial datum and write with the update rule. + * If there are dangling non-aligned bits, perform one more merged write + * Else - field is aligned at the end, no need for any more writes */ + if (obj_desc->common_field.end_field_valid_bits) { + /* + * Part3: + * This is the last datum and the field does not end on a datum boundary. + * Build the partial datum and write with the update rule. + * + * Mask off the unused bits above (after) the end-of-field + */ + mask = MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + merged_datum &= mask; - /* Mask off the unused bits above (after) the end-of-field */ - - mask = MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); - merged_datum &= mask; - - /* Write the last datum with the update rule */ + /* Write the last datum with the update rule */ - status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, - merged_datum, field_datum_byte_offset); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + status = acpi_ex_write_field_datum_with_update_rule (obj_desc, mask, + merged_datum, field_datum_byte_offset); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } } @@ -913,7 +904,6 @@ acpi_ex_insert_into_field ( previous_raw_datum = this_raw_datum; } - return_ACPI_STATUS (status); } diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 552e5e4f96f8..acd14502ea3d 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 83 $ + * $Revision: 92 $ * *****************************************************************************/ @@ -38,424 +38,403 @@ /******************************************************************************* * - * FUNCTION: Acpi_ex_triadic + * FUNCTION: Acpi_ex_get_object_reference * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * Return_desc - Where to store the return object + * PARAMETERS: Obj_desc - Create a reference to this object + * Return_desc - Where to store the reference * * RETURN: Status * - * DESCRIPTION: Execute Triadic operator (3 operands) - * - * ALLOCATION: Deletes one operand descriptor -- other remains on stack + * DESCRIPTION: Obtain and return a "reference" to the target object + * Common code for the Ref_of_op and the Cond_ref_of_op. * ******************************************************************************/ acpi_status -acpi_ex_triadic ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) +acpi_ex_get_object_reference ( + acpi_operand_object *obj_desc, + acpi_operand_object **return_desc, + acpi_walk_state *walk_state) { - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_operand_object *tmp_desc; - ACPI_SIGNAL_FATAL_INFO *fatal; acpi_status status = AE_OK; - FUNCTION_TRACE ("Ex_triadic"); - - -#define obj_desc1 operand[0] -#define obj_desc2 operand[1] -#define res_desc operand[2] + FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc); - switch (opcode) { - - case AML_FATAL_OP: + if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { + if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) { + *return_desc = NULL; + status = AE_TYPE; + goto cleanup; + } - /* Def_fatal := Fatal_op Fatal_type Fatal_code Fatal_arg */ + /* + * Not a Name -- an indirect name pointer would have + * been converted to a direct name pointer in Acpi_ex_resolve_operands + */ + switch (obj_desc->reference.opcode) { + case AML_LOCAL_OP: + case AML_ARG_OP: - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Fatal_op: Type %x Code %x Arg %x <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", - (u32) obj_desc1->integer.value, (u32) obj_desc2->integer.value, - (u32) res_desc->integer.value)); + *return_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode, + obj_desc->reference.offset, walk_state); + break; + default: - fatal = ACPI_MEM_ALLOCATE (sizeof (ACPI_SIGNAL_FATAL_INFO)); - if (fatal) { - fatal->type = (u32) obj_desc1->integer.value; - fatal->code = (u32) obj_desc2->integer.value; - fatal->argument = (u32) res_desc->integer.value; + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n", + obj_desc->reference.opcode)); + *return_desc = NULL; + status = AE_AML_INTERNAL; + goto cleanup; } - /* - * Signal the OS - */ - acpi_os_signal (ACPI_SIGNAL_FATAL, fatal); + } - /* Might return while OS is shutting down */ + else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { + /* Must be a named object; Just return the Node */ - ACPI_MEM_FREE (fatal); - break; + *return_desc = obj_desc; + } + else { + *return_desc = NULL; + status = AE_TYPE; + } - case AML_MID_OP: - /* Def_mid := Mid_op Source Index Length Result */ +cleanup: - /* Create the internal return object (string or buffer) */ + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc)); + return_ACPI_STATUS (status); +} - break; +/******************************************************************************* + * + * FUNCTION: Acpi_ex_do_concatenate + * + * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. + * + ******************************************************************************/ - case AML_INDEX_OP: +acpi_status +acpi_ex_do_concatenate ( + acpi_operand_object *obj_desc, + acpi_operand_object *obj_desc2, + acpi_operand_object **actual_return_desc, + acpi_walk_state *walk_state) +{ + acpi_status status; + u32 i; + acpi_integer this_integer; + acpi_operand_object *return_desc; + NATIVE_CHAR *new_buf; + u32 integer_size = sizeof (acpi_integer); - /* Def_index := Index_op Source Index Destination */ - /* Create the internal return object */ + FUNCTION_ENTRY (); - ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - /* - * At this point, the Obj_desc1 operand is either a Package or a Buffer - */ - if (obj_desc1->common.type == ACPI_TYPE_PACKAGE) { - /* Object to be indexed is a Package */ - - if (obj_desc2->integer.value >= obj_desc1->package.count) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond package end\n")); - status = AE_AML_PACKAGE_LIMIT; - goto cleanup; - } - - if ((res_desc->common.type == INTERNAL_TYPE_REFERENCE) && - (res_desc->reference.opcode == AML_ZERO_OP)) { - /* - * There is no actual result descriptor (the Zero_op Result - * descriptor is a placeholder), so just delete the placeholder and - * return a reference to the package element - */ - acpi_ut_remove_reference (res_desc); - } - - else { - /* - * Each element of the package is an internal object. Get the one - * we are after. - */ - tmp_desc = obj_desc1->package.elements[obj_desc2->integer.value]; - ret_desc->reference.opcode = AML_INDEX_OP; - ret_desc->reference.target_type = tmp_desc->common.type; - ret_desc->reference.object = tmp_desc; - - status = acpi_ex_store (ret_desc, res_desc, walk_state); - ret_desc->reference.object = NULL; - } + /* + * There are three cases to handle: + * 1) Two Integers concatenated to produce a buffer + * 2) Two Strings concatenated to produce a string + * 3) Two Buffers concatenated to produce a buffer + */ + switch (obj_desc->common.type) { + case ACPI_TYPE_INTEGER: + /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { /* - * The local return object must always be a reference to the package element, - * not the element itself. + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper + * 32-bit field */ - ret_desc->reference.opcode = AML_INDEX_OP; - ret_desc->reference.target_type = ACPI_TYPE_PACKAGE; - ret_desc->reference.where = &obj_desc1->package.elements[obj_desc2->integer.value]; + integer_size = sizeof (u32); } - else { - /* Object to be indexed is a Buffer */ - - if (obj_desc2->integer.value >= obj_desc1->buffer.length) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond end of buffer\n")); - status = AE_AML_BUFFER_LIMIT; - goto cleanup; - } + /* Result of two integers is a buffer */ - ret_desc->reference.opcode = AML_INDEX_OP; - ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; - ret_desc->reference.object = obj_desc1; - ret_desc->reference.offset = (u32) obj_desc2->integer.value; - - status = acpi_ex_store (ret_desc, res_desc, walk_state); + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + if (!return_desc) { + return (AE_NO_MEMORY); } - break; - } + /* Need enough space for two integers */ -cleanup: + return_desc->buffer.length = integer_size * 2; + new_buf = ACPI_MEM_CALLOCATE (return_desc->buffer.length); + if (!new_buf) { + REPORT_ERROR + (("Ex_do_concatenate: Buffer allocation failure\n")); + status = AE_NO_MEMORY; + goto cleanup; + } - /* Always delete operands */ + return_desc->buffer.pointer = (u8 *) new_buf; - acpi_ut_remove_reference (obj_desc1); - acpi_ut_remove_reference (obj_desc2); + /* Convert the first integer */ - /* Delete return object on error */ + this_integer = obj_desc->integer.value; + for (i = 0; i < integer_size; i++) { + new_buf[i] = (u8) this_integer; + this_integer >>= 8; + } - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (res_desc); + /* Convert the second integer */ - if (ret_desc) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; + this_integer = obj_desc2->integer.value; + for (; i < (integer_size * 2); i++) { + new_buf[i] = (u8) this_integer; + this_integer >>= 8; } - } - - /* Set the return object and exit */ - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} + break; -/******************************************************************************* - * - * FUNCTION: Acpi_ex_hexadic - * - * PARAMETERS: Opcode - The opcode to be executed - * Walk_state - Current walk state - * Return_desc - Where to store the return object - * - * RETURN: Status - * - * DESCRIPTION: Execute Match operator - * - ******************************************************************************/ + case ACPI_TYPE_STRING: -acpi_status -acpi_ex_hexadic ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_status status = AE_OK; - u32 index; - u32 match_value = (u32) -1; + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); + if (!return_desc) { + return (AE_NO_MEMORY); + } + /* Operand0 is string */ - FUNCTION_TRACE ("Ex_hexadic"); + new_buf = ACPI_MEM_ALLOCATE (obj_desc->string.length + + obj_desc2->string.length + 1); + if (!new_buf) { + REPORT_ERROR + (("Ex_do_concatenate: String allocation failure\n")); + status = AE_NO_MEMORY; + goto cleanup; + } -#define pkg_desc operand[0] -#define op1_desc operand[1] -#define V1_desc operand[2] -#define op2_desc operand[3] -#define V2_desc operand[4] -#define start_desc operand[5] + STRCPY (new_buf, obj_desc->string.pointer); + STRCPY (new_buf + obj_desc->string.length, + obj_desc2->string.pointer); + /* Point the return object to the new string */ - switch (opcode) { + return_desc->string.pointer = new_buf; + return_desc->string.length = obj_desc->string.length += + obj_desc2->string.length; + break; - case AML_MATCH_OP: - /* Validate match comparison sub-opcodes */ + case ACPI_TYPE_BUFFER: - if ((op1_desc->integer.value > MAX_MATCH_OPERATOR) || - (op2_desc->integer.value > MAX_MATCH_OPERATOR)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "operation encoding out of range\n")); - status = AE_AML_OPERAND_VALUE; - goto cleanup; - } + /* Operand0 is a buffer */ - index = (u32) start_desc->integer.value; - if (index >= (u32) pkg_desc->package.count) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Start position value out of range\n")); - status = AE_AML_PACKAGE_LIMIT; - goto cleanup; + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); + if (!return_desc) { + return (AE_NO_MEMORY); } - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { + new_buf = ACPI_MEM_ALLOCATE (obj_desc->buffer.length + + obj_desc2->buffer.length); + if (!new_buf) { + REPORT_ERROR + (("Ex_do_concatenate: Buffer allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; - } + MEMCPY (new_buf, obj_desc->buffer.pointer, + obj_desc->buffer.length); + MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer, + obj_desc2->buffer.length); + /* - * Examine each element until a match is found. Within the loop, - * "continue" signifies that the current element does not match - * and the next should be examined. - * Upon finding a match, the loop will terminate via "break" at - * the bottom. If it terminates "normally", Match_value will be -1 - * (its initial value) indicating that no match was found. When - * returned as a Number, this will produce the Ones value as specified. + * Point the return object to the new buffer */ - for ( ; index < pkg_desc->package.count; ++index) { - /* - * Treat any NULL or non-numeric elements as non-matching. - * TBD [Unhandled] - if an element is a Name, - * should we examine its value? - */ - if (!pkg_desc->package.elements[index] || - ACPI_TYPE_INTEGER != pkg_desc->package.elements[index]->common.type) { - continue; - } - /* - * Within these switch statements: - * "break" (exit from the switch) signifies a match; - * "continue" (proceed to next iteration of enclosing - * "for" loop) signifies a non-match. - */ - switch (op1_desc->integer.value) { + return_desc->buffer.pointer = (u8 *) new_buf; + return_desc->buffer.length = obj_desc->buffer.length + + obj_desc2->buffer.length; + break; - case MATCH_MTR: /* always true */ - break; + default: + status = AE_AML_INTERNAL; + return_desc = NULL; + } - case MATCH_MEQ: /* true if equal */ + *actual_return_desc = return_desc; + return (AE_OK); - if (pkg_desc->package.elements[index]->integer.value - != V1_desc->integer.value) { - continue; - } - break; +cleanup: - case MATCH_MLE: /* true if less than or equal */ + acpi_ut_remove_reference (return_desc); + return (status); +} - if (pkg_desc->package.elements[index]->integer.value - > V1_desc->integer.value) { - continue; - } - break; +/******************************************************************************* + * + * FUNCTION: Acpi_ex_do_math_op + * + * PARAMETERS: Opcode - AML opcode + * Operand0 - Integer operand #0 + * Operand0 - Integer operand #1 + * + * RETURN: Integer result of the operation + * + * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the + * math functions here is to prevent a lot of pointer dereferencing + * to obtain the operands. + * + ******************************************************************************/ - case MATCH_MLT: /* true if less than */ +acpi_integer +acpi_ex_do_math_op ( + u16 opcode, + acpi_integer operand0, + acpi_integer operand1) +{ - if (pkg_desc->package.elements[index]->integer.value - >= V1_desc->integer.value) { - continue; - } - break; + switch (opcode) { + case AML_ADD_OP: /* Add (Operand0, Operand1, Result) */ - case MATCH_MGE: /* true if greater than or equal */ + return (operand0 + operand1); - if (pkg_desc->package.elements[index]->integer.value - < V1_desc->integer.value) { - continue; - } - break; + case AML_BIT_AND_OP: /* And (Operand0, Operand1, Result) */ - case MATCH_MGT: /* true if greater than */ + return (operand0 & operand1); - if (pkg_desc->package.elements[index]->integer.value - <= V1_desc->integer.value) { - continue; - } - break; + case AML_BIT_NAND_OP: /* NAnd (Operand0, Operand1, Result) */ - default: /* undefined */ + return (~(operand0 & operand1)); - continue; - } + case AML_BIT_OR_OP: /* Or (Operand0, Operand1, Result) */ - switch(op2_desc->integer.value) { + return (operand0 | operand1); - case MATCH_MTR: - break; + case AML_BIT_NOR_OP: /* NOr (Operand0, Operand1, Result) */ + return (~(operand0 | operand1)); - case MATCH_MEQ: - if (pkg_desc->package.elements[index]->integer.value - != V2_desc->integer.value) { - continue; - } - break; + case AML_BIT_XOR_OP: /* XOr (Operand0, Operand1, Result) */ + return (operand0 ^ operand1); - case MATCH_MLE: - if (pkg_desc->package.elements[index]->integer.value - > V2_desc->integer.value) { - continue; - } - break; + case AML_MULTIPLY_OP: /* Multiply (Operand0, Operand1, Result) */ + return (operand0 * operand1); - case MATCH_MLT: - if (pkg_desc->package.elements[index]->integer.value - >= V2_desc->integer.value) { - continue; - } - break; + case AML_SHIFT_LEFT_OP: /* Shift_left (Operand, Shift_count, Result) */ + return (operand0 << operand1); - case MATCH_MGE: - if (pkg_desc->package.elements[index]->integer.value - < V2_desc->integer.value) { - continue; - } - break; + case AML_SHIFT_RIGHT_OP: /* Shift_right (Operand, Shift_count, Result) */ + return (operand0 >> operand1); - case MATCH_MGT: - if (pkg_desc->package.elements[index]->integer.value - <= V2_desc->integer.value) { - continue; - } - break; + case AML_SUBTRACT_OP: /* Subtract (Operand0, Operand1, Result) */ + return (operand0 - operand1); - default: + default: - continue; - } + return (0); + } +} - /* Match found: exit from loop */ - match_value = index; - break; +/******************************************************************************* + * + * FUNCTION: Acpi_ex_do_logical_op + * + * PARAMETERS: Opcode - AML opcode + * Operand0 - Integer operand #0 + * Operand0 - Integer operand #1 + * + * RETURN: TRUE/FALSE result of the operation + * + * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the + * functions here is to prevent a lot of pointer dereferencing + * to obtain the operands and to simplify the generation of the + * logical value. + * + * Note: cleanest machine code seems to be produced by the code + * below, rather than using statements of the form: + * Result = (Operand0 == Operand1); + * + ******************************************************************************/ + +u8 +acpi_ex_do_logical_op ( + u16 opcode, + acpi_integer operand0, + acpi_integer operand1) +{ + + + switch (opcode) { + + case AML_LAND_OP: /* LAnd (Operand0, Operand1) */ + + if (operand0 && operand1) { + return (TRUE); } + break; - /* Match_value is the return value */ - ret_desc->integer.value = match_value; + case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ + + if (operand0 == operand1) { + return (TRUE); + } break; - } + case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ -cleanup: + if (operand0 > operand1) { + return (TRUE); + } + break; - /* Free the operands */ - acpi_ut_remove_reference (start_desc); - acpi_ut_remove_reference (V2_desc); - acpi_ut_remove_reference (op2_desc); - acpi_ut_remove_reference (V1_desc); - acpi_ut_remove_reference (op1_desc); - acpi_ut_remove_reference (pkg_desc); + case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ + if (operand0 < operand1) { + return (TRUE); + } + break; - /* Delete return object on error */ - if (ACPI_FAILURE (status) && - (ret_desc)) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; + case AML_LOR_OP: /* LOr (Operand0, Operand1) */ + + if (operand0 || operand1) { + return (TRUE); + } + break; } + return (FALSE); +} - /* Set the return object and exit */ - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} diff --git a/drivers/acpi/executer/exmonad.c b/drivers/acpi/executer/exmonad.c deleted file mode 100644 index 3c5eddb27537..000000000000 --- a/drivers/acpi/executer/exmonad.c +++ /dev/null @@ -1,970 +0,0 @@ - -/****************************************************************************** - * - * Module Name: exmonad - ACPI AML execution for monadic (1 operand) operators - * $Revision: 111 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 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 "acparser.h" -#include "acdispat.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" - - -#define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exmonad") - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_get_object_reference - * - * PARAMETERS: Obj_desc - Create a reference to this object - * Ret_desc - Where to store the reference - * - * RETURN: Status - * - * DESCRIPTION: Obtain and return a "reference" to the target object - * Common code for the Ref_of_op and the Cond_ref_of_op. - * - ******************************************************************************/ - -static acpi_status -acpi_ex_get_object_reference ( - acpi_operand_object *obj_desc, - acpi_operand_object **ret_desc, - acpi_walk_state *walk_state) -{ - acpi_status status = AE_OK; - - - FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc); - - - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { - if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) { - *ret_desc = NULL; - status = AE_TYPE; - goto cleanup; - } - - /* - * Not a Name -- an indirect name pointer would have - * been converted to a direct name pointer in Acpi_ex_resolve_operands - */ - switch (obj_desc->reference.opcode) { - case AML_LOCAL_OP: - case AML_ARG_OP: - - *ret_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode, - obj_desc->reference.offset, walk_state); - break; - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n", - obj_desc->reference.opcode)); - *ret_desc = NULL; - status = AE_AML_INTERNAL; - goto cleanup; - } - - } - - else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - /* Must be a named object; Just return the Node */ - - *ret_desc = obj_desc; - } - - else { - *ret_desc = NULL; - status = AE_TYPE; - } - - -cleanup: - - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *ret_desc)); - return_ACPI_STATUS (status); -} - -#define obj_desc operand[0] -#define res_desc operand[1] - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_monadic1 - * - * PARAMETERS: Opcode - The opcode to be executed - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on - * object stack - * - ******************************************************************************/ - -acpi_status -acpi_ex_monadic1 ( - u16 opcode, - acpi_walk_state *walk_state) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_status status; - - - FUNCTION_TRACE_PTR ("Ex_monadic1", WALK_OPERANDS); - - - /* Examine the opcode */ - - switch (opcode) { - - /* Def_release := Release_op Mutex_object */ - - case AML_RELEASE_OP: - - status = acpi_ex_release_mutex (obj_desc, walk_state); - break; - - - /* Def_reset := Reset_op Acpi_event_object */ - - case AML_RESET_OP: - - status = acpi_ex_system_reset_event (obj_desc); - break; - - - /* Def_signal := Signal_op Acpi_event_object */ - - case AML_SIGNAL_OP: - - status = acpi_ex_system_signal_event (obj_desc); - break; - - - /* Def_sleep := Sleep_op Msec_time */ - - case AML_SLEEP_OP: - - acpi_ex_system_do_suspend ((u32) obj_desc->integer.value); - break; - - - /* Def_stall := Stall_op Usec_time */ - - case AML_STALL_OP: - - acpi_ex_system_do_stall ((u32) obj_desc->integer.value); - break; - - - /* Unknown opcode */ - - default: - - REPORT_ERROR (("Acpi_ex_monadic1: Unknown monadic opcode %X\n", - opcode)); - status = AE_AML_BAD_OPCODE; - break; - - } /* switch */ - - - /* Always delete the operand */ - - acpi_ut_remove_reference (obj_desc); - - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_monadic2_r - * - * PARAMETERS: Opcode - The opcode to be executed - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 2 monadic operator with numeric operand and - * result operand on operand stack - * - ******************************************************************************/ - -acpi_status -acpi_ex_monadic2_r ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *ret_desc = NULL; - acpi_operand_object *ret_desc2 = NULL; - u32 res_val; - acpi_status status = AE_OK; - u32 i; - u32 j; - acpi_integer digit; - - - FUNCTION_TRACE_PTR ("Ex_monadic2_r", WALK_OPERANDS); - - - /* Create a return object of type NUMBER for most opcodes */ - - switch (opcode) { - case AML_BIT_NOT_OP: - case AML_FIND_SET_LEFT_BIT_OP: - case AML_FIND_SET_RIGHT_BIT_OP: - case AML_FROM_BCD_OP: - case AML_TO_BCD_OP: - case AML_COND_REF_OF_OP: - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - break; - } - - - switch (opcode) { - /* Def_not := Not_op Operand Result */ - - case AML_BIT_NOT_OP: - - ret_desc->integer.value = ~obj_desc->integer.value; - break; - - - /* Def_find_set_left_bit := Find_set_left_bit_op Operand Result */ - - case AML_FIND_SET_LEFT_BIT_OP: - - ret_desc->integer.value = obj_desc->integer.value; - - /* - * Acpi specification describes Integer type as a little - * endian unsigned value, so this boundary condition is valid. - */ - for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { - ret_desc->integer.value >>= 1; - } - - ret_desc->integer.value = res_val; - break; - - - /* Def_find_set_right_bit := Find_set_right_bit_op Operand Result */ - - case AML_FIND_SET_RIGHT_BIT_OP: - - ret_desc->integer.value = obj_desc->integer.value; - - /* - * Acpi specification describes Integer type as a little - * endian unsigned value, so this boundary condition is valid. - */ - for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { - ret_desc->integer.value <<= 1; - } - - /* Since returns must be 1-based, subtract from 33 (65) */ - - ret_desc->integer.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val; - break; - - - /* Def_from_bDC := From_bCDOp BCDValue Result */ - - case AML_FROM_BCD_OP: - - /* - * The 64-bit ACPI integer can hold 16 4-bit BCD integers - */ - ret_desc->integer.value = 0; - for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { - /* Get one BCD digit */ - - digit = (acpi_integer) ((obj_desc->integer.value >> (i * 4)) & 0xF); - - /* Check the range of the digit */ - - if (digit > 9) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: \n", - digit)); - status = AE_AML_NUMERIC_OVERFLOW; - goto cleanup; - } - - if (digit > 0) { - /* Sum into the result with the appropriate power of 10 */ - - for (j = 0; j < i; j++) { - digit *= 10; - } - - ret_desc->integer.value += digit; - } - } - break; - - - /* Def_to_bDC := To_bCDOp Operand Result */ - - case AML_TO_BCD_OP: - - - if (obj_desc->integer.value > ACPI_MAX_BCD_VALUE) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %d\n", - obj_desc->integer.value)); - status = AE_AML_NUMERIC_OVERFLOW; - goto cleanup; - } - - ret_desc->integer.value = 0; - for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { - /* Divide by nth factor of 10 */ - - digit = obj_desc->integer.value; - for (j = 0; j < i; j++) { - digit = ACPI_DIVIDE (digit, 10); - } - - /* Create the BCD digit */ - - if (digit > 0) { - ret_desc->integer.value += (ACPI_MODULO (digit, 10) << (i * 4)); - } - } - break; - - - /* Def_cond_ref_of := Cond_ref_of_op Source_object Result */ - - case AML_COND_REF_OF_OP: - - /* - * This op is a little strange because the internal return value is - * different than the return value stored in the result descriptor - * (There are really two return values) - */ - if ((acpi_namespace_node *) obj_desc == acpi_gbl_root_node) { - /* - * This means that the object does not exist in the namespace, - * return FALSE - */ - ret_desc->integer.value = 0; - - /* - * Must delete the result descriptor since there is no reference - * being returned - */ - acpi_ut_remove_reference (res_desc); - goto cleanup; - } - - /* Get the object reference and store it */ - - status = acpi_ex_get_object_reference (obj_desc, &ret_desc2, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - status = acpi_ex_store (ret_desc2, res_desc, walk_state); - - /* The object exists in the namespace, return TRUE */ - - ret_desc->integer.value = ACPI_INTEGER_MAX; - goto cleanup; - break; - - - case AML_STORE_OP: - - /* - * A store operand is typically a number, string, buffer or lvalue - * TBD: [Unhandled] What about a store to a package? - */ - - /* - * Do the store, and be careful about deleting the source object, - * since the object itself may have been stored. - */ - status = acpi_ex_store (obj_desc, res_desc, walk_state); - if (ACPI_FAILURE (status)) { - /* On failure, just delete the Obj_desc */ - - acpi_ut_remove_reference (obj_desc); - return_ACPI_STATUS (status); - } - - /* - * Normally, we would remove a reference on the Obj_desc parameter; - * But since it is being used as the internal return object - * (meaning we would normally increment it), the two cancel out, - * and we simply don't do anything. - */ - *return_desc = obj_desc; - return_ACPI_STATUS (status); - break; - - - case AML_DEBUG_OP: - - /* Reference, returning an Reference */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Debug_op should never get here!\n")); - return_ACPI_STATUS (AE_OK); - break; - - - /* - * ACPI 2.0 Opcodes - */ - case AML_TO_DECSTRING_OP: - status = acpi_ex_convert_to_string (obj_desc, &ret_desc, 10, ACPI_UINT32_MAX, walk_state); - break; - - - case AML_TO_HEXSTRING_OP: - status = acpi_ex_convert_to_string (obj_desc, &ret_desc, 16, ACPI_UINT32_MAX, walk_state); - break; - - case AML_TO_BUFFER_OP: - status = acpi_ex_convert_to_buffer (obj_desc, &ret_desc, walk_state); - break; - - case AML_TO_INTEGER_OP: - status = acpi_ex_convert_to_integer (obj_desc, &ret_desc, walk_state); - break; - - - /* - * These are obsolete opcodes - */ - - /* Def_shift_left_bit := Shift_left_bit_op Source Bit_num */ - /* Def_shift_right_bit := Shift_right_bit_op Source Bit_num */ - - case AML_SHIFT_LEFT_BIT_OP: - case AML_SHIFT_RIGHT_BIT_OP: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is unimplemented\n", - acpi_ps_get_opcode_name (opcode))); - status = AE_SUPPORT; - goto cleanup; - break; - - - default: - - REPORT_ERROR (("Acpi_ex_monadic2_r: Unknown monadic opcode %X\n", - opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - } - - - status = acpi_ex_store (ret_desc, res_desc, walk_state); - - -cleanup: - /* Always delete the operand object */ - - acpi_ut_remove_reference (obj_desc); - - /* Delete return object(s) on error */ - - if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (res_desc); /* Result descriptor */ - if (ret_desc) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; - } - } - - /* Set the return object and exit */ - - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_monadic2 - * - * PARAMETERS: Opcode - The opcode to be executed - * - * RETURN: Status - * - * DESCRIPTION: Execute Type 2 monadic operator with numeric operand: - * Deref_of_op, Ref_of_op, Size_of_op, Type_op, Increment_op, - * Decrement_op, LNot_op, - * - ******************************************************************************/ - -acpi_status -acpi_ex_monadic2 ( - u16 opcode, - acpi_walk_state *walk_state, - acpi_operand_object **return_desc) -{ - acpi_operand_object **operand = &walk_state->operands[0]; - acpi_operand_object *tmp_desc; - acpi_operand_object *ret_desc = NULL; - acpi_status status = AE_OK; - u32 type; - acpi_integer value; - - - FUNCTION_TRACE_PTR ("Ex_monadic2", WALK_OPERANDS); - - - /* Get the operand and decode the opcode */ - - switch (opcode) { - - /* Def_lNot := LNot_op Operand */ - - case AML_LNOT_OP: - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - ret_desc->integer.value = !obj_desc->integer.value; - break; - - - /* Def_decrement := Decrement_op Target */ - /* Def_increment := Increment_op Target */ - - case AML_DECREMENT_OP: - case AML_INCREMENT_OP: - - /* - * Since we are expecting an Reference on the top of the stack, it - * can be either an Node or an internal object. - * - * TBD: [Future] This may be the prototype code for all cases where - * a Reference is expected!! 10/99 - */ - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - ret_desc = obj_desc; - } - - else { - /* - * Duplicate the Reference in a new object so that we can resolve it - * without destroying the original Reference object - */ - ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - ret_desc->reference.opcode = obj_desc->reference.opcode; - ret_desc->reference.offset = obj_desc->reference.offset; - ret_desc->reference.object = obj_desc->reference.object; - } - - - /* - * Convert the Ret_desc Reference to a Number - * (This deletes the original Ret_desc) - */ - status = acpi_ex_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state); - if (ACPI_FAILURE (status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", - acpi_ps_get_opcode_name (opcode), acpi_format_exception(status))); - - goto cleanup; - } - - /* Do the actual increment or decrement */ - - if (AML_INCREMENT_OP == opcode) { - ret_desc->integer.value++; - } - else { - ret_desc->integer.value--; - } - - /* Store the result back in the original descriptor */ - - status = acpi_ex_store (ret_desc, obj_desc, walk_state); - - /* Objdesc was just deleted (because it is an Reference) */ - - obj_desc = NULL; - - break; - - - /* Def_object_type := Object_type_op Source_object */ - - case AML_TYPE_OP: - - if (INTERNAL_TYPE_REFERENCE == obj_desc->common.type) { - /* - * Not a Name -- an indirect name pointer would have - * been converted to a direct name pointer in Resolve_operands - */ - switch (obj_desc->reference.opcode) { - case AML_ZERO_OP: - case AML_ONE_OP: - case AML_ONES_OP: - case AML_REVISION_OP: - - /* Constants are of type Number */ - - type = ACPI_TYPE_INTEGER; - break; - - - case AML_DEBUG_OP: - - /* Per 1.0b spec, Debug object is of type Debug_object */ - - type = ACPI_TYPE_DEBUG_OBJECT; - break; - - - case AML_INDEX_OP: - - /* Get the type of this reference (index into another object) */ - - type = obj_desc->reference.target_type; - if (type == ACPI_TYPE_PACKAGE) { - /* - * The main object is a package, we want to get the type - * of the individual package element that is referenced by - * the index. - */ - type = (*(obj_desc->reference.where))->common.type; - } - - break; - - - case AML_LOCAL_OP: - case AML_ARG_OP: - - type = acpi_ds_method_data_get_type (obj_desc->reference.opcode, - obj_desc->reference.offset, walk_state); - break; - - - default: - - REPORT_ERROR (("Acpi_ex_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n", - obj_desc->reference.opcode)); - status = AE_AML_INTERNAL; - goto cleanup; - } - } - - else { - /* - * It's not a Reference, so it must be a direct name pointer. - */ - type = acpi_ns_get_type ((acpi_namespace_node *) obj_desc); - - /* Convert internal types to external types */ - - switch (type) { - case INTERNAL_TYPE_REGION_FIELD: - case INTERNAL_TYPE_BANK_FIELD: - case INTERNAL_TYPE_INDEX_FIELD: - - type = ACPI_TYPE_FIELD_UNIT; - } - - } - - /* Allocate a descriptor to hold the type. */ - - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - ret_desc->integer.value = type; - break; - - - /* Def_size_of := Size_of_op Source_object */ - - case AML_SIZE_OF_OP: - - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - obj_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) obj_desc); - } - - if (!obj_desc) { - value = 0; - } - - else { - switch (obj_desc->common.type) { - - case ACPI_TYPE_BUFFER: - - value = obj_desc->buffer.length; - break; - - - case ACPI_TYPE_STRING: - - value = obj_desc->string.length; - break; - - - case ACPI_TYPE_PACKAGE: - - value = obj_desc->package.count; - break; - - case INTERNAL_TYPE_REFERENCE: - - value = 4; - break; - - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n", - obj_desc->common.type)); - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - } - - /* - * Now that we have the size of the object, create a result - * object to hold the value - */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - ret_desc->integer.value = value; - break; - - - /* Def_ref_of := Ref_of_op Source_object */ - - case AML_REF_OF_OP: - - status = acpi_ex_get_object_reference (obj_desc, &ret_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - break; - - - /* Def_deref_of := Deref_of_op Obj_reference */ - - case AML_DEREF_OF_OP: - - - /* Check for a method local or argument */ - - if (!VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - /* - * Must resolve/dereference the local/arg reference first - */ - switch (obj_desc->reference.opcode) { - /* Set Obj_desc to the value of the local/arg */ - - case AML_LOCAL_OP: - case AML_ARG_OP: - - acpi_ds_method_data_get_value (obj_desc->reference.opcode, - obj_desc->reference.offset, walk_state, &tmp_desc); - - /* - * Delete our reference to the input object and - * point to the object just retrieved - */ - acpi_ut_remove_reference (obj_desc); - obj_desc = tmp_desc; - break; - - default: - - /* Index op - handled below */ - break; - } - } - - - /* Obj_desc may have changed from the code above */ - - if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { - /* Get the actual object from the Node (This is the dereference) */ - - ret_desc = ((acpi_namespace_node *) obj_desc)->object; - - /* Returning a pointer to the object, add another reference! */ - - acpi_ut_add_reference (ret_desc); - } - - else { - /* - * This must be a reference object produced by the Index - * ASL operation -- check internal opcode - */ - if ((obj_desc->reference.opcode != AML_INDEX_OP) && - (obj_desc->reference.opcode != AML_REF_OF_OP)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", - obj_desc, obj_desc->reference.opcode)); - - status = AE_TYPE; - goto cleanup; - } - - - switch (obj_desc->reference.opcode) { - case AML_INDEX_OP: - - /* - * Supported target types for the Index operator are - * 1) A Buffer - * 2) A Package - */ - if (obj_desc->reference.target_type == ACPI_TYPE_BUFFER_FIELD) { - /* - * The target is a buffer, we must create a new object that - * contains one element of the buffer, the element pointed - * to by the index. - * - * NOTE: index into a buffer is NOT a pointer to a - * sub-buffer of the main buffer, it is only a pointer to a - * single element (byte) of the buffer! - */ - ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - tmp_desc = obj_desc->reference.object; - ret_desc->integer.value = - tmp_desc->buffer.pointer[obj_desc->reference.offset]; - - /* TBD: [Investigate] (see below) Don't add an additional - * ref! - */ - } - - else if (obj_desc->reference.target_type == ACPI_TYPE_PACKAGE) { - /* - * The target is a package, we want to return the referenced - * element of the package. We must add another reference to - * this object, however. - */ - ret_desc = *(obj_desc->reference.where); - if (!ret_desc) { - /* - * We can't return a NULL dereferenced value. This is - * an uninitialized package element and is thus a - * severe error. - */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", - obj_desc)); - status = AE_AML_UNINITIALIZED_ELEMENT; - goto cleanup; - } - - acpi_ut_add_reference (ret_desc); - } - - else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n", - obj_desc->reference.target_type, obj_desc)); - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - break; - - - case AML_REF_OF_OP: - - ret_desc = obj_desc->reference.object; - - /* Add another reference to the object! */ - - acpi_ut_add_reference (ret_desc); - break; - } - } - - break; - - - default: - - REPORT_ERROR (("Acpi_ex_monadic2: Unknown monadic opcode %X\n", - opcode)); - status = AE_AML_BAD_OPCODE; - goto cleanup; - } - - -cleanup: - - if (obj_desc) { - acpi_ut_remove_reference (obj_desc); - } - - /* Delete return object on error */ - - if (ACPI_FAILURE (status) && - (ret_desc)) { - acpi_ut_remove_reference (ret_desc); - ret_desc = NULL; - } - - *return_desc = ret_desc; - return_ACPI_STATUS (status); -} - diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c new file mode 100644 index 000000000000..51eefd56e5d5 --- /dev/null +++ b/drivers/acpi/executer/exoparg1.c @@ -0,0 +1,878 @@ + +/****************************************************************************** + * + * Module Name: exoparg1 - AML execution - opcodes with 1 argument + * $Revision: 120 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000, 2001 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 "acparser.h" +#include "acdispat.h" +#include "acinterp.h" +#include "amlcode.h" +#include "acnamesp.h" + + +#define _COMPONENT ACPI_EXECUTER + MODULE_NAME ("exoparg1") + + +/*! + * Naming convention for AML interpreter execution routines. + * + * The routines that begin execution of AML opcodes are named with a common + * convention based upon the number of arguments, the number of target operands, + * and whether or not a value is returned: + * + * AcpiExOpcode_xA_yT_zR + * + * Where: + * + * xA - ARGUMENTS: The number of arguments (input operands) that are + * required for this opcode type (1 through 6 args). + * yT - TARGETS: The number of targets (output operands) that are required + * for this opcode type (0, 1, or 2 targets). + * zR - RETURN VALUE: Indicates whether this opcode type returns a value + * as the function return (0 or 1). + * + * The AcpiExOpcode* functions are called via the Dispatcher component with + * fully resolved operands. +!*/ + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_1A_0T_0R + * + * PARAMETERS: Walk_state - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on + * object stack + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_1A_0T_0R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_status status = AE_OK; + + + FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Examine the opcode */ + + switch (walk_state->opcode) { + case AML_RELEASE_OP: /* Release (Mutex_object) */ + + status = acpi_ex_release_mutex (operand[0], walk_state); + break; + + + case AML_RESET_OP: /* Reset (Event_object) */ + + status = acpi_ex_system_reset_event (operand[0]); + break; + + + case AML_SIGNAL_OP: /* Signal (Event_object) */ + + status = acpi_ex_system_signal_event (operand[0]); + break; + + + case AML_SLEEP_OP: /* Sleep (Msec_time) */ + + acpi_ex_system_do_suspend ((u32) operand[0]->integer.value); + break; + + + case AML_STALL_OP: /* Stall (Usec_time) */ + + acpi_ex_system_do_stall ((u32) operand[0]->integer.value); + break; + + + case AML_UNLOAD_OP: /* Unload (Handle) */ + + status = acpi_ex_unload_table (operand[0]); + break; + + + default: /* Unknown opcode */ + + REPORT_ERROR (("Acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + break; + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_1A_1T_0R + * + * PARAMETERS: Walk_state - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with one argument, one target, and no + * return value. + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_1A_1T_0R ( + acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + acpi_operand_object **operand = &walk_state->operands[0]; + + + FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + switch (walk_state->opcode) { + + case AML_LOAD_OP: + + status = acpi_ex_load_op (operand[0], operand[1]); + break; + + default: /* Unknown opcode */ + + REPORT_ERROR (("Acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + } + + +cleanup: + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_1A_1T_1R + * + * PARAMETERS: Walk_state - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with one argument, one target, and a + * return value. + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_1A_1T_1R ( + acpi_walk_state *walk_state) +{ + acpi_status status = AE_OK; + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc = NULL; + acpi_operand_object *return_desc2 = NULL; + u32 temp32; + u32 i; + u32 j; + acpi_integer digit; + + + FUNCTION_TRACE_STR ("Ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Create a return object of type Integer for most opcodes */ + + switch (walk_state->opcode) { + case AML_BIT_NOT_OP: + case AML_FIND_SET_LEFT_BIT_OP: + case AML_FIND_SET_RIGHT_BIT_OP: + case AML_FROM_BCD_OP: + case AML_TO_BCD_OP: + case AML_COND_REF_OF_OP: + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + break; + } + + + switch (walk_state->opcode) { + + case AML_BIT_NOT_OP: /* Not (Operand, Result) */ + + return_desc->integer.value = ~operand[0]->integer.value; + break; + + + case AML_FIND_SET_LEFT_BIT_OP: /* Find_set_left_bit (Operand, Result) */ + + + return_desc->integer.value = operand[0]->integer.value; + + /* + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundary condition is valid. + */ + for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + return_desc->integer.value >>= 1; + } + + return_desc->integer.value = temp32; + break; + + + case AML_FIND_SET_RIGHT_BIT_OP: /* Find_set_right_bit (Operand, Result) */ + + + return_desc->integer.value = operand[0]->integer.value; + + /* + * The Acpi specification describes Integer type as a little + * endian unsigned value, so this boundary condition is valid. + */ + for (temp32 = 0; return_desc->integer.value && temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) { + return_desc->integer.value <<= 1; + } + + /* Since the bit position is one-based, subtract from 33 (65) */ + + return_desc->integer.value = temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; + break; + + + case AML_FROM_BCD_OP: /* From_bcd (BCDValue, Result) */ + + /* + * The 64-bit ACPI integer can hold 16 4-bit BCD integers + */ + return_desc->integer.value = 0; + for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { + /* Get one BCD digit */ + + digit = (acpi_integer) ((operand[0]->integer.value >> (i * 4)) & 0xF); + + /* Check the range of the digit */ + + if (digit > 9) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD digit too large: %d\n", + (u32) digit)); + status = AE_AML_NUMERIC_OVERFLOW; + goto cleanup; + } + + if (digit > 0) { + /* Sum into the result with the appropriate power of 10 */ + + for (j = 0; j < i; j++) { + digit *= 10; + } + + return_desc->integer.value += digit; + } + } + break; + + + case AML_TO_BCD_OP: /* To_bcd (Operand, Result) */ + + if (operand[0]->integer.value > ACPI_MAX_BCD_VALUE) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "BCD overflow: %8.8X%8.8X\n", + HIDWORD(operand[0]->integer.value), LODWORD(operand[0]->integer.value))); + status = AE_AML_NUMERIC_OVERFLOW; + goto cleanup; + } + + return_desc->integer.value = 0; + for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { + /* Divide by nth factor of 10 */ + + temp32 = 0; + digit = operand[0]->integer.value; + for (j = 0; j < i; j++) { + acpi_ut_short_divide (&digit, 10, &digit, &temp32); + } + + /* Create the BCD digit from the remainder above */ + + if (digit > 0) { + return_desc->integer.value += (temp32 << (i * 4)); + } + } + break; + + + case AML_COND_REF_OF_OP: /* Cond_ref_of (Source_object, Result) */ + + /* + * This op is a little strange because the internal return value is + * different than the return value stored in the result descriptor + * (There are really two return values) + */ + if ((acpi_namespace_node *) operand[0] == acpi_gbl_root_node) { + /* + * This means that the object does not exist in the namespace, + * return FALSE + */ + return_desc->integer.value = 0; + + /* + * Must delete the result descriptor since there is no reference + * being returned + */ + acpi_ut_remove_reference (operand[1]); + goto cleanup; + } + + /* Get the object reference and store it */ + + status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + status = acpi_ex_store (return_desc2, operand[1], walk_state); + + /* The object exists in the namespace, return TRUE */ + + return_desc->integer.value = ACPI_INTEGER_MAX; + goto cleanup; + break; + + + case AML_STORE_OP: /* Store (Source, Target) */ + + /* + * A store operand is typically a number, string, buffer or lvalue + * Be careful about deleting the source object, + * since the object itself may have been stored. + */ + status = acpi_ex_store (operand[0], operand[1], walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* + * Normally, we would remove a reference on the Operand[0] parameter; + * But since it is being used as the internal return object + * (meaning we would normally increment it), the two cancel out, + * and we simply don't do anything. + */ + walk_state->result_obj = operand[0]; + walk_state->operands[0] = NULL; /* Prevent deletion */ + return_ACPI_STATUS (status); + break; + + + /* + * ACPI 2.0 Opcodes + */ + case AML_COPY_OP: /* Copy (Source, Target) */ + + status = AE_NOT_IMPLEMENTED; + goto cleanup; + break; + + + case AML_TO_DECSTRING_OP: /* To_decimal_string (Data, Result) */ + + status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state); + break; + + + case AML_TO_HEXSTRING_OP: /* To_hex_string (Data, Result) */ + + status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state); + break; + + + case AML_TO_BUFFER_OP: /* To_buffer (Data, Result) */ + + status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state); + break; + + + case AML_TO_INTEGER_OP: /* To_integer (Data, Result) */ + + status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state); + break; + + + /* + * These are two obsolete opcodes + */ + case AML_SHIFT_LEFT_BIT_OP: /* Shift_left_bit (Source, Bit_num) */ + case AML_SHIFT_RIGHT_BIT_OP: /* Shift_right_bit (Source, Bit_num) */ + + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n", + acpi_ps_get_opcode_name (walk_state->opcode))); + status = AE_SUPPORT; + goto cleanup; + break; + + + default: /* Unknown opcode */ + + REPORT_ERROR (("Acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + } + + + /* + * Store the return value computed above into the target object + */ + status = acpi_ex_store (return_desc, operand[1], walk_state); + + +cleanup: + + walk_state->result_obj = return_desc; + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_1A_0T_1R + * + * PARAMETERS: Walk_state - Current state (contains AML opcode) + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with one argument, no target, and a return value + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_1A_0T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *temp_desc; + acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u32 type; + acpi_integer value; + + + FUNCTION_TRACE_STR ("Ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Get the operand and decode the opcode */ + + switch (walk_state->opcode) { + + case AML_LNOT_OP: /* LNot (Operand) */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc->integer.value = !operand[0]->integer.value; + break; + + + case AML_DECREMENT_OP: /* Decrement (Operand) */ + case AML_INCREMENT_OP: /* Increment (Operand) */ + + /* + * Since we are expecting a Reference operand, it + * can be either a Node or an internal object. + */ + return_desc = operand[0]; + if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_INTERNAL)) { + /* Internal reference object - prevent deletion */ + + acpi_ut_add_reference (return_desc); + } + + /* + * Convert the Return_desc Reference to a Number + * (This removes a reference on the Return_desc object) + */ + status = acpi_ex_resolve_operands (AML_LNOT_OP, &return_desc, walk_state); + if (ACPI_FAILURE (status)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n", + acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception(status))); + + goto cleanup; + } + + /* + * Return_desc is now guaranteed to be an Integer object + * Do the actual increment or decrement + */ + if (AML_INCREMENT_OP == walk_state->opcode) { + return_desc->integer.value++; + } + else { + return_desc->integer.value--; + } + + /* Store the result back in the original descriptor */ + + status = acpi_ex_store (return_desc, operand[0], walk_state); + break; + + + case AML_TYPE_OP: /* Object_type (Source_object) */ + + if (INTERNAL_TYPE_REFERENCE == operand[0]->common.type) { + /* + * Not a Name -- an indirect name pointer would have + * been converted to a direct name pointer in Resolve_operands + */ + switch (operand[0]->reference.opcode) { + case AML_ZERO_OP: + case AML_ONE_OP: + case AML_ONES_OP: + case AML_REVISION_OP: + + /* Constants are of type Integer */ + + type = ACPI_TYPE_INTEGER; + break; + + + case AML_DEBUG_OP: + + /* Per 1.0b spec, Debug object is of type "Debug_object" */ + + type = ACPI_TYPE_DEBUG_OBJECT; + break; + + + case AML_INDEX_OP: + + /* Get the type of this reference (index into another object) */ + + type = operand[0]->reference.target_type; + if (type == ACPI_TYPE_PACKAGE) { + /* + * The main object is a package, we want to get the type + * of the individual package element that is referenced by + * the index. + */ + type = (*(operand[0]->reference.where))->common.type; + } + + break; + + + case AML_LOCAL_OP: + case AML_ARG_OP: + + type = acpi_ds_method_data_get_type (operand[0]->reference.opcode, + operand[0]->reference.offset, walk_state); + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R/Type_op: Internal error - Unknown Reference subtype %X\n", + operand[0]->reference.opcode)); + status = AE_AML_INTERNAL; + goto cleanup; + } + } + + else { + /* + * It's not a Reference, so it must be a direct name pointer. + */ + type = acpi_ns_get_type ((acpi_namespace_node *) operand[0]); + + /* Convert internal types to external types */ + + switch (type) { + case INTERNAL_TYPE_REGION_FIELD: + case INTERNAL_TYPE_BANK_FIELD: + case INTERNAL_TYPE_INDEX_FIELD: + + type = ACPI_TYPE_FIELD_UNIT; + } + + } + + /* Allocate a descriptor to hold the type. */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc->integer.value = type; + break; + + + case AML_SIZE_OF_OP: /* Size_of (Source_object) */ + + temp_desc = operand[0]; + if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { + temp_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) operand[0]); + } + + if (!temp_desc) { + value = 0; + } + + else { + switch (temp_desc->common.type) { + case ACPI_TYPE_BUFFER: + value = temp_desc->buffer.length; + break; + + case ACPI_TYPE_STRING: + value = temp_desc->string.length; + break; + + case ACPI_TYPE_PACKAGE: + value = temp_desc->package.count; + break; + + case INTERNAL_TYPE_REFERENCE: + + /* TBD: this must be a reference to a buf/str/pkg?? */ + + value = 4; + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Not Buf/Str/Pkg - found type %X\n", + temp_desc->common.type)); + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + } + + /* + * Now that we have the size of the object, create a result + * object to hold the value + */ + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc->integer.value = value; + break; + + + case AML_REF_OF_OP: /* Ref_of (Source_object) */ + + status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + break; + + + case AML_DEREF_OF_OP: /* Deref_of (Obj_reference) */ + + /* Check for a method local or argument */ + + if (!VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { + /* + * Must resolve/dereference the local/arg reference first + */ + switch (operand[0]->reference.opcode) { + /* Set Operand[0] to the value of the local/arg */ + + case AML_LOCAL_OP: + case AML_ARG_OP: + + acpi_ds_method_data_get_value (operand[0]->reference.opcode, + operand[0]->reference.offset, walk_state, &temp_desc); + + /* + * Delete our reference to the input object and + * point to the object just retrieved + */ + acpi_ut_remove_reference (operand[0]); + operand[0] = temp_desc; + break; + + default: + + /* Index op - handled below */ + break; + } + } + + + /* Operand[0] may have changed from the code above */ + + if (VALID_DESCRIPTOR_TYPE (operand[0], ACPI_DESC_TYPE_NAMED)) { + /* Get the actual object from the Node (This is the dereference) */ + + return_desc = ((acpi_namespace_node *) operand[0])->object; + + /* Returning a pointer to the object, add another reference! */ + + acpi_ut_add_reference (return_desc); + } + + else { + /* + * This must be a reference object produced by the Index + * ASL operation -- check internal opcode + */ + if ((operand[0]->reference.opcode != AML_INDEX_OP) && + (operand[0]->reference.opcode != AML_REF_OF_OP)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode in ref(%p) - %X\n", + operand[0], operand[0]->reference.opcode)); + + status = AE_TYPE; + goto cleanup; + } + + + switch (operand[0]->reference.opcode) { + case AML_INDEX_OP: + + /* + * Supported target types for the Index operator are + * 1) A Buffer + * 2) A Package + */ + if (operand[0]->reference.target_type == ACPI_TYPE_BUFFER_FIELD) { + /* + * The target is a buffer, we must create a new object that + * contains one element of the buffer, the element pointed + * to by the index. + * + * NOTE: index into a buffer is NOT a pointer to a + * sub-buffer of the main buffer, it is only a pointer to a + * single element (byte) of the buffer! + */ + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + temp_desc = operand[0]->reference.object; + return_desc->integer.value = + temp_desc->buffer.pointer[operand[0]->reference.offset]; + + /* TBD: [Investigate] (see below) Don't add an additional + * ref! + */ + } + + else if (operand[0]->reference.target_type == ACPI_TYPE_PACKAGE) { + /* + * The target is a package, we want to return the referenced + * element of the package. We must add another reference to + * this object, however. + */ + return_desc = *(operand[0]->reference.where); + if (!return_desc) { + /* + * We can't return a NULL dereferenced value. This is + * an uninitialized package element and is thus a + * severe error. + */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "NULL package element obj %p\n", + operand[0])); + status = AE_AML_UNINITIALIZED_ELEMENT; + goto cleanup; + } + + acpi_ut_add_reference (return_desc); + } + + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Target_type %X in obj %p\n", + operand[0]->reference.target_type, operand[0])); + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + break; + + + case AML_REF_OF_OP: + + return_desc = operand[0]->reference.object; + + /* Add another reference to the object! */ + + acpi_ut_add_reference (return_desc); + break; + } + } + + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + } + + +cleanup: + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + walk_state->result_obj = return_desc; + return_ACPI_STATUS (status); +} + diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c new file mode 100644 index 000000000000..029b932901e5 --- /dev/null +++ b/drivers/acpi/executer/exoparg2.c @@ -0,0 +1,564 @@ +/****************************************************************************** + * + * Module Name: exoparg2 - AML execution - opcodes with 2 arguments + * $Revision: 97 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000, 2001 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 "acparser.h" +#include "acnamesp.h" +#include "acinterp.h" +#include "acevents.h" +#include "amlcode.h" +#include "acdispat.h" + + +#define _COMPONENT ACPI_EXECUTER + MODULE_NAME ("exoparg2") + + +/*! + * Naming convention for AML interpreter execution routines. + * + * The routines that begin execution of AML opcodes are named with a common + * convention based upon the number of arguments, the number of target operands, + * and whether or not a value is returned: + * + * AcpiExOpcode_xA_yT_zR + * + * Where: + * + * xA - ARGUMENTS: The number of arguments (input operands) that are + * required for this opcode type (1 through 6 args). + * yT - TARGETS: The number of targets (output operands) that are required + * for this opcode type (0, 1, or 2 targets). + * zR - RETURN VALUE: Indicates whether this opcode type returns a value + * as the function return (0 or 1). + * + * The AcpiExOpcode* functions are called via the Dispatcher component with + * fully resolved operands. +!*/ + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_2A_0T_0R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with two arguments, no target, and no return + * value. + * + * ALLOCATION: Deletes both operands + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_2A_0T_0R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_namespace_node *node; + acpi_status status = AE_OK; + + + FUNCTION_TRACE_STR ("Ex_opcode_2A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Examine the opcode */ + + switch (walk_state->opcode) { + + case AML_NOTIFY_OP: /* Notify (Notify_object, Notify_value) */ + + /* The first operand is a namespace node */ + + node = (acpi_namespace_node *) operand[0]; + + /* The node must refer to a device or thermal zone */ + + if (node && operand[1]) /* TBD: is this check necessary? */ { + switch (node->type) { + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_THERMAL: + + /* + * Dispatch the notify to the appropriate handler + * NOTE: the request is queued for execution after this method + * completes. The notify handlers are NOT invoked synchronously + * from this thread -- because handlers may in turn run other + * control methods. + */ + status = acpi_ev_queue_notify_request (node, + (u32) operand[1]->integer.value); + break; + + default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type %X\n", + node->type)); + + status = AE_AML_OPERAND_TYPE; + break; + } + } + break; + + default: + + REPORT_ERROR (("Acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_2A_2T_1R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets + * and one implicit return value. + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_2A_2T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc1 = NULL; + acpi_operand_object *return_desc2 = NULL; + acpi_status status; + + + FUNCTION_TRACE_STR ("Ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* + * Execute the opcode + */ + switch (walk_state->opcode) { + case AML_DIVIDE_OP: /* Divide (Dividend, Divisor, Remainder_result Quotient_result) */ + + return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc1) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc2) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Quotient to Return_desc1, remainder to Return_desc2 */ + + status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, + &return_desc1->integer.value, &return_desc2->integer.value); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + break; + } + + + /* Store the results to the target reference operands */ + + status = acpi_ex_store (return_desc2, operand[2], walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + status = acpi_ex_store (return_desc1, operand[3], walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Return the remainder */ + + walk_state->result_obj = return_desc1; + + +cleanup: + /* + * Since the remainder is not returned indirectly, remove a reference to + * it. Only the quotient is returned indirectly. + */ + acpi_ut_remove_reference (return_desc2); + + if (ACPI_FAILURE (status)) { + /* Delete the return object */ + + acpi_ut_remove_reference (return_desc1); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_2A_1T_1R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with two arguments, one target, and a return + * value. + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_2A_1T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc = NULL; + acpi_operand_object *temp_desc; + u32 index; + acpi_status status = AE_OK; + + + FUNCTION_TRACE_STR ("Ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* + * Execute the opcode + */ + if (walk_state->op_info->flags & AML_MATH) { + /* All simple math opcodes (add, etc.) */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + return_desc->integer.value = acpi_ex_do_math_op (walk_state->opcode, + operand[0]->integer.value, + operand[1]->integer.value); + goto store_result_to_target; + } + + + switch (walk_state->opcode) { + case AML_MOD_OP: /* Mod (Dividend, Divisor, Remainder_result (ACPI 2.0) */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Return_desc will contain the remainder */ + + status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, + NULL, &return_desc->integer.value); + + break; + + + case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */ + + /* + * Convert the second operand if necessary. The first operand + * determines the type of the second operand, (See the Data Types + * section of the ACPI specification.) Both object types are + * guaranteed to be either Integer/String/Buffer by the operand + * resolution mechanism above. + */ + switch (operand[0]->common.type) { + case ACPI_TYPE_INTEGER: + status = acpi_ex_convert_to_integer (operand[1], &operand[1], walk_state); + break; + + case ACPI_TYPE_STRING: + status = acpi_ex_convert_to_string (operand[1], &operand[1], 16, ACPI_UINT32_MAX, walk_state); + break; + + case ACPI_TYPE_BUFFER: + status = acpi_ex_convert_to_buffer (operand[1], &operand[1], walk_state); + break; + + default: + status = AE_AML_INTERNAL; + } + + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* + * Both operands are now known to be the same object type + * (Both are Integer, String, or Buffer), and we can now perform the + * concatenation. + */ + status = acpi_ex_do_concatenate (operand[0], operand[1], &return_desc, walk_state); + break; + + + case AML_TO_STRING_OP: /* To_string (Buffer, Length, Result) (ACPI 2.0) */ + + status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, + (u32) operand[1]->integer.value, walk_state); + break; + + + case AML_CONCAT_RES_OP: /* Concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */ + + status = AE_NOT_IMPLEMENTED; + break; + + + case AML_INDEX_OP: /* Index (Source Index Result) */ + + /* Create the internal return object */ + + return_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + index = (u32) operand[1]->integer.value; + + /* + * At this point, the Source operand is either a Package or a Buffer + */ + if (operand[0]->common.type == ACPI_TYPE_PACKAGE) { + /* Object to be indexed is a Package */ + + if (index >= operand[0]->package.count) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond package end\n")); + status = AE_AML_PACKAGE_LIMIT; + goto cleanup; + } + + if ((operand[2]->common.type == INTERNAL_TYPE_REFERENCE) && + (operand[2]->reference.opcode == AML_ZERO_OP)) { + /* + * There is no actual result descriptor (the Zero_op Result + * descriptor is a placeholder), so just delete the placeholder and + * return a reference to the package element + */ + acpi_ut_remove_reference (operand[2]); + } + + else { + /* + * Each element of the package is an internal object. Get the one + * we are after. + */ + temp_desc = operand[0]->package.elements [index]; + return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.target_type = temp_desc->common.type; + return_desc->reference.object = temp_desc; + + status = acpi_ex_store (return_desc, operand[2], walk_state); + return_desc->reference.object = NULL; + } + + /* + * The local return object must always be a reference to the package element, + * not the element itself. + */ + return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.target_type = ACPI_TYPE_PACKAGE; + return_desc->reference.where = &operand[0]->package.elements [index]; + } + + else { + /* Object to be indexed is a Buffer */ + + if (index >= operand[0]->buffer.length) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond end of buffer\n")); + status = AE_AML_BUFFER_LIMIT; + goto cleanup; + } + + return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; + return_desc->reference.object = operand[0]; + return_desc->reference.offset = index; + + status = acpi_ex_store (return_desc, operand[2], walk_state); + } + + walk_state->result_obj = return_desc; + goto cleanup; + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + break; + } + + +store_result_to_target: + + if (ACPI_SUCCESS (status)) { + /* + * Store the result of the operation (which is now in Return_desc) into + * the Target descriptor. + */ + status = acpi_ex_store (return_desc, operand[2], walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + walk_state->result_obj = return_desc; + } + + +cleanup: + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_2A_0T_1R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_2A_0T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u8 logical_result = FALSE; + + + FUNCTION_TRACE_STR ("Ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + /* Create the internal return object */ + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* + * Execute the Opcode + */ + if (walk_state->op_info->flags & AML_LOGICAL) /* Logical_op (Operand0, Operand1) */ { + logical_result = acpi_ex_do_logical_op (walk_state->opcode, + operand[0]->integer.value, + operand[1]->integer.value); + goto store_logical_result; + } + + + switch (walk_state->opcode) { + case AML_ACQUIRE_OP: /* Acquire (Mutex_object, Timeout) */ + + status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state); + if (status == AE_TIME) { + logical_result = TRUE; /* TRUE = Acquire timed out */ + status = AE_OK; + } + break; + + + case AML_WAIT_OP: /* Wait (Event_object, Timeout) */ + + status = acpi_ex_system_wait_event (operand[1], operand[0]); + if (status == AE_TIME) { + logical_result = TRUE; /* TRUE, Wait timed out */ + status = AE_OK; + } + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + break; + } + + +store_logical_result: + /* + * Set return value to according to Logical_result. logical TRUE (all ones) + * Default is FALSE (zero) + */ + if (logical_result) { + return_desc->integer.value = ACPI_INTEGER_MAX; + } + + walk_state->result_obj = return_desc; + + +cleanup: + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + return_ACPI_STATUS (status); +} + + diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c new file mode 100644 index 000000000000..345315877254 --- /dev/null +++ b/drivers/acpi/executer/exoparg3.c @@ -0,0 +1,235 @@ + +/****************************************************************************** + * + * Module Name: exoparg3 - AML execution - opcodes with 3 arguments + * $Revision: 3 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000, 2001 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 "acinterp.h" +#include "acparser.h" +#include "amlcode.h" + + +#define _COMPONENT ACPI_EXECUTER + MODULE_NAME ("exoparg3") + + +/*! + * Naming convention for AML interpreter execution routines. + * + * The routines that begin execution of AML opcodes are named with a common + * convention based upon the number of arguments, the number of target operands, + * and whether or not a value is returned: + * + * AcpiExOpcode_xA_yT_zR + * + * Where: + * + * xA - ARGUMENTS: The number of arguments (input operands) that are + * required for this opcode type (1 through 6 args). + * yT - TARGETS: The number of targets (output operands) that are required + * for this opcode type (0, 1, or 2 targets). + * zR - RETURN VALUE: Indicates whether this opcode type returns a value + * as the function return (0 or 1). + * + * The AcpiExOpcode* functions are called via the Dispatcher component with + * fully resolved operands. +!*/ + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_3A_0T_0R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute Triadic operator (3 operands) + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_3A_0T_0R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + ACPI_SIGNAL_FATAL_INFO *fatal; + acpi_status status = AE_OK; + + + FUNCTION_TRACE_STR ("Ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + switch (walk_state->opcode) { + + case AML_FATAL_OP: /* Fatal (Fatal_type Fatal_code Fatal_arg) */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Fatal_op: Type %x Code %x Arg %x <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + (u32) operand[0]->integer.value, (u32) operand[1]->integer.value, + (u32) operand[2]->integer.value)); + + + fatal = ACPI_MEM_ALLOCATE (sizeof (ACPI_SIGNAL_FATAL_INFO)); + if (fatal) { + fatal->type = (u32) operand[0]->integer.value; + fatal->code = (u32) operand[1]->integer.value; + fatal->argument = (u32) operand[2]->integer.value; + } + + /* + * Always signal the OS! + */ + acpi_os_signal (ACPI_SIGNAL_FATAL, fatal); + + /* Might return while OS is shutting down, just continue */ + + ACPI_MEM_FREE (fatal); + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + break; + } + + +cleanup: + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_3A_1T_1R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute Triadic operator (3 operands) + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_3A_1T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc = NULL; + char *buffer; + acpi_status status = AE_OK; + u32 index; + u32 length; + + + FUNCTION_TRACE_STR ("Ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + switch (walk_state->opcode) { + case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */ + + /* + * Create the return object. The Source operand is guaranteed to be + * either a String or a Buffer, so just use its type. + */ + return_desc = acpi_ut_create_internal_object (operand[0]->common.type); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Get the Integer values from the objects */ + + index = (u32) operand[1]->integer.value; + length = (u32) operand[2]->integer.value; + + /* + * If the index is beyond the length of the String/Buffer, or if the + * requested length is zero, return a zero-length String/Buffer + */ + if ((index < operand[0]->string.length) && + (length > 0)) { + /* Truncate request if larger than the actual String/Buffer */ + + if ((index + length) > + operand[0]->string.length) { + length = operand[0]->string.length - index; + } + + /* Allocate a new buffer for the String/Buffer */ + + buffer = ACPI_MEM_CALLOCATE (length + 1); + if (!buffer) { + return (AE_NO_MEMORY); + } + + /* Copy the portion requested */ + + MEMCPY (buffer, operand[0]->string.pointer + index, + length); + + /* Set the length of the new String/Buffer */ + + return_desc->string.pointer = buffer; + return_desc->string.length = length; + } + + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + break; + } + + /* Store the result in the target */ + + status = acpi_ex_store (return_desc, operand[3], walk_state); + +cleanup: + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + /* Set the return object and exit */ + + walk_state->result_obj = return_desc; + return_ACPI_STATUS (status); +} + + diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c new file mode 100644 index 000000000000..ceda2b488918 --- /dev/null +++ b/drivers/acpi/executer/exoparg6.c @@ -0,0 +1,276 @@ + +/****************************************************************************** + * + * Module Name: exoparg6 - AML execution - opcodes with 6 arguments + * $Revision: 4 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000, 2001 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 "acinterp.h" +#include "acparser.h" +#include "amlcode.h" + + +#define _COMPONENT ACPI_EXECUTER + MODULE_NAME ("exoparg6") + + +/*! + * Naming convention for AML interpreter execution routines. + * + * The routines that begin execution of AML opcodes are named with a common + * convention based upon the number of arguments, the number of target operands, + * and whether or not a value is returned: + * + * AcpiExOpcode_xA_yT_zR + * + * Where: + * + * xA - ARGUMENTS: The number of arguments (input operands) that are + * required for this opcode type (1 through 6 args). + * yT - TARGETS: The number of targets (output operands) that are required + * for this opcode type (0, 1, or 2 targets). + * zR - RETURN VALUE: Indicates whether this opcode type returns a value + * as the function return (0 or 1). + * + * The AcpiExOpcode* functions are called via the Dispatcher component with + * fully resolved operands. +!*/ + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_do_match + * + * PARAMETERS: Match_op - The AML match operand + * Package_value - Value from the target package + * Match_value - Value to be matched + * + * RETURN: TRUE if the match is successful, FALSE otherwise + * + * DESCRIPTION: Implements the low-level match for the ASL Match operator + * + ******************************************************************************/ + +u8 +acpi_ex_do_match ( + u32 match_op, + acpi_integer package_value, + acpi_integer match_value) +{ + + switch (match_op) { + case MATCH_MTR: /* always true */ + + break; + + + case MATCH_MEQ: /* true if equal */ + + if (package_value != match_value) { + return (FALSE); + } + break; + + + case MATCH_MLE: /* true if less than or equal */ + + if (package_value > match_value) { + return (FALSE); + } + break; + + + case MATCH_MLT: /* true if less than */ + + if (package_value >= match_value) { + return (FALSE); + } + break; + + + case MATCH_MGE: /* true if greater than or equal */ + + if (package_value < match_value) { + return (FALSE); + } + break; + + + case MATCH_MGT: /* true if greater than */ + + if (package_value <= match_value) { + return (FALSE); + } + break; + + + default: /* undefined */ + + return (FALSE); + } + + + return TRUE; +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_opcode_6A_0T_1R + * + * PARAMETERS: Walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value + * + ******************************************************************************/ + +acpi_status +acpi_ex_opcode_6A_0T_1R ( + acpi_walk_state *walk_state) +{ + acpi_operand_object **operand = &walk_state->operands[0]; + acpi_operand_object *return_desc = NULL; + acpi_status status = AE_OK; + u32 index; + acpi_operand_object *this_element; + + + FUNCTION_TRACE_STR ("Ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + + + switch (walk_state->opcode) { + case AML_MATCH_OP: + /* + * Match (Search_package[0], Match_op1[1], Match_object1[2], + * Match_op2[3], Match_object2[4], Start_index[5]) + */ + + /* Validate match comparison sub-opcodes */ + + if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) || + (operand[3]->integer.value > MAX_MATCH_OPERATOR)) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "operation encoding out of range\n")); + status = AE_AML_OPERAND_VALUE; + goto cleanup; + } + + index = (u32) operand[5]->integer.value; + if (index >= (u32) operand[0]->package.count) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n")); + status = AE_AML_PACKAGE_LIMIT; + goto cleanup; + } + + return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); + if (!return_desc) { + status = AE_NO_MEMORY; + goto cleanup; + + } + + /* Default return value if no match found */ + + return_desc->integer.value = ACPI_INTEGER_MAX; + + /* + * Examine each element until a match is found. Within the loop, + * "continue" signifies that the current element does not match + * and the next should be examined. + * Upon finding a match, the loop will terminate via "break" at + * the bottom. If it terminates "normally", Match_value will be -1 + * (its initial value) indicating that no match was found. When + * returned as a Number, this will produce the Ones value as specified. + */ + for ( ; index < operand[0]->package.count; index++) { + this_element = operand[0]->package.elements[index]; + + /* + * Treat any NULL or non-numeric elements as non-matching. + * TBD [Unhandled] - if an element is a Name, + * should we examine its value? + */ + if (!this_element || + this_element->common.type != ACPI_TYPE_INTEGER) { + continue; + } + + + /* + * Within these switch statements: + * "break" (exit from the switch) signifies a match; + * "continue" (proceed to next iteration of enclosing + * "for" loop) signifies a non-match. + */ + if (!acpi_ex_do_match ((u32) operand[1]->integer.value, + this_element->integer.value, operand[2]->integer.value)) { + continue; + } + + + if (!acpi_ex_do_match ((u32) operand[3]->integer.value, + this_element->integer.value, operand[4]->integer.value)) { + continue; + } + + /* Match found: Index is the return value */ + + return_desc->integer.value = index; + break; + } + + break; + + + case AML_LOAD_TABLE_OP: + + status = AE_NOT_IMPLEMENTED; + goto cleanup; + break; + + + default: + + REPORT_ERROR (("Acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", + walk_state->opcode)); + status = AE_AML_BAD_OPCODE; + goto cleanup; + break; + } + + + walk_state->result_obj = return_desc; + + +cleanup: + + /* Delete return object on error */ + + if (ACPI_FAILURE (status)) { + acpi_ut_remove_reference (return_desc); + } + + return_ACPI_STATUS (status); +} diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index b2e513547257..0f1e4ae20eb8 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 95 $ + * $Revision: 99 $ * *****************************************************************************/ @@ -243,7 +243,7 @@ acpi_ex_prep_common_field_object ( /******************************************************************************* * - * FUNCTION: Acpi_ex_prep_region_field_value + * FUNCTION: Acpi_ex_prep_field_value * * PARAMETERS: Node - Owning Node * Region_node - Region in which field is being defined @@ -253,280 +253,128 @@ acpi_ex_prep_common_field_object ( * * RETURN: Status * - * DESCRIPTION: Construct an acpi_operand_object of type Def_field and + * DESCRIPTION: Construct an acpi_operand_object of type Def_field and * connect it to the parent Node. * ******************************************************************************/ acpi_status -acpi_ex_prep_region_field_value ( - acpi_namespace_node *node, - acpi_handle region_node, - u8 field_flags, - u32 field_bit_position, - u32 field_bit_length) +acpi_ex_prep_field_value ( + ACPI_CREATE_FIELD_INFO *info) { acpi_operand_object *obj_desc; u32 type; acpi_status status; - FUNCTION_TRACE ("Ex_prep_region_field_value"); + FUNCTION_TRACE ("Ex_prep_field_value"); /* Parameter validation */ - if (!region_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Region_node\n")); - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } + if (info->field_type != INTERNAL_TYPE_INDEX_FIELD) { + if (!info->region_node) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Region_node\n")); + return_ACPI_STATUS (AE_AML_NO_OPERAND); + } + + type = acpi_ns_get_type (info->region_node); + if (type != ACPI_TYPE_REGION) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %s\n", + type, acpi_ut_get_type_name (type))); - type = acpi_ns_get_type (region_node); - if (type != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %s\n", - type, acpi_ut_get_type_name (type))); - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } } - /* Allocate a new object */ + /* Allocate a new region object */ - obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REGION_FIELD); + obj_desc = acpi_ut_create_internal_object (info->field_type); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } - - /* Obj_desc and Region valid */ - - DUMP_OPERANDS ((acpi_operand_object **) &node, IMODE_EXECUTE, - "Ex_prep_region_field_value", 1, "case Region_field"); - DUMP_OPERANDS ((acpi_operand_object **) ®ion_node, IMODE_EXECUTE, - "Ex_prep_region_field_value", 1, "case Region_field"); - /* Initialize areas of the object that are common to all fields */ - status = acpi_ex_prep_common_field_object (obj_desc, field_flags, - field_bit_position, field_bit_length); + status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags, + info->field_bit_position, info->field_bit_length); if (ACPI_FAILURE (status)) { + acpi_ut_delete_object_desc (obj_desc); return_ACPI_STATUS (status); } - /* Initialize areas of the object that are specific to this field type */ - - obj_desc->field.region_obj = acpi_ns_get_attached_object (region_node); - - /* An additional reference for the container */ + /* Initialize areas of the object that are specific to the field type */ - acpi_ut_add_reference (obj_desc->field.region_obj); + switch (info->field_type) { + case INTERNAL_TYPE_REGION_FIELD: + obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node); - /* Debug info */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bitoff=%X Off=%X Gran=%X Region %p\n", - obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->field.region_obj)); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "set Named_obj %p (%4.4s) val = %p\n", - node, &(node->name), obj_desc)); + /* An additional reference for the container */ + acpi_ut_add_reference (obj_desc->field.region_obj); - /* - * Store the constructed descriptor (Obj_desc) into the parent Node, - * preserving the current type of that Named_obj. - */ - status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node)); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_prep_bank_field_value - * - * PARAMETERS: Node - Owning Node - * Region_node - Region in which field is being defined - * Bank_register_node - Bank selection register node - * Bank_val - Value to store in selection register - * Field_flags - Access, Lock_rule, and Update_rule - * Field_bit_position - Field start position - * Field_bit_length - Field length in number of bits - * - * RETURN: Status - * - * DESCRIPTION: Construct an object of type Bank_field and attach it to the - * parent Node. - * - ******************************************************************************/ + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Region_field: Bitoff=%X Off=%X Gran=%X Region %p\n", + obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, + obj_desc->field.access_bit_width, obj_desc->field.region_obj)); + break; -acpi_status -acpi_ex_prep_bank_field_value ( - acpi_namespace_node *node, - acpi_namespace_node *region_node, - acpi_namespace_node *bank_register_node, - u32 bank_val, - u8 field_flags, - u32 field_bit_position, - u32 field_bit_length) -{ - acpi_operand_object *obj_desc; - u32 type; - acpi_status status; + case INTERNAL_TYPE_BANK_FIELD: - FUNCTION_TRACE ("Ex_prep_bank_field_value"); + obj_desc->bank_field.value = info->bank_value; + obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node); + obj_desc->bank_field.bank_register_obj = acpi_ns_get_attached_object (info->register_node); + /* An additional reference for the attached objects */ - /* Parameter validation */ + acpi_ut_add_reference (obj_desc->bank_field.region_obj); + acpi_ut_add_reference (obj_desc->bank_field.bank_register_obj); - if (!region_node) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Region_node\n")); - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bank Field: Bit_off=%X Off=%X Gran=%X Region %p Bank_reg %p\n", + obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset, + obj_desc->field.access_bit_width, obj_desc->bank_field.region_obj, + obj_desc->bank_field.bank_register_obj)); + break; - type = acpi_ns_get_type (region_node); - if (type != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %s\n", - type, acpi_ut_get_type_name (type))); - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); - } - /* Allocate a new object */ + case INTERNAL_TYPE_INDEX_FIELD: - obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_BANK_FIELD); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } + obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node); + obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node); + obj_desc->index_field.value = (u32) (info->field_bit_position / + obj_desc->field.access_bit_width); - /* Obj_desc and Region valid */ + if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Index Object\n")); + return_ACPI_STATUS (AE_AML_INTERNAL); + } - DUMP_OPERANDS ((acpi_operand_object **) &node, IMODE_EXECUTE, - "Ex_prep_bank_field_value", 1, "case Bank_field"); - DUMP_OPERANDS ((acpi_operand_object **) ®ion_node, IMODE_EXECUTE, - "Ex_prep_bank_field_value", 1, "case Bank_field"); + /* An additional reference for the attached objects */ - /* Initialize areas of the object that are common to all fields */ + acpi_ut_add_reference (obj_desc->index_field.data_obj); + acpi_ut_add_reference (obj_desc->index_field.index_obj); - status = acpi_ex_prep_common_field_object (obj_desc, field_flags, - field_bit_position, field_bit_length); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Index_field: bitoff=%X off=%X gran=%X Index %p Data %p\n", + obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset, + obj_desc->field.access_bit_width, obj_desc->index_field.index_obj, + obj_desc->index_field.data_obj)); + break; } - /* Initialize areas of the object that are specific to this field type */ - - obj_desc->bank_field.value = bank_val; - obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (region_node); - obj_desc->bank_field.bank_register_obj = acpi_ns_get_attached_object (bank_register_node); - - /* An additional reference for the attached objects */ - - acpi_ut_add_reference (obj_desc->bank_field.region_obj); - acpi_ut_add_reference (obj_desc->bank_field.bank_register_obj); - - /* Debug info */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bit_off=%X Off=%X Gran=%X Region %p Bank_reg %p\n", - obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->bank_field.region_obj, - obj_desc->bank_field.bank_register_obj)); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Set Named_obj %p (%4.4s) val=%p\n", - node, &(node->name), obj_desc)); - - /* * Store the constructed descriptor (Obj_desc) into the parent Node, * preserving the current type of that Named_obj. */ - status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node)); - return_ACPI_STATUS (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_prep_index_field_value - * - * PARAMETERS: Node - Owning Node - * Index_reg - Index register - * Data_reg - Data register - * Field_flags - Access, Lock_rule, and Update_rule - * Field_bit_position - Field start position - * Field_bit_length - Field length in number of bits - * - * RETURN: Status - * - * DESCRIPTION: Construct an acpi_operand_object of type Index_field and - * connect it to the parent Node. - * - ******************************************************************************/ - -acpi_status -acpi_ex_prep_index_field_value ( - acpi_namespace_node *node, - acpi_namespace_node *index_reg, - acpi_namespace_node *data_reg, - u8 field_flags, - u32 field_bit_position, - u32 field_bit_length) -{ - acpi_operand_object *obj_desc; - acpi_status status; - - - FUNCTION_TRACE ("Ex_prep_index_field_value"); - - - /* Parameter validation */ - - if (!index_reg || !data_reg) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null handle\n")); - return_ACPI_STATUS (AE_AML_NO_OPERAND); - } - - /* Allocate a new object descriptor */ - - obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_INDEX_FIELD); - if (!obj_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* Initialize areas of the object that are common to all fields */ - - status = acpi_ex_prep_common_field_object (obj_desc, field_flags, - field_bit_position, field_bit_length); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - /* Initialize areas of the object that are specific to this field type */ - - obj_desc->index_field.data_obj = acpi_ns_get_attached_object (data_reg); - obj_desc->index_field.index_obj = acpi_ns_get_attached_object (index_reg); - obj_desc->index_field.value = (u32) (field_bit_position / - obj_desc->field.access_bit_width); - - /* An additional reference for the attached objects */ - - acpi_ut_add_reference (obj_desc->index_field.data_obj); - acpi_ut_add_reference (obj_desc->index_field.index_obj); - - /* Debug info */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "bitoff=%X off=%X gran=%X Index %p Data %p\n", - obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset, - obj_desc->field.access_bit_width, obj_desc->index_field.index_obj, - obj_desc->index_field.data_obj)); + status = acpi_ns_attach_object (info->field_node, obj_desc, + (u8) acpi_ns_get_type (info->field_node)); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "set Named_obj %p (%4.4s) val = %p\n", - node, &(node->name), obj_desc)); + info->field_node, (char*)&(info->field_node->name), obj_desc)); + /* Remove local reference to the object */ - /* - * Store the constructed descriptor (Obj_desc) into the parent Node, - * preserving the current type of that Named_obj. - */ - status = acpi_ns_attach_object (node, obj_desc, (u8) acpi_ns_get_type (node)); + acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index da346d7d6343..30fee9097c81 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exregion - ACPI default Op_region (address space) handlers - * $Revision: 58 $ + * $Revision: 61 $ * *****************************************************************************/ @@ -47,7 +47,7 @@ * Value - Pointer to in or out value * Handler_context - Pointer to Handler's context * Region_context - Pointer to context specific to the - * accessed region + * accessed region * * RETURN: Status * @@ -143,7 +143,7 @@ acpi_ex_system_memory_space_handler ( ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "IO %d (%d width) Address=%8.8lX%8.8lX\n", function, bit_width, + "System_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, HIDWORD (address), LODWORD (address))); /* Perform the memory read or write */ @@ -207,7 +207,7 @@ acpi_ex_system_memory_space_handler ( * Value - Pointer to in or out value * Handler_context - Pointer to Handler's context * Region_context - Pointer to context specific to the - * accessed region + * accessed region * * RETURN: Status * @@ -231,7 +231,7 @@ acpi_ex_system_io_space_handler ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "IO %d (%d width) Address=%8.8lX%8.8lX\n", function, bit_width, + "System_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, HIDWORD (address), LODWORD (address))); /* Decode the function parameter */ @@ -270,7 +270,7 @@ acpi_ex_system_io_space_handler ( * Value - Pointer to in or out value * Handler_context - Pointer to Handler's context * Region_context - Pointer to context specific to the - * accessed region + * accessed region * * RETURN: Status * @@ -311,7 +311,7 @@ acpi_ex_pci_config_space_handler ( pci_register = (u16) address; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "IO %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", + "Pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", function, bit_width, pci_id->segment, pci_id->bus, pci_id->device, pci_id->function, pci_register)); @@ -339,3 +339,77 @@ acpi_ex_pci_config_space_handler ( return_ACPI_STATUS (status); } + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_cmos_space_handler + * + * PARAMETERS: Function - Read or Write operation + * Address - Where in the space to read or write + * Bit_width - Field width in bits (8, 16, or 32) + * Value - Pointer to in or out value + * Handler_context - Pointer to Handler's context + * Region_context - Pointer to context specific to the + * accessed region + * + * RETURN: Status + * + * DESCRIPTION: Handler for the CMOS address space (Op Region) + * + ******************************************************************************/ + +acpi_status +acpi_ex_cmos_space_handler ( + u32 function, + ACPI_PHYSICAL_ADDRESS address, + u32 bit_width, + u32 *value, + void *handler_context, + void *region_context) +{ + acpi_status status = AE_OK; + + + FUNCTION_TRACE ("Ex_cmos_space_handler"); + + + return_ACPI_STATUS (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ex_pci_bar_space_handler + * + * PARAMETERS: Function - Read or Write operation + * Address - Where in the space to read or write + * Bit_width - Field width in bits (8, 16, or 32) + * Value - Pointer to in or out value + * Handler_context - Pointer to Handler's context + * Region_context - Pointer to context specific to the + * accessed region + * + * RETURN: Status + * + * DESCRIPTION: Handler for the PCI Bar_target address space (Op Region) + * + ******************************************************************************/ + +acpi_status +acpi_ex_pci_bar_space_handler ( + u32 function, + ACPI_PHYSICAL_ADDRESS address, + u32 bit_width, + u32 *value, + void *handler_context, + void *region_context) +{ + acpi_status status = AE_OK; + + + FUNCTION_TRACE ("Ex_pci_bar_space_handler"); + + + return_ACPI_STATUS (status); +} + diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index a8f4b80140cb..1609599038d6 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exresnte - AML Interpreter object resolution - * $Revision: 41 $ + * $Revision: 43 $ * *****************************************************************************/ @@ -43,14 +43,15 @@ * * FUNCTION: Acpi_ex_resolve_node_to_value * - * PARAMETERS: Stack_ptr - Pointer to a location on a stack that contains - * a pointer to a Node - * Walk_state - Current state + * PARAMETERS: Object_ptr - Pointer to a location that contains + * a pointer to a NS node, and will recieve a + * pointer to the resolved object. + * Walk_state - Current state. Valid only if executing AML + * code. NULL if simply resolving an object * * RETURN: Status * - * DESCRIPTION: Resolve a Namespace node (AKA a "direct name pointer") to - * a valued object + * DESCRIPTION: Resolve a Namespace node to a valued object * * Note: for some of the data types, the pointer attached to the Node * can be either a pointer to an actual internal object or a pointer into the @@ -66,12 +67,12 @@ acpi_status acpi_ex_resolve_node_to_value ( - acpi_namespace_node **stack_ptr, + acpi_namespace_node **object_ptr, acpi_walk_state *walk_state) { acpi_status status = AE_OK; - acpi_operand_object *val_desc; + acpi_operand_object *source_desc; acpi_operand_object *obj_desc = NULL; acpi_namespace_node *node; acpi_object_type8 entry_type; @@ -85,12 +86,12 @@ acpi_ex_resolve_node_to_value ( * The stack pointer points to a acpi_namespace_node (Node). Get the * object that is attached to the Node. */ - node = *stack_ptr; - val_desc = acpi_ns_get_attached_object (node); + node = *object_ptr; + source_desc = acpi_ns_get_attached_object (node); entry_type = acpi_ns_get_type ((acpi_handle) node); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p Val_desc=%p Type=%X\n", - node, val_desc, entry_type)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p Source_desc=%p Type=%X\n", + node, source_desc, entry_type)); /* @@ -103,7 +104,7 @@ acpi_ex_resolve_node_to_value ( return_ACPI_STATUS (AE_OK); } - if (!val_desc) { + if (!source_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object attached to node %p\n", node)); return_ACPI_STATUS (AE_AML_NO_OPERAND); @@ -117,60 +118,60 @@ acpi_ex_resolve_node_to_value ( case ACPI_TYPE_PACKAGE: - if (ACPI_TYPE_PACKAGE != val_desc->common.type) { + if (ACPI_TYPE_PACKAGE != source_desc->common.type) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n", - acpi_ut_get_type_name (val_desc->common.type))); + acpi_ut_get_type_name (source_desc->common.type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ - obj_desc = val_desc; + obj_desc = source_desc; acpi_ut_add_reference (obj_desc); break; case ACPI_TYPE_BUFFER: - if (ACPI_TYPE_BUFFER != val_desc->common.type) { + if (ACPI_TYPE_BUFFER != source_desc->common.type) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n", - acpi_ut_get_type_name (val_desc->common.type))); + acpi_ut_get_type_name (source_desc->common.type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ - obj_desc = val_desc; + obj_desc = source_desc; acpi_ut_add_reference (obj_desc); break; case ACPI_TYPE_STRING: - if (ACPI_TYPE_STRING != val_desc->common.type) { + if (ACPI_TYPE_STRING != source_desc->common.type) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n", - acpi_ut_get_type_name (val_desc->common.type))); + acpi_ut_get_type_name (source_desc->common.type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ - obj_desc = val_desc; + obj_desc = source_desc; acpi_ut_add_reference (obj_desc); break; case ACPI_TYPE_INTEGER: - if (ACPI_TYPE_INTEGER != val_desc->common.type) { + if (ACPI_TYPE_INTEGER != source_desc->common.type) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n", - acpi_ut_get_type_name (val_desc->common.type))); + acpi_ut_get_type_name (source_desc->common.type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* Return an additional reference to the object */ - obj_desc = val_desc; + obj_desc = source_desc; acpi_ut_add_reference (obj_desc); break; @@ -180,10 +181,10 @@ acpi_ex_resolve_node_to_value ( case INTERNAL_TYPE_BANK_FIELD: case INTERNAL_TYPE_INDEX_FIELD: - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Field_read Node=%p Val_desc=%p Type=%X\n", - node, val_desc, entry_type)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Field_read Node=%p Source_desc=%p Type=%X\n", + node, source_desc, entry_type)); - status = acpi_ex_read_data_from_field (val_desc, &obj_desc); + status = acpi_ex_read_data_from_field (source_desc, &obj_desc); break; @@ -200,7 +201,7 @@ acpi_ex_resolve_node_to_value ( /* Return an additional reference to the object */ - obj_desc = val_desc; + obj_desc = source_desc; acpi_ut_add_reference (obj_desc); break; @@ -222,7 +223,7 @@ acpi_ex_resolve_node_to_value ( */ case INTERNAL_TYPE_REFERENCE: - switch (val_desc->reference.opcode) { + switch (source_desc->reference.opcode) { case AML_ZERO_OP: @@ -241,13 +242,13 @@ acpi_ex_resolve_node_to_value ( case AML_REVISION_OP: - temp_val = ACPI_CA_VERSION; + temp_val = ACPI_CA_SUPPORT_LEVEL; break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n", - val_desc->reference.opcode)); + source_desc->reference.opcode)); return_ACPI_STATUS (AE_AML_BAD_OPCODE); } @@ -261,9 +262,15 @@ acpi_ex_resolve_node_to_value ( obj_desc->integer.value = temp_val; - /* Truncate value if we are executing from a 32-bit ACPI table */ - - acpi_ex_truncate_for32bit_table (obj_desc, walk_state); + /* + * Truncate value if we are executing from a 32-bit ACPI table + * AND actually executing AML code. If we are resolving + * an object in the namespace via an external call to the + * subsystem, we will have a null Walk_state + */ + if (walk_state) { + acpi_ex_truncate_for32bit_table (obj_desc, walk_state); + } break; @@ -281,7 +288,7 @@ acpi_ex_resolve_node_to_value ( /* Put the object descriptor on the stack */ - *stack_ptr = (void *) obj_desc; + *object_ptr = (void *) obj_desc; return_ACPI_STATUS (status); } diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 077c617ae1c6..fe430310a59f 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exresolv - AML Interpreter object resolution - * $Revision: 99 $ + * $Revision: 101 $ * *****************************************************************************/ @@ -131,12 +131,14 @@ acpi_ex_get_buffer_field_value ( (result_desc->integer.value >> obj_desc->buffer_field.start_field_bit_offset) & mask; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "** Read from buffer %p byte %ld bit %d width %d addr %p mask %08lx val %08lx\n", + "** Read from buffer %p byte %d bit %d width %d addr %p mask %08X val %8.8X%8.8X\n", obj_desc->buffer_field.buffer_obj->buffer.pointer, obj_desc->buffer_field.base_byte_offset, obj_desc->buffer_field.start_field_bit_offset, obj_desc->buffer_field.bit_length, - location, mask, result_desc->integer.value)); + location, mask, + HIDWORD(result_desc->integer.value), + LODWORD(result_desc->integer.value))); return_ACPI_STATUS (AE_OK); } @@ -323,7 +325,7 @@ acpi_ex_resolve_object_to_value ( break; case AML_REVISION_OP: - obj_desc->integer.value = ACPI_CA_VERSION; + obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL; break; } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 60965f6388c5..5917b4f9b470 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exresop - AML Interpreter operand/object resolution - * $Revision: 38 $ + * $Revision: 41 $ * *****************************************************************************/ @@ -120,7 +120,7 @@ acpi_ex_resolve_operands ( op_info = acpi_ps_get_opcode_info (opcode); - if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) { + if (op_info->class == AML_CLASS_UNKNOWN) { return_ACPI_STATUS (AE_AML_BAD_OPCODE); } @@ -146,7 +146,7 @@ acpi_ex_resolve_operands ( */ while (GET_CURRENT_ARG_TYPE (arg_types)) { if (!stack_ptr || !*stack_ptr) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null stack entry at %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null stack entry at %p\n", stack_ptr)); return_ACPI_STATUS (AE_AML_INTERNAL); @@ -183,7 +183,7 @@ acpi_ex_resolve_operands ( * Decode the Reference */ op_info = acpi_ps_get_opcode_info (opcode); - if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) { + if (op_info->class == AML_CLASS_UNKNOWN) { return_ACPI_STATUS (AE_AML_BAD_OPCODE); } diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 7daab63b3a88..de9e2e4781b7 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exstore - AML Interpreter object store support - * $Revision: 148 $ + * $Revision: 150 $ * *****************************************************************************/ @@ -42,15 +42,14 @@ * * FUNCTION: Acpi_ex_store * - * PARAMETERS: *Val_desc - Value to be stored + * PARAMETERS: *Source_desc - Value to be stored * *Dest_desc - Where to store it. Must be an NS node * or an acpi_operand_object of type - * Reference; if the latter the descriptor - * will be either reused or deleted. + * Reference; * * RETURN: Status * - * DESCRIPTION: Store the value described by Val_desc into the location + * DESCRIPTION: Store the value described by Source_desc into the location * described by Dest_desc. Called by various interpreter * functions to store the result of an operation into * the destination operand. @@ -59,7 +58,7 @@ acpi_status acpi_ex_store ( - acpi_operand_object *val_desc, + acpi_operand_object *source_desc, acpi_operand_object *dest_desc, acpi_walk_state *walk_state) { @@ -72,7 +71,7 @@ acpi_ex_store ( /* Validate parameters */ - if (!val_desc || !dest_desc) { + if (!source_desc || !dest_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } @@ -84,7 +83,7 @@ acpi_ex_store ( * Dest is a namespace node, * Storing an object into a Name "container" */ - status = acpi_ex_store_object_to_node (val_desc, + status = acpi_ex_store_object_to_node (source_desc, (acpi_namespace_node *) dest_desc, walk_state); /* All done, that's it */ @@ -101,7 +100,7 @@ acpi_ex_store ( ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Destination is not a Reference_obj [%p]\n", dest_desc)); - DUMP_STACK_ENTRY (val_desc); + DUMP_STACK_ENTRY (source_desc); DUMP_STACK_ENTRY (dest_desc); DUMP_OPERANDS (&dest_desc, IMODE_EXECUTE, "Ex_store", 2, "Target is not a Reference_obj"); @@ -125,7 +124,7 @@ acpi_ex_store ( /* Storing an object into a Name "container" */ - status = acpi_ex_store_object_to_node (val_desc, ref_desc->reference.object, + status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object, walk_state); break; @@ -134,7 +133,7 @@ acpi_ex_store ( /* Storing to an Index (pointer into a packager or buffer) */ - status = acpi_ex_store_object_to_index (val_desc, ref_desc, walk_state); + status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state); break; @@ -144,7 +143,7 @@ acpi_ex_store ( /* Store to a method local/arg */ status = acpi_ds_store_object_to_local (ref_desc->reference.opcode, - ref_desc->reference.offset, val_desc, walk_state); + ref_desc->reference.offset, source_desc, walk_state); break; @@ -157,39 +156,39 @@ acpi_ex_store ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Write to Debug Object: ****:\n\n")); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ", - acpi_ut_get_type_name (val_desc->common.type))); + acpi_ut_get_type_name (source_desc->common.type))); - switch (val_desc->common.type) { + switch (source_desc->common.type) { case ACPI_TYPE_INTEGER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%X (%d)\n", - (u32) val_desc->integer.value, (u32) val_desc->integer.value)); + (u32) source_desc->integer.value, (u32) source_desc->integer.value)); break; case ACPI_TYPE_BUFFER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Length 0x%X\n", - (u32) val_desc->buffer.length)); + (u32) source_desc->buffer.length)); break; case ACPI_TYPE_STRING: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", val_desc->string.pointer)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s\n", source_desc->string.pointer)); break; case ACPI_TYPE_PACKAGE: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - 0x%X\n", - (u32) val_desc->package.elements)); + (u32) source_desc->package.elements)); break; default: - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%p\n", val_desc)); + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "@0x%p\n", source_desc)); break; } @@ -224,12 +223,6 @@ acpi_ex_store ( } /* switch (Ref_desc->Reference.Opcode) */ - /* Always delete the reference descriptor object */ - - if (ref_desc) { - acpi_ut_remove_reference (ref_desc); - } - return_ACPI_STATUS (status); } @@ -238,7 +231,7 @@ acpi_ex_store ( * * FUNCTION: Acpi_ex_store_object_to_index * - * PARAMETERS: *Val_desc - Value to be stored + * PARAMETERS: *Source_desc - Value to be stored * *Node - Named object to receive the value * * RETURN: Status @@ -249,7 +242,7 @@ acpi_ex_store ( acpi_status acpi_ex_store_object_to_index ( - acpi_operand_object *val_desc, + acpi_operand_object *source_desc, acpi_operand_object *dest_desc, acpi_walk_state *walk_state) { @@ -278,7 +271,7 @@ acpi_ex_store_object_to_index ( if (dest_desc->reference.target_type == ACPI_TYPE_PACKAGE) { /* * The object at *(Dest_desc->Reference.Where) is the - * element within the package that is to be modified. + * element within the package that is to be modified. */ obj_desc = *(dest_desc->reference.where); if (obj_desc) { @@ -288,16 +281,12 @@ acpi_ex_store_object_to_index ( * * TBD: [Investigate] Should both the src and dest be required * to be packages? - * && (Val_desc->Common.Type == ACPI_TYPE_PACKAGE) + * && (Source_desc->Common.Type == ACPI_TYPE_PACKAGE) */ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - /* - * Take away the reference for being part of a package and - * delete - */ - acpi_ut_remove_reference (obj_desc); - acpi_ut_remove_reference (obj_desc); + /* Take away the reference for being part of a package */ + acpi_ut_remove_reference (obj_desc); obj_desc = NULL; } } @@ -307,9 +296,9 @@ acpi_ex_store_object_to_index ( * If the Obj_desc is NULL, it means that an uninitialized package * element has been used as a destination (this is OK), therefore, * we must create the destination element to match the type of the - * source element NOTE: Val_desc can be of any type. + * source element NOTE: Source_desccan be of any type. */ - obj_desc = acpi_ut_create_internal_object (val_desc->common.type); + obj_desc = acpi_ut_create_internal_object (source_desc->common.type); if (!obj_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -318,29 +307,25 @@ acpi_ex_store_object_to_index ( * If the source is a package, copy the source to the new dest */ if (ACPI_TYPE_PACKAGE == obj_desc->common.type) { - status = acpi_ut_copy_ipackage_to_ipackage (val_desc, obj_desc, walk_state); + status = acpi_ut_copy_ipackage_to_ipackage (source_desc, obj_desc, walk_state); if (ACPI_FAILURE (status)) { acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } } - /* - * Install the new descriptor into the package and add a - * reference to the newly created descriptor for now being - * part of the parent package - */ + /* Install the new descriptor into the package */ + *(dest_desc->reference.where) = obj_desc; - acpi_ut_add_reference (obj_desc); } if (ACPI_TYPE_PACKAGE != obj_desc->common.type) { /* * The destination element is not a package, so we need to - * convert the contents of the source (Val_desc) and copy into + * convert the contents of the source (Source_desc) and copy into * the destination (Obj_desc) */ - status = acpi_ex_store_object_to_object (val_desc, obj_desc, + status = acpi_ex_store_object_to_object (source_desc, obj_desc, walk_state); if (ACPI_FAILURE (status)) { /* @@ -380,7 +365,7 @@ acpi_ex_store_object_to_index ( * The assignment of the individual elements will be slightly * different for each source type. */ - switch (val_desc->common.type) { + switch (source_desc->common.type) { case ACPI_TYPE_INTEGER: /* * Type is Integer, assign bytewise @@ -389,7 +374,7 @@ acpi_ex_store_object_to_index ( */ length = sizeof (acpi_integer); for (i = length; i != 0; i--) { - value = (u8)(val_desc->integer.value >> (MUL_8 (i - 1))); + value = (u8)(source_desc->integer.value >> (MUL_8 (i - 1))); obj_desc->buffer.pointer[dest_desc->reference.offset] = value; } break; @@ -400,9 +385,9 @@ acpi_ex_store_object_to_index ( * Type is Buffer, the Length is in the structure. * Just loop through the elements and assign each one in turn. */ - length = val_desc->buffer.length; + length = source_desc->buffer.length; for (i = 0; i < length; i++) { - value = val_desc->buffer.pointer[i]; + value = source_desc->buffer.pointer[i]; obj_desc->buffer.pointer[dest_desc->reference.offset] = value; } break; @@ -413,9 +398,9 @@ acpi_ex_store_object_to_index ( * Type is String, the Length is in the structure. * Just loop through the elements and assign each one in turn. */ - length = val_desc->string.length; + length = source_desc->string.length; for (i = 0; i < length; i++) { - value = val_desc->string.pointer[i]; + value = source_desc->string.pointer[i]; obj_desc->buffer.pointer[dest_desc->reference.offset] = value; } break; @@ -427,7 +412,7 @@ acpi_ex_store_object_to_index ( ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Source must be Number/Buffer/String type, not %X\n", - val_desc->common.type)); + source_desc->common.type)); status = AE_AML_OPERAND_TYPE; break; } @@ -548,6 +533,7 @@ acpi_ex_store_object_to_node ( * Source_desc reference count is incremented by Attach_object. */ status = acpi_ns_attach_object (node, target_desc, target_type); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Store %s into %s via Convert/Attach\n", acpi_ut_get_type_name (target_desc->common.type), @@ -564,7 +550,6 @@ acpi_ex_store_object_to_node ( /* No conversions for all other types. Just attach the source object */ status = acpi_ns_attach_object (node, source_desc, source_desc->common.type); - break; } diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 26cb7c3d96fd..844f52f5964a 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exutils - interpreter/scanner utilities - * $Revision: 84 $ + * $Revision: 85 $ * *****************************************************************************/ @@ -265,16 +265,16 @@ acpi_ex_release_global_lock ( * * FUNCTION: Acpi_ex_digits_needed * - * PARAMETERS: val - Value to be represented - * base - Base of representation + * PARAMETERS: Value - Value to be represented + * Base - Base of representation * - * RETURN: the number of digits needed to represent val in base + * RETURN: the number of digits needed to represent Value in Base * ******************************************************************************/ u32 acpi_ex_digits_needed ( - acpi_integer val, + acpi_integer value, u32 base) { u32 num_digits = 0; @@ -289,9 +289,11 @@ acpi_ex_digits_needed ( else { /* - * acpi_integer is unsigned, which is why we don't worry about the '-' + * acpi_integer is unsigned, which is why we don't worry about a '-' */ - for (num_digits = 1; (val = ACPI_DIVIDE (val,base)); ++num_digits) { ; } + for (num_digits = 1; + (acpi_ut_short_divide (&value, base, &value, NULL)); + ++num_digits) { ; } } return_VALUE (num_digits); @@ -394,17 +396,18 @@ acpi_ex_unsigned_integer_to_string ( { u32 count; u32 digits_needed; + u32 remainder; FUNCTION_ENTRY (); digits_needed = acpi_ex_digits_needed (value, 10); - out_string[digits_needed] = '\0'; + out_string[digits_needed] = 0; for (count = digits_needed; count > 0; count--) { - out_string[count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (value, 10))); - value = ACPI_DIVIDE (value, 10); + acpi_ut_short_divide (&value, 10, &value, &remainder); + out_string[count-1] = (NATIVE_CHAR) ('0' + remainder); } return (AE_OK); diff --git a/drivers/acpi/executer/exxface.c b/drivers/acpi/executer/exxface.c deleted file mode 100644 index 51efc293bdb5..000000000000 --- a/drivers/acpi/executer/exxface.c +++ /dev/null @@ -1,102 +0,0 @@ - -/****************************************************************************** - * - * Module Name: exxface - External interpreter interfaces - * $Revision: 29 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000, 2001 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 "acinterp.h" - - -#define _COMPONENT ACPI_EXECUTER - MODULE_NAME ("exxface") - -#if 0 - -/* - * DEFINE_AML_GLOBALS is tested in amlcode.h - * to determine whether certain global names should be "defined" or only - * "declared" in the current compilation. This enhances maintainability - * by enabling a single header file to embody all knowledge of the names - * in question. - * - * Exactly one module of any executable should #define DEFINE_GLOBALS - * before #including the header files which use this convention. The - * names in question will be defined and initialized in that module, - * and declared as extern in all other modules which #include those - * header files. - */ - -#define DEFINE_AML_GLOBALS -#include "amlcode.h" -#include "acparser.h" -#include "acnamesp.h" - - -/******************************************************************************* - * - * FUNCTION: Acpi_ex_execute_method - * - * PARAMETERS: Pcode - Pointer to the pcode stream - * Pcode_length - Length of pcode that comprises the method - * **Params - List of parameters to pass to method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * - * RETURN: Status - * - * DESCRIPTION: Execute a control method - * - ******************************************************************************/ - -acpi_status -acpi_ex_execute_method ( - acpi_namespace_node *method_node, - acpi_operand_object **params, - acpi_operand_object **return_obj_desc) -{ - acpi_status status; - - - FUNCTION_TRACE ("Ex_execute_method"); - - - /* - * The point here is to lock the interpreter and call the low - * level execute. - */ - status = acpi_ex_enter_interpreter (); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - - status = acpi_psx_execute (method_node, params, return_obj_desc); - - acpi_ex_exit_interpreter (); - - return_ACPI_STATUS (status); -} - - -#endif |
