📄 exprep.c
字号:
/****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities * *****************************************************************************//* * Copyright (C) 2000 - 2005, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */#include <acpi/acpi.h>#include <acpi/acinterp.h>#include <acpi/amlcode.h>#include <acpi/acnamesp.h>#define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME ("exprep")#ifdef ACPI_UNDER_DEVELOPMENT/******************************************************************************* * * FUNCTION: acpi_ex_generate_access * * PARAMETERS: field_bit_offset - Start of field within parent region/buffer * field_bit_length - Length of field in bits * region_length - Length of parent in bytes * * RETURN: Field granularity (8, 16, 32 or 64) and * byte_alignment (1, 2, 3, or 4) * * DESCRIPTION: Generate an optimal access width for fields defined with the * any_acc keyword. * * NOTE: Need to have the region_length in order to check for boundary * conditions (end-of-region). However, the region_length is a deferred * operation. Therefore, to complete this implementation, the generation * of this access width must be deferred until the region length has * been evaluated. * ******************************************************************************/static u32acpi_ex_generate_access ( u32 field_bit_offset, u32 field_bit_length, u32 region_length){ u32 field_byte_length; u32 field_byte_offset; u32 field_byte_end_offset; u32 access_byte_width; u32 field_start_offset; u32 field_end_offset; u32 minimum_access_width = 0xFFFFFFFF; u32 minimum_accesses = 0xFFFFFFFF; u32 accesses; ACPI_FUNCTION_TRACE ("ex_generate_access"); /* Round Field start offset and length to "minimal" byte boundaries */ field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8)); field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8)); field_byte_length = field_byte_end_offset - field_byte_offset; ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Bit length %d, Bit offset %d\n", field_bit_length, field_bit_offset)); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Byte Length %d, Byte Offset %d, End Offset %d\n", field_byte_length, field_byte_offset, field_byte_end_offset)); /* * Iterative search for the maximum access width that is both aligned * and does not go beyond the end of the region * * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes) */ for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) { /* * 1) Round end offset up to next access boundary and make sure that this * does not go beyond the end of the parent region. * 2) When the Access width is greater than the field_byte_length, we are done. * (This does not optimize for the perfectly aligned case yet). */ if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) { field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) / access_byte_width; field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset), access_byte_width) / access_byte_width; accesses = field_end_offset - field_start_offset; ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "access_width %d end is within region\n", access_byte_width)); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Field Start %d, Field End %d -- requires %d accesses\n", field_start_offset, field_end_offset, accesses)); /* Single access is optimal */ if (accesses <= 1) { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Entire field can be accessed with one operation of size %d\n", access_byte_width)); return_VALUE (access_byte_width); } /* * Fits in the region, but requires more than one read/write. * try the next wider access on next iteration */ if (accesses < minimum_accesses) { minimum_accesses = accesses; minimum_access_width = access_byte_width; } } else { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "access_width %d end is NOT within region\n", access_byte_width)); if (access_byte_width == 1) { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Field goes beyond end-of-region!\n")); return_VALUE (0); /* Field does not fit in the region at all */ } /* This width goes beyond the end-of-region, back off to previous access */ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Backing off to previous optimal access width of %d\n", minimum_access_width)); return_VALUE (minimum_access_width); } } /* Could not read/write field with one operation, just use max access width */ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Cannot access field in one operation, using width 8\n")); return_VALUE (8);}#endif /* ACPI_UNDER_DEVELOPMENT *//******************************************************************************* * * FUNCTION: acpi_ex_decode_field_access * * PARAMETERS: Access - Encoded field access bits * Length - Field length. * * RETURN: Field granularity (8, 16, 32 or 64) and * byte_alignment (1, 2, 3, or 4) * * DESCRIPTION: Decode the access_type bits of a field definition. * ******************************************************************************/static u32acpi_ex_decode_field_access ( union acpi_operand_object *obj_desc, u8 field_flags, u32 *return_byte_alignment){ u32 access; u32 byte_alignment; u32 bit_length; ACPI_FUNCTION_TRACE ("ex_decode_field_access"); access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK); switch (access) { case AML_FIELD_ACCESS_ANY:#ifdef ACPI_UNDER_DEVELOPMENT byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.bit_length, 0xFFFFFFFF /* Temp until we pass region_length as param */); bit_length = byte_alignment * 8;#endif byte_alignment = 1; bit_length = 8; break; case AML_FIELD_ACCESS_BYTE: case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ byte_alignment = 1; bit_length = 8; break; case AML_FIELD_ACCESS_WORD: byte_alignment = 2; bit_length = 16; break; case AML_FIELD_ACCESS_DWORD: byte_alignment = 4; bit_length = 32; break; case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ byte_alignment = 8; bit_length = 64; break; default: /* Invalid field access type */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown field access type %X\n", access)); return_VALUE (0); } if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { /* * buffer_field access can be on any byte boundary, so the * byte_alignment is always 1 byte -- regardless of any byte_alignment * implied by the field access type. */ byte_alignment = 1; } *return_byte_alignment = byte_alignment;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -