acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
{
    union acpi_operand_object **operand = &walk_state->operands[0];
    union acpi_operand_object *return_desc = NULL;
    acpi_status status = AE_OK;
    u64 index;
    union acpi_operand_object *this_element;

    ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R,
                            acpi_ps_get_opcode_name(walk_state->opcode));

    switch (walk_state->opcode) {
    case AML_MATCH_OP:



        if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
                (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
            ACPI_ERROR((AE_INFO, "Match operator out of range"));
            status = AE_AML_OPERAND_VALUE;
            goto cleanup;
        }



        index = operand[5]->integer.value;
        if (index >= operand[0]->package.count) {
            ACPI_ERROR((AE_INFO,
                        "Index (0x%8.8X%8.8X) beyond package end (0x%X)",
                        ACPI_FORMAT_UINT64(index),
                        operand[0]->package.count));
            status = AE_AML_PACKAGE_LIMIT;
            goto cleanup;
        }




        return_desc = acpi_ut_create_integer_object(ACPI_UINT64_MAX);
        if (!return_desc) {
            status = AE_NO_MEMORY;
            goto cleanup;

        }

        for (; index < operand[0]->package.count; index++) {



            this_element = operand[0]->package.elements[index];



            if (!this_element) {
                continue;
            }

            if (!acpi_ex_do_match((u32) operand[1]->integer.value,
                                  this_element, operand[2])) {
                continue;
            }

            if (!acpi_ex_do_match((u32) operand[3]->integer.value,
                                  this_element, operand[4])) {
                continue;
            }



            return_desc->integer.value = index;
            break;
        }
        break;

    case AML_LOAD_TABLE_OP:

        status = acpi_ex_load_table_op(walk_state, &return_desc);
        break;

    default:

        ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X",
                    walk_state->opcode));
        status = AE_AML_BAD_OPCODE;
        goto cleanup;
    }

cleanup:



    if (ACPI_FAILURE(status)) {
        acpi_ut_remove_reference(return_desc);
    }



    else {
        walk_state->result_obj = return_desc;
    }

    return_ACPI_STATUS(status);
}
acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
{
    union acpi_operand_object **operand = &walk_state->operands[0];
    union acpi_operand_object *return_desc = NULL;
    acpi_status status = AE_OK;
    acpi_integer index;
    union acpi_operand_object *this_element;

    ACPI_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_pkg[0], match_op1[1], match_obj1[2],
         *                      match_op2[3], match_obj2[4], start_index[5])
         */

        /* Validate both Match Term Operators (MTR, MEQ, etc.) */

        if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
                (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
            ACPI_ERROR((AE_INFO, "Match operator out of range"));
            status = AE_AML_OPERAND_VALUE;
            goto cleanup;
        }

        /* Get the package start_index, validate against the package length */

        index = operand[5]->integer.value;
        if (index >= operand[0]->package.count) {
            ACPI_ERROR((AE_INFO,
                        "Index (%X%8.8X) beyond package end (%X)",
                        ACPI_FORMAT_UINT64(index),
                        operand[0]->package.count));
            status = AE_AML_PACKAGE_LIMIT;
            goto cleanup;
        }

        /* Create an integer for the return value */

        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. Both match conditions
         * must be satisfied for a match to occur. 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
         * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
         * match was found.
         */
        for (; index < operand[0]->package.count; index++) {

            /* Get the current package element */

            this_element = operand[0]->package.elements[index];

            /* Treat any uninitialized (NULL) elements as non-matching */

            if (!this_element) {
                continue;
            }

            /*
             * Both match conditions must be satisfied. Execution of a 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, operand[2])) {
                continue;
            }

            if (!acpi_ex_do_match((u32) operand[3]->integer.value,
                                  this_element, operand[4])) {
                continue;
            }

            /* Match found: Index is the return value */

            return_desc->integer.value = index;
            break;
        }
        break;

    case AML_LOAD_TABLE_OP:

        status = acpi_ex_load_table_op(walk_state, &return_desc);
        break;

    default:

        ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
                    walk_state->opcode));
        status = AE_AML_BAD_OPCODE;
        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);
}
Example #3
0
acpi_status
acpi_ex_opcode_6A_0T_1R (
	struct acpi_walk_state          *walk_state)
{
	union acpi_operand_object       **operand = &walk_state->operands[0];
	union acpi_operand_object       *return_desc = NULL;
	acpi_status                     status = AE_OK;
	u32                             index;
	union acpi_operand_object       *this_element;


	ACPI_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.
			 */
			if (!this_element ||
				ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) {
				continue;
			}

			/*
			 * "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 = acpi_ex_load_table_op (walk_state, &return_desc);
		break;


	default:

		ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
				walk_state->opcode));
		status = AE_AML_BAD_OPCODE;
		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);
}