📄 ammonad.c
字号:
}
status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
cleanup:
/* Always delete the operand object */
acpi_cm_remove_reference (obj_desc);
/* Delete return object(s) on error */
if (ACPI_FAILURE (status)) {
acpi_cm_remove_reference (res_desc); /* Result descriptor */
if (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_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_aml_exec_monadic2 (
u16 opcode,
ACPI_WALK_STATE *walk_state,
ACPI_OPERAND_OBJECT **return_desc)
{
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_OPERAND_OBJECT *tmp_desc;
ACPI_OPERAND_OBJECT *ret_desc = NULL;
ACPI_STATUS resolve_status;
ACPI_STATUS status;
u32 type;
ACPI_INTEGER value;
/* Attempt to resolve the operands */
resolve_status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
/* Always get all operands */
status = acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
/* Now we can check the status codes */
if (ACPI_FAILURE (resolve_status)) {
goto cleanup;
}
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Get the operand and decode the opcode */
switch (opcode) {
/* Def_lNot := LNot_op Operand */
case AML_LNOT_OP:
ret_desc = acpi_cm_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
* an 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_cm_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_aml_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);
if (ACPI_FAILURE (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_aml_exec_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:
/* 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_aml_exec_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_HANDLE) obj_desc);
}
/* Allocate a descriptor to hold the type. */
ret_desc = acpi_cm_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 (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:
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_cm_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_aml_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_cm_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_cm_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)) {
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_cm_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.
*/
status = AE_AML_UNINITIALIZED_ELEMENT;
goto cleanup;
}
acpi_cm_add_reference (ret_desc);
}
else {
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_cm_add_reference (ret_desc);
break;
}
}
break;
default:
REPORT_ERROR (("Acpi_aml_exec_monadic2: Unknown monadic opcode %X\n",
opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
cleanup:
if (obj_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;
}
*return_desc = ret_desc;
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -