📄 amdyadic.c
字号:
if (!obj_desc2->integer.value) {
REPORT_ERROR
(("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n"));
status = AE_AML_DIVIDE_BY_ZERO;
goto cleanup;
}
ret_desc2 = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER);
if (!ret_desc2) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Remainder (modulo) */
ret_desc->integer.value = ACPI_MODULO (obj_desc->integer.value,
obj_desc2->integer.value);
/* Result (what we used to call the quotient) */
ret_desc2->integer.value = ACPI_DIVIDE (obj_desc->integer.value,
obj_desc2->integer.value);
break;
/* Def_multiply := Multiply_op Operand1 Operand2 Result */
case AML_MULTIPLY_OP:
ret_desc->integer.value = obj_desc->integer.value *
obj_desc2->integer.value;
break;
/* Def_shift_left := Shift_left_op Operand Shift_count Result */
case AML_SHIFT_LEFT_OP:
ret_desc->integer.value = obj_desc->integer.value <<
obj_desc2->integer.value;
break;
/* Def_shift_right := Shift_right_op Operand Shift_count Result */
case AML_SHIFT_RIGHT_OP:
ret_desc->integer.value = obj_desc->integer.value >>
obj_desc2->integer.value;
break;
/* Def_subtract := Subtract_op Operand1 Operand2 Result */
case AML_SUBTRACT_OP:
ret_desc->integer.value = obj_desc->integer.value -
obj_desc2->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 (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
status = acpi_aml_convert_to_integer (&obj_desc2, walk_state);
break;
case ACPI_TYPE_STRING:
status = acpi_aml_convert_to_string (&obj_desc2, walk_state);
break;
case ACPI_TYPE_BUFFER:
status = acpi_aml_convert_to_buffer (&obj_desc2, 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_aml_do_concatenate (obj_desc, obj_desc2, &ret_desc, walk_state);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
break;
default:
REPORT_ERROR (("Acpi_aml_exec_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 Obj_desc) into
* the result descriptor, or the location pointed to by the result
* descriptor (Res_desc).
*/
status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
if (AML_DIVIDE_OP == opcode) {
status = acpi_aml_exec_store (ret_desc2, res_desc2, walk_state);
/*
* Since the remainder is not returned, remove a reference to
* the object we created earlier
*/
acpi_cm_remove_reference (ret_desc2);
}
cleanup:
/* Always delete the operands */
acpi_cm_remove_reference (obj_desc);
acpi_cm_remove_reference (obj_desc2);
/* Delete return object on error */
if (ACPI_FAILURE (status)) {
/* On failure, delete the result ops */
acpi_cm_remove_reference (res_desc);
acpi_cm_remove_reference (res_desc2);
if (ret_desc) {
/* And delete the internal return object */
acpi_cm_remove_reference (ret_desc);
ret_desc = NULL;
}
}
/* Set the return object and exit */
*return_desc = ret_desc;
return (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_aml_exec_dyadic2_s
*
* PARAMETERS: Opcode - The opcode to be executed
*
* RETURN: Status
*
* DESCRIPTION: Execute Type 2 dyadic synchronization operator
*
* ALLOCATION: Deletes one operand descriptor -- other remains on stack
*
******************************************************************************/
ACPI_STATUS
acpi_aml_exec_dyadic2_s (
u16 opcode,
ACPI_WALK_STATE *walk_state,
ACPI_OPERAND_OBJECT **return_desc)
{
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_OPERAND_OBJECT *time_desc;
ACPI_OPERAND_OBJECT *ret_desc = NULL;
ACPI_STATUS status;
/* Resolve all operands */
status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
/* Get all operands */
status |= acpi_ds_obj_stack_pop_object (&time_desc, walk_state);
status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
if (ACPI_FAILURE (status)) {
/* Invalid parameters on object stack */
goto cleanup;
}
/* Create the internal return object */
ret_desc = acpi_cm_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_aml_acquire_mutex (time_desc, obj_desc, walk_state);
break;
/* Def_wait := Wait_op Acpi_event_object Timeout */
case AML_WAIT_OP:
status = acpi_aml_system_wait_event (time_desc, obj_desc);
break;
default:
REPORT_ERROR (("Acpi_aml_exec_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_cm_remove_reference (time_desc);
acpi_cm_remove_reference (obj_desc);
/* Delete return object on error */
if (ACPI_FAILURE (status) &&
(ret_desc)) {
acpi_cm_remove_reference (ret_desc);
ret_desc = NULL;
}
/* Set the return object and exit */
*return_desc = ret_desc;
return (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_aml_exec_dyadic2
*
* PARAMETERS: Opcode - The opcode to be executed
*
* 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_aml_exec_dyadic2 (
u16 opcode,
ACPI_WALK_STATE *walk_state,
ACPI_OPERAND_OBJECT **return_desc)
{
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_OPERAND_OBJECT *obj_desc2;
ACPI_OPERAND_OBJECT *ret_desc = NULL;
ACPI_STATUS status;
u8 lboolean;
/* Resolve all operands */
status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
/* Get all operands */
status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
if (ACPI_FAILURE (status)) {
/* Invalid parameters on object stack */
goto cleanup;
}
/* Create the internal return object */
ret_desc = acpi_cm_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) (obj_desc->integer.value &&
obj_desc2->integer.value);
break;
/* Def_lEqual := LEqual_op Operand1 Operand2 */
case AML_LEQUAL_OP:
lboolean = (u8) (obj_desc->integer.value ==
obj_desc2->integer.value);
break;
/* Def_lGreater := LGreater_op Operand1 Operand2 */
case AML_LGREATER_OP:
lboolean = (u8) (obj_desc->integer.value >
obj_desc2->integer.value);
break;
/* Def_lLess := LLess_op Operand1 Operand2 */
case AML_LLESS_OP:
lboolean = (u8) (obj_desc->integer.value <
obj_desc2->integer.value);
break;
/* Def_lOr := LOr_op Operand1 Operand2 */
case AML_LOR_OP:
lboolean = (u8) (obj_desc->integer.value ||
obj_desc2->integer.value);
break;
default:
REPORT_ERROR (("Acpi_aml_exec_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_cm_remove_reference (obj_desc);
acpi_cm_remove_reference (obj_desc2);
/* Delete return object on error */
if (ACPI_FAILURE (status) &&
(ret_desc)) {
acpi_cm_remove_reference (ret_desc);
ret_desc = NULL;
}
/* Set the return object and exit */
*return_desc = ret_desc;
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -