ACPI_STATUS AcpiExSystemIoSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; UINT32 Value32; ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address))); /* Decode the function parameter */ switch (Function) { case ACPI_READ: Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address, &Value32, BitWidth); *Value = Value32; break; case ACPI_WRITE: Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address, (UINT32) *Value, BitWidth); break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }
acpi_status acpi_ex_system_io_space_handler(u32 function, acpi_physical_address address, u32 bit_width, u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; u32 value32; ACPI_FUNCTION_TRACE(ex_system_io_space_handler); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); /* Decode the function parameter */ switch (function) { case ACPI_READ: status = acpi_hw_read_port((acpi_io_address) address, &value32, bit_width); *value = value32; break; case ACPI_WRITE: status = acpi_hw_write_port((acpi_io_address) address, (u32) * value, bit_width); break; default: status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS(status); }
ACPI_STATUS AcpiDsEvalRegionOperands ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT *OperandDesc; ACPI_NAMESPACE_NODE *Node; ACPI_PARSE_OBJECT *NextOp; ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op); /* * This is where we evaluate the address and length fields of the * OpRegion declaration */ Node = Op->Common.Node; /* NextOp points to the op that holds the SpaceID */ NextOp = Op->Common.Value.Arg; /* NextOp points to address op */ NextOp = NextOp->Common.Next; /* Evaluate/create the address and length operands */ Status = AcpiDsCreateOperands (WalkState, NextOp); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Resolve the length and address operands to numbers */ Status = AcpiExResolveOperands (Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { return_ACPI_STATUS (AE_NOT_EXIST); } /* * Get the length operand and save it * (at Top of stack) */ OperandDesc = WalkState->Operands[WalkState->NumOperands - 1]; ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value; AcpiUtRemoveReference (OperandDesc); /* * Get the address and save it * (at top of stack - 1) */ OperandDesc = WalkState->Operands[WalkState->NumOperands - 2]; ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) OperandDesc->Integer.Value; AcpiUtRemoveReference (OperandDesc); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", ObjDesc, ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address), ObjDesc->Region.Length)); /* Now the address and length are valid for this opregion */ ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID; return_ACPI_STATUS (Status); }
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_OWNER_ID_MAX) && (info->owner_id != this_node->owner_id)) { return (AE_OK); } if (!(info->display_type & ACPI_DISPLAY_SHORT)) { /* 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_WARNING((AE_INFO, "Invalid ACPI Object Type %08X", type)); } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { this_node->name.integer = acpi_ut_repair_name(this_node->name.ascii); ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); } acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); } /* * Now we can print out the pertinent information */ acpi_os_printf(" %-12s %p %2.2X ", acpi_ut_get_type_name(type), this_node, this_node->owner_id); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; /* Temp nodes are those nodes created by a control method */ if (this_node->flags & ANOBJ_TEMPORARY) { acpi_os_printf("(T) "); } switch (info->display_type & ACPI_DISPLAY_MASK) { 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, ACPI_CAST_PTR(void, 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_NATIVE_UINT (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); ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); 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 %X [%s])\n", obj_type, acpi_ut_get_type_name(obj_type)); bytes_to_dump = sizeof(union acpi_operand_object); } ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); break; default: break; } /* 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_BUFFER: case ACPI_TYPE_STRING: /* * NOTE: takes advantage of common fields between string/buffer */ bytes_to_dump = obj_desc->string.length; obj_desc = (void *)obj_desc->string.pointer; acpi_os_printf("(Buffer/String pointer %p length %X)\n", obj_desc, bytes_to_dump); ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); goto cleanup; 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); }
ACPI_STATUS AcpiEvAddressSpaceDispatch ( ACPI_OPERAND_OBJECT *RegionObj, ACPI_OPERAND_OBJECT *FieldObj, UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, UINT64 *Value) { ACPI_STATUS Status; ACPI_ADR_SPACE_HANDLER Handler; ACPI_ADR_SPACE_SETUP RegionSetup; ACPI_OPERAND_OBJECT *HandlerDesc; ACPI_OPERAND_OBJECT *RegionObj2; void *RegionContext = NULL; ACPI_CONNECTION_INFO *Context; ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); if (!RegionObj2) { return_ACPI_STATUS (AE_NOT_EXIST); } /* Ensure that there is a handler associated with this region */ HandlerDesc = RegionObj->Region.Handler; if (!HandlerDesc) { ACPI_ERROR ((AE_INFO, "No handler for Region [%4.4s] (%p) [%s]", AcpiUtGetNodeName (RegionObj->Region.Node), RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (AE_NOT_EXIST); } Context = HandlerDesc->AddressSpace.Context; /* * It may be the case that the region has never been initialized. * Some types of regions require special init code */ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) { /* This region has not been initialized yet, do it */ RegionSetup = HandlerDesc->AddressSpace.Setup; if (!RegionSetup) { /* No initialization routine, exit with error */ ACPI_ERROR ((AE_INFO, "No init routine for region(%p) [%s]", RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will * potentially execute control methods (for example, the _REG method * for this region) */ AcpiExExitInterpreter (); Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, Context, &RegionContext); /* Re-enter the interpreter */ AcpiExEnterInterpreter (); /* Check for failure of the Region Setup */ if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "During region initialization: [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (Status); } /* Region initialization may have been completed by RegionSetup */ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) { RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; /* * Save the returned context for use in all accesses to * the handler for this particular region */ if (!(RegionObj2->Extra.RegionContext)) { RegionObj2->Extra.RegionContext = RegionContext; } } } /* We have everything we need, we can invoke the address space handler */ Handler = HandlerDesc->AddressSpace.Handler; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", &RegionObj->Region.Handler->AddressSpace, Handler, ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), AcpiUtGetRegionName (RegionObj->Region.SpaceId))); /* * Special handling for GenericSerialBus and GeneralPurposeIo: * There are three extra parameters that must be passed to the * handler via the context: * 1) Connection buffer, a resource template from Connection() op. * 2) Length of the above buffer. * 3) Actual access length from the AccessAs() op. */ if (((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) || (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) && Context && FieldObj) { /* Get the Connection (ResourceTemplate) buffer */ Context->Connection = FieldObj->Field.ResourceBuffer; Context->Length = FieldObj->Field.ResourceLength; Context->AccessLength = FieldObj->Field.AccessLength; } if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ AcpiExExitInterpreter(); } /* Call the handler */ Status = Handler (Function, (RegionObj->Region.Address + RegionOffset), BitWidth, Value, Context, RegionObj2->Extra.RegionContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); } if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ AcpiExEnterInterpreter (); } return_ACPI_STATUS (Status); }
/******************************************************************************* * * FUNCTION: acpi_ex_system_memory_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value * handler_context - Pointer to Handler's context * region_context - Pointer to context specific to the * accessed region * * RETURN: Status * * DESCRIPTION: Handler for the System Memory address space (Op Region) * ******************************************************************************/ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; void *logical_addr_ptr = NULL; struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size map_length; acpi_size page_boundary_map_length; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); /* Validate and translate the bit width */ switch (bit_width) { case 8: length = 1; break; case 16: length = 2; break; case 32: length = 4; break; case 64: length = 8; break; default: ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u", bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || (((u64) address + length) > ((u64) mem_info->mapped_physical_address + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (mem_info->mapped_length) { /* Valid mapping, delete it */ acpi_os_unmap_memory(mem_info->mapped_logical_address, mem_info->mapped_length); } /* * Attempt to map from the requested address to the end of the region. * However, we will never map more than one page, nor will we cross * a page boundary. */ map_length = (acpi_size) ((mem_info->address + mem_info->length) - address); /* * If mapping the entire remaining portion of the region will cross * a page boundary, just map up to the page boundary, do not cross. * On some systems, crossing a page boundary while mapping regions * can cause warnings if the pages have different attributes * due to resource management */ page_boundary_map_length = ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address; if (!page_boundary_map_length) { page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; } if (map_length > page_boundary_map_length) { map_length = page_boundary_map_length; } /* Create a new mapping starting at the address given */ mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length); if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at 0x%8.8X%8.8X, size %u", ACPI_FORMAT_NATIVE_UINT(address), (u32) map_length)); mem_info->mapped_length = 0; return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the physical address and mapping size */ mem_info->mapped_physical_address = address; mem_info->mapped_length = map_length; } /* * Generate a logical pointer corresponding to the address we want to * access */ logical_addr_ptr = mem_info->mapped_logical_address + ((u64) address - (u64) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (function) { case ACPI_READ: *value = 0; switch (bit_width) { case 8: *value = (u64) ACPI_GET8(logical_addr_ptr); break; case 16: *value = (u64) ACPI_GET16(logical_addr_ptr); break; case 32: *value = (u64) ACPI_GET32(logical_addr_ptr); break; case 64: *value = (u64) ACPI_GET64(logical_addr_ptr); break; default: /* bit_width was already validated */ break; } break; case ACPI_WRITE: switch (bit_width) { case 8: ACPI_SET8(logical_addr_ptr) = (u8) * value; break; case 16: ACPI_SET16(logical_addr_ptr) = (u16) * value; break; case 32: ACPI_SET32(logical_addr_ptr) = (u32) * value; break; case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; default: /* bit_width was already validated */ break; } break; default: status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS(status); }
acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, u32 region_offset, u32 bit_width, acpi_integer * value) { acpi_status status; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; union acpi_operand_object *region_obj2; void *region_context = NULL; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); region_obj2 = acpi_ns_get_secondary_object(region_obj); if (!region_obj2) { return_ACPI_STATUS(AE_NOT_EXIST); } /* Ensure that there is a handler associated with this region */ handler_desc = region_obj->region.handler; if (!handler_desc) { ACPI_ERROR((AE_INFO, "No handler for Region [%4.4s] (%p) [%s]", acpi_ut_get_node_name(region_obj->region.node), region_obj, acpi_ut_get_region_name(region_obj->region. space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } /* * It may be the case that the region has never been initialized. * Some types of regions require special init code */ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { /* This region has not been initialized yet, do it */ region_setup = handler_desc->address_space.setup; if (!region_setup) { /* No initialization routine, exit with error */ ACPI_ERROR((AE_INFO, "No init routine for region(%p) [%s]", region_obj, acpi_ut_get_region_name(region_obj->region. space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will * potentially execute control methods (for example, the _REG method * for this region) */ acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, ®ion_context); /* Re-enter the interpreter */ acpi_ex_enter_interpreter(); /* Check for failure of the Region Setup */ if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During region initialization: [%s]", acpi_ut_get_region_name(region_obj-> region. space_id))); return_ACPI_STATUS(status); } /* Region initialization may have been completed by region_setup */ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; if (region_obj2->extra.region_context) { /* The handler for this region was already installed */ ACPI_FREE(region_context); } else { /* * Save the returned context for use in all accesses to * this particular region */ region_obj2->extra.region_context = region_context; } } } /* We have everything we need, we can invoke the address space handler */ handler = handler_desc->address_space.handler; ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + region_offset), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ acpi_ex_exit_interpreter(); } /* Call the handler */ status = handler(function, (region_obj->region.address + region_offset), bit_width, value, handler_desc->address_space.context, region_obj2->extra.region_context); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. space_id))); } if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ acpi_ex_enter_interpreter(); } return_ACPI_STATUS(status); }
ACPI_STATUS AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; ACPI_SIZE MapLength; ACPI_SIZE PageBoundaryMapLength; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler); /* Validate and translate the bit width */ switch (BitWidth) { case 8: Length = 1; break; case 16: Length = 2; break; case 32: Length = 4; break; case 64: Length = 8; break; default: ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u", BitWidth)); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder); if (Remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((Address < MemInfo->MappedPhysicalAddress) || (((UINT64) Address + Length) > ((UINT64) MemInfo->MappedPhysicalAddress + MemInfo->MappedLength))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (MemInfo->MappedLength) { /* Valid mapping, delete it */ AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress, MemInfo->MappedLength); } /* * October 2009: Attempt to map from the requested address to the * end of the region. However, we will never map more than one * page, nor will we cross a page boundary. */ MapLength = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); /* * If mapping the entire remaining portion of the region will cross * a page boundary, just map up to the page boundary, do not cross. * On some systems, crossing a page boundary while mapping regions * can cause warnings if the pages have different attributes * due to resource management. * * This has the added benefit of constraining a single mapping to * one page, which is similar to the original code that used a 4k * maximum window. */ PageBoundaryMapLength = ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address; if (PageBoundaryMapLength == 0) { PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE; } if (MapLength > PageBoundaryMapLength) { MapLength = PageBoundaryMapLength; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory ( (ACPI_PHYSICAL_ADDRESS) Address, MapLength); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at 0x%8.8X%8.8X, size %u", ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; MemInfo->MappedLength = MapLength; } /* * Generate a logical pointer corresponding to the address we want to * access */ LogicalAddrPtr = MemInfo->MappedLogicalAddress + ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (Function) { case ACPI_READ: *Value = 0; switch (BitWidth) { case 8: *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr); break; case 16: *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr); break; case 32: *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr); break; case 64: *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr); break; default: /* BitWidth was already validated */ break; } break; case ACPI_WRITE: switch (BitWidth) { case 8: ACPI_SET8 (LogicalAddrPtr, *Value); break; case 16: ACPI_SET16 (LogicalAddrPtr, *Value); break; case 32: ACPI_SET32 (LogicalAddrPtr, *Value); break; case 64: ACPI_SET64 (LogicalAddrPtr, *Value); break; default: /* BitWidth was already validated */ break; } break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiEvAddressSpaceDispatch ( ACPI_OPERAND_OBJECT *RegionObj, UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, ACPI_INTEGER *Value) { ACPI_STATUS Status; ACPI_ADR_SPACE_HANDLER Handler; ACPI_ADR_SPACE_SETUP RegionSetup; ACPI_OPERAND_OBJECT *HandlerDesc; ACPI_OPERAND_OBJECT *RegionObj2; void *RegionContext = NULL; ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); if (!RegionObj2) { return_ACPI_STATUS (AE_NOT_EXIST); } /* Ensure that there is a handler associated with this region */ HandlerDesc = RegionObj->Region.Handler; if (!HandlerDesc) { ACPI_ERROR ((AE_INFO, "No handler for Region [%4.4s] (%p) [%s]", AcpiUtGetNodeName (RegionObj->Region.Node), RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (AE_NOT_EXIST); } /* * It may be the case that the region has never been initialized. * Some types of regions require special init code */ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) { /* This region has not been initialized yet, do it */ RegionSetup = HandlerDesc->AddressSpace.Setup; if (!RegionSetup) { /* No initialization routine, exit with error */ ACPI_ERROR ((AE_INFO, "No init routine for region(%p) [%s]", RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will * potentially execute control methods (for example, the _REG method * for this region) */ AcpiExExitInterpreter (); Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, HandlerDesc->AddressSpace.Context, &RegionContext); /* Re-enter the interpreter */ AcpiExEnterInterpreter (); /* Check for failure of the Region Setup */ if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "During region initialization: [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); return_ACPI_STATUS (Status); } /* Region initialization may have been completed by RegionSetup */ if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) { RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; if (RegionObj2->Extra.RegionContext) { /* The handler for this region was already installed */ ACPI_FREE (RegionContext); } else { /* * Save the returned context for use in all accesses to * this particular region */ RegionObj2->Extra.RegionContext = RegionContext; } } } /* We have everything we need, we can invoke the address space handler */ Handler = HandlerDesc->AddressSpace.Handler; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", &RegionObj->Region.Handler->AddressSpace, Handler, ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), AcpiUtGetRegionName (RegionObj->Region.SpaceId))); if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ AcpiExExitInterpreter(); } /* Call the handler */ Status = Handler (Function, (RegionObj->Region.Address + RegionOffset), BitWidth, Value, HandlerDesc->AddressSpace.Context, RegionObj2->Extra.RegionContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", AcpiUtGetRegionName (RegionObj->Region.SpaceId))); } if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ AcpiExEnterInterpreter (); } return_ACPI_STATUS (Status); }
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); 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_validate_handle(obj_handle); if (!this_node) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n", obj_handle)); return (AE_OK); } type = this_node->type; if ((info->owner_id != ACPI_OWNER_ID_MAX) && (info->owner_id != this_node->owner_id)) { return (AE_OK); } if (!(info->display_type & ACPI_DISPLAY_SHORT)) { acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " "); if (type > ACPI_TYPE_LOCAL_MAX) { ACPI_WARNING((AE_INFO, "Invalid ACPI Object Type 0x%08X", type)); } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { this_node->name.integer = acpi_ut_repair_name(this_node->name.ascii); ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); } acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); } acpi_os_printf(" %-12s %p %2.2X ", acpi_ut_get_type_name(type), this_node, this_node->owner_id); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; if (this_node->flags & ANOBJ_TEMPORARY) { acpi_os_printf("(T) "); } switch (info->display_type & ACPI_DISPLAY_MASK) { case ACPI_DISPLAY_SUMMARY: if (!obj_desc) { switch (type) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_PACKAGE: case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: case ACPI_TYPE_METHOD: acpi_os_printf("<No attached object>"); break; default: break; } 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, ACPI_CAST_PTR(void, 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); 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_NATIVE_UINT (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_ut_get_reference_name(obj_desc)); 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; } 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) { acpi_os_printf("\n"); return (AE_OK); } acpi_os_printf("(R%u)", obj_desc->common.reference_count); switch (type) { case ACPI_TYPE_METHOD: 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 (!(acpi_dbg_level & ACPI_LV_VALUES)) { return (AE_OK); } dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; while (obj_desc) { obj_type = ACPI_TYPE_INVALID; acpi_os_printf("Attached Object %p: ", obj_desc); 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); ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); break; case ACPI_DESC_TYPE_OPERAND: obj_type = obj_desc->common.type; if (obj_type > ACPI_TYPE_LOCAL_MAX) { acpi_os_printf ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n", obj_type); bytes_to_dump = 32; } else { acpi_os_printf ("(Pointer to ACPI Object type %.2X [%s])\n", obj_type, acpi_ut_get_type_name(obj_type)); bytes_to_dump = sizeof(union acpi_operand_object); } ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); break; default: break; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { goto cleanup; } switch (obj_type) { case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: bytes_to_dump = obj_desc->string.length; obj_desc = (void *)obj_desc->string.pointer; acpi_os_printf("(Buffer/String pointer %p length %X)\n", obj_desc, bytes_to_dump); ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); goto cleanup; 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; } cleanup: acpi_os_printf("\n"); return (AE_OK); }
acpi_status acpi_ds_eval_table_region_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; struct acpi_namespace_node *node; union acpi_parse_object *next_op; u32 table_index; struct acpi_table_header *table; ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); /* * This is where we evaluate the signature_string and oem_iDString * and oem_table_iDString of the data_table_region declaration */ node = op->common.node; /* next_op points to signature_string op */ next_op = op->common.value.arg; /* * Evaluate/create the signature_string and oem_iDString * and oem_table_iDString operands */ status = acpi_ds_create_operands(walk_state, next_op); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Resolve the signature_string and oem_iDString * and oem_table_iDString operands */ status = acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } operand = &walk_state->operands[0]; /* Find the ACPI table */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, operand[2]->string.pointer, &table_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_ut_remove_reference(operand[0]); acpi_ut_remove_reference(operand[1]); acpi_ut_remove_reference(operand[2]); status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return_ACPI_STATUS(AE_NOT_EXIST); } obj_desc->region.address = (acpi_physical_address) ACPI_TO_INTEGER(table); obj_desc->region.length = table->length; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ obj_desc->region.flags |= AOPOBJ_DATA_VALID; return_ACPI_STATUS(status); }
acpi_status acpi_ds_eval_region_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; ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); /* * This is where we evaluate the address and length fields of the * op_region declaration */ node = op->common.node; /* next_op points to the op that holds the space_ID */ next_op = op->common.value.arg; /* next_op points to address op */ next_op = next_op->common.next; /* Evaluate/create the address and length operands */ status = acpi_ds_create_operands(walk_state, next_op); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Resolve the length and address operands to numbers */ status = acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return_ACPI_STATUS(AE_NOT_EXIST); } /* * Get the length operand and save it * (at Top of stack) */ operand_desc = walk_state->operands[walk_state->num_operands - 1]; obj_desc->region.length = (u32) operand_desc->integer.value; acpi_ut_remove_reference(operand_desc); /* * Get the address and save it * (at top of stack - 1) */ operand_desc = walk_state->operands[walk_state->num_operands - 2]; obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value; acpi_ut_remove_reference(operand_desc); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ obj_desc->region.flags |= AOPOBJ_DATA_VALID; return_ACPI_STATUS(status); }
ACPI_STATUS AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, ACPI_INTEGER *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; ACPI_SIZE WindowSize; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler); /* Validate and translate the bit width */ switch (BitWidth) { case 8: Length = 1; break; case 16: Length = 2; break; case 32: Length = 4; break; case 64: Length = 8; break; default: ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %d", BitWidth)); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void) AcpiUtShortDivide ((ACPI_INTEGER) Address, Length, NULL, &Remainder); if (Remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((Address < MemInfo->MappedPhysicalAddress) || (((ACPI_INTEGER) Address + Length) > ((ACPI_INTEGER) MemInfo->MappedPhysicalAddress + MemInfo->MappedLength))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (MemInfo->MappedLength) { /* Valid mapping, delete it */ AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress, MemInfo->MappedLength); } /* * Don't attempt to map memory beyond the end of the region, and * constrain the maximum mapping size to something reasonable. */ WindowSize = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); if (WindowSize > ACPI_SYSMEM_REGION_WINDOW_SIZE) { WindowSize = ACPI_SYSMEM_REGION_WINDOW_SIZE; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory ( (ACPI_PHYSICAL_ADDRESS) Address, WindowSize); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) WindowSize)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; MemInfo->MappedLength = WindowSize; } /* * Generate a logical pointer corresponding to the address we want to * access */ LogicalAddrPtr = MemInfo->MappedLogicalAddress + ((ACPI_INTEGER) Address - (ACPI_INTEGER) MemInfo->MappedPhysicalAddress); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (Function) { case ACPI_READ: *Value = 0; switch (BitWidth) { case 8: *Value = (ACPI_INTEGER) ACPI_GET8 (LogicalAddrPtr); break; case 16: *Value = (ACPI_INTEGER) ACPI_GET16 (LogicalAddrPtr); break; case 32: *Value = (ACPI_INTEGER) ACPI_GET32 (LogicalAddrPtr); break; case 64: *Value = (ACPI_INTEGER) ACPI_GET64 (LogicalAddrPtr); break; default: /* BitWidth was already validated */ break; } break; case ACPI_WRITE: switch (BitWidth) { case 8: ACPI_SET8 (LogicalAddrPtr) = (UINT8) *Value; break; case 16: ACPI_SET16 (LogicalAddrPtr) = (UINT16) *Value; break; case 32: ACPI_SET32 ( LogicalAddrPtr) = (UINT32) *Value; break; case 64: ACPI_SET64 (LogicalAddrPtr) = (UINT64) *Value; break; default: /* BitWidth was already validated */ break; } break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }
/******************************************************************************* * * FUNCTION: acpi_ex_system_memory_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value * handler_context - Pointer to Handler's context * region_context - Pointer to context specific to the * accessed region * * RETURN: Status * * DESCRIPTION: Handler for the System Memory address space (Op Region) * ******************************************************************************/ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, acpi_integer * value, void *handler_context, void *region_context) { acpi_status status = AE_OK; void *logical_addr_ptr = NULL; struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size window_size; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); /* Validate and translate the bit width */ switch (bit_width) { case 8: length = 1; break; case 16: length = 2; break; case 32: length = 4; break; case 64: length = 8; break; default: ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %d", bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void)acpi_ut_short_divide((acpi_integer) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || (((acpi_integer) address + length) > ((acpi_integer) mem_info-> mapped_physical_address + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (mem_info->mapped_length) { /* Valid mapping, delete it */ acpi_os_unmap_memory(mem_info->mapped_logical_address, mem_info->mapped_length); } /* * Don't attempt to map memory beyond the end of the region, and * constrain the maximum mapping size to something reasonable. */ window_size = (acpi_size) ((mem_info->address + mem_info->length) - address); if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) { window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE; } /* Create a new mapping starting at the address given */ mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, window_size); if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_NATIVE_UINT(address), (u32) window_size)); mem_info->mapped_length = 0; return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the physical address and mapping size */ mem_info->mapped_physical_address = address; mem_info->mapped_length = window_size; } /* * Generate a logical pointer corresponding to the address we want to * access */ logical_addr_ptr = mem_info->mapped_logical_address + ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (function) { case ACPI_READ: *value = 0; switch (bit_width) { case 8: *value = (acpi_integer) ACPI_GET8(logical_addr_ptr); break; case 16: *value = (acpi_integer) ACPI_GET16(logical_addr_ptr); break; case 32: *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); break; case 64: *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); break; default: /* bit_width was already validated */ break; } break; case ACPI_WRITE: switch (bit_width) { case 8: ACPI_SET8(logical_addr_ptr) = (u8) * value; break; case 16: ACPI_SET16(logical_addr_ptr) = (u16) * value; break; case 32: ACPI_SET32(logical_addr_ptr) = (u32) * value; break; case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; default: /* bit_width was already validated */ break; } break; default: status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS(status); }
ACPI_STATUS AcpiDsEvalTableRegionOperands ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT **Operand; ACPI_NAMESPACE_NODE *Node; ACPI_PARSE_OBJECT *NextOp; UINT32 TableIndex; ACPI_TABLE_HEADER *Table; ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op); /* * This is where we evaluate the Signature string, OemId string, * and OemTableId string of the Data Table Region declaration */ Node = Op->Common.Node; /* NextOp points to Signature string op */ NextOp = Op->Common.Value.Arg; /* * Evaluate/create the Signature string, OemId string, * and OemTableId string operands */ Status = AcpiDsCreateOperands (WalkState, NextOp); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Resolve the Signature string, OemId string, * and OemTableId string operands */ Status = AcpiExResolveOperands (Op->Common.AmlOpcode, ACPI_WALK_OPERANDS, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } Operand = &WalkState->Operands[0]; /* Find the ACPI table */ Status = AcpiTbFindTable (Operand[0]->String.Pointer, Operand[1]->String.Pointer, Operand[2]->String.Pointer, &TableIndex); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } AcpiUtRemoveReference (Operand[0]); AcpiUtRemoveReference (Operand[1]); AcpiUtRemoveReference (Operand[2]); Status = AcpiGetTableByIndex (TableIndex, &Table); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { return_ACPI_STATUS (AE_NOT_EXIST); } ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table); ObjDesc->Region.Length = Table->Length; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", ObjDesc, ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address), ObjDesc->Region.Length)); /* Now the address and length are valid for this opregion */ ObjDesc->Region.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_ev_address_space_dispatch(union acpi_operand_object *region_obj, union acpi_operand_object *field_obj, u32 function, u32 region_offset, u32 bit_width, u64 *value) { acpi_status status; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; union acpi_operand_object *region_obj2; void *region_context = NULL; struct acpi_connection_info *context; acpi_physical_address address; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); region_obj2 = acpi_ns_get_secondary_object(region_obj); if (!region_obj2) { return_ACPI_STATUS(AE_NOT_EXIST); } /* Ensure that there is a handler associated with this region */ handler_desc = region_obj->region.handler; if (!handler_desc) { ACPI_ERROR((AE_INFO, "No handler for Region [%4.4s] (%p) [%s]", acpi_ut_get_node_name(region_obj->region.node), region_obj, acpi_ut_get_region_name(region_obj->region. space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } context = handler_desc->address_space.context; /* * It may be the case that the region has never been initialized. * Some types of regions require special init code */ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { /* This region has not been initialized yet, do it */ region_setup = handler_desc->address_space.setup; if (!region_setup) { /* No initialization routine, exit with error */ ACPI_ERROR((AE_INFO, "No init routine for region(%p) [%s]", region_obj, acpi_ut_get_region_name(region_obj->region. space_id))); return_ACPI_STATUS(AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will * potentially execute control methods (for example, the _REG method * for this region) */ acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, context, ®ion_context); /* Re-enter the interpreter */ acpi_ex_enter_interpreter(); /* Check for failure of the Region Setup */ if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During region initialization: [%s]", acpi_ut_get_region_name(region_obj-> region. space_id))); return_ACPI_STATUS(status); } /* Region initialization may have been completed by region_setup */ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; /* * Save the returned context for use in all accesses to * the handler for this particular region */ if (!(region_obj2->extra.region_context)) { region_obj2->extra.region_context = region_context; } } } /* We have everything we need, we can invoke the address space handler */ handler = handler_desc->address_space.handler; address = (region_obj->region.address + region_offset); /* * Special handling for generic_serial_bus and general_purpose_io: * There are three extra parameters that must be passed to the * handler via the context: * 1) Connection buffer, a resource template from Connection() op * 2) Length of the above buffer * 3) Actual access length from the access_as() op * * In addition, for general_purpose_io, the Address and bit_width fields * are defined as follows: * 1) Address is the pin number index of the field (bit offset from * the previous Connection) * 2) bit_width is the actual bit length of the field (number of pins) */ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && context && field_obj) { /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; } if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; address = field_obj->field.pin_number_index; bit_width = field_obj->field.bit_length; } ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_NATIVE_UINT(address), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ acpi_ex_exit_interpreter(); } /* Call the handler */ status = handler(function, address, bit_width, value, context, region_obj2->extra.region_context); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. space_id))); } if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter */ acpi_ex_enter_interpreter(); } return_ACPI_STATUS(status); }
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_validate_handle(obj_handle); if (!this_node) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n", obj_handle)); return (AE_OK); } type = this_node->type; /* Check if the owner matches */ if ((info->owner_id != ACPI_OWNER_ID_MAX) && (info->owner_id != this_node->owner_id)) { return (AE_OK); } if (!(info->display_type & ACPI_DISPLAY_SHORT)) { /* 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_WARNING((AE_INFO, "Invalid ACPI Object Type 0x%08X", type)); } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { this_node->name.integer = acpi_ut_repair_name(this_node->name.ascii); ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); } acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); } /* Now we can print out the pertinent information */ acpi_os_printf(" %-12s %p %2.2X ", acpi_ut_get_type_name(type), this_node, this_node->owner_id); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; obj_desc = acpi_ns_get_attached_object(this_node); acpi_dbg_level = dbg_level; /* Temp nodes are those nodes created by a control method */ if (this_node->flags & ANOBJ_TEMPORARY) { acpi_os_printf("(T) "); } switch (info->display_type & ACPI_DISPLAY_MASK) { 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, ACPI_CAST_PTR(void, 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_NATIVE_UINT (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_ut_get_reference_name(obj_desc)); 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); } <<<<<<< HEAD acpi_os_printf("(R%u)", obj_desc->common.reference_count); =======