示例#1
0
文件: tbget.c 项目: kzlin129/tt-gpl
acpi_status
acpi_tb_get_table_header (
	struct acpi_pointer             *address,
	struct acpi_table_header        *return_header)
{
	acpi_status                     status = AE_OK;
	struct acpi_table_header        *header = NULL;


	ACPI_FUNCTION_TRACE ("tb_get_table_header");


	/*
	 * Flags contains the current processor mode (Virtual or Physical
	 * addressing) The pointer_type is either Logical or Physical
	 */
	switch (address->pointer_type) {
	case ACPI_PHYSMODE_PHYSPTR:
	case ACPI_LOGMODE_LOGPTR:

		/* Pointer matches processor mode, copy the header */

		ACPI_MEMCPY (return_header, address->pointer.logical,
			sizeof (struct acpi_table_header));
		break;


	case ACPI_LOGMODE_PHYSPTR:

		/* Create a logical address for the physical pointer*/

		status = acpi_os_map_memory (address->pointer.physical,
				 sizeof (struct acpi_table_header), (void *) &header);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR ((
				"Could not map memory at %8.8X%8.8X for length %X\n",
				ACPI_FORMAT_UINT64 (address->pointer.physical),
				sizeof (struct acpi_table_header)));
			return_ACPI_STATUS (status);
		}

		/* Copy header and delete mapping */

		ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
		acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
		break;


	default:

		ACPI_REPORT_ERROR (("Invalid address flags %X\n",
			address->pointer_type));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
		return_header->signature));

	return_ACPI_STATUS (AE_OK);
}
示例#2
0
acpi_status
acpi_ev_install_xrupt_handlers (
	void)
{
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");


	/* Install the SCI handler */

	status = acpi_ev_install_sci_handler ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR ((
				"Unable to install System Control Interrupt Handler, %s\n",
				acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	/* Install the handler for the Global Lock */

	status = acpi_ev_init_global_lock_handler ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR ((
				"Unable to initialize Global Lock handler, %s\n",
				acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	acpi_gbl_events_initialized = TRUE;
	return_ACPI_STATUS (status);
}
示例#3
0
acpi_status
acpi_tb_install_table (
    struct acpi_table_desc          *table_info)
{
    acpi_status                     status;

    ACPI_FUNCTION_TRACE ("tb_install_table");


    /* Lock tables while installing */

    status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
    if (ACPI_FAILURE (status)) {
        ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
                            table_info->pointer->signature, acpi_format_exception (status)));
        return_ACPI_STATUS (status);
    }

    /* Install the table into the global data structure */

    status = acpi_tb_init_table_descriptor (table_info->type, table_info);
    if (ACPI_FAILURE (status)) {
        ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n",
                            table_info->pointer->signature, acpi_format_exception (status)));
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
                       acpi_gbl_table_data[table_info->type].name, table_info->pointer));

    (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
    return_ACPI_STATUS (status);
}
示例#4
0
acpi_status acpi_ev_initialize_events(void)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE("ev_initialize_events");

	/* Make sure we have ACPI tables */

	if (!acpi_gbl_DSDT) {
		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No ACPI tables present!\n"));
		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
	}

	/*
	 * Initialize the Fixed and General Purpose Events. This is done prior to
	 * enabling SCIs to prevent interrupts from occurring before the handlers are
	 * installed.
	 */
	status = acpi_ev_fixed_event_initialize();
	if (ACPI_FAILURE(status)) {
		ACPI_REPORT_ERROR(("Unable to initialize fixed events, %s\n",
				   acpi_format_exception(status)));
		return_ACPI_STATUS(status);
	}

	status = acpi_ev_gpe_initialize();
	if (ACPI_FAILURE(status)) {
		ACPI_REPORT_ERROR(("Unable to initialize general purpose events, %s\n", acpi_format_exception(status)));
		return_ACPI_STATUS(status);
	}

	return_ACPI_STATUS(status);
}
示例#5
0
文件: tbget.c 项目: kzlin129/tt-gpl
static acpi_status
acpi_tb_table_override (
	struct acpi_table_header        *header,
	struct acpi_table_desc          *table_info)
{
	struct acpi_table_header        *new_table;
	acpi_status                     status;
	struct acpi_pointer             address;


	ACPI_FUNCTION_TRACE ("tb_table_override");


	/*
	 * The OSL will examine the header and decide whether to override this
	 * table.  If it decides to override, a table will be returned in new_table,
	 * which we will then copy.
	 */
	status = acpi_os_table_override (header, &new_table);
	if (ACPI_FAILURE (status)) {
		/* Some severe error from the OSL, but we basically ignore it */

		ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	if (!new_table) {
		/* No table override */

		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
	}

	/*
	 * We have a new table to override the old one.  Get a copy of
	 * the new one.  We know that the new table has a logical pointer.
	 */
	address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
	address.pointer.logical = new_table;

	status = acpi_tb_get_this_table (&address, new_table, table_info);
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	/* Copy the table info */

	ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
		table_info->pointer->signature));

	return_ACPI_STATUS (AE_OK);
}
示例#6
0
acpi_status
acpi_initialize_subsystem (
	void)
{
	acpi_status                     status;

	ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");


	ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ());


	/* Initialize all globals used by the subsystem */

	acpi_ut_init_globals ();

	/* Initialize the OS-Dependent layer */

	status = acpi_os_initialize ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	/* Create the default mutex objects */

	status = acpi_ut_mutex_initialize ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	/*
	 * Initialize the namespace manager and
	 * the root of the namespace tree
	 */

	status = acpi_ns_root_initialize ();
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
			acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}


	/* If configured, initialize the AML debugger */

	ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());

	return_ACPI_STATUS (status);
}
示例#7
0
acpi_status
acpi_tb_validate_rsdt (
	struct acpi_table_header        *table_ptr)
{
	int                             no_match;


	ACPI_FUNCTION_NAME ("tb_validate_rsdt");


	/*
	 * For RSDP revision 0 or 1, we use the RSDT.
	 * For RSDP revision 2 and above, we use the XSDT
	 */
	if (acpi_gbl_RSDP->revision < 2) {
		no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
				  sizeof (RSDT_SIG) -1);
	}
	else {
		no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
				  sizeof (XSDT_SIG) -1);
	}

	if (no_match) {
		/* Invalid RSDT or XSDT signature */

		ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));

		ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);

		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
			"RSDT/XSDT signature at %X (%p) is invalid\n",
			acpi_gbl_RSDP->rsdt_physical_address,
			(void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address));

		if (acpi_gbl_RSDP->revision < 2) {
			ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
		}
		else {
			ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
		}

		ACPI_DUMP_BUFFER ((char *) table_ptr, 48);

		return (AE_BAD_SIGNATURE);
	}

	return (AE_OK);
}
示例#8
0
NATIVE_CHAR *
AcpiNsGetExternalPathname (
    ACPI_NAMESPACE_NODE     *Node)
{
    NATIVE_CHAR             *NameBuffer;
    ACPI_SIZE               Size;


    ACPI_FUNCTION_TRACE_PTR ("NsGetExternalPathname", Node);


    /* Calculate required buffer size based on depth below root */

    Size = AcpiNsGetPathnameLength (Node);

    /* Allocate a buffer to be returned to caller */

    NameBuffer = ACPI_MEM_CALLOCATE (Size);
    if (!NameBuffer)
    {
        ACPI_REPORT_ERROR (("NsGetTablePathname: allocation failure\n"));
        return_PTR (NULL);
    }

    /* Build the path in the allocated buffer */

    AcpiNsBuildExternalPath (Node, Size, NameBuffer);
    return_PTR (NameBuffer);
}
示例#9
0
acpi_status
acpi_ex_system_do_stall (
	u32                             how_long)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_ENTRY ();


	if (how_long > 255) /* 255 microseconds */ {
		/*
		 * Longer than 255 usec, this is an error
		 *
		 * (ACPI specifies 100 usec as max, but this gives some slack in
		 * order to support existing BIOSs)
		 */
		ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
		status = AE_AML_OPERAND_VALUE;
	}
	else {
		acpi_os_stall (how_long);
	}

	return (status);
}
示例#10
0
文件: utmath.c 项目: kame/kame
ACPI_STATUS
AcpiUtDivide (
    ACPI_INTEGER            *InDividend,
    ACPI_INTEGER            *InDivisor,
    ACPI_INTEGER            *OutQuotient,
    ACPI_INTEGER            *OutRemainder)
{
    ACPI_FUNCTION_TRACE ("UtDivide");


    /* Always check for a zero divisor */

    if (*InDivisor == 0)
    {
        ACPI_REPORT_ERROR (("AcpiUtDivide: Divide by zero\n"));
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
    }


    /* Return only what was requested */

    if (OutQuotient)
    {
        *OutQuotient = *InDividend / *InDivisor;
    }
    if (OutRemainder)
    {
        *OutRemainder = *InDividend % *InDivisor;
    }

    return_ACPI_STATUS (AE_OK);
}
示例#11
0
static u32
acpi_ev_global_lock_handler (
	void                            *context)
{
	u8                              acquired = FALSE;
	acpi_status                     status;


	/*
	 * Attempt to get the lock
	 * If we don't get it now, it will be marked pending and we will
	 * take another interrupt when it becomes free.
	 */
	ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
	if (acquired) {
		/* Got the lock, now wake all threads waiting for it */

		acpi_gbl_global_lock_acquired = TRUE;

		/* Run the Global Lock thread which will signal all waiting threads */

		status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
				  acpi_ev_global_lock_thread, context);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n",
				acpi_format_exception (status)));

			return (ACPI_INTERRUPT_NOT_HANDLED);
		}
	}

	return (ACPI_INTERRUPT_HANDLED);
}
示例#12
0
acpi_status
acpi_ut_divide (
	acpi_integer                    in_dividend,
	acpi_integer                    in_divisor,
	acpi_integer                    *out_quotient,
	acpi_integer                    *out_remainder)
{
	ACPI_FUNCTION_TRACE ("ut_divide");


	/* Always check for a zero divisor */

	if (in_divisor == 0) {
		ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
	}


	/* Return only what was requested */

	if (out_quotient) {
		*out_quotient = in_dividend / in_divisor;
	}
	if (out_remainder) {
		*out_remainder = in_dividend % in_divisor;
	}

	return_ACPI_STATUS (AE_OK);
}
示例#13
0
union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
{
	union acpi_operand_object *string_desc;
	char *string;

	ACPI_FUNCTION_TRACE_U32("ut_create_string_object", string_size);

	/* Create a new String object */

	string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
	if (!string_desc) {
		return_PTR(NULL);
	}

	/*
	 * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
	 * NOTE: Zero-length strings are NULL terminated
	 */
	string = ACPI_MEM_CALLOCATE(string_size + 1);
	if (!string) {
		ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size));
		acpi_ut_remove_reference(string_desc);
		return_PTR(NULL);
	}

	/* Complete string object initialization */

	string_desc->string.pointer = string;
	string_desc->string.length = (u32) string_size;

	/* Return the new string descriptor */

	return_PTR(string_desc);
}
示例#14
0
char *
acpi_ns_get_external_pathname (
	struct acpi_namespace_node      *node)
{
	char                            *name_buffer;
	acpi_size                       size;


	ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node);


	/* Calculate required buffer size based on depth below root */

	size = acpi_ns_get_pathname_length (node);

	/* Allocate a buffer to be returned to caller */

	name_buffer = ACPI_MEM_CALLOCATE (size);
	if (!name_buffer) {
		ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n"));
		return_PTR (NULL);
	}

	/* Build the path in the allocated buffer */

	acpi_ns_build_external_path (node, size, name_buffer);
	return_PTR (name_buffer);
}
示例#15
0
u32
acpi_ev_fixed_event_dispatch (
	u32                             event)
{


	ACPI_FUNCTION_ENTRY ();


	/* Clear the status bit */

	(void) acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
			 1, ACPI_MTX_DO_NOT_LOCK);

	/*
	 * Make sure we've got a handler.  If not, report an error.
	 * The event is disabled to prevent further interrupts.
	 */
	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
		(void) acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
				0, ACPI_MTX_DO_NOT_LOCK);

		ACPI_REPORT_ERROR (
			("No installed handler for fixed event [%08X]\n",
			event));

		return (ACPI_INTERRUPT_NOT_HANDLED);
	}

	/* Invoke the Fixed Event handler */

	return ((acpi_gbl_fixed_event_handlers[event].handler)(
			  acpi_gbl_fixed_event_handlers[event].context));
}
示例#16
0
文件: tbget.c 项目: kzlin129/tt-gpl
acpi_status
acpi_tb_get_table (
	struct acpi_pointer             *address,
	struct acpi_table_desc          *table_info)
{
	acpi_status                     status;
	struct acpi_table_header        header;


	ACPI_FUNCTION_TRACE ("tb_get_table");


	/* Get the header in order to get signature and table size */

	status = acpi_tb_get_table_header (address, &header);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Get the entire table */

	status = acpi_tb_get_table_body (address, &header, table_info);
	if (ACPI_FAILURE (status)) {
		ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
			header.length, acpi_format_exception (status)));
		return_ACPI_STATUS (status);
	}

	return_ACPI_STATUS (AE_OK);
}
示例#17
0
ACPI_STATUS
AcpiTbGetSecondaryTable (
    ACPI_POINTER            *Address,
    ACPI_STRING             Signature,
    ACPI_TABLE_DESC         *TableInfo)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;


    ACPI_FUNCTION_TRACE_STR ("TbGetSecondaryTable", Signature);


    /* Get the header in order to match the signature */

    Status = AcpiTbGetTableHeader (Address, &Header);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Signature must match request */

    if (ACPI_STRNCMP (Header.Signature, Signature, ACPI_NAME_SIZE))
    {
        ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
            Signature, Header.Signature));
        return_ACPI_STATUS (AE_BAD_SIGNATURE);
    }

    /*
     * Check the table signature and make sure it is recognized.
     * Also checks the header checksum
     */
    TableInfo->Pointer = &Header;
    Status = AcpiTbRecognizeTable (TableInfo, ACPI_TABLE_SECONDARY);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Get the entire table */

    Status = AcpiTbGetTableBody (Address, &Header, TableInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Install the table */

    Status = AcpiTbInstallTable (TableInfo);
    return_ACPI_STATUS (Status);
}
示例#18
0
static acpi_status
acpi_tb_get_secondary_table (
	struct acpi_pointer             *address,
	acpi_string                     signature,
	struct acpi_table_desc          *table_info)
{
	acpi_status                     status;
	struct acpi_table_header        header;


	ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature);


	/* Get the header in order to match the signature */

	status = acpi_tb_get_table_header (address, &header);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Signature must match request */

	if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
		ACPI_REPORT_ERROR ((
			"Incorrect table signature - wanted [%s] found [%4.4s]\n",
			signature, header.signature));
		return_ACPI_STATUS (AE_BAD_SIGNATURE);
	}

	/*
	 * Check the table signature and make sure it is recognized.
	 * Also checks the header checksum
	 */
	table_info->pointer = &header;
	status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Get the entire table */

	status = acpi_tb_get_table_body (address, &header, table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Install the table */

	status = acpi_tb_install_table (table_info);
	return_ACPI_STATUS (status);
}
示例#19
0
文件: utmath.c 项目: kame/kame
ACPI_STATUS
AcpiUtShortDivide (
    ACPI_INTEGER            *InDividend,
    UINT32                  Divisor,
    ACPI_INTEGER            *OutQuotient,
    UINT32                  *OutRemainder)
{
    UINT64_OVERLAY          Dividend;
    UINT64_OVERLAY          Quotient;
    UINT32                  Remainder32;


    ACPI_FUNCTION_TRACE ("UtShortDivide");

    Dividend.Full = *InDividend;

    /* Always check for a zero divisor */

    if (Divisor == 0)
    {
        ACPI_REPORT_ERROR (("AcpiUtShortDivide: Divide by zero\n"));
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
    }

    /*
     * The quotient is 64 bits, the remainder is always 32 bits,
     * and is generated by the second divide.
     */
    ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor,
                       Quotient.Part.Hi, Remainder32);
    ACPI_DIV_64_BY_32 (Remainder32, Dividend.Part.Lo,  Divisor,
                       Quotient.Part.Lo, Remainder32);

    /* Return only what was requested */

    if (OutQuotient)
    {
        *OutQuotient = Quotient.Full;
    }
    if (OutRemainder)
    {
        *OutRemainder = Remainder32;
    }

    return_ACPI_STATUS (AE_OK);
}
示例#20
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);
}
示例#21
0
acpi_status
acpi_ut_short_divide (
	acpi_integer                    dividend,
	u32                             divisor,
	acpi_integer                    *out_quotient,
	u32                             *out_remainder)
{
	union uint64_overlay            dividend_ovl;
	union uint64_overlay            quotient;
	u32                             remainder32;


	ACPI_FUNCTION_TRACE ("ut_short_divide");


	/* Always check for a zero divisor */

	if (divisor == 0) {
		ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
	}

	dividend_ovl.full = dividend;

	/*
	 * The quotient is 64 bits, the remainder is always 32 bits,
	 * and is generated by the second divide.
	 */
	ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor,
			  quotient.part.hi, remainder32);
	ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor,
			  quotient.part.lo, remainder32);

	/* Return only what was requested */

	if (out_quotient) {
		*out_quotient = quotient.full;
	}
	if (out_remainder) {
		*out_remainder = remainder32;
	}

	return_ACPI_STATUS (AE_OK);
}
示例#22
0
static void ACPI_SYSTEM_XFACE
acpi_ev_global_lock_thread (
	void                            *context)
{
	acpi_status                     status;


	/* Signal threads that are waiting for the lock */

	if (acpi_gbl_global_lock_thread_count) {
		/* Send sufficient units to the semaphore */

		status = acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore,
				 acpi_gbl_global_lock_thread_count);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n"));
		}
	}
}
示例#23
0
acpi_status
acpi_ut_copy_ipackage_to_ipackage (
	union acpi_operand_object       *source_obj,
	union acpi_operand_object       *dest_obj,
	struct acpi_walk_state          *walk_state)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage");


	dest_obj->common.type   = ACPI_GET_OBJECT_TYPE (source_obj);
	dest_obj->common.flags  = source_obj->common.flags;
	dest_obj->package.count = source_obj->package.count;

	/*
	 * Create the object array and walk the source package tree
	 */
	dest_obj->package.elements = ACPI_MEM_CALLOCATE (
			   ((acpi_size) source_obj->package.count + 1) *
			   sizeof (void *));
	if (!dest_obj->package.elements) {
		ACPI_REPORT_ERROR (
			("aml_build_copy_internal_package_object: Package allocation failure\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * Copy the package element-by-element by walking the package "tree".
	 * This handles nested packages of arbitrary depth.
	 */
	status = acpi_ut_walk_package_tree (source_obj, dest_obj,
			 acpi_ut_copy_ielement_to_ielement, walk_state);
	if (ACPI_FAILURE (status)) {
		/* On failure, delete the destination package object */

		acpi_ut_remove_reference (dest_obj);
	}

	return_ACPI_STATUS (status);
}
示例#24
0
union acpi_operand_object *
acpi_ut_create_buffer_object (
	acpi_size                       buffer_size)
{
	union acpi_operand_object       *buffer_desc;
	u8                              *buffer = NULL;


	ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);


	/* Create a new Buffer object */

	buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
	if (!buffer_desc) {
		return_PTR (NULL);
	}

	/* Create an actual buffer only if size > 0 */

	if (buffer_size > 0) {
		/* Allocate the actual buffer */

		buffer = ACPI_MEM_CALLOCATE (buffer_size);
		if (!buffer) {
			ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
				(u32) buffer_size));
			acpi_ut_remove_reference (buffer_desc);
			return_PTR (NULL);
		}
	}

	/* Complete buffer object initialization */

	buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
	buffer_desc->buffer.pointer = buffer;
	buffer_desc->buffer.length = (u32) buffer_size;

	/* Return the new buffer descriptor */

	return_PTR (buffer_desc);
}
示例#25
0
ACPI_OPERAND_OBJECT *
AcpiUtCreateBufferObject (
    ACPI_SIZE               BufferSize)
{
    ACPI_OPERAND_OBJECT     *BufferDesc;
    UINT8                   *Buffer;


    ACPI_FUNCTION_TRACE_U32 ("UtCreateBufferObject", BufferSize);


    /*
     * Create a new Buffer object
     */
    BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
    if (!BufferDesc)
    {
        return_PTR (NULL);
    }

    /* Allocate the actual buffer */

    Buffer = ACPI_MEM_CALLOCATE (BufferSize);
    if (!Buffer)
    {
        ACPI_REPORT_ERROR (("CreateBuffer: could not allocate size %X\n", 
            (UINT32) BufferSize));
        AcpiUtRemoveReference (BufferDesc);
        return_PTR (NULL);
    }

    /* Complete buffer object initialization */

    BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
    BufferDesc->Buffer.Pointer = Buffer;
    BufferDesc->Buffer.Length = (UINT32) BufferSize;

    /* Return the new buffer descriptor */

    return_PTR (BufferDesc);
}
示例#26
0
ACPI_STATUS
AcpiEnable (void)
{
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE ("AcpiEnable");


    /* Make sure we have the FADT*/

    if (!AcpiGbl_FADT)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
    }

    if (AcpiHwGetMode() == ACPI_SYS_MODE_ACPI)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
    }
    else
    {
        /* Transition to ACPI mode */

        Status = AcpiHwSetMode (ACPI_SYS_MODE_ACPI);
        if (ACPI_FAILURE (Status))
        {
            ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
            return_ACPI_STATUS (Status);
        }

        ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
    }

    return_ACPI_STATUS (Status);
}
示例#27
0
acpi_status
acpi_ex_get_object_reference (
	union acpi_operand_object       *obj_desc,
	union acpi_operand_object       **return_desc,
	struct acpi_walk_state          *walk_state)
{
	union acpi_operand_object       *reference_obj;
	union acpi_operand_object       *referenced_obj;


	ACPI_FUNCTION_TRACE_PTR ("ex_get_object_reference", obj_desc);


	*return_desc = NULL;

	switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
	case ACPI_DESC_TYPE_OPERAND:

		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
		}

		/*
		 * Must be a reference to a Local or Arg
		 */
		switch (obj_desc->reference.opcode) {
		case AML_LOCAL_OP:
		case AML_ARG_OP:

			/* The referenced object is the pseudo-node for the local/arg */

			referenced_obj = obj_desc->reference.object;
			break;

		default:

			ACPI_REPORT_ERROR (("Unknown Reference subtype in get ref %X\n",
				obj_desc->reference.opcode));
			return_ACPI_STATUS (AE_AML_INTERNAL);
		}
		break;


	case ACPI_DESC_TYPE_NAMED:

		/*
		 * A named reference that has already been resolved to a Node
		 */
		referenced_obj = obj_desc;
		break;


	default:

		ACPI_REPORT_ERROR (("Invalid descriptor type in get ref: %X\n",
				ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
		return_ACPI_STATUS (AE_TYPE);
	}


	/* Create a new reference object */

	reference_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
	if (!reference_obj) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	reference_obj->reference.opcode = AML_REF_OF_OP;
	reference_obj->reference.object = referenced_obj;
	*return_desc = reference_obj;

	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
			obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));

	return_ACPI_STATUS (AE_OK);
}
示例#28
0
acpi_status
acpi_ex_do_concatenate (
	union acpi_operand_object       *obj_desc1,
	union acpi_operand_object       *obj_desc2,
	union acpi_operand_object       **actual_return_desc,
	struct acpi_walk_state          *walk_state)
{
	acpi_status                     status;
	u32                             i;
	acpi_integer                    this_integer;
	union acpi_operand_object       *return_desc;
	char                            *new_buf;


	ACPI_FUNCTION_ENTRY ();


	/*
	 * There are three cases to handle:
	 *
	 * 1) Two Integers concatenated to produce a new Buffer
	 * 2) Two Strings concatenated to produce a new String
	 * 3) Two Buffers concatenated to produce a new Buffer
	 */
	switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) {
	case ACPI_TYPE_INTEGER:

		/* Result of two Integers is a Buffer */
		/* Need enough buffer space for two integers */

		return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		new_buf = (char *) return_desc->buffer.pointer;

		/* Convert the first integer */

		this_integer = obj_desc1->integer.value;
		for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
			new_buf[i] = (char) this_integer;
			this_integer >>= 8;
		}

		/* Convert the second integer */

		this_integer = obj_desc2->integer.value;
		for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) {
			new_buf[i] = (char) this_integer;
			this_integer >>= 8;
		}

		break;


	case ACPI_TYPE_STRING:

		/* Result of two Strings is a String */

		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		/* Operand0 is string  */

		new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length +
				   (acpi_size) obj_desc2->string.length + 1);
		if (!new_buf) {
			ACPI_REPORT_ERROR
				(("ex_do_concatenate: String allocation failure\n"));
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		/* Concatenate the strings */

		ACPI_STRCPY (new_buf, obj_desc1->string.pointer);
		ACPI_STRCPY (new_buf + obj_desc1->string.length,
				  obj_desc2->string.pointer);

		/* Complete the String object initialization */

		return_desc->string.pointer = new_buf;
		return_desc->string.length = obj_desc1->string.length +
				   obj_desc2->string.length;
		break;


	case ACPI_TYPE_BUFFER:

		/* Result of two Buffers is a Buffer */

		return_desc = acpi_ut_create_buffer_object (
				   (acpi_size) obj_desc1->buffer.length +
				   (acpi_size) obj_desc2->buffer.length);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		new_buf = (char *) return_desc->buffer.pointer;

		/* Concatenate the buffers */

		ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer,
				  obj_desc1->buffer.length);
		ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer,
				   obj_desc2->buffer.length);

		break;


	default:

		/* Invalid object type, should not happen here */

		ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
				ACPI_GET_OBJECT_TYPE (obj_desc1)));
		status = AE_AML_INTERNAL;
		return_desc = NULL;
	}

	*actual_return_desc = return_desc;
	return (AE_OK);


cleanup:

	acpi_ut_remove_reference (return_desc);
	return (status);
}
示例#29
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_0T_0R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute opcode with two arguments, no target, and no return
 *              value.
 *
 * ALLOCATION:  Deletes both operands
 *
 ******************************************************************************/
acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
{
	union acpi_operand_object **operand = &walk_state->operands[0];
	struct acpi_namespace_node *node;
	u32 value;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R",
				acpi_ps_get_opcode_name(walk_state->opcode));

	/* Examine the opcode */

	switch (walk_state->opcode) {
	case AML_NOTIFY_OP:	/* Notify (notify_object, notify_value) */

		/* The first operand is a namespace node */

		node = (struct acpi_namespace_node *)operand[0];

		/* Second value is the notify value */

		value = (u32) operand[1]->integer.value;

		/* Are notifies allowed on this object? */

		if (!acpi_ev_is_notify_object(node)) {
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
					  "Unexpected notify object type [%s]\n",
					  acpi_ut_get_type_name(node->type)));

			status = AE_AML_OPERAND_TYPE;
			break;
		}
#ifdef ACPI_GPE_NOTIFY_CHECK
		/*
		 * GPE method wake/notify check.  Here, we want to ensure that we
		 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
		 * GPE method during system runtime.  If we do, the GPE is marked
		 * as "wake-only" and disabled.
		 *
		 * 1) Is the Notify() value == device_wake?
		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
		 * 3) Did the original GPE happen at system runtime?
		 *    (versus during wake)
		 *
		 * If all three cases are true, this is a wake-only GPE that should
		 * be disabled at runtime.
		 */
		if (value == 2) {	/* device_wake */
			status =
			    acpi_ev_check_for_wake_only_gpe(walk_state->
							    gpe_event_info);
			if (ACPI_FAILURE(status)) {
				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */

				return_ACPI_STATUS(AE_OK)
			}
		}
#endif

		/*
		 * Dispatch the notify to the appropriate handler
		 * NOTE: the request is queued for execution after this method
		 * completes.  The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 */
		status = acpi_ev_queue_notify_request(node, value);
		break;

	default:

		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
		status = AE_AML_BAD_OPCODE;
	}
示例#30
0
void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
{
	union acpi_operand_object *obj_desc;
	struct acpi_namespace_node *method_node;
	acpi_status status;

	ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state);

	if (!walk_state) {
		return_VOID;
	}

	/* The current method object was saved in the walk state */

	obj_desc = walk_state->method_desc;
	if (!obj_desc) {
		return_VOID;
	}

	/* Delete all arguments and locals */

	acpi_ds_method_data_delete_all(walk_state);

	/*
	 * Lock the parser while we terminate this method.
	 * If this is the last thread executing the method,
	 * we have additional cleanup to perform
	 */
	status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	/* Signal completion of the execution of this method if necessary */

	if (walk_state->method_desc->method.semaphore) {
		status =
		    acpi_os_signal_semaphore(walk_state->method_desc->method.
					     semaphore, 1);
		if (ACPI_FAILURE(status)) {
			ACPI_REPORT_ERROR(("Could not signal method semaphore\n"));

			/* Ignore error and continue cleanup */
		}
	}

	if (walk_state->method_desc->method.thread_count) {
		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
				  "*** Not deleting method namespace, there are still %d threads\n",
				  walk_state->method_desc->method.
				  thread_count));
	} else {		/* This is the last executing thread */

		/*
		 * Support to dynamically change a method from not_serialized to
		 * Serialized if it appears that the method is written foolishly and
		 * does not support multiple thread execution.  The best example of this
		 * is if such a method creates namespace objects and blocks.  A second
		 * thread will fail with an AE_ALREADY_EXISTS exception
		 *
		 * This code is here because we must wait until the last thread exits
		 * before creating the synchronization semaphore.
		 */
		if ((walk_state->method_desc->method.concurrency == 1) &&
		    (!walk_state->method_desc->method.semaphore)) {
			status = acpi_os_create_semaphore(1, 1,
							  &walk_state->
							  method_desc->method.
							  semaphore);
		}

		/*
		 * There are no more threads executing this method.  Perform
		 * additional cleanup.
		 *
		 * The method Node is stored in the walk state
		 */
		method_node = walk_state->method_node;

		/*
		 * Delete any namespace entries created immediately underneath
		 * the method
		 */
		status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
		if (ACPI_FAILURE(status)) {
			goto exit;
		}

		if (method_node->child) {
			acpi_ns_delete_namespace_subtree(method_node);
		}

		/*
		 * Delete any namespace entries created anywhere else within
		 * the namespace
		 */
		acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
						  method.owner_id);
		status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		acpi_ut_release_owner_id(&walk_state->method_desc->method.
					 owner_id);
	}

      exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
	return_VOID;
}