patch-2.4.10 linux/drivers/acpi/executer/exmisc.c
Next file: linux/drivers/acpi/executer/exmonad.c
Previous file: linux/drivers/acpi/executer/exfldio.c
Back to the patch index
Back to the overall index
- Lines: 704
- Date:
Sun Sep 23 09:42:32 2001
- Orig file:
v2.4.9/linux/drivers/acpi/executer/exmisc.c
- Orig date:
Tue Jul 3 17:08:19 2001
diff -u --recursive --new-file v2.4.9/linux/drivers/acpi/executer/exmisc.c linux/drivers/acpi/executer/exmisc.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
- * $Revision: 77 $
+ * $Revision: 83 $
*
*****************************************************************************/
@@ -38,194 +38,154 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_ex_fatal
+ * FUNCTION: Acpi_ex_triadic
*
- * PARAMETERS: none
+ * PARAMETERS: Opcode - The opcode to be executed
+ * Walk_state - Current walk state
+ * Return_desc - Where to store the return object
*
- * RETURN: Status. If the OS returns from the OSD call, we just keep
- * on going.
+ * RETURN: Status
*
- * DESCRIPTION: Execute Fatal operator
+ * DESCRIPTION: Execute Triadic operator (3 operands)
*
- * ACPI SPECIFICATION REFERENCES:
- * Def_fatal := Fatal_op Fatal_type Fatal_code Fatal_arg
- * Fatal_type := Byte_data
- * Fatal_code := DWord_data
- * Fatal_arg := Term_arg=>Integer
+ * ALLOCATION: Deletes one operand descriptor -- other remains on stack
*
******************************************************************************/
-ACPI_STATUS
-acpi_ex_fatal (
- ACPI_WALK_STATE *walk_state)
+acpi_status
+acpi_ex_triadic (
+ u16 opcode,
+ acpi_walk_state *walk_state,
+ acpi_operand_object **return_desc)
{
- ACPI_OPERAND_OBJECT *type_desc;
- ACPI_OPERAND_OBJECT *code_desc;
- ACPI_OPERAND_OBJECT *arg_desc;
- ACPI_STATUS status;
+ 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;
- /* Resolve operands */
+ FUNCTION_TRACE ("Ex_triadic");
- status = acpi_ex_resolve_operands (AML_FATAL_OP, WALK_OPERANDS, walk_state);
- /* Get operands */
- status |= acpi_ds_obj_stack_pop_object (&arg_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&code_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&type_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- /* Invalid parameters on object stack */
+#define obj_desc1 operand[0]
+#define obj_desc2 operand[1]
+#define res_desc operand[2]
- goto cleanup;
- }
+ switch (opcode) {
- /* Def_fatal := Fatal_op Fatal_type Fatal_code Fatal_arg */
+ case AML_FATAL_OP:
+ /* Def_fatal := Fatal_op Fatal_type Fatal_code Fatal_arg */
- /*
- * TBD: [Unhandled] call OSD interface to notify OS of fatal error
- * requiring shutdown!
- */
+ 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));
-cleanup:
+ 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;
+ }
- /* Free the operands */
+ /*
+ * Signal the OS
+ */
+ acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
- acpi_ut_remove_reference (arg_desc);
- acpi_ut_remove_reference (code_desc);
- acpi_ut_remove_reference (type_desc);
+ /* Might return while OS is shutting down */
+ ACPI_MEM_FREE (fatal);
+ break;
- /* If we get back from the OS call, we might as well keep going. */
- REPORT_WARNING (("An AML \"fatal\" Opcode (Fatal_op) was executed\n"));
- return (AE_OK);
-}
+ case AML_MID_OP:
+ /* Def_mid := Mid_op Source Index Length Result */
-/*******************************************************************************
- *
- * FUNCTION: Acpi_ex_index
- *
- * PARAMETERS: none
- *
- * RETURN: Status
- *
- * DESCRIPTION: Execute Index operator
- *
- * ALLOCATION: Deletes one operand descriptor -- other remains on stack
- *
- * ACPI SPECIFICATION REFERENCES:
- * Def_index := Index_op Buff_pkg_obj Index_value Result
- * Index_value := Term_arg=>Integer
- * Name_string := <Root_char Name_path> | <Prefix_path Name_path>
- * Result := Super_name
- * Super_name := Name_string | Arg_obj | Local_obj | Debug_obj | Def_index
- * Local4_op | Local5_op | Local6_op | Local7_op
- *
- ******************************************************************************/
+ /* Create the internal return object (string or buffer) */
-ACPI_STATUS
-acpi_ex_index (
- ACPI_WALK_STATE *walk_state,
- ACPI_OPERAND_OBJECT **return_desc)
-{
- ACPI_OPERAND_OBJECT *obj_desc;
- ACPI_OPERAND_OBJECT *idx_desc;
- ACPI_OPERAND_OBJECT *res_desc;
- ACPI_OPERAND_OBJECT *ret_desc = NULL;
- ACPI_OPERAND_OBJECT *tmp_desc;
- ACPI_STATUS status;
-
-
- /* Resolve operands */
- /* First operand can be either a package or a buffer */
-
- status = acpi_ex_resolve_operands (AML_INDEX_OP, WALK_OPERANDS, walk_state);
- /* Get all operands */
-
- status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&idx_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- /* Invalid parameters on object stack */
+ break;
- goto cleanup;
- }
+ case AML_INDEX_OP:
- /* Create the internal return object */
+ /* Def_index := Index_op Source Index Destination */
- ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
- if (!ret_desc) {
- status = AE_NO_MEMORY;
- goto cleanup;
- }
+ /* Create the internal return object */
+ ret_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
+ if (!ret_desc) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
+ }
- /*
- * At this point, the Obj_desc operand is either a Package or a Buffer
- */
+ /*
+ * 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_desc->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 (idx_desc->integer.value >= obj_desc->package.count) {
- 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);
+ }
- 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
- */
+ 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;
- acpi_ut_remove_reference (res_desc);
- }
+ status = acpi_ex_store (ret_desc, res_desc, walk_state);
+ ret_desc->reference.object = NULL;
+ }
- else {
/*
- * Each element of the package is an internal object. Get the one
- * we are after.
+ * The local return object must always be a reference to the package element,
+ * not the element itself.
*/
-
- tmp_desc = obj_desc->package.elements[idx_desc->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;
+ ret_desc->reference.target_type = ACPI_TYPE_PACKAGE;
+ ret_desc->reference.where = &obj_desc1->package.elements[obj_desc2->integer.value];
}
- /*
- * The local return object must always be a reference to the package element,
- * not the element itself.
- */
- ret_desc->reference.opcode = AML_INDEX_OP;
- ret_desc->reference.target_type = ACPI_TYPE_PACKAGE;
- ret_desc->reference.where = &obj_desc->package.elements[idx_desc->integer.value];
- }
-
- else {
- /* Object to be indexed is a Buffer */
+ else {
+ /* Object to be indexed is a Buffer */
- if (idx_desc->integer.value >= obj_desc->buffer.length) {
- status = AE_AML_BUFFER_LIMIT;
- goto cleanup;
- }
+ 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;
+ }
- ret_desc->reference.opcode = AML_INDEX_OP;
- ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
- ret_desc->reference.object = obj_desc;
- ret_desc->reference.offset = (u32) idx_desc->integer.value;
+ 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);
+ status = acpi_ex_store (ret_desc, res_desc, walk_state);
+ }
+ break;
}
@@ -233,8 +193,8 @@
/* Always delete operands */
- acpi_ut_remove_reference (obj_desc);
- acpi_ut_remove_reference (idx_desc);
+ acpi_ut_remove_reference (obj_desc1);
+ acpi_ut_remove_reference (obj_desc2);
/* Delete return object on error */
@@ -250,239 +210,227 @@
/* Set the return object and exit */
*return_desc = ret_desc;
- return (status);
+ return_ACPI_STATUS (status);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_ex_match
+ * FUNCTION: Acpi_ex_hexadic
*
- * PARAMETERS: none
+ * 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
*
- * ACPI SPECIFICATION REFERENCES:
- * Def_match := Match_op Search_pkg Opcode1 Operand1
- * Opcode2 Operand2 Start_index
- * Opcode1 := Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
- * Opcode2 := Byte_data: MTR, MEQ, MLE, MLT, MGE, or MGT
- * Operand1 := Term_arg=>Integer
- * Operand2 := Term_arg=>Integer
- * Search_pkg := Term_arg=>Package_object
- * Start_index := Term_arg=>Integer
- *
******************************************************************************/
-ACPI_STATUS
-acpi_ex_match (
- ACPI_WALK_STATE *walk_state,
- ACPI_OPERAND_OBJECT **return_desc)
+acpi_status
+acpi_ex_hexadic (
+ u16 opcode,
+ acpi_walk_state *walk_state,
+ acpi_operand_object **return_desc)
{
- ACPI_OPERAND_OBJECT *pkg_desc;
- ACPI_OPERAND_OBJECT *op1_desc;
- ACPI_OPERAND_OBJECT *V1_desc;
- ACPI_OPERAND_OBJECT *op2_desc;
- ACPI_OPERAND_OBJECT *V2_desc;
- ACPI_OPERAND_OBJECT *start_desc;
- ACPI_OPERAND_OBJECT *ret_desc = NULL;
- ACPI_STATUS status;
+ 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;
- /* Resolve all operands */
+ FUNCTION_TRACE ("Ex_hexadic");
- status = acpi_ex_resolve_operands (AML_MATCH_OP, WALK_OPERANDS, walk_state);
- /* Get all operands */
+#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]
- status |= acpi_ds_obj_stack_pop_object (&start_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&V2_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&op2_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&V1_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&op1_desc, walk_state);
- status |= acpi_ds_obj_stack_pop_object (&pkg_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- /* Invalid parameters on object stack */
+ switch (opcode) {
- goto cleanup;
- }
+ case AML_MATCH_OP:
- /* Validate match comparison sub-opcodes */
+ /* Validate match comparison sub-opcodes */
- if ((op1_desc->integer.value > MAX_MATCH_OPERATOR) ||
- (op2_desc->integer.value > MAX_MATCH_OPERATOR)) {
- status = AE_AML_OPERAND_VALUE;
- goto cleanup;
- }
-
- index = (u32) start_desc->integer.value;
- if (index >= (u32) pkg_desc->package.count) {
- status = AE_AML_PACKAGE_LIMIT;
- goto cleanup;
- }
-
- ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
- if (!ret_desc) {
- status = AE_NO_MEMORY;
- goto cleanup;
+ 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;
+ }
- }
+ 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;
+ }
- /*
- * 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.
- */
+ ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ if (!ret_desc) {
+ status = AE_NO_MEMORY;
+ goto cleanup;
- 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.
+ * 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.
*/
- switch (op1_desc->integer.value) {
+ 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;
+ }
- case MATCH_MTR: /* always true */
+ /*
+ * 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) {
- break;
+ case MATCH_MTR: /* always true */
+ break;
- case MATCH_MEQ: /* true if equal */
- if (pkg_desc->package.elements[index]->integer.value
- != V1_desc->integer.value) {
- continue;
- }
- break;
+ case MATCH_MEQ: /* true if equal */
+ if (pkg_desc->package.elements[index]->integer.value
+ != V1_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MLE: /* true if less than or equal */
- if (pkg_desc->package.elements[index]->integer.value
- > V1_desc->integer.value) {
- continue;
- }
- break;
+ case MATCH_MLE: /* true if less than or equal */
+ if (pkg_desc->package.elements[index]->integer.value
+ > V1_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MLT: /* true if less than */
- if (pkg_desc->package.elements[index]->integer.value
- >= V1_desc->integer.value) {
- continue;
- }
- break;
+ case MATCH_MLT: /* true if less than */
+ if (pkg_desc->package.elements[index]->integer.value
+ >= V1_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MGE: /* true if greater than or equal */
- if (pkg_desc->package.elements[index]->integer.value
- < V1_desc->integer.value) {
- continue;
- }
- break;
+ case MATCH_MGE: /* true if greater than or equal */
+
+ if (pkg_desc->package.elements[index]->integer.value
+ < V1_desc->integer.value) {
+ continue;
+ }
+ break;
+
+
+ case MATCH_MGT: /* true if greater than */
+
+ if (pkg_desc->package.elements[index]->integer.value
+ <= V1_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MGT: /* true if greater than */
+ default: /* undefined */
- if (pkg_desc->package.elements[index]->integer.value
- <= V1_desc->integer.value) {
continue;
}
- break;
- default: /* undefined */
+ switch(op2_desc->integer.value) {
- continue;
- }
+ case MATCH_MTR:
+ break;
- switch(op2_desc->integer.value) {
- case MATCH_MTR:
+ case MATCH_MEQ:
- break;
+ if (pkg_desc->package.elements[index]->integer.value
+ != V2_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MEQ:
+ case MATCH_MLE:
- if (pkg_desc->package.elements[index]->integer.value
- != V2_desc->integer.value) {
- continue;
- }
- break;
+ if (pkg_desc->package.elements[index]->integer.value
+ > V2_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MLE:
+ case MATCH_MLT:
- if (pkg_desc->package.elements[index]->integer.value
- > V2_desc->integer.value) {
- continue;
- }
- break;
+ if (pkg_desc->package.elements[index]->integer.value
+ >= V2_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MLT:
+ case MATCH_MGE:
- if (pkg_desc->package.elements[index]->integer.value
- >= V2_desc->integer.value) {
- continue;
- }
- break;
+ if (pkg_desc->package.elements[index]->integer.value
+ < V2_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MGE:
+ case MATCH_MGT:
- if (pkg_desc->package.elements[index]->integer.value
- < V2_desc->integer.value) {
- continue;
- }
- break;
+ if (pkg_desc->package.elements[index]->integer.value
+ <= V2_desc->integer.value) {
+ continue;
+ }
+ break;
- case MATCH_MGT:
+ default:
- if (pkg_desc->package.elements[index]->integer.value
- <= V2_desc->integer.value) {
continue;
}
- break;
+ /* Match found: exit from loop */
- default:
-
- continue;
+ match_value = index;
+ break;
}
- /* Match found: exit from loop */
+ /* Match_value is the return value */
- match_value = index;
+ ret_desc->integer.value = match_value;
break;
- }
-
- /* Match_value is the return value */
- ret_desc->integer.value = match_value;
+ }
cleanup:
@@ -509,5 +457,5 @@
/* Set the return object and exit */
*return_desc = ret_desc;
- return (status);
+ return_ACPI_STATUS (status);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)