⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evgpeblk.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		status = AE_NO_MEMORY;		goto error_exit;	}	/* Save the new Info arrays in the GPE block */	gpe_block->register_info = gpe_register_info;	gpe_block->event_info  = gpe_event_info;	/*	 * 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,	 * and the enable registers occupy the second half.	 */	this_register = gpe_register_info;	this_event   = gpe_event_info;	for (i = 0; i < gpe_block->register_count; i++) {		/* Init the register_info for this GPE register (8 GPEs) */		this_register->base_gpe_number = (u8) (gpe_block->block_base_number +				   (i * ACPI_GPE_REGISTER_WIDTH));		ACPI_STORE_ADDRESS (this_register->status_address.address,				 (gpe_block->block_address.address				 + i));		ACPI_STORE_ADDRESS (this_register->enable_address.address,				 (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 = ACPI_GPE_REGISTER_WIDTH;		this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;		this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;		this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;		/* Init the event_info for each GPE within this register */		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {			this_event->register_bit = acpi_gbl_decode_to8bit[j];			this_event->register_info = this_register;			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'.		 */		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,				 &this_register->enable_address);		if (ACPI_FAILURE (status)) {			goto error_exit;		}		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,				 &this_register->status_address);		if (ACPI_FAILURE (status)) {			goto error_exit;		}		this_register++;	}	return_ACPI_STATUS (AE_OK);error_exit:	if (gpe_register_info) {		ACPI_MEM_FREE (gpe_register_info);	}	if (gpe_event_info) {		ACPI_MEM_FREE (gpe_event_info);	}	return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION:    acpi_ev_create_gpe_block * * PARAMETERS:  gpe_device          - Handle to the parent GPE block *              gpe_block_address   - Address and space_iD *              register_count      - Number of GPE register pairs in the block *              gpe_block_base_number - Starting GPE number for the block *              interrupt_level     - H/W interrupt for the block *              return_gpe_block    - Where the new block descriptor is returned * * RETURN:      Status * * DESCRIPTION: Create and Install a block of GPE registers * ******************************************************************************/acpi_statusacpi_ev_create_gpe_block (	struct acpi_namespace_node      *gpe_device,	struct acpi_generic_address     *gpe_block_address,	u32                             register_count,	u8                              gpe_block_base_number,	u32                             interrupt_level,	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;	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");	if (!register_count) {		return_ACPI_STATUS (AE_OK);	}	/* Allocate a new GPE block */	gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));	if (!gpe_block) {		return_ACPI_STATUS (AE_NO_MEMORY);	}	/* Initialize the new GPE block */	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 */	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) */	status = acpi_ev_install_gpe_block (gpe_block, interrupt_level);	if (ACPI_FAILURE (status)) {		ACPI_MEM_FREE (gpe_block);		return_ACPI_STATUS (status);	}	/* Find all GPE methods (_Lxx, _Exx) for this block */	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,			  ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info,			  gpe_block, NULL);	/*	 * 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.)		 */		gpe_info.gpe_block = gpe_block;		gpe_info.gpe_device = gpe_device;		status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,				  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe,				  &gpe_info, NULL);	}	/*	 * 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.	 */	wake_gpe_count = 0;	gpe_enabled_count = 0;	for (i = 0; i < gpe_block->register_count; i++) {		for (j = 0; j < 8; j++) {			/* Get the info block for this particular GPE */			gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&				 (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {				gpe_enabled_count++;			}			if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {				wake_gpe_count++;			}		}	}	/* 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_level));	/* 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 */	if (return_gpe_block) {		(*return_gpe_block) = gpe_block;	}	return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ev_gpe_initialize * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Initialize the GPE data structures * ******************************************************************************/acpi_statusacpi_ev_gpe_initialize (	void){	u32                             register_count0 = 0;	u32                             register_count1 = 0;	u32                             gpe_number_max = 0;	acpi_status                     status;	ACPI_FUNCTION_TRACE ("ev_gpe_initialize");	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);	if (ACPI_FAILURE (status)) {		return_ACPI_STATUS (status);	}	/*	 * Initialize the GPE Block(s) 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 (acpi_gbl_fadt_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 (acpi_gbl_fadt_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_DEBUG_PRINT ((ACPI_DB_INIT,				"There are no GPE blocks defined in the FADT\n"));		status = AE_OK;		goto cleanup;	}	/* 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));		status = AE_BAD_VALUE;		goto cleanup;	}cleanup:	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);	return_ACPI_STATUS (AE_OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -