static acpi_status acpi_db_integrity_walk(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_integrity_info *info = (struct acpi_integrity_info *)context; struct acpi_namespace_node *node = (struct acpi_namespace_node *)obj_handle; union acpi_operand_object *object; u8 alias = TRUE; info->nodes++; /* Verify the NS node, and dereference aliases */ while (alias) { if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { acpi_os_printf ("Invalid Descriptor Type for Node %p [%s] - " "is %2.2X should be %2.2X\n", node, acpi_ut_get_descriptor_name(node), ACPI_GET_DESCRIPTOR_TYPE(node), ACPI_DESC_TYPE_NAMED); return (AE_OK); } if ((node->type == ACPI_TYPE_LOCAL_ALIAS) || (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { node = (struct acpi_namespace_node *)node->object; } else { alias = FALSE; } } if (node->type > ACPI_TYPE_LOCAL_MAX) { acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n", node, node->type); return (AE_OK); } if (!acpi_ut_valid_nameseg(node->name.ascii)) { acpi_os_printf("Invalid AcpiName for Node %p\n", node); return (AE_OK); } object = acpi_ns_get_attached_object(node); if (object) { info->objects++; if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf ("Invalid Descriptor Type for Object %p [%s]\n", object, acpi_ut_get_descriptor_name(object)); } } return (AE_OK); }
u8 acpi_ut_valid_internal_object(void *object) { ACPI_FUNCTION_NAME(ut_valid_internal_object); /* Check for a null pointer */ if (!object) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n")); return (FALSE); } /* Check the descriptor type field */ switch (ACPI_GET_DESCRIPTOR_TYPE(object)) { case ACPI_DESC_TYPE_OPERAND: /* The object appears to be a valid union acpi_operand_object */ return (TRUE); default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%p is not not an ACPI operand obj [%s]\n", object, acpi_ut_get_descriptor_name(object))); break; } return (FALSE); }
u8 acpi_ut_valid_internal_object(void *object) { ACPI_FUNCTION_NAME(ut_valid_internal_object); if (!object) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n")); return (FALSE); } switch (ACPI_GET_DESCRIPTOR_TYPE(object)) { case ACPI_DESC_TYPE_OPERAND: return (TRUE); default: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p is not not an ACPI operand obj [%s]\n", object, acpi_ut_get_descriptor_name(object))); break; } return (FALSE); }
void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc) { u32 i; if (!obj_desc) { acpi_os_printf(" Uninitialized"); return; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf(" %p [%s]", obj_desc, acpi_ut_get_descriptor_name(obj_desc)); return; } acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc)); switch (obj_desc->common.type) { case ACPI_TYPE_INTEGER: acpi_os_printf(" %8.8X%8.8X", ACPI_FORMAT_UINT64(obj_desc->integer.value)); break; case ACPI_TYPE_STRING: acpi_os_printf("(%u) \"%.24s", obj_desc->string.length, obj_desc->string.pointer); if (obj_desc->string.length > 24) { acpi_os_printf("..."); } else { acpi_os_printf("\""); } break; case ACPI_TYPE_BUFFER: acpi_os_printf("(%u)", obj_desc->buffer.length); for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) { acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]); } break; default: acpi_os_printf(" %p", obj_desc); break; } }
void acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) { ACPI_FUNCTION_TRACE(ex_dump_object_descriptor); if (!obj_desc) { return_VOID; } if (!flags) { if (! ((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return_VOID; } } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) { acpi_ex_dump_namespace_node((struct acpi_namespace_node *) obj_desc, flags); acpi_os_printf("\nAttached Object (%p):\n", ((struct acpi_namespace_node *)obj_desc)-> object); acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *) obj_desc)->object, flags); return_VOID; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf ("ExDumpObjectDescriptor: %p is not an ACPI operand object: [%s]\n", obj_desc, acpi_ut_get_descriptor_name(obj_desc)); return_VOID; } if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) { return_VOID; } /* Common Fields */ acpi_ex_dump_object(obj_desc, acpi_ex_dump_common); /* Object-specific fields */ acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]); return_VOID; }
void acpi_ut_delete_object_desc(union acpi_operand_object *object) { ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object); if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { ACPI_ERROR((AE_INFO, "%p is not an ACPI Operand object [%s]", object, acpi_ut_get_descriptor_name(object))); return_VOID; } (void)acpi_os_release_object(acpi_gbl_operand_cache, object); return_VOID; }
void acpi_ut_delete_object_desc(union acpi_operand_object *object) { ACPI_FUNCTION_TRACE_PTR("ut_delete_object_desc", object); /* Object must be an union acpi_operand_object */ if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "%p is not an ACPI Operand object [%s]\n", object, acpi_ut_get_descriptor_name(object))); return_VOID; } (void)acpi_os_release_object(acpi_gbl_operand_cache, object); return_VOID; }
struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string) { struct acpi_namespace_node *node; acpi_size address; if ((*in_string >= 0x30) && (*in_string <= 0x39)) { /* Numeric argument, convert */ address = strtoul(in_string, NULL, 16); node = ACPI_TO_POINTER(address); if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) { acpi_os_printf("Address %p is invalid", node); return (NULL); } /* Make sure pointer is valid NS node */ if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { acpi_os_printf ("Address %p is not a valid namespace node [%s]\n", node, acpi_ut_get_descriptor_name(node)); return (NULL); } } else { /* * Alpha argument: The parameter is a name string that must be * resolved to a Namespace object. */ node = acpi_db_local_ns_lookup(in_string); if (!node) { acpi_os_printf ("Could not find [%s] in namespace, defaulting to root node\n", in_string); node = acpi_gbl_root_node; } } return (node); }
void acpi_db_display_internal_object(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { u8 type; acpi_os_printf("%p ", obj_desc); if (!obj_desc) { acpi_os_printf("<Null Object>\n"); return; } /* Decode the object type */ switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { case ACPI_DESC_TYPE_PARSER: acpi_os_printf("<Parser> "); break; case ACPI_DESC_TYPE_NAMED: acpi_db_decode_node((struct acpi_namespace_node *)obj_desc); break; case ACPI_DESC_TYPE_OPERAND: type = obj_desc->common.type; if (type > ACPI_TYPE_LOCAL_MAX) { acpi_os_printf(" Type %X [Invalid Type]", (u32)type); return; } /* Decode the ACPI object type */ switch (obj_desc->common.type) { case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf("[%s] ", acpi_ut_get_reference_name(obj_desc)); /* Decode the refererence */ switch (obj_desc->reference.class) { case ACPI_REFCLASS_LOCAL: acpi_os_printf("%X ", obj_desc->reference.value); if (walk_state) { obj_desc = walk_state->local_variables [obj_desc->reference.value].object; acpi_os_printf("%p", obj_desc); acpi_db_decode_internal_object (obj_desc); } break; case ACPI_REFCLASS_ARG: acpi_os_printf("%X ", obj_desc->reference.value); if (walk_state) { obj_desc = walk_state->arguments [obj_desc->reference.value].object; acpi_os_printf("%p", obj_desc); acpi_db_decode_internal_object (obj_desc); } break; case ACPI_REFCLASS_INDEX: switch (obj_desc->reference.target_type) { case ACPI_TYPE_BUFFER_FIELD: acpi_os_printf("%p", obj_desc->reference. object); acpi_db_decode_internal_object (obj_desc->reference.object); break; case ACPI_TYPE_PACKAGE: acpi_os_printf("%p", obj_desc->reference. where); if (!obj_desc->reference.where) { acpi_os_printf (" Uninitialized WHERE pointer"); } else { acpi_db_decode_internal_object(* (obj_desc-> reference. where)); } break; default: acpi_os_printf ("Unknown index target type"); break; } break; case ACPI_REFCLASS_REFOF: if (!obj_desc->reference.object) { acpi_os_printf ("Uninitialized reference subobject pointer"); break; } /* Reference can be to a Node or an Operand object */ switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc->reference.object)) { case ACPI_DESC_TYPE_NAMED: acpi_db_decode_node(obj_desc->reference. object); break; case ACPI_DESC_TYPE_OPERAND: acpi_db_decode_internal_object (obj_desc->reference.object); break; default: break; } break; case ACPI_REFCLASS_NAME: acpi_db_decode_node(obj_desc->reference.node); break; case ACPI_REFCLASS_DEBUG: case ACPI_REFCLASS_TABLE: acpi_os_printf("\n"); break; default: /* Unknown reference class */ acpi_os_printf("%2.2X\n", obj_desc->reference.class); break; } break; default: acpi_os_printf("<Obj> "); acpi_db_decode_internal_object(obj_desc); break; } break; default: acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]", acpi_ut_get_descriptor_name(obj_desc)); break; } acpi_os_printf("\n"); }
acpi_status acpi_ns_lookup(union acpi_generic_state *scope_info, char *pathname, acpi_object_type type, acpi_interpreter_mode interpreter_mode, u32 flags, struct acpi_walk_state *walk_state, struct acpi_namespace_node **return_node) { acpi_status status; char *path = pathname; struct acpi_namespace_node *prefix_node; struct acpi_namespace_node *current_node = NULL; struct acpi_namespace_node *this_node = NULL; u32 num_segments; u32 num_carats; acpi_name simple_name; acpi_object_type type_to_check_for; acpi_object_type this_search_type; u32 search_parent_flag = ACPI_NS_SEARCH_PARENT; u32 local_flags; ACPI_FUNCTION_TRACE(ns_lookup); if (!return_node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT); *return_node = ACPI_ENTRY_NOT_FOUND; acpi_gbl_ns_lookup_count++; if (!acpi_gbl_root_node) { return_ACPI_STATUS(AE_NO_NAMESPACE); } /* * Get the prefix scope. * A null scope means use the root scope */ if ((!scope_info) || (!scope_info->scope.node)) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Null scope prefix, using root node (%p)\n", acpi_gbl_root_node)); prefix_node = acpi_gbl_root_node; } else { prefix_node = scope_info->scope.node; if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) != ACPI_DESC_TYPE_NAMED) { ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]", prefix_node, acpi_ut_get_descriptor_name(prefix_node))); return_ACPI_STATUS(AE_AML_INTERNAL); } if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { /* * This node might not be a actual "scope" node (such as a * Device/Method, etc.) It could be a Package or other object node. * Backup up the tree to find the containing scope node. */ while (!acpi_ns_opens_scope(prefix_node->type) && prefix_node->type != ACPI_TYPE_ANY) { prefix_node = acpi_ns_get_parent_node(prefix_node); } } } /* Save type TBD: may be no longer necessary */ type_to_check_for = type; /* * Begin examination of the actual pathname */ if (!pathname) { /* A Null name_path is allowed and refers to the root */ num_segments = 0; this_node = acpi_gbl_root_node; path = ""; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Null Pathname (Zero segments), Flags=%X\n", flags)); } else { /* * Name pointer is valid (and must be in internal name format) * * Check for scope prefixes: * * As represented in the AML stream, a namepath consists of an * optional scope prefix followed by a name segment part. * * If present, the scope prefix is either a Root Prefix (in * which case the name is fully qualified), or one or more * Parent Prefixes (in which case the name's scope is relative * to the current scope). */ if (*path == (u8) AML_ROOT_PREFIX) { /* Pathname is fully qualified, start from the root */ this_node = acpi_gbl_root_node; search_parent_flag = ACPI_NS_NO_UPSEARCH; /* Point to name segment part */ path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Path is absolute from root [%p]\n", this_node)); } else { /* Pathname is relative to current scope, start there */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching relative to prefix scope [%4.4s] (%p)\n", acpi_ut_get_node_name(prefix_node), prefix_node)); /* * Handle multiple Parent Prefixes (carat) by just getting * the parent node for each prefix instance. */ this_node = prefix_node; num_carats = 0; while (*path == (u8) AML_PARENT_PREFIX) { /* Name is fully qualified, no search rules apply */ search_parent_flag = ACPI_NS_NO_UPSEARCH; /* * Point past this prefix to the name segment * part or the next Parent Prefix */ path++; /* Backup to the parent node */ num_carats++; this_node = acpi_ns_get_parent_node(this_node); if (!this_node) { /* Current scope has no parent scope */ ACPI_ERROR((AE_INFO, "ACPI path has too many parent prefixes (^) - reached beyond root node")); return_ACPI_STATUS(AE_NOT_FOUND); } } if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Search scope is [%4.4s], path has %d carat(s)\n", acpi_ut_get_node_name (this_node), num_carats)); } } /* * Determine the number of ACPI name segments in this pathname. * * The segment part consists of either: * - A Null name segment (0) * - A dual_name_prefix followed by two 4-byte name segments * - A multi_name_prefix followed by a byte indicating the * number of segments and the segments themselves. * - A single 4-byte name segment * * Examine the name prefix opcode, if any, to determine the number of * segments. */ switch (*path) { case 0: /* * Null name after a root or parent prefixes. We already * have the correct target node and there are no name segments. */ num_segments = 0; type = this_node->type; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Prefix-only Pathname (Zero name segments), Flags=%X\n", flags)); break; case AML_DUAL_NAME_PREFIX: /* More than one name_seg, search rules do not apply */ search_parent_flag = ACPI_NS_NO_UPSEARCH; /* Two segments, point to first name segment */ num_segments = 2; path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Dual Pathname (2 segments, Flags=%X)\n", flags)); break; case AML_MULTI_NAME_PREFIX_OP: /* More than one name_seg, search rules do not apply */ search_parent_flag = ACPI_NS_NO_UPSEARCH; /* Extract segment count, point to first name segment */ path++; num_segments = (u32) (u8) * path; path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Multi Pathname (%d Segments, Flags=%X)\n", num_segments, flags)); break; default: /* * Not a Null name, no Dual or Multi prefix, hence there is * only one name segment and Pathname is already pointing to it. */ num_segments = 1; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Simple Pathname (1 segment, Flags=%X)\n", flags)); break; } ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path)); } /* * Search namespace for each segment of the name. Loop through and * verify (or add to the namespace) each name segment. * * The object type is significant only at the last name * segment. (We don't care about the types along the path, only * the type of the final target object.) */ this_search_type = ACPI_TYPE_ANY; current_node = this_node; while (num_segments && current_node) { num_segments--; if (!num_segments) { /* * This is the last segment, enable typechecking */ this_search_type = type; /* * Only allow automatic parent search (search rules) if the caller * requested it AND we have a single, non-fully-qualified name_seg */ if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) && (flags & ACPI_NS_SEARCH_PARENT)) { local_flags |= ACPI_NS_SEARCH_PARENT; } /* Set error flag according to caller */ if (flags & ACPI_NS_ERROR_IF_FOUND) { local_flags |= ACPI_NS_ERROR_IF_FOUND; } } /* Extract one ACPI name from the front of the pathname */ ACPI_MOVE_32_TO_32(&simple_name, path); /* Try to find the single (4 character) ACPI name */ status = acpi_ns_search_and_enter(simple_name, walk_state, current_node, interpreter_mode, this_search_type, local_flags, &this_node); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) { /* Name not found in ACPI namespace */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] not found in scope [%4.4s] %p\n", (char *)&simple_name, (char *)¤t_node->name, current_node)); } *return_node = this_node; return_ACPI_STATUS(status); } /* More segments to follow? */ if (num_segments > 0) { /* * If we have an alias to an object that opens a scope (such as a * device or processor), we need to dereference the alias here so that * we can access any children of the original node (via the remaining * segments). */ if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { if (!this_node->object) { return_ACPI_STATUS(AE_NOT_EXIST); } if (acpi_ns_opens_scope (((struct acpi_namespace_node *)this_node-> object)->type)) { this_node = (struct acpi_namespace_node *) this_node->object; } } } /* Special handling for the last segment (num_segments == 0) */ else { /* * Sanity typecheck of the target object: * * If 1) This is the last segment (num_segments == 0) * 2) And we are looking for a specific type * (Not checking for TYPE_ANY) * 3) Which is not an alias * 4) Which is not a local type (TYPE_SCOPE) * 5) And the type of target object is known (not TYPE_ANY) * 6) And target object does not match what we are looking for * * Then we have a type mismatch. Just warn and ignore it. */ if ((type_to_check_for != ACPI_TYPE_ANY) && (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && (this_node->type != ACPI_TYPE_ANY) && (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ ACPI_WARNING((AE_INFO, "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", ACPI_CAST_PTR(char, &simple_name), acpi_ut_get_type_name(this_node-> type), acpi_ut_get_type_name (type_to_check_for))); } /* * If this is the last name segment and we are not looking for a * specific type, but the type of found object is known, use that type * to (later) see if it opens a scope. */ if (type == ACPI_TYPE_ANY) { type = this_node->type; } } /* Point to next name segment and make this node current */ path += ACPI_NAME_SIZE; current_node = this_node; }
/******************************************************************************* * * FUNCTION: acpi_ns_attach_object * * PARAMETERS: node - Parent Node * object - Object to be attached * type - Type of object, or ACPI_TYPE_ANY if not * known * * RETURN: Status * * DESCRIPTION: Record the given object as the value associated with the * name whose acpi_handle is passed. If Object is NULL * and Type is ACPI_TYPE_ANY, set the name as having no value. * Note: Future may require that the Node->Flags field be passed * as a parameter. * * MUTEX: Assumes namespace is locked * ******************************************************************************/ acpi_status acpi_ns_attach_object(struct acpi_namespace_node *node, union acpi_operand_object *object, acpi_object_type type) { union acpi_operand_object *obj_desc; union acpi_operand_object *last_obj_desc; acpi_object_type object_type = ACPI_TYPE_ANY; ACPI_FUNCTION_TRACE(ns_attach_object); /* * Parameter validation */ if (!node) { /* Invalid handle */ ACPI_ERROR((AE_INFO, "Null NamedObj handle")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ ACPI_ERROR((AE_INFO, "Null object, but type not ACPI_TYPE_ANY")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { /* Not a name handle */ ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", node, acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Check if this object is already attached */ if (node->object == object) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj %p already installed in NameObj %p\n", object, node)); return_ACPI_STATUS(AE_OK); } /* If null object, we will just install it */ if (!object) { obj_desc = NULL; object_type = ACPI_TYPE_ANY; } /* * If the source object is a namespace Node with an attached object, * we will use that (attached) object */ else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) && ((struct acpi_namespace_node *)object)->object) { /* * Value passed is a name handle and that name has a * non-null value. Use that name's value and type. */ obj_desc = ((struct acpi_namespace_node *)object)->object; object_type = ((struct acpi_namespace_node *)object)->type; } /* * Otherwise, we will use the parameter object, but we must type * it first */ else { obj_desc = (union acpi_operand_object *)object; /* Use the given type */ object_type = type; } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", obj_desc, node, acpi_ut_get_node_name(node))); /* Detach an existing attached object if present */ if (node->object) { acpi_ns_detach_object(node); } if (obj_desc) { /* * Must increment the new value's reference count * (if it is an internal object) */ acpi_ut_add_reference(obj_desc); /* * Handle objects with multiple descriptors - walk * to the end of the descriptor list */ last_obj_desc = obj_desc; while (last_obj_desc->common.next_object) { last_obj_desc = last_obj_desc->common.next_object; } /* Install the object at the front of the object list */ last_obj_desc->common.next_object = node->object; } node->type = (u8) object_type; node->object = obj_desc; return_ACPI_STATUS(AE_OK); }
void acpi_ut_dump_allocations(u32 component, const char *module) { struct acpi_debug_mem_block *element; union acpi_descriptor *descriptor; u32 num_outstanding = 0; u8 descriptor_type; ACPI_FUNCTION_TRACE(ut_dump_allocations); if (acpi_gbl_disable_mem_tracking) { return_VOID; } /* * Walk the allocation list. */ if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) { return_VOID; } element = acpi_gbl_global_list->list_head; while (element) { if ((element->component & component) && ((module == NULL) || (0 == strcmp(module, element->module)))) { descriptor = ACPI_CAST_PTR(union acpi_descriptor, &element->user_space); if (element->size < sizeof(struct acpi_common_descriptor)) { acpi_os_printf("%p Length 0x%04X %9.9s-%u " "[Not a Descriptor - too small]\n", descriptor, element->size, element->module, element->line); } else { /* Ignore allocated objects that are in a cache */ if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) != ACPI_DESC_TYPE_CACHED) { acpi_os_printf ("%p Length 0x%04X %9.9s-%u [%s] ", descriptor, element->size, element->module, element->line, acpi_ut_get_descriptor_name (descriptor)); /* Validate the descriptor type using Type field and length */ descriptor_type = 0; /* Not a valid descriptor type */ switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { case ACPI_DESC_TYPE_OPERAND: if (element->size == sizeof(union acpi_operand_object)) { descriptor_type = ACPI_DESC_TYPE_OPERAND; } break; case ACPI_DESC_TYPE_PARSER: if (element->size == sizeof(union acpi_parse_object)) { descriptor_type = ACPI_DESC_TYPE_PARSER; } break; case ACPI_DESC_TYPE_NAMED: if (element->size == sizeof(struct acpi_namespace_node)) { descriptor_type = ACPI_DESC_TYPE_NAMED; } break; default: break; } /* Display additional info for the major descriptor types */ switch (descriptor_type) { case ACPI_DESC_TYPE_OPERAND: acpi_os_printf ("%12.12s RefCount 0x%04X\n", acpi_ut_get_type_name (descriptor->object.common. type), descriptor->object.common. reference_count); break; case ACPI_DESC_TYPE_PARSER: acpi_os_printf ("AmlOpcode 0x%04hX\n", descriptor->op.asl. aml_opcode); break; case ACPI_DESC_TYPE_NAMED: acpi_os_printf("%4.4s\n", acpi_ut_get_node_name (&descriptor-> node)); break; default: acpi_os_printf("\n"); break; } } } num_outstanding++; } element = element->next; }
acpi_status acpi_ns_lookup(union acpi_generic_state *scope_info, char *pathname, acpi_object_type type, acpi_interpreter_mode interpreter_mode, u32 flags, struct acpi_walk_state *walk_state, struct acpi_namespace_node **return_node) { acpi_status status; char *path = pathname; struct acpi_namespace_node *prefix_node; struct acpi_namespace_node *current_node = NULL; struct acpi_namespace_node *this_node = NULL; u32 num_segments; u32 num_carats; acpi_name simple_name; acpi_object_type type_to_check_for; acpi_object_type this_search_type; u32 search_parent_flag = ACPI_NS_SEARCH_PARENT; u32 local_flags; ACPI_FUNCTION_TRACE(ns_lookup); if (!return_node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT); *return_node = ACPI_ENTRY_NOT_FOUND; acpi_gbl_ns_lookup_count++; if (!acpi_gbl_root_node) { return_ACPI_STATUS(AE_NO_NAMESPACE); } if ((!scope_info) || (!scope_info->scope.node)) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Null scope prefix, using root node (%p)\n", acpi_gbl_root_node)); prefix_node = acpi_gbl_root_node; } else { prefix_node = scope_info->scope.node; if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) != ACPI_DESC_TYPE_NAMED) { ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]", prefix_node, acpi_ut_get_descriptor_name(prefix_node))); return_ACPI_STATUS(AE_AML_INTERNAL); } if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { while (!acpi_ns_opens_scope(prefix_node->type) && prefix_node->type != ACPI_TYPE_ANY) { prefix_node = prefix_node->parent; } } } type_to_check_for = type; if (!pathname) { num_segments = 0; this_node = acpi_gbl_root_node; path = ""; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Null Pathname (Zero segments), Flags=%X\n", flags)); } else { if (*path == (u8) AML_ROOT_PREFIX) { this_node = acpi_gbl_root_node; search_parent_flag = ACPI_NS_NO_UPSEARCH; path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Path is absolute from root [%p]\n", this_node)); } else { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching relative to prefix scope [%4.4s] (%p)\n", acpi_ut_get_node_name(prefix_node), prefix_node)); this_node = prefix_node; num_carats = 0; while (*path == (u8) AML_PARENT_PREFIX) { search_parent_flag = ACPI_NS_NO_UPSEARCH; path++; num_carats++; this_node = this_node->parent; if (!this_node) { ACPI_ERROR((AE_INFO, "ACPI path has too many parent prefixes (^) " "- reached beyond root node")); return_ACPI_STATUS(AE_NOT_FOUND); } } if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Search scope is [%4.4s], path has %u carat(s)\n", acpi_ut_get_node_name (this_node), num_carats)); } } switch (*path) { case 0: num_segments = 0; type = this_node->type; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Prefix-only Pathname (Zero name segments), Flags=%X\n", flags)); break; case AML_DUAL_NAME_PREFIX: search_parent_flag = ACPI_NS_NO_UPSEARCH; num_segments = 2; path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Dual Pathname (2 segments, Flags=%X)\n", flags)); break; case AML_MULTI_NAME_PREFIX_OP: search_parent_flag = ACPI_NS_NO_UPSEARCH; path++; num_segments = (u32) (u8) * path; path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Multi Pathname (%u Segments, Flags=%X)\n", num_segments, flags)); break; default: num_segments = 1; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Simple Pathname (1 segment, Flags=%X)\n", flags)); break; } ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path)); } this_search_type = ACPI_TYPE_ANY; current_node = this_node; while (num_segments && current_node) { num_segments--; if (!num_segments) { this_search_type = type; if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) && (flags & ACPI_NS_SEARCH_PARENT)) { local_flags |= ACPI_NS_SEARCH_PARENT; } if (flags & ACPI_NS_ERROR_IF_FOUND) { local_flags |= ACPI_NS_ERROR_IF_FOUND; } } ACPI_MOVE_32_TO_32(&simple_name, path); status = acpi_ns_search_and_enter(simple_name, walk_state, current_node, interpreter_mode, this_search_type, local_flags, &this_node); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] not found in scope [%4.4s] %p\n", (char *)&simple_name, (char *)¤t_node->name, current_node)); } *return_node = this_node; return_ACPI_STATUS(status); } if (num_segments > 0) { if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { if (!this_node->object) { return_ACPI_STATUS(AE_NOT_EXIST); } if (acpi_ns_opens_scope (((struct acpi_namespace_node *) this_node->object)->type)) { this_node = (struct acpi_namespace_node *) this_node->object; } } } else { if ((type_to_check_for != ACPI_TYPE_ANY) && (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && (this_node->type != ACPI_TYPE_ANY) && (this_node->type != type_to_check_for)) { ACPI_WARNING((AE_INFO, "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", ACPI_CAST_PTR(char, &simple_name), acpi_ut_get_type_name(this_node-> type), acpi_ut_get_type_name (type_to_check_for))); } if (type == ACPI_TYPE_ANY) { type = this_node->type; } } path += ACPI_NAME_SIZE; current_node = this_node; }
void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) { u32 length; u32 index; ACPI_FUNCTION_NAME(ex_dump_operand) if (! ((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return; } if (!obj_desc) { /* This could be a null element of a package */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n")); return; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ", obj_desc)); ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC); return; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p is not a node or operand object: [%s]\n", obj_desc, acpi_ut_get_descriptor_name(obj_desc))); ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object)); return; } /* obj_desc is a valid object */ if (depth > 0) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p ", depth, " ", depth, obj_desc)); } else { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p ", obj_desc)); } /* Decode object type */ switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_LOCAL_REFERENCE: switch (obj_desc->reference.opcode) { case AML_DEBUG_OP: acpi_os_printf("Reference: Debug\n"); break; case AML_NAME_OP: ACPI_DUMP_PATHNAME(obj_desc->reference.object, "Reference: Name: ", ACPI_LV_INFO, _COMPONENT); ACPI_DUMP_ENTRY(obj_desc->reference.object, ACPI_LV_INFO); break; case AML_INDEX_OP: acpi_os_printf("Reference: Index %p\n", obj_desc->reference.object); break; case AML_REF_OF_OP: acpi_os_printf("Reference: (RefOf) %p\n", obj_desc->reference.object); break; case AML_ARG_OP: acpi_os_printf("Reference: Arg%d", obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { /* Value is an Integer */ acpi_os_printf(" value is [%8.8X%8.8x]", ACPI_FORMAT_UINT64(obj_desc-> integer. value)); } acpi_os_printf("\n"); break; case AML_LOCAL_OP: acpi_os_printf("Reference: Local%d", obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { /* Value is an Integer */ acpi_os_printf(" value is [%8.8X%8.8x]", ACPI_FORMAT_UINT64(obj_desc-> integer. value)); } acpi_os_printf("\n"); break; case AML_INT_NAMEPATH_OP: acpi_os_printf("Reference.Node->Name %X\n", obj_desc->reference.node->name.integer); break; default: /* Unknown opcode */ acpi_os_printf("Unknown Reference opcode=%X\n", obj_desc->reference.opcode); break; } break; case ACPI_TYPE_BUFFER: acpi_os_printf("Buffer len %X @ %p\n", obj_desc->buffer.length, obj_desc->buffer.pointer); length = obj_desc->buffer.length; if (length > 64) { length = 64; } /* Debug only -- dump the buffer contents */ if (obj_desc->buffer.pointer) { acpi_os_printf("Buffer Contents: "); for (index = 0; index < length; index++) { acpi_os_printf(" %02x", obj_desc->buffer.pointer[index]); } acpi_os_printf("\n"); } break; case ACPI_TYPE_INTEGER: acpi_os_printf("Integer %8.8X%8.8X\n", ACPI_FORMAT_UINT64(obj_desc->integer.value)); break; case ACPI_TYPE_PACKAGE: acpi_os_printf("Package [Len %X] ElementArray %p\n", obj_desc->package.count, obj_desc->package.elements); /* * If elements exist, package element pointer is valid, * and debug_level exceeds 1, dump package's elements. */ if (obj_desc->package.count && obj_desc->package.elements && acpi_dbg_level > 1) { for (index = 0; index < obj_desc->package.count; index++) { acpi_ex_dump_operand(obj_desc->package. elements[index], depth + 1); } } break; case ACPI_TYPE_REGION: acpi_os_printf("Region %s (%X)", acpi_ut_get_region_name(obj_desc->region. space_id), obj_desc->region.space_id); /* * If the address and length have not been evaluated, * don't print them. */ if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) { acpi_os_printf("\n"); } else { acpi_os_printf(" base %8.8X%8.8X Length %X\n", ACPI_FORMAT_UINT64(obj_desc->region. address), obj_desc->region.length); } break; case ACPI_TYPE_STRING: acpi_os_printf("String length %X @ %p ", obj_desc->string.length, obj_desc->string.pointer); acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); acpi_os_printf("\n"); break; case ACPI_TYPE_LOCAL_BANK_FIELD: acpi_os_printf("BankField\n"); break; case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_os_printf ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n", obj_desc->field.bit_length, obj_desc->field.access_byte_width, obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset); acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf("IndexField\n"); break; case ACPI_TYPE_BUFFER_FIELD: acpi_os_printf("BufferField: %X bits at byte %X bit %X of\n", obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset, obj_desc->buffer_field.start_field_bit_offset); if (!obj_desc->buffer_field.buffer_obj) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n")); } else if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) { acpi_os_printf("*not a Buffer*\n"); } else { acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj, depth + 1); } break; case ACPI_TYPE_EVENT: acpi_os_printf("Event\n"); break; case ACPI_TYPE_METHOD: acpi_os_printf("Method(%X) @ %p:%X\n", obj_desc->method.param_count, obj_desc->method.aml_start, obj_desc->method.aml_length); break; case ACPI_TYPE_MUTEX: acpi_os_printf("Mutex\n"); break; case ACPI_TYPE_DEVICE: acpi_os_printf("Device\n"); break; case ACPI_TYPE_POWER: acpi_os_printf("Power\n"); break; case ACPI_TYPE_PROCESSOR: acpi_os_printf("Processor\n"); break; case ACPI_TYPE_THERMAL: acpi_os_printf("Thermal\n"); break; default: /* Unknown Type */ acpi_os_printf("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE(obj_desc)); break; } return; }
acpi_status acpi_ns_dump_one_object ( acpi_handle obj_handle, u32 level, void *context, void **return_value) { struct acpi_walk_info *info = (struct acpi_walk_info *) context; struct acpi_namespace_node *this_node; union acpi_operand_object *obj_desc = NULL; acpi_object_type obj_type; acpi_object_type type; u32 bytes_to_dump; u32 dbg_level; u32 i; ACPI_FUNCTION_NAME ("ns_dump_one_object"); /* Is output enabled? */ if (!(acpi_dbg_level & info->debug_level)) { return (AE_OK); } if (!obj_handle) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); return (AE_OK); } this_node = acpi_ns_map_handle_to_node (obj_handle); type = this_node->type; /* Check if the owner matches */ if ((info->owner_id != ACPI_UINT32_MAX) && (info->owner_id != this_node->owner_id)) { return (AE_OK); } /* Indent the object according to the level */ acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " "); /* Check the node type and name */ if (type > ACPI_TYPE_LOCAL_MAX) { ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type)); } if (!acpi_ut_valid_acpi_name (this_node->name.integer)) { ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name.integer)); } /* * Now we can print out the pertinent information */ acpi_os_printf ("%4.4s %-12s %p ", acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object (this_node); acpi_dbg_level = dbg_level; switch (info->display_type) { case ACPI_DISPLAY_SUMMARY: if (!obj_desc) { /* No attached object, we are done */ acpi_os_printf ("\n"); return (AE_OK); } switch (type) { case ACPI_TYPE_PROCESSOR: acpi_os_printf ("ID %X Len %.4X Addr %p\n", obj_desc->processor.proc_id, obj_desc->processor.length, (char *) obj_desc->processor.address); break; case ACPI_TYPE_DEVICE: acpi_os_printf ("Notify Object: %p\n", obj_desc); break; case ACPI_TYPE_METHOD: acpi_os_printf ("Args %X Len %.4X Aml %p\n", (u32) obj_desc->method.param_count, obj_desc->method.aml_length, obj_desc->method.aml_start); break; case ACPI_TYPE_INTEGER: acpi_os_printf ("= %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; case ACPI_TYPE_PACKAGE: if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { acpi_os_printf ("Elements %.2X\n", obj_desc->package.count); } else { acpi_os_printf ("[Length not yet evaluated]\n"); } break; case ACPI_TYPE_BUFFER: if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { acpi_os_printf ("Len %.2X", obj_desc->buffer.length); /* Dump some of the buffer */ if (obj_desc->buffer.length > 0) { acpi_os_printf (" ="); for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) { acpi_os_printf (" %.2hX", obj_desc->buffer.pointer[i]); } } acpi_os_printf ("\n"); } else { acpi_os_printf ("[Length not yet evaluated]\n"); } break; case ACPI_TYPE_STRING: acpi_os_printf ("Len %.2X ", obj_desc->string.length); acpi_ut_print_string (obj_desc->string.pointer, 32); acpi_os_printf ("\n"); break; case ACPI_TYPE_REGION: acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id)); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n", ACPI_FORMAT_UINT64 (obj_desc->region.address), obj_desc->region.length); } else { acpi_os_printf (" [Address/Length not yet evaluated]\n"); } break; case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf ("[%s]\n", acpi_ps_get_opcode_name (obj_desc->reference.opcode)); break; case ACPI_TYPE_BUFFER_FIELD: if (obj_desc->buffer_field.buffer_obj && obj_desc->buffer_field.buffer_obj->buffer.node) { acpi_os_printf ("Buf [%4.4s]", acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node)); } break; case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_os_printf ("Rgn [%4.4s]", acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node)); break; case ACPI_TYPE_LOCAL_BANK_FIELD: acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]", acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node), acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]", acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node), acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), obj_desc); break; default: acpi_os_printf ("Object %p\n", obj_desc); break; } /* Common field handling */ switch (type) { case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n", (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.bit_length, obj_desc->common_field.access_byte_width); break; default: break; } break; case ACPI_DISPLAY_OBJECTS: acpi_os_printf ("O:%p", obj_desc); if (!obj_desc) { /* No attached object, we are done */ acpi_os_printf ("\n"); return (AE_OK); } acpi_os_printf ("(R%d)", obj_desc->common.reference_count); switch (type) { case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ acpi_os_printf (" M:%p-%X\n", obj_desc->method.aml_start, obj_desc->method.aml_length); break; case ACPI_TYPE_INTEGER: acpi_os_printf (" I:%8.8X8.8%X\n", ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; case ACPI_TYPE_STRING: acpi_os_printf (" S:%p-%X\n", obj_desc->string.pointer, obj_desc->string.length); break; case ACPI_TYPE_BUFFER: acpi_os_printf (" B:%p-%X\n", obj_desc->buffer.pointer, obj_desc->buffer.length); break; default: acpi_os_printf ("\n"); break; } break; default: acpi_os_printf ("\n"); break; } /* If debug turned off, done */ if (!(acpi_dbg_level & ACPI_LV_VALUES)) { return (AE_OK); } /* If there is an attached object, display it */ dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object (this_node); acpi_dbg_level = dbg_level; /* Dump attached objects */ while (obj_desc) { obj_type = ACPI_TYPE_INVALID; acpi_os_printf (" Attached Object %p: ", obj_desc); /* Decode the type of attached object and dump the contents */ switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) { case ACPI_DESC_TYPE_NAMED: acpi_os_printf ("(Ptr to Node)\n"); bytes_to_dump = sizeof (struct acpi_namespace_node); break; case ACPI_DESC_TYPE_OPERAND: obj_type = ACPI_GET_OBJECT_TYPE (obj_desc); if (obj_type > ACPI_TYPE_LOCAL_MAX) { acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type); bytes_to_dump = 32; } else { acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n", acpi_ut_get_type_name (obj_type), obj_type); bytes_to_dump = sizeof (union acpi_operand_object); } break; default: acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n", acpi_ut_get_descriptor_name (obj_desc)); bytes_to_dump = 16; break; } ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump); /* If value is NOT an internal object, we are done */ if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { goto cleanup; } /* * Valid object, get the pointer to next level, if any */ switch (obj_type) { case ACPI_TYPE_STRING: obj_desc = (void *) obj_desc->string.pointer; break; case ACPI_TYPE_BUFFER: obj_desc = (void *) obj_desc->buffer.pointer; break; case ACPI_TYPE_BUFFER_FIELD: obj_desc = (union acpi_operand_object *) obj_desc->buffer_field.buffer_obj; break; case ACPI_TYPE_PACKAGE: obj_desc = (void *) obj_desc->package.elements; break; case ACPI_TYPE_METHOD: obj_desc = (void *) obj_desc->method.aml_start; break; case ACPI_TYPE_LOCAL_REGION_FIELD: obj_desc = (void *) obj_desc->field.region_obj; break; case ACPI_TYPE_LOCAL_BANK_FIELD: obj_desc = (void *) obj_desc->bank_field.region_obj; break; case ACPI_TYPE_LOCAL_INDEX_FIELD: obj_desc = (void *) obj_desc->index_field.index_obj; break; default: goto cleanup; } obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ } cleanup: acpi_os_printf ("\n"); return (AE_OK); }
void acpi_ex_dump_object_descriptor ( union acpi_operand_object *obj_desc, u32 flags) { u32 i; ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor"); if (!flags) { if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return_VOID; } } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) { acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags); acpi_os_printf ("\nAttached Object (%p):\n", ((struct acpi_namespace_node *) obj_desc)->object); acpi_ex_dump_object_descriptor ( ((struct acpi_namespace_node *) obj_desc)->object, flags); return_VOID; } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf ( "ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n", obj_desc, acpi_ut_get_descriptor_name (obj_desc)); return_VOID; } /* Common Fields */ acpi_ex_out_string ("Type", acpi_ut_get_object_type_name (obj_desc)); acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count); acpi_ex_out_integer ("Flags", obj_desc->common.flags); /* Object-specific Fields */ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_INTEGER: acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value", ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; case ACPI_TYPE_STRING: acpi_ex_out_integer ("Length", obj_desc->string.length); acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer); acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX); acpi_os_printf ("\n"); break; case ACPI_TYPE_BUFFER: acpi_ex_out_integer ("Length", obj_desc->buffer.length); acpi_ex_out_pointer ("Pointer", obj_desc->buffer.pointer); ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length); break; case ACPI_TYPE_PACKAGE: acpi_ex_out_integer ("Flags", obj_desc->package.flags); acpi_ex_out_integer ("Count", obj_desc->package.count); acpi_ex_out_pointer ("Elements", obj_desc->package.elements); /* Dump the package contents */ if (obj_desc->package.count > 0) { acpi_os_printf ("\nPackage Contents:\n"); for (i = 0; i < obj_desc->package.count; i++) { acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]); if (obj_desc->package.elements[i]) { acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc->package.elements[i])); } acpi_os_printf ("\n"); } } break; case ACPI_TYPE_DEVICE: acpi_ex_out_pointer ("Handler", obj_desc->device.handler); acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify); break; case ACPI_TYPE_EVENT: acpi_ex_out_pointer ("Semaphore", obj_desc->event.semaphore); break; case ACPI_TYPE_METHOD: acpi_ex_out_integer ("param_count", obj_desc->method.param_count); acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency); acpi_ex_out_pointer ("Semaphore", obj_desc->method.semaphore); acpi_ex_out_integer ("owning_id", obj_desc->method.owning_id); acpi_ex_out_integer ("aml_length", obj_desc->method.aml_length); acpi_ex_out_pointer ("aml_start", obj_desc->method.aml_start); break; case ACPI_TYPE_MUTEX: acpi_ex_out_integer ("sync_level", obj_desc->mutex.sync_level); acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread); acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth); acpi_ex_out_pointer ("Semaphore", obj_desc->mutex.semaphore); break; case ACPI_TYPE_REGION: acpi_ex_out_integer ("space_id", obj_desc->region.space_id); acpi_ex_out_integer ("Flags", obj_desc->region.flags); acpi_ex_out_address ("Address", obj_desc->region.address); acpi_ex_out_integer ("Length", obj_desc->region.length); acpi_ex_out_pointer ("Handler", obj_desc->region.handler); acpi_ex_out_pointer ("Next", obj_desc->region.next); break; case ACPI_TYPE_POWER: acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level); acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order); acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify); break; case ACPI_TYPE_PROCESSOR: acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id); acpi_ex_out_integer ("Length", obj_desc->processor.length); acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); acpi_ex_out_pointer ("Handler", obj_desc->processor.handler); break; case ACPI_TYPE_THERMAL: acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler); break; case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags); acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width); acpi_ex_out_integer ("bit_length", obj_desc->common_field.bit_length); acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset); acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset); acpi_ex_out_integer ("datum_valid_bits", obj_desc->common_field.datum_valid_bits); acpi_ex_out_integer ("end_fld_valid_bits",obj_desc->common_field.end_field_valid_bits); acpi_ex_out_integer ("end_buf_valid_bits",obj_desc->common_field.end_buffer_valid_bits); acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node); switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_BUFFER_FIELD: acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj); break; case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj); break; case ACPI_TYPE_LOCAL_BANK_FIELD: acpi_ex_out_integer ("Value", obj_desc->bank_field.value); acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj); acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_ex_out_integer ("Value", obj_desc->index_field.value); acpi_ex_out_pointer ("Index", obj_desc->index_field.index_obj); acpi_ex_out_pointer ("Data", obj_desc->index_field.data_obj); break; default: /* All object types covered above */ break; } break; case ACPI_TYPE_LOCAL_REFERENCE: acpi_ex_out_integer ("target_type", obj_desc->reference.target_type); acpi_ex_out_string ("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name); acpi_ex_out_integer ("Offset", obj_desc->reference.offset); acpi_ex_out_pointer ("obj_desc", obj_desc->reference.object); acpi_ex_out_pointer ("Node", obj_desc->reference.node); acpi_ex_out_pointer ("Where", obj_desc->reference.where); break; case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id); acpi_ex_out_pointer ("Next", obj_desc->address_space.next); acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list); acpi_ex_out_pointer ("Node", obj_desc->address_space.node); acpi_ex_out_pointer ("Context", obj_desc->address_space.context); break; case ACPI_TYPE_LOCAL_NOTIFY: acpi_ex_out_pointer ("Node", obj_desc->notify.node); acpi_ex_out_pointer ("Context", obj_desc->notify.context); break; case ACPI_TYPE_LOCAL_ALIAS: case ACPI_TYPE_LOCAL_METHOD_ALIAS: case ACPI_TYPE_LOCAL_EXTRA: case ACPI_TYPE_LOCAL_DATA: default: acpi_os_printf ( "ex_dump_object_descriptor: Display not implemented for object type %s\n", acpi_ut_get_object_type_name (obj_desc)); break; } return_VOID; }
static acpi_status acpi_ds_init_buffer_field(u16 aml_opcode, union acpi_operand_object *obj_desc, union acpi_operand_object *buffer_desc, union acpi_operand_object *offset_desc, union acpi_operand_object *length_desc, union acpi_operand_object *result_desc) { u32 offset; u32 bit_offset; u32 bit_count; u8 field_flags; acpi_status status; ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); /* Host object must be a Buffer */ if (buffer_desc->common.type != ACPI_TYPE_BUFFER) { ACPI_ERROR((AE_INFO, "Target of Create Field is not a Buffer object - %s", acpi_ut_get_object_type_name(buffer_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; } /* * The last parameter to all of these opcodes (result_desc) started * out as a name_string, and should therefore now be a NS node * after resolution in acpi_ex_resolve_operands(). */ if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { ACPI_ERROR((AE_INFO, "(%s) destination not a NS Node [%s]", acpi_ps_get_opcode_name(aml_opcode), acpi_ut_get_descriptor_name(result_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; } offset = (u32) offset_desc->integer.value; /* * Setup the Bit offsets and counts, according to the opcode */ switch (aml_opcode) { case AML_CREATE_FIELD_OP: /* Offset is in bits, count is in bits */ field_flags = AML_FIELD_ACCESS_BYTE; bit_offset = offset; bit_count = (u32) length_desc->integer.value; /* Must have a valid (>0) bit count */ if (bit_count == 0) { ACPI_ERROR((AE_INFO, "Attempt to CreateField of length zero")); status = AE_AML_OPERAND_VALUE; goto cleanup; } break; case AML_CREATE_BIT_FIELD_OP: /* Offset is in bits, Field is one bit */ bit_offset = offset; bit_count = 1; field_flags = AML_FIELD_ACCESS_BYTE; break; case AML_CREATE_BYTE_FIELD_OP: /* Offset is in bytes, field is one byte */ bit_offset = 8 * offset; bit_count = 8; field_flags = AML_FIELD_ACCESS_BYTE; break; case AML_CREATE_WORD_FIELD_OP: /* Offset is in bytes, field is one word */ bit_offset = 8 * offset; bit_count = 16; field_flags = AML_FIELD_ACCESS_WORD; break; case AML_CREATE_DWORD_FIELD_OP: /* Offset is in bytes, field is one dword */ bit_offset = 8 * offset; bit_count = 32; field_flags = AML_FIELD_ACCESS_DWORD; break; case AML_CREATE_QWORD_FIELD_OP: /* Offset is in bytes, field is one qword */ bit_offset = 8 * offset; bit_count = 64; field_flags = AML_FIELD_ACCESS_QWORD; break; default: ACPI_ERROR((AE_INFO, "Unknown field creation opcode 0x%02X", aml_opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } /* Entire field must fit within the current length of the buffer */ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { ACPI_ERROR((AE_INFO, "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)", acpi_ut_get_node_name(result_desc), bit_offset + bit_count, acpi_ut_get_node_name(buffer_desc->buffer.node), 8 * (u32) buffer_desc->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } /* * Initialize areas of the field object that are common to all fields * For field_flags, use LOCK_RULE = 0 (NO_LOCK), * UPDATE_RULE = 0 (UPDATE_PRESERVE) */ status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0, bit_offset, bit_count); if (ACPI_FAILURE(status)) { goto cleanup; } obj_desc->buffer_field.buffer_obj = buffer_desc; /* Reference count for buffer_desc inherits obj_desc count */ buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count + obj_desc->common.reference_count); cleanup: /* Always delete the operands */ acpi_ut_remove_reference(offset_desc); acpi_ut_remove_reference(buffer_desc); if (aml_opcode == AML_CREATE_FIELD_OP) { acpi_ut_remove_reference(length_desc); } /* On failure, delete the result descriptor */ if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(result_desc); /* Result descriptor */ } else { /* Now the address and length are valid for this buffer_field */ obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; } return_ACPI_STATUS(status); }
static int acpi_ex_dump_operand(char * buf, int maxlen, union acpi_operand_object *obj_desc, u32 depth) { u32 length; int str_len = 0; ACPI_FUNCTION_NAME(ex_dump_operand) if (maxlen <= 0) { return maxlen; } if (!obj_desc) { /* This could be a null element of a package */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n")); return maxlen; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ", obj_desc)); ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC); return maxlen; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p is not a node or operand object: [%s]\n", obj_desc, acpi_ut_get_descriptor_name(obj_desc))); ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object)); return maxlen; } /* obj_desc is a valid object */ if (depth > 0) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p ", depth, " ", depth, obj_desc)); } else { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p ", obj_desc)); } /* Decode object type */ switch (obj_desc->common.type) { #if 0 case ACPI_TYPE_LOCAL_REFERENCE: //str_len += snprintf(buf + str_len, maxlen - str_len, "Reference: [%s] ", // acpi_ut_get_reference_name(obj_desc)); switch (obj_desc->reference.class) { case ACPI_REFCLASS_DEBUG: str_len += snprintf(buf + str_len, maxlen - str_len, "\n"); break; case ACPI_REFCLASS_INDEX: str_len += snprintf(buf + str_len, maxlen - str_len, "%p\n", obj_desc->reference.object); break; case ACPI_REFCLASS_TABLE: str_len += snprintf(buf + str_len, maxlen - str_len, "Table Index %X\n", obj_desc->reference.value); break; case ACPI_REFCLASS_REFOF: //str_len += snprintf(buf + str_len, maxlen - str_len, "%p [%s]\n", obj_desc->reference.object, // acpi_ut_get_type_name(((union // acpi_operand_object // *) // obj_desc-> // reference. // object)->common. // type)); break; case ACPI_REFCLASS_NAME: str_len += snprintf(buf + str_len, maxlen - str_len, "- [%4.4s]\n", obj_desc->reference.node->name.ascii); break; case ACPI_REFCLASS_ARG: case ACPI_REFCLASS_LOCAL: str_len += snprintf(buf + str_len, maxlen - str_len, "%X\n", obj_desc->reference.value); break; default: /* Unknown reference class */ str_len += snprintf(buf + str_len, maxlen - str_len, "%2.2X\n", obj_desc->reference.class); break; } break; case ACPI_TYPE_BUFFER: str_len += snprintf(buf + str_len, maxlen - str_len, "Buffer length %.2X @ %p\n", obj_desc->buffer.length, obj_desc->buffer.pointer); /* Debug only -- dump the buffer contents */ if (obj_desc->buffer.pointer) { length = obj_desc->buffer.length; if (length > 128) { length = 128; } str_len += snprintf(buf + str_len, maxlen - str_len, "Buffer Contents: (displaying length 0x%.2X)\n", length); ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length); } break; #endif case ACPI_TYPE_INTEGER: str_len += snprintf(buf + str_len, maxlen - str_len, "Integer %8.8X%8.8X\n", ACPI_FORMAT_UINT64(obj_desc->integer.value)); break; #if 0 case ACPI_TYPE_PACKAGE: str_len += snprintf(buf + str_len, maxlen - str_len, "Package [Len %X] ElementArray %p\n", obj_desc->package.count, obj_desc->package.elements); ///* // * If elements exist, package element pointer is valid, // * and debug_level exceeds 1, dump package's elements. // */ //if (obj_desc->package.count && // obj_desc->package.elements && acpi_dbg_level > 1) { // for (index = 0; index < obj_desc->package.count; index++) { // acpi_ex_dump_operand(obj_desc->package. // elements[index], // depth + 1); // } //} break; case ACPI_TYPE_REGION: //str_len += snprintf(buf + str_len, maxlen - str_len, "Region %s (%X)", // acpi_ut_get_region_name(obj_desc->region. // space_id), // obj_desc->region.space_id); /* * If the address and length have not been evaluated, * don't print them. */ if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) { str_len += snprintf(buf + str_len, maxlen - str_len, "\n"); } else { str_len += snprintf(buf + str_len, maxlen - str_len, " base %8.8X%8.8X Length %X\n", ACPI_FORMAT_NATIVE_UINT(obj_desc->region. address), obj_desc->region.length); } break; case ACPI_TYPE_STRING: str_len += snprintf(buf + str_len, maxlen - str_len, "String length %X @ %p ", obj_desc->string.length, obj_desc->string.pointer); //acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); str_len += snprintf(buf + str_len, maxlen - str_len, "\n"); break; case ACPI_TYPE_LOCAL_BANK_FIELD: str_len += snprintf(buf + str_len, maxlen - str_len, "BankField\n"); break; case ACPI_TYPE_LOCAL_REGION_FIELD: str_len += snprintf(buf + str_len, maxlen - str_len, "RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at " "byte=%X bit=%X of below:\n", obj_desc->field.bit_length, obj_desc->field.access_byte_width, obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset); //acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: str_len += snprintf(buf + str_len, maxlen - str_len, "IndexField\n"); break; case ACPI_TYPE_BUFFER_FIELD: str_len += snprintf(buf + str_len, maxlen - str_len, "BufferField: %X bits at byte %X bit %X of\n", obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset, obj_desc->buffer_field.start_field_bit_offset); if (!obj_desc->buffer_field.buffer_obj) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n")); } else if ((obj_desc->buffer_field.buffer_obj)->common.type != ACPI_TYPE_BUFFER) { str_len += snprintf(buf + str_len, maxlen - str_len, "*not a Buffer*\n"); } else { //acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj, // depth + 1); } break; case ACPI_TYPE_EVENT: str_len += snprintf(buf + str_len, maxlen - str_len, "Event\n"); break; case ACPI_TYPE_METHOD: str_len += snprintf(buf + str_len, maxlen - str_len, "Method(%X) @ %p:%X\n", obj_desc->method.param_count, obj_desc->method.aml_start, obj_desc->method.aml_length); break; case ACPI_TYPE_MUTEX: str_len += snprintf(buf + str_len, maxlen - str_len, "Mutex\n"); break; case ACPI_TYPE_DEVICE: str_len += snprintf(buf + str_len, maxlen - str_len, "Device\n"); break; case ACPI_TYPE_POWER: str_len += snprintf(buf + str_len, maxlen - str_len, "Power\n"); break; case ACPI_TYPE_PROCESSOR: str_len += snprintf(buf + str_len, maxlen - str_len, "Processor\n"); break; case ACPI_TYPE_THERMAL: str_len += snprintf(buf + str_len, maxlen - str_len, "Thermal\n"); break; #endif default: /* Unknown Type */ str_len += snprintf(buf + str_len, maxlen - str_len, "Unknown Type %X\n", obj_desc->common.type); break; } return str_len; }
acpi_status acpi_ns_attach_object(struct acpi_namespace_node *node, union acpi_operand_object *object, acpi_object_type type) { union acpi_operand_object *obj_desc; union acpi_operand_object *last_obj_desc; acpi_object_type object_type = ACPI_TYPE_ANY; ACPI_FUNCTION_TRACE(ns_attach_object); if (!node) { ACPI_ERROR((AE_INFO, "Null NamedObj handle")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { ACPI_ERROR((AE_INFO, "Null object, but type not ACPI_TYPE_ANY")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", node, acpi_ut_get_descriptor_name(node))); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (node->object == object) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj %p already installed in NameObj %p\n", object, node)); return_ACPI_STATUS(AE_OK); } if (!object) { obj_desc = NULL; object_type = ACPI_TYPE_ANY; } else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) && ((struct acpi_namespace_node *)object)->object) { obj_desc = ((struct acpi_namespace_node *)object)->object; object_type = ((struct acpi_namespace_node *)object)->type; } else { obj_desc = (union acpi_operand_object *)object; object_type = type; } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", obj_desc, node, acpi_ut_get_node_name(node))); if (node->object) { acpi_ns_detach_object(node); } if (obj_desc) { acpi_ut_add_reference(obj_desc); last_obj_desc = obj_desc; while (last_obj_desc->common.next_object) { last_obj_desc = last_obj_desc->common.next_object; } last_obj_desc->common.next_object = node->object; } node->type = (u8) object_type; node->object = obj_desc; return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ds_store_object_to_local ( u16 opcode, u32 index, union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status; struct acpi_namespace_node *node; union acpi_operand_object *current_obj_desc; union acpi_operand_object *new_obj_desc; ACPI_FUNCTION_TRACE ("ds_store_object_to_local"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n", opcode, index, obj_desc)); /* Parameter validation */ if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get the namespace node for the arg/local */ status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } current_obj_desc = acpi_ns_get_attached_object (node); if (current_obj_desc == obj_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", obj_desc)); return_ACPI_STATUS (status); } /* * If the reference count on the object is more than one, we must * take a copy of the object before we store. A reference count * of exactly 1 means that the object was just created during the * evaluation of an expression, and we can safely use it since it * is not used anywhere else. */ new_obj_desc = obj_desc; if (obj_desc->common.reference_count > 1) { status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } } /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do * an indirect store! */ if (current_obj_desc) { /* * Check for an indirect store if an argument * contains an object reference (stored as an Node). * We don't allow this automatic dereferencing for * locals, since a store to a local should overwrite * anything there, including an object reference. * * If both Arg0 and Local0 contain ref_of (Local4): * * Store (1, Arg0) - Causes indirect store to local4 * Store (1, Local0) - Stores 1 in local0, overwriting * the reference to local4 * Store (1, de_refof (Local0)) - Causes indirect store to local4 * * Weird, but true. */ if (opcode == AML_ARG_OP) { /* * Make sure that the object is the correct type. This may be overkill, but * it is here because references were NS nodes in the past. Now they are * operand objects of type Reference. */ if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) { ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n", acpi_ut_get_descriptor_name (current_obj_desc))); return_ACPI_STATUS (AE_AML_INTERNAL); } /* * If we have a valid reference object that came from ref_of(), do the * indirect store */ if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) && (current_obj_desc->reference.opcode == AML_REF_OF_OP)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Arg (%p) is an obj_ref(Node), storing in node %p\n", new_obj_desc, current_obj_desc)); /* * Store this object to the Node (perform the indirect store) * NOTE: No implicit conversion is performed, as per the ACPI * specification rules on storing to Locals/Args. */ status = acpi_ex_store_object_to_node (new_obj_desc, current_obj_desc->reference.object, walk_state, ACPI_NO_IMPLICIT_CONVERSION); /* Remove local reference if we copied the object above */ if (new_obj_desc != obj_desc) { acpi_ut_remove_reference (new_obj_desc); } return_ACPI_STATUS (status); } } /* * Delete the existing object * before storing the new one */ acpi_ds_method_data_delete_value (opcode, index, walk_state); } /* * Install the Obj descriptor (*new_obj_desc) into * the descriptor for the Arg or Local. * (increments the object reference count by one) */ status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state); /* Remove local reference if we copied the object above */ if (new_obj_desc != obj_desc) { acpi_ut_remove_reference (new_obj_desc); } return_ACPI_STATUS (status); }