Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96db255c authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

[ACPI] ACPICA 20051102



Modified the subsystem initialization sequence to improve
GPE support. The GPE initialization has been split into
two parts in order to defer execution of the _PRW methods
(Power Resources for Wake) until after the hardware is
fully initialized and the SCI handler is installed. This
allows the _PRW methods to access fields protected by the
Global Lock. This will fix systems where a NO_GLOBAL_LOCK
exception has been seen during initialization.

Fixed a regression with the ConcatenateResTemplate()
ASL operator introduced in the 20051021 release.

Implemented support for "local" internal ACPI object
types within the debugger "Object" command and the
acpi_walk_namespace() external interfaces. These local
types include RegionFields, BankFields, IndexFields, Alias,
and reference objects.

Moved common AML resource handling code into a new file,
"utresrc.c". This code is shared by both the Resource
Manager and the AML Debugger.

Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 0897831b
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -98,6 +98,48 @@ acpi_status acpi_ev_initialize_events(void)
	return_ACPI_STATUS(status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ev_install_fadt_gpes
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
 *              (0 and 1). This causes the _PRW methods to be run, so the HW
 *              must be fully initialized at this point, including global lock
 *              support.
 *
 ******************************************************************************/

acpi_status acpi_ev_install_fadt_gpes(void)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE("ev_install_fadt_gpes");

	/* Namespace must be locked */

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

	/* FADT GPE Block 0 */

	(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
					   acpi_gbl_gpe_fadt_blocks[0]);

	/* FADT GPE Block 1 */

	(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
					   acpi_gbl_gpe_fadt_blocks[1]);

	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ev_install_xrupt_handlers
+101 −58
Original line number Diff line number Diff line
@@ -319,8 +319,8 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
	gpe_event_info =
	    &gpe_block->event_info[gpe_number - gpe_block->block_base_number];

	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
				      ACPI_GPE_TYPE_RUNTIME);
	gpe_event_info->flags = (u8)
	    (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);

	gpe_event_info->dispatch.method_node =
	    (struct acpi_namespace_node *)obj_handle;
@@ -443,6 +443,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,

		gpe_event_info->flags &=
		    ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);

		status =
		    acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
		if (ACPI_FAILURE(status)) {
@@ -566,7 +567,8 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)

	/* Disable this interrupt */

	status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
	status =
	    acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
					     acpi_ev_gpe_xrupt_handler);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
@@ -771,7 +773,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
	/*
	 * Initialize the GPE Register and Event structures. A goal of these
	 * tables is to hide the fact that there are two separate GPE register sets
	 * in a given gpe hardware block, the status registers occupy the first half,
	 * in a given GPE hardware block, the status registers occupy the first half,
	 * and the enable registers occupy the second half.
	 */
	this_register = gpe_register_info;
@@ -812,11 +814,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
			this_event++;
		}

		/*
		 * Clear the status/enable registers.  Note that status registers
		 * are cleared by writing a '1', while enable registers are cleared
		 * by writing a '0'.
		 */
		/* Disable all GPEs within this register */

		status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00,
						 &this_register->
						 enable_address);
@@ -824,6 +823,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
			goto error_exit;
		}

		/* Clear any pending GPE events within this register */

		status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF,
						 &this_register->
						 status_address);
@@ -860,7 +861,9 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create and Install a block of GPE registers
 * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
 *              the block are disabled at exit.
 *              Note: Assumes namespace is locked.
 *
 ******************************************************************************/

@@ -872,14 +875,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
			 u32 interrupt_number,
			 struct acpi_gpe_block_info **return_gpe_block)
{
	struct acpi_gpe_block_info *gpe_block;
	struct acpi_gpe_event_info *gpe_event_info;
	acpi_native_uint i;
	acpi_native_uint j;
	u32 wake_gpe_count;
	u32 gpe_enabled_count;
	acpi_status status;
	struct acpi_gpe_walk_info gpe_info;
	struct acpi_gpe_block_info *gpe_block;

	ACPI_FUNCTION_TRACE("ev_create_gpe_block");

@@ -896,22 +893,24 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,

	/* Initialize the new GPE block */

	gpe_block->node = gpe_device;
	gpe_block->register_count = register_count;
	gpe_block->block_base_number = gpe_block_base_number;
	gpe_block->node = gpe_device;

	ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
		    sizeof(struct acpi_generic_address));

	/* Create the register_info and event_info sub-structures */

	/*
	 * Create the register_info and event_info sub-structures
	 * Note: disables and clears all GPEs in the block
	 */
	status = acpi_ev_create_gpe_info_blocks(gpe_block);
	if (ACPI_FAILURE(status)) {
		ACPI_MEM_FREE(gpe_block);
		return_ACPI_STATUS(status);
	}

	/* Install the new block in the global list(s) */
	/* Install the new block in the global lists */

	status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
	if (ACPI_FAILURE(status)) {
@@ -926,16 +925,70 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
					acpi_ev_save_method_info, gpe_block,
					NULL);

	/* Return the new block */

	if (return_gpe_block) {
		(*return_gpe_block) = gpe_block;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
			  "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
			  (u32) gpe_block->block_base_number,
			  (u32) (gpe_block->block_base_number +
				 ((gpe_block->register_count *
				   ACPI_GPE_REGISTER_WIDTH) - 1)),
			  gpe_device->name.ascii, gpe_block->register_count,
			  interrupt_number));

	return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ev_initialize_gpe_block
 *
 * PARAMETERS:  gpe_device          - Handle to the parent GPE block
 *              gpe_block           - Gpe Block info
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Initialize and enable a GPE block. First find and run any
 *              _PRT methods associated with the block, then enable the
 *              appropriate GPEs.
 *              Note: Assumes namespace is locked.
 *
 ******************************************************************************/

acpi_status
acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
			     struct acpi_gpe_block_info *gpe_block)
{
	acpi_status status;
	struct acpi_gpe_event_info *gpe_event_info;
	struct acpi_gpe_walk_info gpe_info;
	u32 wake_gpe_count;
	u32 gpe_enabled_count;
	acpi_native_uint i;
	acpi_native_uint j;

	ACPI_FUNCTION_TRACE("ev_initialize_gpe_block");

	/* Ignore a null GPE block (e.g., if no GPE block 1 exists) */

	if (!gpe_block) {
		return_ACPI_STATUS(AE_OK);
	}

	/*
	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
	 * is No, they should only be enabled just as the machine goes to sleep.
	 * Runtime option: Should wake GPEs be enabled at runtime?  The default
	 * is no, they should only be enabled just as the machine goes to sleep.
	 */
	if (acpi_gbl_leave_wake_gpes_disabled) {
		/*
		 * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods.
		 * (Each GPE that has one or more _PRWs that reference it is by
		 * definition a WAKE GPE and will not be enabled while the machine
		 * is running.)
		 * Differentiate runtime vs wake GPEs, via the _PRW control methods.
		 * Each GPE that has one or more _PRWs that reference it is by
		 * definition a wake GPE and will not be enabled while the machine
		 * is running.
		 */
		gpe_info.gpe_block = gpe_block;
		gpe_info.gpe_device = gpe_device;
@@ -948,9 +1001,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
	}

	/*
	 * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
	 * and 2) have a corresponding _Lxx or _Exx method.  All other GPEs must
	 * be enabled via the acpi_enable_gpe() external interface.
	 * Enable all GPEs in this block that have these attributes:
	 * 1) are "runtime" or "run/wake" GPEs, and
	 * 2) have a corresponding _Lxx or _Exx method
	 *
	 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
	 * external interface.
	 */
	wake_gpe_count = 0;
	gpe_enabled_count = 0;
@@ -976,32 +1032,19 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
		}
	}

	/* Dump info about this GPE block */

	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
			  "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
			  (u32) gpe_block->block_base_number,
			  (u32) (gpe_block->block_base_number +
				 ((gpe_block->register_count *
				   ACPI_GPE_REGISTER_WIDTH) - 1)),
			  gpe_device->name.ascii, gpe_block->register_count,
			  interrupt_number));

	/* Enable all valid GPEs found above */

	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);

	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
			  "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
			  wake_gpe_count, gpe_enabled_count));

	/* Return the new block */
	/* Enable all valid runtime GPEs found above */

	if (return_gpe_block) {
		(*return_gpe_block) = gpe_block;
	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);
	if (ACPI_FAILURE(status)) {
		ACPI_REPORT_ERROR(("Could not enable GPEs in gpe_block %p\n",
				   gpe_block));
	}

	return_ACPI_STATUS(AE_OK);
	return_ACPI_STATUS(status);
}

/*******************************************************************************
+7 −0
Original line number Diff line number Diff line
@@ -626,6 +626,13 @@ acpi_install_gpe_block(acpi_handle gpe_device,
		goto unlock_and_exit;
	}

	/* Run the _PRW methods and enable the GPEs */

	status = acpi_ev_initialize_gpe_block(node, gpe_block);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	/* Get the device_object attached to the node */

	obj_desc = acpi_ns_get_attached_object(node);
+402 −254

File changed.

Preview size limit exceeded, changes collapsed.

+30 −17
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/amlresrc.h>

#define _COMPONENT          ACPI_EXECUTER
ACPI_MODULE_NAME("exmisc")
@@ -157,40 +158,52 @@ acpi_ex_concat_template(union acpi_operand_object *operand0,
			union acpi_operand_object **actual_return_desc,
			struct acpi_walk_state *walk_state)
{
	acpi_status status;
	union acpi_operand_object *return_desc;
	u8 *new_buf;
	u8 *end_tag1;
	u8 *end_tag2;
	u8 *end_tag;
	acpi_size length0;
	acpi_size length1;
	acpi_size length2;

	ACPI_FUNCTION_TRACE("ex_concat_template");

	/* Find the end_tags in each resource template */
	/*
	 * Find the end_tag descriptor in each resource template.
	 * Note: returned pointers point TO the end_tag, not past it.
	 *
	 * Compute the length of each resource template
	 */
	status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);

	end_tag1 = acpi_ut_get_resource_end_tag(operand0);
	end_tag2 = acpi_ut_get_resource_end_tag(operand1);
	if (!end_tag1 || !end_tag2) {
		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
	status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Compute the length of each part */
	/* Include the end_tag in the second template length */

	length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer);
	length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2;	/* Size of END_TAG */
	length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer) +
	    sizeof(struct aml_resource_end_tag);

	/* Create a new buffer object for the result */

	return_desc = acpi_ut_create_buffer_object(length1 + length2);
	return_desc = acpi_ut_create_buffer_object(length0 + length1);
	if (!return_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Copy the templates to the new descriptor */

	/*
	 * Copy the templates to the new buffer, 0 first, then 1 follows. One
	 * end_tag descriptor is copied from Operand1.
	 */
	new_buf = return_desc->buffer.pointer;
	ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1);
	ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2);
	ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0);
	ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1);

	/* Compute the new checksum */

@@ -198,7 +211,7 @@ acpi_ex_concat_template(union acpi_operand_object *operand0,
	    acpi_ut_generate_checksum(return_desc->buffer.pointer,
				      (return_desc->buffer.length - 1));

	/* Return the completed template descriptor */
	/* Return the completed resource template */

	*actual_return_desc = return_desc;
	return_ACPI_STATUS(AE_OK);
Loading