Esempio n. 1
0
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);
}
Esempio n. 2
0
acpi_status
acpi_ev_gpe_initialize (void)
{
	u32                             register_count0 = 0;
	u32                             register_count1 = 0;
	u32                             gpe_number_max = 0;
	acpi_handle                     gpe_device;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_gpe_initialize");


	/* Get a handle to the predefined _GPE object */

	status = acpi_get_handle (NULL, "\\_GPE", &gpe_device);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/*
	 * Initialize the GPE Blocks defined in the FADT
	 *
	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
	 * section "General-Purpose Event Registers", we have:
	 *
	 * "Each register block contains two registers of equal length
	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
	 *  half the GPE1_LEN. If a generic register block is not supported
	 *  then its respective block pointer and block length values in the
	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
	 *  to be the same size."
	 */

	/*
	 * Determine the maximum GPE number for this machine.
	 *
	 * Note: both GPE0 and GPE1 are optional, and either can exist without
	 * the other.
	 *
	 * If EITHER the register length OR the block address are zero, then that
	 * particular block is not supported.
	 */
	if (acpi_gbl_FADT->gpe0_blk_len &&
		acpi_gbl_FADT->xgpe0_blk.address) {
		/* GPE block 0 exists (has both length and address > 0) */

		register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);

		gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;

		/* Install GPE Block 0 */

		status = acpi_ev_create_gpe_block (gpe_device, &acpi_gbl_FADT->xgpe0_blk,
				 register_count0, 0, acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR ((
				"Could not create GPE Block 0, %s\n",
				acpi_format_exception (status)));
		}
	}

	if (acpi_gbl_FADT->gpe1_blk_len &&
		acpi_gbl_FADT->xgpe1_blk.address) {
		/* GPE block 1 exists (has both length and address > 0) */

		register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);

		/* Check for GPE0/GPE1 overlap (if both banks exist) */

		if ((register_count0) &&
			(gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
			ACPI_REPORT_ERROR ((
				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
				gpe_number_max, acpi_gbl_FADT->gpe1_base,
				acpi_gbl_FADT->gpe1_base +
				((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));

			/* Ignore GPE1 block by setting the register count to zero */

			register_count1 = 0;
		}
		else {
			/* Install GPE Block 1 */

			status = acpi_ev_create_gpe_block (gpe_device, &acpi_gbl_FADT->xgpe1_blk,
					 register_count1, acpi_gbl_FADT->gpe1_base,
					 acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]);
			if (ACPI_FAILURE (status)) {
				ACPI_REPORT_ERROR ((
					"Could not create GPE Block 1, %s\n",
					acpi_format_exception (status)));
			}

			/*
			 * GPE0 and GPE1 do not have to be contiguous in the GPE number
			 * space. However, GPE0 always starts at GPE number zero.
			 */
			gpe_number_max = acpi_gbl_FADT->gpe1_base +
					   ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
		}
	}

	/* Exit if there are no GPE registers */

	if ((register_count0 + register_count1) == 0) {
		/* GPEs are not required by ACPI, this is OK */

		ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
		return_ACPI_STATUS (AE_OK);
	}

	/* Check for Max GPE number out-of-range */

	if (gpe_number_max > ACPI_GPE_MAX) {
		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
			gpe_number_max));
		return_ACPI_STATUS (AE_BAD_VALUE);
	}

	return_ACPI_STATUS (AE_OK);
}