Skip to content

Commit

Permalink
ACPI: ACPICA 20060526
Browse files Browse the repository at this point in the history
Restructured, flattened, and simplified the internal
interfaces for namespace object evaluation - resulting
in smaller code, less CPU stack use, and fewer
interfaces. (With assistance from Mikhail Kouzmich)

Fixed a problem with the CopyObject operator where the
first parameter was not typed correctly for the parser,
interpreter, compiler, and disassembler. Caused various
errors and unexpected behavior.

Fixed a problem where a ShiftLeft or ShiftRight of
more than 64 bits produced incorrect results with some
C compilers. Since the behavior of C compilers when
the shift value is larger than the datatype width is
apparently not well defined, the interpreter now detects
this condition and simply returns zero as expected in all
such cases. (BZ 395)

Fixed problem reports (Valery Podrezov) integrated: -
Update String-to-Integer conversion to match ACPI 3.0A spec
http://bugzilla.kernel.org/show_bug.cgi?id=5329
Allow interpreter to handle nested method declarations
http://bugzilla.kernel.org/show_bug.cgi?id=5361

Fixed problem reports (Fiodor Suietov) integrated: -
acpi_terminate() doesn't free debug memory allocation
list objects (BZ 355) - After Core Subsystem
shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) -
acpi_os_unmap_memory() for RSDP can be invoked inconsistently
(BZ 357) - Resource Manager should return AE_TYPE for
non-device objects (BZ 358) - Incomplete cleanup branch
in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free()
instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360)
- Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) -
Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362)
- acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT
is loaded (BZ 365) - Status of the Global Initialization
Handler call not used (BZ 366) - Incorrect object parameter
to Global Initialization Handler (BZ 367)

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Bob Moore authored and Len Brown committed Jun 14, 2006
1 parent b8d3519 commit 4119532
Show file tree
Hide file tree
Showing 39 changed files with 981 additions and 1,057 deletions.
20 changes: 16 additions & 4 deletions drivers/acpi/dispatcher/dsmethod.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
struct acpi_namespace_node *method_node;
struct acpi_walk_state *next_walk_state = NULL;
union acpi_operand_object *obj_desc;
struct acpi_parameter_info info;
struct acpi_evaluate_info *info;
u32 i;

ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
Expand Down Expand Up @@ -319,12 +319,24 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
*/
this_walk_state->operands[this_walk_state->num_operands] = NULL;

info.parameters = &this_walk_state->operands[0];
info.parameter_type = ACPI_PARAM_ARGS;
/*
* Allocate and initialize the evaluation information block
* TBD: this is somewhat inefficient, should change interface to
* ds_init_aml_walk. For now, keeps this struct off the CPU stack
*/
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
if (!info) {
return_ACPI_STATUS(AE_NO_MEMORY);
}

info->parameters = &this_walk_state->operands[0];
info->parameter_type = ACPI_PARAM_ARGS;

status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
obj_desc->method.aml_start,
obj_desc->method.aml_length, &info, 3);
obj_desc->method.aml_length, info, 3);

ACPI_FREE(info);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/dispatcher/dswexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,

case AML_CLASS_NAMED_OBJECT:

if (walk_state->walk_type == ACPI_WALK_METHOD) {
if (walk_state->walk_type & ACPI_WALK_METHOD) {
/*
* Found a named object declaration during method execution;
* we must enter this object into the namespace. The created
Expand Down
5 changes: 4 additions & 1 deletion drivers/acpi/dispatcher/dswstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
struct acpi_namespace_node *method_node,
u8 * aml_start,
u32 aml_length,
struct acpi_parameter_info *info, u8 pass_number)
struct acpi_evaluate_info *info, u8 pass_number)
{
acpi_status status;
struct acpi_parse_state *parser_state = &walk_state->parser_state;
Expand Down Expand Up @@ -825,9 +825,12 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
return;
}

/* There should not be any open scopes */

if (walk_state->parser_state.scope) {
ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
walk_state));
acpi_ps_cleanup_scope(&walk_state->parser_state);
}

/* Always must free any linked control states */
Expand Down
39 changes: 26 additions & 13 deletions drivers/acpi/events/evgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*
* RETURN: None
*
* DESCRIPTION: Perform the actual execution of a GPE control method. This
* function is called from an invocation of acpi_os_exece
* (and therefore does NOT execute at interrupt level) so that
* DESCRIPTION: Perform the actual execution of a GPE control method. This
* function is called from an invocation of acpi_os_execute and
* therefore does NOT execute at interrupt level - so that
* the control method itself is not executed in the context of
* an interrupt handler.
*
Expand All @@ -502,7 +502,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
u32 gpe_number = 0;
acpi_status status;
struct acpi_gpe_event_info local_gpe_event_info;
struct acpi_parameter_info info;
struct acpi_evaluate_info *info;

ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

Expand Down Expand Up @@ -540,16 +540,29 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
*/
if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD) {
/*
* Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
* control method that corresponds to this GPE
*/
info.node = local_gpe_event_info.dispatch.method_node;
info.parameters =
ACPI_CAST_PTR(union acpi_operand_object *, gpe_event_info);
info.parameter_type = ACPI_PARAM_GPE;

status = acpi_ns_evaluate_by_handle(&info);
/* Allocate the evaluation information block */

info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
if (!info) {
status = AE_NO_MEMORY;
} else {
/*
* Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
* control method that corresponds to this GPE
*/
info->prefix_node =
local_gpe_event_info.dispatch.method_node;
info->parameters =
ACPI_CAST_PTR(union acpi_operand_object *,
gpe_event_info);
info->parameter_type = ACPI_PARAM_GPE;
info->flags = ACPI_IGNORE_RETURN_VALUE;

status = acpi_ns_evaluate(info);
ACPI_FREE(info);
}

if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"While evaluating method [%4.4s] for GPE[%2X]",
Expand Down
18 changes: 11 additions & 7 deletions drivers/acpi/events/evmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evmisc")

/* Names for Notify() values, used for debug output */
#ifdef ACPI_DEBUG_OUTPUT
static const char *acpi_notify_value_names[] = {
"Bus Check",
"Device Check",
"Device Wake",
"Eject request",
"Eject Request",
"Device Check Light",
"Frequency Mismatch",
"Bus Mode Mismatch",
Expand Down Expand Up @@ -191,8 +192,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
notify_info->notify.value = (u16) notify_value;
notify_info->notify.handler_obj = handler_obj;

status = acpi_os_execute(OSL_NOTIFY_HANDLER,
acpi_ev_notify_dispatch, notify_info);
status =
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
notify_info);
if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(notify_info);
}
Expand Down Expand Up @@ -345,8 +347,9 @@ static u32 acpi_ev_global_lock_handler(void *context)

/* Run the Global Lock thread which will signal all waiting threads */

status = acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
acpi_ev_global_lock_thread, context);
status =
acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
acpi_ev_global_lock_thread, context);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not queue Global Lock thread"));
Expand Down Expand Up @@ -462,8 +465,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
* Acquire the global lock semaphore first.
* Since this wait will block, we must release the interpreter
*/
status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
timeout);
status =
acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
timeout);
return_ACPI_STATUS(status);
}

Expand Down
65 changes: 39 additions & 26 deletions drivers/acpi/events/evregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ acpi_status acpi_ev_initialize_op_regions(void)
acpi_status
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
{
struct acpi_parameter_info info;
union acpi_operand_object *params[3];
struct acpi_evaluate_info *info;
union acpi_operand_object *args[3];
union acpi_operand_object *region_obj2;
acpi_status status;

Expand All @@ -209,47 +209,60 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
return_ACPI_STATUS(AE_OK);
}

/* Allocate and initialize the evaluation information block */

info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
if (!info) {
return_ACPI_STATUS(AE_NO_MEMORY);
}

info->prefix_node = region_obj2->extra.method_REG;
info->pathname = NULL;
info->parameters = args;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;

/*
* The _REG method has two arguments:
*
* Arg0, Integer: Operation region space ID
* Same value as region_obj->Region.space_id
* Arg1, Integer: connection status
* 1 for connecting the handler,
* 0 for disconnecting the handler
* Passed as a parameter
* Arg0 - Integer:
* Operation region space ID Same value as region_obj->Region.space_id
*
* Arg1 - Integer:
* connection status 1 for connecting the handler, 0 for disconnecting
* the handler (Passed as a parameter)
*/
params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!params[0]) {
return_ACPI_STATUS(AE_NO_MEMORY);
args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!args[0]) {
status = AE_NO_MEMORY;
goto cleanup1;
}

params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!params[1]) {
args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!args[1]) {
status = AE_NO_MEMORY;
goto cleanup;
goto cleanup2;
}

/* Setup the parameter objects */

params[0]->integer.value = region_obj->region.space_id;
params[1]->integer.value = function;
params[2] = NULL;

info.node = region_obj2->extra.method_REG;
info.parameters = params;
info.parameter_type = ACPI_PARAM_ARGS;
args[0]->integer.value = region_obj->region.space_id;
args[1]->integer.value = function;
args[2] = NULL;

/* Execute the method, no return value */

ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
(ACPI_TYPE_METHOD, info.node, NULL));
status = acpi_ns_evaluate_by_handle(&info);
(ACPI_TYPE_METHOD, info->prefix_node, NULL));

status = acpi_ns_evaluate(info);
acpi_ut_remove_reference(args[1]);

acpi_ut_remove_reference(params[1]);
cleanup2:
acpi_ut_remove_reference(args[0]);

cleanup:
acpi_ut_remove_reference(params[0]);
cleanup1:
ACPI_FREE(info);
return_ACPI_STATUS(status);
}

Expand Down
5 changes: 3 additions & 2 deletions drivers/acpi/events/evrgnini.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,

/* Find any "_REG" method associated with this region definition */

status = acpi_ns_search_node(*reg_name_ptr, node,
ACPI_TYPE_METHOD, &method_node);
status =
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
&method_node);
if (ACPI_SUCCESS(status)) {
/*
* The _REG method is optional and there can be only one per region
Expand Down
10 changes: 4 additions & 6 deletions drivers/acpi/executer/exconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
* location within the namespace where the table will be loaded.
*/
status =
acpi_ns_get_node_by_path(operand[3]->string.pointer,
start_node, ACPI_NS_SEARCH_PARENT,
&parent_node);
acpi_ns_get_node(start_node, operand[3]->string.pointer,
ACPI_NS_SEARCH_PARENT, &parent_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
Expand All @@ -237,9 +236,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
/* Find the node referenced by the parameter_path_string */

status =
acpi_ns_get_node_by_path(operand[4]->string.pointer,
start_node, ACPI_NS_SEARCH_PARENT,
&parameter_node);
acpi_ns_get_node(start_node, operand[4]->string.pointer,
ACPI_NS_SEARCH_PARENT, &parameter_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
Expand Down
24 changes: 13 additions & 11 deletions drivers/acpi/executer/exfldio.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
* length of one field datum (access width) must fit within the region.
* (Region length is specified in bytes)
*/
if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
field_datum_byte_offset +
obj_desc->common_field.
access_byte_width)) {
if (rgn_desc->region.length <
(obj_desc->common_field.base_byte_offset +
field_datum_byte_offset +
obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpreter_slack) {
/*
* Slack mode only: We will go ahead and allow access to this
Expand Down Expand Up @@ -811,13 +811,15 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,

mask =
ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
datum_count =
ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
obj_desc->common_field.access_bit_width);
field_datum_count =
ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.access_bit_width);

datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
obj_desc->common_field.access_bit_width);

field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
obj_desc->common_field.
start_field_bit_offset,
obj_desc->common_field.
access_bit_width);

/* Get initial Datum from the input buffer */

Expand Down
14 changes: 14 additions & 0 deletions drivers/acpi/executer/exmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,24 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1)

case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */

/*
* We need to check if the shiftcount is larger than the integer bit
* width since the behavior of this is not well-defined in the C language.
*/
if (integer1 >= acpi_gbl_integer_bit_width) {
return (0);
}
return (integer0 << integer1);

case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */

/*
* We need to check if the shiftcount is larger than the integer bit
* width since the behavior of this is not well-defined in the C language.
*/
if (integer1 >= acpi_gbl_integer_bit_width) {
return (0);
}
return (integer0 >> integer1);

case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
Expand Down
18 changes: 8 additions & 10 deletions drivers/acpi/executer/exoparg1.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,16 +874,14 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
* Field, so we need to resolve the node to a value.
*/
status =
acpi_ns_get_node_by_path(operand[0]->string.
pointer,
walk_state->
scope_info->scope.
node,
ACPI_NS_SEARCH_PARENT,
ACPI_CAST_INDIRECT_PTR
(struct
acpi_namespace_node,
&return_desc));
acpi_ns_get_node(walk_state->scope_info->
scope.node,
operand[0]->string.pointer,
ACPI_NS_SEARCH_PARENT,
ACPI_CAST_INDIRECT_PTR
(struct
acpi_namespace_node,
&return_desc));
if (ACPI_FAILURE(status)) {
goto cleanup;
}
Expand Down
Loading

0 comments on commit 4119532

Please sign in to comment.