/******************************************************************************* * * FUNCTION: acpi_ps_get_next_package_length * * PARAMETERS: parser_state - Current parser state object * * RETURN: Decoded package length. On completion, the AML pointer points * past the length byte or bytes. * * DESCRIPTION: Decode and return a package length field. * Note: Largest package length is 28 bits, from ACPI specification *
******************************************************************************/
/* * Byte 0 bits [6:7] contain the number of additional bytes * used to encode the package length, either 0,1,2, or 3
*/
byte_count = (aml[0] >> 6);
parser_state->aml += ((acpi_size)byte_count + 1);
/* Get bytes 3, 2, 1 as needed */
while (byte_count) { /* * Final bit positions for the package length bytes: * Byte3->[20:27] * Byte2->[12:19] * Byte1->[04:11] * Byte0->[00:03]
*/
package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
byte_count--;
}
/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_package_end * * PARAMETERS: parser_state - Current parser state object * * RETURN: Pointer to end-of-package +1 * * DESCRIPTION: Get next package length and return a pointer past the end of * the package. Consumes the package length field *
******************************************************************************/
return_PTR(start + package_length); /* end of package */
}
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_namestring * * PARAMETERS: parser_state - Current parser state object * * RETURN: Pointer to the start of the name string (pointer points into * the AML. * * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name * prefix characters. Set parser state to point past the string. * (Name is consumed from the AML.) *
******************************************************************************/
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_namepath * * PARAMETERS: parser_state - Current parser state object * arg - Where the namepath will be stored * arg_count - If the namepath points to a control method * the method's argument is returned here. * possible_method_call - Whether the namepath can possibly be the * start of a method call * * RETURN: Status * * DESCRIPTION: Get next name (if method call, return # of required args). * Names are looked up in the internal namespace to determine * if the name represents a control method. If a method * is found, the number of arguments to the method is returned. * This information is critical for parsing to continue correctly. *
******************************************************************************/
acpi_status
acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state, union acpi_parse_object *arg, u8 possible_method_call)
{
acpi_status status; char *path; union acpi_parse_object *name_op; union acpi_operand_object *method_desc; struct acpi_namespace_node *node;
u8 *start = parser_state->aml;
if (!path) {
arg->common.value.name = path;
return_ACPI_STATUS(AE_OK);
}
/* * Lookup the name in the internal namespace, starting with the current * scope. We don't want to add anything new to the namespace here, * however, so we use MODE_EXECUTE. * Allow searching of the parent tree, but don't open a new scope - * we just want to lookup the object (must be mode EXECUTE to perform * the upsearch)
*/
status = acpi_ns_lookup(walk_state->scope_info, path,
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
NULL, &node);
/* * If this name is a control method invocation, we must * setup the method call
*/ if (ACPI_SUCCESS(status) &&
possible_method_call && (node->type == ACPI_TYPE_METHOD)) { if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
ARGP_SUPERNAME)
|| (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
ARGP_TARGET)) { /* * acpi_ps_get_next_namestring has increased the AML pointer past * the method invocation namestring, so we need to restore the * saved AML pointer back to the original method invocation * namestring.
*/
walk_state->parser_state.aml = start;
walk_state->arg_count = 1;
acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
}
/* This name is actually a control method invocation */
/* * Special handling if the name was not found during the lookup - * some not_found cases are allowed
*/ if (status == AE_NOT_FOUND) {
/* 1) not_found is ok during load pass 1/2 (allow forward references) */
if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
ACPI_PARSE_EXECUTE) {
status = AE_OK;
}
/* 2) not_found during a cond_ref_of(x) is ok by definition */
elseif (walk_state->op->common.aml_opcode ==
AML_CONDITIONAL_REF_OF_OP) {
status = AE_OK;
}
/* * 3) not_found while building a Package is ok at this point, we * may flag as an error later if slack mode is not enabled. * (Some ASL code depends on allowing this behavior)
*/ elseif ((arg->common.parent) &&
((arg->common.parent->common.aml_opcode ==
AML_PACKAGE_OP)
|| (arg->common.parent->common.aml_opcode ==
AML_VARIABLE_PACKAGE_OP))) {
status = AE_OK;
}
}
/* Final exception check (may have been changed from code above) */
if (ACPI_FAILURE(status)) {
ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
ACPI_PARSE_EXECUTE) {
/* Report a control method execution error */
status = acpi_ds_method_error(status, walk_state);
}
}
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_simple_arg * * PARAMETERS: parser_state - Current parser state object * arg_type - The argument type (AML_*_ARG) * arg - Where the argument is returned * * RETURN: None * * DESCRIPTION: Get the next simple argument (constant, string, or namestring) *
******************************************************************************/
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_field * * PARAMETERS: parser_state - Current parser state object * * RETURN: A newly allocated FIELD op * * DESCRIPTION: Get next field (named_field, reserved_field, or access_field) *
******************************************************************************/
#ifdef ACPI_ASL_COMPILER /* * Because the package length isn't represented as a parse tree object, * take comments surrounding this and add to the previously created * parse node.
*/ if (field->common.inline_comment) {
field->common.name_comment =
field->common.inline_comment;
}
field->common.inline_comment = acpi_gbl_current_inline_comment;
acpi_gbl_current_inline_comment = NULL; #endif
/* Get the length which is encoded as a package length */
case AML_INT_ACCESSFIELD_OP: case AML_INT_EXTACCESSFIELD_OP:
/* * Get access_type and access_attrib and merge into the field Op * access_type is first operand, access_attribute is second. stuff * these bytes into the node integer value for convenience.
*/
/* * Argument for Connection operator can be either a Buffer * (resource descriptor), or a name_string.
*/
aml = parser_state->aml; if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
parser_state->aml++;
/* Link the buffer/namestring to parent (CONNECTION_OP) */
acpi_ps_append_arg(field, arg); break;
default:
/* Opcode was set in previous switch */ break;
}
return_PTR(field);
}
/******************************************************************************* * * FUNCTION: acpi_ps_free_field_list * * PARAMETERS: start - First Op in field list * * RETURN: None. * * DESCRIPTION: Free all Op objects inside a field list. *
******************************************************************************/
staticvoid acpi_ps_free_field_list(union acpi_parse_object *start)
{ union acpi_parse_object *cur = start; union acpi_parse_object *next; union acpi_parse_object *arg;
while (cur) {
next = cur->common.next;
/* AML_INT_CONNECTION_OP can have a single argument */
arg = acpi_ps_get_arg(cur, 0); if (arg) {
acpi_ps_free_op(arg);
}
acpi_ps_free_op(cur);
cur = next;
}
}
/******************************************************************************* * * FUNCTION: acpi_ps_get_next_arg * * PARAMETERS: walk_state - Current state * parser_state - Current parser state object * arg_type - The argument type (AML_*_ARG) * return_arg - Where the next arg is returned * * RETURN: Status, and an op object containing the next argument. * * DESCRIPTION: Get next argument (including complex list arguments that require * pushing the parser stack) *
******************************************************************************/
acpi_status
acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state,
u32 arg_type, union acpi_parse_object **return_arg)
{ union acpi_parse_object *arg = NULL; union acpi_parse_object *prev = NULL; union acpi_parse_object *field;
u32 subop;
acpi_status status = AE_OK;
while (parser_state->aml < parser_state->pkg_end) {
field = acpi_ps_get_next_field(parser_state); if (!field) { if (arg) {
acpi_ps_free_field_list(arg);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.