Beispiel #1
0
acpi_status
acpi_tb_validate_table_header (
	struct acpi_table_header        *table_header)
{
	acpi_name                       signature;


	ACPI_FUNCTION_NAME ("tb_validate_table_header");


	/* Verify that this is a valid address */

	if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Cannot read table header at %p\n", table_header));

		return (AE_BAD_ADDRESS);
	}

	/* Ensure that the signature is 4 ASCII characters */

	ACPI_MOVE_32_TO_32 (&signature, table_header->signature);
	if (!acpi_ut_valid_acpi_name (signature)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Table signature at %p [%p] has invalid characters\n",
			table_header, &signature));

		ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
			(char *) &signature));

		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
		return (AE_BAD_SIGNATURE);
	}

	/* Validate the table length */

	if (table_header->length < sizeof (struct acpi_table_header)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Invalid length in table header %p name %4.4s\n",
			table_header, (char *) &signature));

		ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
			(u32) table_header->length));

		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
		return (AE_BAD_HEADER);
	}

	return (AE_OK);
}
Beispiel #2
0
acpi_status
acpi_tb_verify_table_checksum (
	struct acpi_table_header        *table_header)
{
	u8                              checksum;
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("tb_verify_table_checksum");


	/* Compute the checksum on the table */

	checksum = acpi_tb_checksum (table_header, table_header->length);

	/* Return the appropriate exception */

	if (checksum) {
		ACPI_REPORT_WARNING ((
			"Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
			table_header->signature, (u32) table_header->checksum,
			(u32) checksum));

		status = AE_BAD_CHECKSUM;
	}
	return_ACPI_STATUS (status);
}
Beispiel #3
0
static void
acpi_ut_fadt_register_error (
	char                            *register_name,
	u32                             value,
	acpi_size                       offset)
{

	ACPI_REPORT_WARNING (
		("Invalid FADT value %s=%X at offset %X FADT=%p\n",
		register_name, value, (u32) offset, acpi_gbl_FADT));
}
Beispiel #4
0
acpi_owner_id
acpi_ut_allocate_owner_id (
	u32                             id_type)
{
	acpi_owner_id                   owner_id = 0xFFFF;


	ACPI_FUNCTION_TRACE ("ut_allocate_owner_id");


	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES)))
	{
		return (0);
	}

	switch (id_type)
	{
	case ACPI_OWNER_TYPE_TABLE:

		owner_id = acpi_gbl_next_table_owner_id;
		acpi_gbl_next_table_owner_id++;

		/* Check for wraparound */

		if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
		{
			acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
			ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
		}
		break;


	case ACPI_OWNER_TYPE_METHOD:

		owner_id = acpi_gbl_next_method_owner_id;
		acpi_gbl_next_method_owner_id++;

		if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
		{
			/* Check for wraparound */

			acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
		}
		break;

	default:
		break;
	}

	(void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
	return_VALUE (owner_id);
}
Beispiel #5
0
acpi_object_type
acpi_ns_get_type (
	struct acpi_namespace_node      *node)
{
	ACPI_FUNCTION_TRACE ("ns_get_type");


	if (!node) {
		ACPI_REPORT_WARNING (("ns_get_type: Null Node input pointer\n"));
		return_VALUE (ACPI_TYPE_ANY);
	}

	return_VALUE ((acpi_object_type) node->type);
}
Beispiel #6
0
u32
acpi_ns_local (
	acpi_object_type                type)
{
	ACPI_FUNCTION_TRACE ("ns_local");


	if (!acpi_ut_valid_object_type (type)) {
		/* Type code out of range  */

		ACPI_REPORT_WARNING (("ns_local: Invalid Object Type\n"));
		return_VALUE (ACPI_NS_NORMAL);
	}

	return_VALUE ((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
}
Beispiel #7
0
u32
acpi_ns_opens_scope (
	acpi_object_type                type)
{
	ACPI_FUNCTION_TRACE_STR ("ns_opens_scope", acpi_ut_get_type_name (type));


	if (!acpi_ut_valid_object_type (type)) {
		/* type code out of range  */

		ACPI_REPORT_WARNING (("ns_opens_scope: Invalid Object Type %X\n", type));
		return_VALUE (ACPI_NS_NORMAL);
	}

	return_VALUE (((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
}
Beispiel #8
0
ACPI_STATUS
AcpiTbBuildCommonFacs (
    ACPI_TABLE_DESC         *TableInfo)
{

    ACPI_FUNCTION_TRACE ("TbBuildCommonFacs");


    /* Absolute minimum length is 24, but the ACPI spec says 64 */

    if (AcpiGbl_FACS->Length < 24)
    {
        ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", AcpiGbl_FACS->Length));
        return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    }

    if (AcpiGbl_FACS->Length < 64)
    {
        ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
            AcpiGbl_FACS->Length));
    }

    /* Copy fields to the new FACS */

    AcpiGbl_CommonFACS.GlobalLock = &(AcpiGbl_FACS->GlobalLock);

    if ((AcpiGbl_RSDP->Revision < 2) ||
        (AcpiGbl_FACS->Length < 32)  ||
        (!(ACPI_GET_ADDRESS (AcpiGbl_FACS->XFirmwareWakingVector))))
    {
        /* ACPI 1.0 FACS or short table or optional X_ field is zero */

        AcpiGbl_CommonFACS.FirmwareWakingVector = ACPI_CAST_PTR (UINT64, &(AcpiGbl_FACS->FirmwareWakingVector));
        AcpiGbl_CommonFACS.VectorWidth = 32;
    }
    else
    {
        /* ACPI 2.0 FACS with valid X_ field */

        AcpiGbl_CommonFACS.FirmwareWakingVector = &AcpiGbl_FACS->XFirmwareWakingVector;
        AcpiGbl_CommonFACS.VectorWidth = 64;
    }

    return_ACPI_STATUS (AE_OK);
}
Beispiel #9
0
acpi_status
acpi_ev_release_global_lock (
	void)
{
	u8                              pending = FALSE;
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("ev_release_global_lock");


	if (!acpi_gbl_global_lock_thread_count) {
		ACPI_REPORT_WARNING((
			"Cannot release HW Global Lock, it has not been acquired\n"));
		return_ACPI_STATUS (AE_NOT_ACQUIRED);
	}

	/* One fewer thread has the global lock */

	acpi_gbl_global_lock_thread_count--;
	if (acpi_gbl_global_lock_thread_count) {
		/* There are still some threads holding the lock, cannot release */

		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * No more threads holding lock, we can do the actual hardware
	 * release
	 */
	ACPI_RELEASE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, pending);
	acpi_gbl_global_lock_acquired = FALSE;

	/*
	 * If the pending bit was set, we must write GBL_RLS to the control
	 * register
	 */
	if (pending) {
		status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
				 1, ACPI_MTX_LOCK);
	}

	return_ACPI_STATUS (status);
}
Beispiel #10
0
ACPI_STATUS
AcpiTbConvertTableFadt (void)
{
    FADT_DESCRIPTOR_REV2   *LocalFadt;
    ACPI_TABLE_DESC        *TableDesc;


    ACPI_FUNCTION_TRACE ("TbConvertTableFadt");


    /*
     * AcpiGbl_FADT is valid
     * Allocate and zero the 2.0 FADT buffer
     */
    LocalFadt = ACPI_MEM_CALLOCATE (sizeof (FADT_DESCRIPTOR_REV2));
    if (LocalFadt == NULL)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * FADT length and version validation.  The table must be at least as
     * long as the version 1.0 FADT
     */
    if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV1))
    {
        ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", AcpiGbl_FADT->Header.Length));
        return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    }

    if (AcpiGbl_FADT->Header.Revision >= FADT2_REVISION_ID)
    {
        if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV2))
        {
            /* Length is too short to be a V2.0 table */

            ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
                        AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Revision));

            AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT);
        }
        else
        {
            /* Valid V2.0 table */

            AcpiTbConvertFadt2 (LocalFadt, AcpiGbl_FADT);
        }
    }
    else
    {
        /* Valid V1.0 table */

        AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT);
    }

    /*
     * Global FADT pointer will point to the new common V2.0 FADT
     */
    AcpiGbl_FADT = LocalFadt;
    AcpiGbl_FADT->Header.Length = sizeof (FADT_DESCRIPTOR);

    /* Free the original table */

    TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_FADT];
    AcpiTbDeleteSingleTable (TableDesc);

    /* Install the new table */

    TableDesc->Pointer      = (ACPI_TABLE_HEADER *) AcpiGbl_FADT;
    TableDesc->Allocation   = ACPI_MEM_ALLOCATED;
    TableDesc->Length       = sizeof (FADT_DESCRIPTOR_REV2);

    /* Dump the entire FADT */

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
        "Hex dump of common internal FADT, size %d (%X)\n",
        AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Length));
    ACPI_DUMP_BUFFER ((UINT8 *) (AcpiGbl_FADT), AcpiGbl_FADT->Header.Length);

    return_ACPI_STATUS (AE_OK);
}
Beispiel #11
0
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);
}
Beispiel #12
0
ACPI_STATUS
AcpiNsDumpOneObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    ACPI_NAMESPACE_NODE     *ThisNode;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    ACPI_OBJECT_TYPE        ObjType;
    ACPI_OBJECT_TYPE        Type;
    UINT32                  BytesToDump;
    UINT32                  DbgLevel;
    UINT32                  i;


    ACPI_FUNCTION_NAME ("NsDumpOneObject");


    /* Is output enabled? */

    if (!(AcpiDbgLevel & Info->DebugLevel))
    {
        return (AE_OK);
    }

    if (!ObjHandle)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
        return (AE_OK);
    }

    ThisNode = AcpiNsMapHandleToNode (ObjHandle);
    Type = ThisNode->Type;

    /* Check if the owner matches */

    if ((Info->OwnerId != ACPI_UINT32_MAX) &&
        (Info->OwnerId != ThisNode->OwnerId))
    {
        return (AE_OK);
    }

    /* Indent the object according to the level */

    AcpiOsPrintf ("%2d%*s", (UINT32) 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 (!AcpiUtValidAcpiName (ThisNode->Name.Integer))
    {
        ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name.Integer));
    }

    /*
     * Now we can print out the pertinent information
     */
    AcpiOsPrintf ("%4.4s %-12s %p ",
            ThisNode->Name.Ascii, AcpiUtGetTypeName (Type), ThisNode);

    DbgLevel = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    switch (Info->DisplayType)
    {
    case ACPI_DISPLAY_SUMMARY:

        if (!ObjDesc)
        {
            /* No attached object, we are done */

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        switch (Type)
        {
        case ACPI_TYPE_PROCESSOR:

            AcpiOsPrintf ("ID %X Len %.4X Addr %p\n",
                        ObjDesc->Processor.ProcId,
                        ObjDesc->Processor.Length,
                        (char *) ObjDesc->Processor.Address);
            break;


        case ACPI_TYPE_DEVICE:

            AcpiOsPrintf ("Notify object: %p", ObjDesc);
            break;


        case ACPI_TYPE_METHOD:

            AcpiOsPrintf ("Args %X Len %.4X Aml %p\n",
                        (UINT32) ObjDesc->Method.ParamCount,
                        ObjDesc->Method.AmlLength,
                        ObjDesc->Method.AmlStart);
            break;


        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf ("= %8.8X%8.8X\n",
                        ACPI_HIDWORD (ObjDesc->Integer.Value),
                        ACPI_LODWORD (ObjDesc->Integer.Value));
            break;


        case ACPI_TYPE_PACKAGE:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Elements %.2X\n",
                            ObjDesc->Package.Count);
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_BUFFER:

            if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf ("Len %.2X",
                            ObjDesc->Buffer.Length);

                /* Dump some of the buffer */

                if (ObjDesc->Buffer.Length > 0)
                {
                    AcpiOsPrintf (" =");
                    for (i = 0; (i < ObjDesc->Buffer.Length && i < 12); i++)
                    {
                        AcpiOsPrintf (" %.2hX", ObjDesc->Buffer.Pointer[i]);
                    }
                }
                AcpiOsPrintf ("\n");
            }
            else
            {
                AcpiOsPrintf ("[Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_STRING:

            AcpiOsPrintf ("Len %.2X ", ObjDesc->String.Length);
            AcpiUtPrintString (ObjDesc->String.Pointer, 32);
            AcpiOsPrintf ("\n");
            break;


        case ACPI_TYPE_REGION:

            AcpiOsPrintf ("[%s]", AcpiUtGetRegionName (ObjDesc->Region.SpaceId));
            if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
            {
                AcpiOsPrintf (" Addr %8.8X%8.8X Len %.4X\n",
                            ACPI_HIDWORD (ObjDesc->Region.Address),
                            ACPI_LODWORD (ObjDesc->Region.Address),
                            ObjDesc->Region.Length);
            }
            else
            {
                AcpiOsPrintf (" [Address/Length not yet evaluated]\n");
            }
            break;


        case ACPI_TYPE_LOCAL_REFERENCE:

            AcpiOsPrintf ("[%s]\n",
                    AcpiPsGetOpcodeName (ObjDesc->Reference.Opcode));
            break;


        case ACPI_TYPE_BUFFER_FIELD:

            if (ObjDesc->BufferField.BufferObj &&
                ObjDesc->BufferField.BufferObj->Buffer.Node)
            {
                AcpiOsPrintf ("Buf [%4.4s]",
                        ObjDesc->BufferField.BufferObj->Buffer.Node->Name.Ascii);
            }
            break;


        case ACPI_TYPE_LOCAL_REGION_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s]",
                    ObjDesc->CommonField.RegionObj->Region.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_BANK_FIELD:

            AcpiOsPrintf ("Rgn [%4.4s] Bnk [%4.4s]",
                    ObjDesc->CommonField.RegionObj->Region.Node->Name.Ascii,
                    ObjDesc->BankField.BankObj->CommonField.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_INDEX_FIELD:

            AcpiOsPrintf ("Idx [%4.4s] Dat [%4.4s]",
                    ObjDesc->IndexField.IndexObj->CommonField.Node->Name.Ascii,
                    ObjDesc->IndexField.DataObj->CommonField.Node->Name.Ascii);
            break;


        case ACPI_TYPE_LOCAL_ALIAS:

            AcpiOsPrintf ("Target %4.4s (%p)\n", ((ACPI_NAMESPACE_NODE *) ObjDesc)->Name.Ascii, ObjDesc);
            break;

        default:

            AcpiOsPrintf ("Object %p\n", ObjDesc);
            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:

            AcpiOsPrintf (" Off %.2X Len %.2X Acc %.2hd\n",
                    (ObjDesc->CommonField.BaseByteOffset * 8)
                        + ObjDesc->CommonField.StartFieldBitOffset,
                    ObjDesc->CommonField.BitLength,
                    ObjDesc->CommonField.AccessByteWidth);
            break;

        default:
            break;
        }
        break;


    case ACPI_DISPLAY_OBJECTS:

        AcpiOsPrintf ("O:%p", ObjDesc);
        if (!ObjDesc)
        {
            /* No attached object, we are done */

            AcpiOsPrintf ("\n");
            return (AE_OK);
        }

        AcpiOsPrintf ("(R%d)",
                ObjDesc->Common.ReferenceCount);

        switch (Type)
        {
        case ACPI_TYPE_METHOD:

            /* Name is a Method and its AML offset/length are set */

            AcpiOsPrintf (" M:%p-%X\n", ObjDesc->Method.AmlStart,
                                        ObjDesc->Method.AmlLength);
            break;

        case ACPI_TYPE_INTEGER:

            AcpiOsPrintf (" N:%X%X\n", ACPI_HIDWORD(ObjDesc->Integer.Value),
                                       ACPI_LODWORD(ObjDesc->Integer.Value));
            break;

        case ACPI_TYPE_STRING:

            AcpiOsPrintf (" S:%p-%X\n", ObjDesc->String.Pointer,
                                        ObjDesc->String.Length);
            break;

        case ACPI_TYPE_BUFFER:

            AcpiOsPrintf (" B:%p-%X\n", ObjDesc->Buffer.Pointer,
                                        ObjDesc->Buffer.Length);
            break;

        default:

            AcpiOsPrintf ("\n");
            break;
        }
        break;


    default:
        AcpiOsPrintf ("\n");
        break;
    }

    /* If debug turned off, done */

    if (!(AcpiDbgLevel & ACPI_LV_VALUES))
    {
        return (AE_OK);
    }


    /* If there is an attached object, display it */

    DbgLevel     = AcpiDbgLevel;
    AcpiDbgLevel = 0;
    ObjDesc      = AcpiNsGetAttachedObject (ThisNode);
    AcpiDbgLevel = DbgLevel;

    /* Dump attached objects */

    while (ObjDesc)
    {
        ObjType = ACPI_TYPE_INVALID;
        AcpiOsPrintf ("        Attached Object %p: ", ObjDesc);

        /* Decode the type of attached object and dump the contents */

        switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
        {
        case ACPI_DESC_TYPE_NAMED:

            AcpiOsPrintf ("(Ptr to Node)\n");
            BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
            break;


        case ACPI_DESC_TYPE_OPERAND:

            ObjType = ACPI_GET_OBJECT_TYPE (ObjDesc);

            if (ObjType > ACPI_TYPE_LOCAL_MAX)
            {
                AcpiOsPrintf ("(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType);
                BytesToDump = 32;
            }
            else
            {
                AcpiOsPrintf ("(Ptr to ACPI Object type %s, %X)\n",
                                    AcpiUtGetTypeName (ObjType), ObjType);
                BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
            }
            break;


        default:

            AcpiOsPrintf ("(String or Buffer ptr - not an object descriptor)\n");
            BytesToDump = 16;
            break;
        }

        ACPI_DUMP_BUFFER (ObjDesc, BytesToDump);

        /* If value is NOT an internal object, we are done */

        if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
        {
            goto Cleanup;
        }

        /*
         * Valid object, get the pointer to next level, if any
         */
        switch (ObjType)
        {
        case ACPI_TYPE_STRING:
            ObjDesc = (void *) ObjDesc->String.Pointer;
            break;

        case ACPI_TYPE_BUFFER:
            ObjDesc = (void *) ObjDesc->Buffer.Pointer;
            break;

        case ACPI_TYPE_BUFFER_FIELD:
            ObjDesc = (ACPI_OPERAND_OBJECT *) ObjDesc->BufferField.BufferObj;
            break;

        case ACPI_TYPE_PACKAGE:
            ObjDesc = (void *) ObjDesc->Package.Elements;
            break;

        case ACPI_TYPE_METHOD:
            ObjDesc = (void *) ObjDesc->Method.AmlStart;
            break;

        case ACPI_TYPE_LOCAL_REGION_FIELD:
            ObjDesc = (void *) ObjDesc->Field.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_BANK_FIELD:
            ObjDesc = (void *) ObjDesc->BankField.RegionObj;
            break;

        case ACPI_TYPE_LOCAL_INDEX_FIELD:
            ObjDesc = (void *) ObjDesc->IndexField.IndexObj;
            break;

        default:
            goto Cleanup;
        }

        ObjType = ACPI_TYPE_INVALID;   /* Terminate loop after next pass */
    }

Cleanup:
    AcpiOsPrintf ("\n");
    return (AE_OK);
}
Beispiel #13
0
ACPI_STATUS
AcpiDsScopeStackPush (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_OBJECT_TYPE        Type,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_GENERIC_STATE      *ScopeInfo;
    ACPI_GENERIC_STATE      *OldScopeInfo;


    ACPI_FUNCTION_TRACE ("DsScopeStackPush");


    if (!Node)
    {
        /* Invalid scope   */

        ACPI_REPORT_ERROR (("DsScopeStackPush: null scope passed\n"));
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Make sure object type is valid */

    if (!AcpiUtValidObjectType (Type))
    {
        ACPI_REPORT_WARNING (("DsScopeStackPush: type code out of range\n"));
    }


    /* Allocate a new scope object */

    ScopeInfo = AcpiUtCreateGenericState ();
    if (!ScopeInfo)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Init new scope object */

    ScopeInfo->Common.DataType  = ACPI_DESC_TYPE_STATE_WSCOPE;
    ScopeInfo->Scope.Node       = Node;
    ScopeInfo->Common.Value     = (UINT16) Type;

    WalkState->ScopeDepth++;

    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
        "[%.2d] Pushed scope ", (UINT32) WalkState->ScopeDepth));

    OldScopeInfo = WalkState->ScopeInfo;
    if (OldScopeInfo)
    {
        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
            "[%4.4s] (%10s)",
            OldScopeInfo->Scope.Node->Name.Ascii,
            AcpiUtGetTypeName (OldScopeInfo->Common.Value)));
    }
    else
    {
        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
            "[\\___] (%10s)", "ROOT"));
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
        ", New scope -> [%4.4s] (%s)\n",
        ScopeInfo->Scope.Node->Name.Ascii,
        AcpiUtGetTypeName (ScopeInfo->Common.Value)));

    /* Push new scope object onto stack */

    AcpiUtPushGenericState (&WalkState->ScopeInfo, ScopeInfo);

    return_ACPI_STATUS (AE_OK);
}
Beispiel #14
0
ACPI_STATUS
AcpiDsBuildInternalBufferObj (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  BufferLength,
    ACPI_OPERAND_OBJECT     **ObjDescPtr)
{
    ACPI_PARSE_OBJECT       *Arg;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_PARSE_OBJECT       *ByteList;
    UINT32                  ByteListLength = 0;


    ACPI_FUNCTION_TRACE ("DsBuildInternalBufferObj");


    ObjDesc = *ObjDescPtr;
    if (ObjDesc)
    {
        /*
         * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
         * The buffer object already exists (from the NS node)
         */
    }
    else
    {
        /* Create a new buffer object */

        ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
        *ObjDescPtr = ObjDesc;
        if (!ObjDesc)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }
    }

    /*
     * Second arg is the buffer data (optional) ByteList can be either
     * individual bytes or a string initializer.  In either case, a
     * ByteList appears in the AML.
     */
    Arg = Op->Common.Value.Arg;         /* skip first arg */

    ByteList = Arg->Named.Next;
    if (ByteList)
    {
        if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                "Expecting bytelist, got AML opcode %X in op %p\n",
                ByteList->Common.AmlOpcode, ByteList));

            AcpiUtRemoveReference (ObjDesc);
            return (AE_TYPE);
        }

        ByteListLength = ByteList->Common.Value.Integer32;
    }

    /*
     * The buffer length (number of bytes) will be the larger of:
     * 1) The specified buffer length and
     * 2) The length of the initializer byte list
     */
    ObjDesc->Buffer.Length = BufferLength;
    if (ByteListLength > BufferLength)
    {
        ObjDesc->Buffer.Length = ByteListLength;
    }

    /* Allocate the buffer */

    if (ObjDesc->Buffer.Length == 0)
    {
        ObjDesc->Buffer.Pointer = NULL;
        ACPI_REPORT_WARNING (("Buffer created with zero length in AML\n"));
    }
    else
    {
        ObjDesc->Buffer.Pointer = ACPI_MEM_CALLOCATE (
                                        ObjDesc->Buffer.Length);
        if (!ObjDesc->Buffer.Pointer)
        {
            AcpiUtDeleteObjectDesc (ObjDesc);
            return_ACPI_STATUS (AE_NO_MEMORY);
        }

        /* Initialize buffer from the ByteList (if present) */

        if (ByteList)
        {
            ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
                         ByteListLength);
        }
    }

    ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
    Op->Common.Node = (ACPI_NAMESPACE_NODE *) ObjDesc;
    return_ACPI_STATUS (AE_OK);
}
Beispiel #15
0
void
acpi_ns_delete_children (
	struct acpi_namespace_node      *parent_node)
{
	struct acpi_namespace_node      *child_node;
	struct acpi_namespace_node      *next_node;
	struct acpi_namespace_node      *node;
	u8                              flags;


	ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node);


	if (!parent_node) {
		return_VOID;
	}

	/* If no children, all done! */

	child_node = parent_node->child;
	if (!child_node) {
		return_VOID;
	}

	/*
	 * Deallocate all children at this level
	 */
	do {
		/* Get the things we need */

		next_node   = child_node->peer;
		flags       = child_node->flags;

		/* Grandchildren should have all been deleted already */

		if (child_node->child) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n",
				parent_node, child_node));
		}

		/* Now we can free this child object */

		ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
			child_node, acpi_gbl_current_node_count));

		/*
		 * Detach an object if there is one, then free the child node
		 */
		acpi_ns_detach_object (child_node);

		/*
		 * Decrement the reference count(s) of all parents up to
		 * the root! (counts were incremented when the node was created)
		 */
		node = child_node;
		while ((node = acpi_ns_get_parent_node (node)) != NULL) {
			node->reference_count--;
		}

		/* There should be only one reference remaining on this node */

		if (child_node->reference_count != 1) {
			ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
				child_node->reference_count, child_node));
		}

		/* Now we can delete the node */

		ACPI_MEM_FREE (child_node);

		/* And move on to the next child in the list */

		child_node = next_node;

	} while (!(flags & ANOBJ_END_OF_PEER_LIST));


	/* Clear the parent's child pointer */

	parent_node->child = NULL;

	return_VOID;
}
Beispiel #16
0
acpi_status
acpi_tb_get_required_tables (
	void)
{
	acpi_status                     status = AE_OK;
	u32                             i;
	struct acpi_table_desc          table_info;
	struct acpi_pointer             address;


	ACPI_FUNCTION_TRACE ("tb_get_required_tables");

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
		acpi_gbl_rsdt_table_count));


	address.pointer_type  = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;

	/*
	 * Loop through all table pointers found in RSDT.
	 * This will NOT include the FACS and DSDT - we must get
	 * them after the loop.
	 *
	 * The only tables we are interested in getting here is the FADT and
	 * any SSDTs.
	 */
	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
		/* Get the table address from the common internal XSDT */

		address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];

		/*
		 * Get the tables needed by this subsystem (FADT and any SSDTs).
		 * NOTE: All other tables are completely ignored at this time.
		 */
		status = acpi_tb_get_primary_table (&address, &table_info);
		if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
			ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
				acpi_format_exception (status),
				ACPI_FORMAT_UINT64 (address.pointer.value)));
		}
	}

	/* We must have a FADT to continue */

	if (!acpi_gbl_FADT) {
		ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
	}

	/*
	 * Convert the FADT to a common format.  This allows earlier revisions of the
	 * table to coexist with newer versions, using common access code.
	 */
	status = acpi_tb_convert_table_fadt ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
		return_ACPI_STATUS (status);
	}

	/*
	 * Get the FACS (Pointed to by the FADT)
	 */
	address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;

	status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	/*
	 * Create the common FACS pointer table
	 * (Contains pointers to the original table)
	 */
	status = acpi_tb_build_common_facs (&table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/*
	 * Get/install the DSDT (Pointed to by the FADT)
	 */
	address.pointer.value = acpi_gbl_FADT->Xdsdt;

	status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
		return_ACPI_STATUS (status);
	}

	/* Set Integer Width (32/64) based upon DSDT revision */

	acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);

	/* Dump the entire DSDT */

	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
		"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
		acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
	ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);

	/* Always delete the RSDP mapping, we are done with it */

	acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
	return_ACPI_STATUS (status);
}
Beispiel #17
0
acpi_status
acpi_ex_setup_region (
	union acpi_operand_object       *obj_desc,
	u32                             field_datum_byte_offset)
{
	acpi_status                     status = AE_OK;
	union acpi_operand_object       *rgn_desc;


	ACPI_FUNCTION_TRACE_U32 ("ex_setup_region", field_datum_byte_offset);


	rgn_desc = obj_desc->common_field.region_obj;

	/* We must have a valid region */

	if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
			ACPI_GET_OBJECT_TYPE (rgn_desc),
			acpi_ut_get_object_type_name (rgn_desc)));

		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
	}

	/*
	 * If the Region Address and Length have not been previously evaluated,
	 * evaluate them now and save the results.
	 */
	if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
		status = acpi_ds_get_region_arguments (rgn_desc);
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}
	}

	if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
		/* SMBus has a non-linear address space */

		return_ACPI_STATUS (AE_OK);
	}

#ifdef ACPI_UNDER_DEVELOPMENT
	/*
	 * If the Field access is any_acc, we can now compute the optimal
	 * access (because we know know the length of the parent region)
	 */
	if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}
	}
#endif

	/*
	 * Validate the request.  The entire request from the byte offset for a
	 * length of one field datum (access width) must fit within the region.
	 * (Region length is specified in bytes)
	 */
	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
			   + field_datum_byte_offset
			   + obj_desc->common_field.access_byte_width)) {
		if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
			/*
			 * This is the case where the access_type (acc_word, etc.) is wider
			 * than the region itself.  For example, a region of length one
			 * byte, and a field with Dword access specified.
			 */
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
				obj_desc->common_field.node->name.ascii, obj_desc->common_field.access_byte_width,
				rgn_desc->region.node->name.ascii, rgn_desc->region.length));
		}

		/*
		 * Offset rounded up to next multiple of field width
		 * exceeds region length, indicate an error
		 */
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
			obj_desc->common_field.node->name.ascii, obj_desc->common_field.base_byte_offset,
			field_datum_byte_offset, obj_desc->common_field.access_byte_width,
			rgn_desc->region.node->name.ascii, rgn_desc->region.length));

		#ifdef CONFIG_ACPI_RELAXED_AML
		{
			/*
			 * Allow access to the field if it is within the region size
			 * rounded up to a multiple of the access byte width.  This
			 * overcomes "off-by-one" programming errors in the AML often
			 * found in Toshiba laptops.  These errors were allowed by
			 * the Microsoft ASL compiler.
			 */
			u32 rounded_length = ACPI_ROUND_UP(rgn_desc->region.length,
									obj_desc->common_field.access_byte_width);

			if (rounded_length < (obj_desc->common_field.base_byte_offset
						+ field_datum_byte_offset
						+ obj_desc->common_field.access_byte_width)) {
				return_ACPI_STATUS (AE_AML_REGION_LIMIT);
			} else {
				static int	warn_once = 1;
				if (warn_once) {
					// Could also associate a flag with each field, and
					// warn once for each field.
					ACPI_REPORT_WARNING((
						"The ACPI AML in your computer contains errors, "
						"please nag the manufacturer to correct it.\n"));
					ACPI_REPORT_WARNING((
						"Allowing relaxed access to fields; "
						"turn on CONFIG_ACPI_DEBUG for details.\n"));
					warn_once = 0;
				}
				return_ACPI_STATUS (AE_OK);
			}
		}
		#else
			return_ACPI_STATUS (AE_AML_REGION_LIMIT);
		#endif
	}

	return_ACPI_STATUS (AE_OK);
}
Beispiel #18
0
ACPI_STATUS
AcpiTbGetRequiredTables (
    void)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  i;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_POINTER            Address;


    ACPI_FUNCTION_TRACE ("TbGetRequiredTables");

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
        AcpiGbl_RsdtTableCount));


    Address.PointerType   = AcpiGbl_TableFlags | ACPI_LOGICAL_ADDRESSING;

    /*
     * Loop through all table pointers found in RSDT.
     * This will NOT include the FACS and DSDT - we must get
     * them after the loop.
     *
     * The only tables we are interested in getting here is the FADT and
     * any SSDTs.
     */
    for (i = 0; i < AcpiGbl_RsdtTableCount; i++)
    {
        /* Get the table addresss from the common internal XSDT */

        Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_XSDT->TableOffsetEntry[i]);

        /*
         * Get the tables needed by this subsystem (FADT and any SSDTs).
         * NOTE: All other tables are completely ignored at this time.
         */
        Status = AcpiTbGetPrimaryTable (&Address, &TableInfo);
        if ((Status != AE_OK) && (Status != AE_TABLE_NOT_SUPPORTED))
        {
            ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
                AcpiFormatException (Status),
                ACPI_HIDWORD (Address.Pointer.Value),
                ACPI_LODWORD (Address.Pointer.Value)));
        }
    }

    /* We must have a FADT to continue */

    if (!AcpiGbl_FADT)
    {
        ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
    }

    /*
     * Convert the FADT to a common format.  This allows earlier revisions of the
     * table to coexist with newer versions, using common access code.
     */
    Status = AcpiTbConvertTableFadt ();
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
        return_ACPI_STATUS (Status);
    }

    /*
     * Get the FACS (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XFirmwareCtrl);

    Status = AcpiTbGetSecondaryTable (&Address, FACS_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
            AcpiFormatException (Status)));
        return_ACPI_STATUS (Status);
    }

    /*
     * Create the common FACS pointer table
     * (Contains pointers to the original table)
     */
    Status = AcpiTbBuildCommonFacs (&TableInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Get/install the DSDT (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XDsdt);

    Status = AcpiTbGetSecondaryTable (&Address, DSDT_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
        return_ACPI_STATUS (Status);
    }

    /* Set Integer Width (32/64) based upon DSDT revision */

    AcpiUtSetIntegerWidth (AcpiGbl_DSDT->Revision);

    /* Dump the entire DSDT */

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
        "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
        AcpiGbl_DSDT->Length, AcpiGbl_DSDT->Length, AcpiGbl_IntegerBitWidth));
    ACPI_DUMP_BUFFER ((UINT8 *) AcpiGbl_DSDT, AcpiGbl_DSDT->Length);

    /* Always delete the RSDP mapping, we are done with it */

    AcpiTbDeleteAcpiTable (ACPI_TABLE_RSDP);
    return_ACPI_STATUS (Status);
}
Beispiel #19
0
ACPI_STATUS
AcpiNsLoadTable (
    ACPI_TABLE_DESC         *TableDesc,
    ACPI_NAMESPACE_NODE     *Node)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE ("NsLoadTable");


    /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */

    if (!(AcpiGbl_AcpiTableData[TableDesc->Type].Flags & ACPI_TABLE_EXECUTABLE))
    {
        /* Just ignore this table */

        return_ACPI_STATUS (AE_OK);
    }

    /* Check validity of the AML start and length */

    if (!TableDesc->AmlStart)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n"));
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", TableDesc->AmlStart));

    /* Ignore table if there is no AML contained within */

    if (!TableDesc->AmlLength)
    {
        ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", TableDesc->Pointer->Signature));
        return_ACPI_STATUS (AE_OK);
    }

    /*
     * Parse the table and load the namespace with all named
     * objects found within.  Control methods are NOT parsed
     * at this time.  In fact, the control methods cannot be
     * parsed until the entire namespace is loaded, because
     * if a control method makes a forward reference (call)
     * to another control method, we can't continue parsing
     * because we don't know how many arguments to parse next!
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Loading table into namespace ****\n"));

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiNsParseTable (TableDesc, Node->Child);
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Now we can parse the control methods.  We always parse
     * them here for a sanity check, and if configured for
     * just-in-time parsing, we delete the control method
     * parse trees.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
        "**** Begin Table Method Parsing and Object Initialization ****\n"));

    Status = AcpiDsInitializeObjects (TableDesc, Node);

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
        "**** Completed Table Method Parsing and Object Initialization ****\n"));

    return_ACPI_STATUS (Status);
}
Beispiel #20
0
acpi_status
acpi_ns_load_table (
	struct acpi_table_desc          *table_desc,
	struct acpi_namespace_node      *node)
{
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ns_load_table");


	/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */

	if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
		/* Just ignore this table */

		return_ACPI_STATUS (AE_OK);
	}

	/* Check validity of the AML start and length */

	if (!table_desc->aml_start) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n"));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n",
		table_desc->aml_start));

	/* Ignore table if there is no AML contained within */

	if (!table_desc->aml_length) {
		ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n",
			table_desc->pointer->signature));
		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * Parse the table and load the namespace with all named
	 * objects found within.  Control methods are NOT parsed
	 * at this time.  In fact, the control methods cannot be
	 * parsed until the entire namespace is loaded, because
	 * if a control method makes a forward reference (call)
	 * to another control method, we can't continue parsing
	 * because we don't know how many arguments to parse next!
	 */
	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"**** Loading table into namespace ****\n"));

	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	status = acpi_ns_parse_table (table_desc, node->child);
	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);

	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/*
	 * Now we can parse the control methods.  We always parse
	 * them here for a sanity check, and if configured for
	 * just-in-time parsing, we delete the control method
	 * parse trees.
	 */
	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"**** Begin Table Method Parsing and Object Initialization ****\n"));

	status = acpi_ds_initialize_objects (table_desc, node);

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"**** Completed Table Method Parsing and Object Initialization ****\n"));

	return_ACPI_STATUS (status);
}
Beispiel #21
0
acpi_status
acpi_ds_scope_stack_push (
	struct acpi_namespace_node      *node,
	acpi_object_type                type,
	struct acpi_walk_state          *walk_state)
{
	union acpi_generic_state        *scope_info;
	union acpi_generic_state        *old_scope_info;


	ACPI_FUNCTION_TRACE ("ds_scope_stack_push");


	if (!node) {
		/* Invalid scope   */

		ACPI_REPORT_ERROR (("ds_scope_stack_push: null scope passed\n"));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Make sure object type is valid */

	if (!acpi_ut_valid_object_type (type)) {
		ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
	}

	/* Allocate a new scope object */

	scope_info = acpi_ut_create_generic_state ();
	if (!scope_info) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Init new scope object */

	scope_info->common.data_type = ACPI_DESC_TYPE_STATE_WSCOPE;
	scope_info->scope.node      = node;
	scope_info->common.value    = (u16) type;

	walk_state->scope_depth++;

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
		"[%.2d] Pushed scope ", (u32) walk_state->scope_depth));

	old_scope_info = walk_state->scope_info;
	if (old_scope_info) {
		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
			"[%4.4s] (%s)",
			acpi_ut_get_node_name (old_scope_info->scope.node),
			acpi_ut_get_type_name (old_scope_info->common.value)));
	}
	else {
		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
			"[\\___] (%s)", "ROOT"));
	}

	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
		", New scope -> [%4.4s] (%s)\n",
		acpi_ut_get_node_name (scope_info->scope.node),
		acpi_ut_get_type_name (scope_info->common.value)));

	/* Push new scope object onto stack */

	acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
	return_ACPI_STATUS (AE_OK);
}