acpi_status acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, union acpi_parse_object *op) { acpi_status status; union acpi_operand_object *obj_desc; union acpi_operand_object *operand_desc; struct acpi_namespace_node *node; union acpi_parse_object *next_op; union acpi_parse_object *arg; ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); /* * This is where we evaluate the bank_value field of the * bank_field declaration */ /* next_op points to the op that holds the Region */ next_op = op->common.value.arg; /* next_op points to the op that holds the Bank Register */ next_op = next_op->common.next; /* next_op points to the op that holds the Bank Value */ next_op = next_op->common.next; /* * Set proper index into operand stack for acpi_ds_obj_stack_push * invoked inside acpi_ds_create_operand. * * We use walk_state->Operands[0] to store the evaluated bank_value */ walk_state->operand_index = 0; status = acpi_ds_create_operand(walk_state, next_op, 0); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, acpi_ps_get_opcode_name(op->common.aml_opcode), 1); /* * Get the bank_value operand and save it * (at Top of stack) */ operand_desc = walk_state->operands[0]; /* Arg points to the start Bank Field */ arg = acpi_ps_get_arg(op, 4); while (arg) { /* Ignore OFFSET and ACCESSAS terms here */ if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { node = arg->common.node; obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return_ACPI_STATUS(AE_NOT_EXIST); } obj_desc->bank_field.value = (u32) operand_desc->integer.value; } /* Move to next field in the list */ arg = arg->common.next; } acpi_ut_remove_reference(operand_desc); return_ACPI_STATUS(status); }
ACPI_STATUS acpi_ps_get_next_walk_op ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op, ACPI_PARSE_UPWARDS ascending_callback) { ACPI_PARSE_OBJECT *next; ACPI_PARSE_OBJECT *parent; ACPI_PARSE_OBJECT *grand_parent; ACPI_STATUS status; /* Check for a argument only if we are descending in the tree */ if (walk_state->next_op_info != NEXT_OP_UPWARD) { /* Look for an argument or child of the current op */ next = acpi_ps_get_arg (op, 0); if (next) { /* Still going downward in tree (Op is not completed yet) */ walk_state->prev_op = op; walk_state->next_op = next; walk_state->next_op_info = NEXT_OP_DOWNWARD; return (AE_OK); } /* * No more children, this Op is complete. Save Next and Parent * in case the Op object gets deleted by the callback routine */ next = op->next; parent = op->parent; status = ascending_callback (walk_state, op); /* * If we are back to the starting point, the walk is complete. */ if (op == walk_state->origin) { /* Reached the point of origin, the walk is complete */ walk_state->prev_op = op; walk_state->next_op = NULL; return (status); } /* * Check for a sibling to the current op. A sibling means * we are still going "downward" in the tree. */ if (next) { /* There is a sibling, it will be next */ walk_state->prev_op = op; walk_state->next_op = next; walk_state->next_op_info = NEXT_OP_DOWNWARD; /* Continue downward */ return (status); } /* * Drop into the loop below because we are moving upwards in * the tree */ } else { /* * We are resuming a walk, and we were (are) going upward in the tree. * So, we want to drop into the parent loop below. */ parent = op; } /* * Look for a sibling of the current Op's parent * Continue moving up the tree until we find a node that has not been * visited, or we get back to where we started. */ while (parent) { /* We are moving up the tree, therefore this parent Op is complete */ grand_parent = parent->parent; next = parent->next; status = ascending_callback (walk_state, parent); /* * If we are back to the starting point, the walk is complete. */ if (parent == walk_state->origin) { /* Reached the point of origin, the walk is complete */ walk_state->prev_op = parent; walk_state->next_op = NULL; return (status); } /* * If there is a sibling to this parent (it is not the starting point * Op), then we will visit it. */ if (next) { /* found sibling of parent */ walk_state->prev_op = parent; walk_state->next_op = next; walk_state->next_op_info = NEXT_OP_DOWNWARD; return (status); } /* No siblings, no errors, just move up one more level in the tree */ op = parent; parent = grand_parent; walk_state->prev_op = op; } /* Got all the way to the top of the tree, we must be done! */ /* However, the code should have terminated in the loop above */ walk_state->next_op = NULL; return (AE_OK); }
void acpi_ps_get_next_namepath ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT *arg, u32 *arg_count, u8 method_call) { NATIVE_CHAR *path; ACPI_PARSE_OBJECT *name_op; ACPI_PARSE_OBJECT *op; ACPI_PARSE_OBJECT *count; path = acpi_ps_get_next_namestring (parser_state); if (!path || !method_call) { /* Null name case, create a null namepath object */ acpi_ps_init_op (arg, AML_NAMEPATH_OP); arg->value.name = path; return; } if (acpi_gbl_parsed_namespace_root) { /* * Lookup the name in the parsed namespace */ op = NULL; if (method_call) { op = acpi_ps_find (acpi_ps_get_parent_scope (parser_state), path, AML_METHOD_OP, 0); } if (op) { if (op->opcode == AML_METHOD_OP) { /* * The name refers to a control method, so this namepath is a * method invocation. We need to 1) Get the number of arguments * associated with this method, and 2) Change the NAMEPATH * object into a METHODCALL object. */ count = acpi_ps_get_arg (op, 0); if (count && count->opcode == AML_BYTE_OP) { name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP); if (name_op) { /* Change arg into a METHOD CALL and attach the name */ acpi_ps_init_op (arg, AML_METHODCALL_OP); name_op->value.name = path; /* Point METHODCALL/NAME to the METHOD Node */ name_op->node = (ACPI_NAMESPACE_NODE *) op; acpi_ps_append_arg (arg, name_op); *arg_count = count->value.integer & METHOD_FLAGS_ARG_COUNT; } } return; } /* * Else this is normal named object reference. * Just init the NAMEPATH object with the pathname. * (See code below) */ } } /* * Either we didn't find the object in the namespace, or the object is * something other than a control method. Just initialize the Op with the * pathname */ acpi_ps_init_op (arg, AML_NAMEPATH_OP); arg->value.name = path; return; }
void acpi_db_display_path ( acpi_parse_object *op) { acpi_parse_object *prev; acpi_parse_object *search; u32 name; u8 do_dot = FALSE; acpi_parse_object *name_path; const acpi_opcode_info *op_info; /* We are only interested in named objects */ op_info = acpi_ps_get_opcode_info (op->opcode); if (!(op_info->flags & AML_NSNODE)) { return; } if (op_info->flags & AML_CREATE) { /* Field creation - check for a fully qualified namepath */ if (op->opcode == AML_CREATE_FIELD_OP) { name_path = acpi_ps_get_arg (op, 3); } else { name_path = acpi_ps_get_arg (op, 2); } if ((name_path) && (name_path->value.string) && (name_path->value.string[0] == '\\')) { acpi_db_display_namestring (name_path->value.string); return; } } prev = NULL; /* Start with Root Node */ while (prev != op) { /* Search upwards in the tree to find scope with "prev" as its parent */ search = op; for (; ;) { if (search->parent == prev) { break; } /* Go up one level */ search = search->parent; } if (prev) { op_info = acpi_ps_get_opcode_info (search->opcode); if (!(op_info->flags & AML_FIELD)) { /* below root scope, append scope name */ if (do_dot) { /* append dot */ acpi_os_printf ("."); } if (op_info->flags & AML_CREATE) { if (op->opcode == AML_CREATE_FIELD_OP) { name_path = acpi_ps_get_arg (op, 3); } else { name_path = acpi_ps_get_arg (op, 2); } if ((name_path) && (name_path->value.string)) { acpi_os_printf ("%4.4s", name_path->value.string); } } else { name = acpi_ps_get_name (search); acpi_os_printf ("%4.4s", &name); } do_dot = TRUE; } } prev = search; } }
void acpi_db_display_op ( acpi_walk_state *walk_state, acpi_parse_object *origin, u32 num_opcodes) { acpi_parse_object *op = origin; acpi_parse_object *arg; acpi_parse_object *depth; u32 depth_count = 0; u32 last_depth = 0; u32 i; u32 j; if (op) { while (op) { /* indentation */ depth_count = 0; if (!acpi_gbl_db_opt_verbose) { depth_count++; } /* Determine the nesting depth of this argument */ for (depth = op->parent; depth; depth = depth->parent) { arg = acpi_ps_get_arg (depth, 0); while (arg && arg != origin) { arg = arg->next; } if (arg) { break; } depth_count++; } /* Open a new block if we are nested further than last time */ if (depth_count > last_depth) { VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth)); for (i = 0; i < last_depth; i++) { acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); } if (acpi_db_block_type (op) == BLOCK_PAREN) { acpi_os_printf ("(\n"); } else { acpi_os_printf ("{\n"); } } /* Close a block if we are nested less than last time */ else if (depth_count < last_depth) { for (j = 0; j < (last_depth - depth_count); j++) { VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - j)); for (i = 0; i < (last_depth - j - 1); i++) { acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); } if (acpi_db_block_type (op) == BLOCK_PAREN) { acpi_os_printf (")\n"); } else { acpi_os_printf ("}\n"); } } } /* In verbose mode, print the AML offset, opcode and depth count */ VERBOSE_PRINT ((DB_FULL_OP_INFO, (unsigned) op->aml_offset, op->opcode, depth_count)); /* Indent the output according to the depth count */ for (i = 0; i < depth_count; i++) { acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); } /* Now print the opcode */ acpi_db_display_opcode (walk_state, op); /* Resolve a name reference */ if ((op->opcode == AML_INT_NAMEPATH_OP && op->value.name) && (op->parent) && (acpi_gbl_db_opt_verbose)) { acpi_ps_display_object_pathname (walk_state, op); } acpi_os_printf ("\n"); /* Get the next node in the tree */ op = acpi_ps_get_depth_next (origin, op); last_depth = depth_count; num_opcodes--; if (!num_opcodes) { op = NULL; } } /* Close the last block(s) */ depth_count = last_depth -1; for (i = 0; i < last_depth; i++) { VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - i)); for (j = 0; j < depth_count; j++) { acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); } acpi_os_printf ("}\n"); depth_count--; } } else { acpi_db_display_opcode (walk_state, op); } }
acpi_status acpi_ds_create_buffer_field(union acpi_parse_object *op, struct acpi_walk_state *walk_state) { union acpi_parse_object *arg; struct acpi_namespace_node *node; acpi_status status; union acpi_operand_object *obj_desc; union acpi_operand_object *second_desc = NULL; u32 flags; ACPI_FUNCTION_TRACE(ds_create_buffer_field); /* * Get the name_string argument (name of the new buffer_field) */ if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { /* For create_field, name is the 4th argument */ arg = acpi_ps_get_arg(op, 3); } else { /* For all other create_xXXField operators, name is the 3rd argument */ arg = acpi_ps_get_arg(op, 2); } if (!arg) { return_ACPI_STATUS(AE_AML_NO_OPERAND); } if (walk_state->deferred_node) { node = walk_state->deferred_node; status = AE_OK; } else { /* Execute flag should always be set when this function is entered */ if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { return_ACPI_STATUS(AE_AML_INTERNAL); } /* Creating new namespace node, should not already exist */ flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; /* * Mark node temporary if we are executing a normal control * method. (Don't mark if this is a module-level code method) */ if (walk_state->method_node && !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { flags |= ACPI_NS_TEMPORARY; } /* Enter the name_string into the namespace */ status = acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &node); if (ACPI_FAILURE(status)) { ACPI_ERROR_NAMESPACE(arg->common.value.string, status); return_ACPI_STATUS(status); } } /* * We could put the returned object (Node) on the object stack for later, * but for now, we will put it in the "op" object that the parser uses, * so we can get it again at the end of this scope. */ op->common.node = node; /* * If there is no object attached to the node, this node was just created * and we need to create the field object. Otherwise, this was a lookup * of an existing node and we don't want to create the field object again. */ obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { return_ACPI_STATUS(AE_OK); } /* * The Field definition is not fully parsed at this time. * (We must save the address of the AML for the buffer and index operands) */ /* Create the buffer field object */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD); if (!obj_desc) { status = AE_NO_MEMORY; goto cleanup; } /* * Remember location in AML stream of the field unit opcode and operands -- * since the buffer and index operands must be evaluated. */ second_desc = obj_desc->common.next_object; second_desc->extra.aml_start = op->named.data; second_desc->extra.aml_length = op->named.length; obj_desc->buffer_field.node = node; /* Attach constructed field descriptors to parent node */ status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD); if (ACPI_FAILURE(status)) { goto cleanup; } cleanup: /* Remove local reference to the object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); }