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

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

ACPICA: Implement simplified Table Manager



The Table Manager component has been completely
redesigned and reimplemented. The new design is much
simpler, and reduces the overall code and data size of
the kernel-resident ACPICA by approximately 5%. Also,
it is now possible to obtain the ACPI tables very early
during kernel initialization, even before dynamic memory
management is initialized.

Signed-off-by: default avatarAlexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 2e42005b
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acnamesp.h>
#include <acpi/actables.h>

#define _COMPONENT          ACPI_DISPATCHER
ACPI_MODULE_NAME("dsinit")
@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
	 * We are only interested in NS nodes owned by the table that
	 * was just loaded
	 */
	if (node->owner_id != info->table_desc->owner_id) {
	if (node->owner_id != info->owner_id) {
		return (AE_OK);
	}

@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
 ******************************************************************************/

acpi_status
acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
acpi_ds_initialize_objects(acpi_native_uint table_index,
			   struct acpi_namespace_node * start_node)
{
	acpi_status status;
	struct acpi_init_walk_info info;
	struct acpi_table_header *table;
	acpi_owner_id owner_id;

	ACPI_FUNCTION_TRACE(ds_initialize_objects);

	status = acpi_tb_get_owner_id(table_index, &owner_id);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
			  "**** Starting initialization of namespace objects ****\n"));
	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
	info.op_region_count = 0;
	info.object_count = 0;
	info.device_count = 0;
	info.table_desc = table_desc;
	info.table_index = table_index;
	info.owner_id = owner_id;

	/* Walk entire namespace from the supplied root */

@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
	}

	status = acpi_get_table_by_index(table_index, &table);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
			      "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
			      table_desc->pointer->signature,
			      table_desc->owner_id, info.object_count,
			      table->signature, owner_id, info.object_count,
			      info.device_count, info.method_count,
			      info.op_region_count));

+0 −7
Original line number Diff line number Diff line
@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void)

	ACPI_FUNCTION_TRACE(ev_initialize_events);

	/* Make sure we have ACPI tables */

	if (!acpi_gbl_DSDT) {
		ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
		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
+26 −23
Original line number Diff line number Diff line
@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32

	/* Install new interrupt handler if not SCI_INT */

	if (interrupt_number != acpi_gbl_FADT->sci_int) {
	if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
		status = acpi_os_install_interrupt_handler(interrupt_number,
							   acpi_ev_gpe_xrupt_handler,
							   gpe_xrupt);
@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)

	/* We never want to remove the SCI interrupt handler */

	if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) {
	if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
		gpe_xrupt->gpe_block_list_head = NULL;
		return_ACPI_STATUS(AE_OK);
	}
@@ -803,17 +803,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
				   (gpe_block->block_address.address
				    + i + gpe_block->register_count));

		this_register->status_address.address_space_id =
		    gpe_block->block_address.address_space_id;
		this_register->enable_address.address_space_id =
		    gpe_block->block_address.address_space_id;
		this_register->status_address.register_bit_width =
		this_register->status_address.space_id =
		    gpe_block->block_address.space_id;
		this_register->enable_address.space_id =
		    gpe_block->block_address.space_id;
		this_register->status_address.bit_width =
		    ACPI_GPE_REGISTER_WIDTH;
		this_register->enable_address.register_bit_width =
		this_register->enable_address.bit_width =
		    ACPI_GPE_REGISTER_WIDTH;
		this_register->status_address.register_bit_offset =
		this_register->status_address.bit_offset =
		    ACPI_GPE_REGISTER_WIDTH;
		this_register->enable_address.register_bit_offset =
		this_register->enable_address.bit_offset =
		    ACPI_GPE_REGISTER_WIDTH;

		/* Init the event_info for each GPE within this register */
@@ -1109,11 +1109,12 @@ acpi_status acpi_ev_gpe_initialize(void)
	 * 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) {
	if (acpi_gbl_FADT.gpe0_block_length &&
	    acpi_gbl_FADT.xgpe0_block.address) {

		/* GPE block 0 exists (has both length and address > 0) */

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

		gpe_number_max =
		    (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
@@ -1121,9 +1122,9 @@ acpi_status acpi_ev_gpe_initialize(void)
		/* Install GPE Block 0 */

		status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
						  &acpi_gbl_FADT->xgpe0_blk,
						  &acpi_gbl_FADT.xgpe0_block,
						  register_count0, 0,
						  acpi_gbl_FADT->sci_int,
						  acpi_gbl_FADT.sci_interrupt,
						  &acpi_gbl_gpe_fadt_blocks[0]);

		if (ACPI_FAILURE(status)) {
@@ -1132,20 +1133,21 @@ acpi_status acpi_ev_gpe_initialize(void)
		}
	}

	if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) {
	if (acpi_gbl_FADT.gpe1_block_length &&
	    acpi_gbl_FADT.xgpe1_block.address) {

		/* GPE block 1 exists (has both length and address > 0) */

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

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

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

@@ -1157,10 +1159,11 @@ acpi_status acpi_ev_gpe_initialize(void)

			status =
			    acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
						     &acpi_gbl_FADT->xgpe1_blk,
						     &acpi_gbl_FADT.xgpe1_block,
						     register_count1,
						     acpi_gbl_FADT->gpe1_base,
						     acpi_gbl_FADT->sci_int,
						     acpi_gbl_FADT.gpe1_base,
						     acpi_gbl_FADT.
						     sci_interrupt,
						     &acpi_gbl_gpe_fadt_blocks
						     [1]);

@@ -1173,7 +1176,7 @@ acpi_status acpi_ev_gpe_initialize(void)
			 * 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 +
			gpe_number_max = acpi_gbl_FADT.gpe1_base +
			    ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
		}
	}
+15 −4
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ static const char *acpi_notify_value_names[] = {
};
#endif

/* Pointer to FACS needed for the Global Lock */

static struct acpi_table_facs *facs = NULL;

/* Local prototypes */

static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
@@ -306,7 +310,7 @@ static u32 acpi_ev_global_lock_handler(void *context)
	 * 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);
	ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
	if (acquired) {

		/* Got the lock, now wake all threads waiting for it */
@@ -342,6 +346,13 @@ acpi_status acpi_ev_init_global_lock_handler(void)

	ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);

	status =
	    acpi_get_table(ACPI_SIG_FACS, 0,
			   (struct acpi_table_header **)&facs);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	acpi_gbl_global_lock_present = TRUE;
	status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
						  acpi_ev_global_lock_handler,
@@ -414,7 +425,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)

	/* Attempt to acquire the actual hardware lock */

	ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
	ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
	if (acquired) {

		/* We got the lock */
@@ -438,6 +449,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
	 */
	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
					       ACPI_WAIT_FOREVER);

	return_ACPI_STATUS(status);
}

@@ -472,8 +484,7 @@ acpi_status acpi_ev_release_global_lock(void)

		/* Allow any thread to release the lock */

		ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock,
					 pending);
		ACPI_RELEASE_GLOBAL_LOCK(facs, pending);

		/*
		 * If the pending bit was set, we must write GBL_RLS to the control
+7 −5
Original line number Diff line number Diff line
@@ -142,7 +142,8 @@ u32 acpi_ev_install_sci_handler(void)

	ACPI_FUNCTION_TRACE(ev_install_sci_handler);

	status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
	status =
	    acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
					      acpi_ev_sci_xrupt_handler,
					      acpi_gbl_gpe_xrupt_list_head);
	return_ACPI_STATUS(status);
@@ -175,7 +176,8 @@ acpi_status acpi_ev_remove_sci_handler(void)

	/* Just let the OS remove the handler and disable the level */

	status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
	status =
	    acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
					     acpi_ev_sci_xrupt_handler);

	return_ACPI_STATUS(status);
Loading