exprep.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
  4.  *              $Revision: 99 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acinterp.h"
  26. #include "amlcode.h"
  27. #include "acnamesp.h"
  28. #include "acparser.h"
  29. #define _COMPONENT          ACPI_EXECUTER
  30.  MODULE_NAME         ("exprep")
  31. /*******************************************************************************
  32.  *
  33.  * FUNCTION:    Acpi_ex_decode_field_access_type
  34.  *
  35.  * PARAMETERS:  Access          - Encoded field access bits
  36.  *              Length          - Field length.
  37.  *
  38.  * RETURN:      Field granularity (8, 16, 32 or 64)
  39.  *
  40.  * DESCRIPTION: Decode the Access_type bits of a field definition.
  41.  *
  42.  ******************************************************************************/
  43. static u32
  44. acpi_ex_decode_field_access_type (
  45. u32                     access,
  46. u16                     length,
  47. u32                     *alignment)
  48. {
  49. PROC_NAME ("Ex_decode_field_access_type");
  50. switch (access) {
  51. case ACCESS_ANY_ACC:
  52. *alignment = 8;
  53. /* Use the length to set the access type */
  54. if (length <= 8) {
  55. return (8);
  56. }
  57. else if (length <= 16) {
  58. return (16);
  59. }
  60. else if (length <= 32) {
  61. return (32);
  62. }
  63. else if (length <= 64) {
  64. return (64);
  65. }
  66. /* Default is 8 (byte) */
  67. return (8);
  68. break;
  69. case ACCESS_BYTE_ACC:
  70. *alignment = 8;
  71. return (8);
  72. break;
  73. case ACCESS_WORD_ACC:
  74. *alignment = 16;
  75. return (16);
  76. break;
  77. case ACCESS_DWORD_ACC:
  78. *alignment = 32;
  79. return (32);
  80. break;
  81. case ACCESS_QWORD_ACC:  /* ACPI 2.0 */
  82. *alignment = 64;
  83. return (64);
  84. break;
  85. default:
  86. /* Invalid field access type */
  87. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  88. "Unknown field access type %xn",
  89. access));
  90. return (0);
  91. }
  92. }
  93. /*******************************************************************************
  94.  *
  95.  * FUNCTION:    Acpi_ex_prep_common_field_object
  96.  *
  97.  * PARAMETERS:  Obj_desc            - The field object
  98.  *              Field_flags         - Access, Lock_rule, and Update_rule.
  99.  *                                    The format of a Field_flag is described
  100.  *                                    in the ACPI specification
  101.  *              Field_bit_position  - Field start position
  102.  *              Field_bit_length    - Field length in number of bits
  103.  *
  104.  * RETURN:      Status
  105.  *
  106.  * DESCRIPTION: Initialize the areas of the field object that are common
  107.  *              to the various types of fields.
  108.  *
  109.  ******************************************************************************/
  110. acpi_status
  111. acpi_ex_prep_common_field_object (
  112. acpi_operand_object     *obj_desc,
  113. u8                      field_flags,
  114. u32                     field_bit_position,
  115. u32                     field_bit_length)
  116. {
  117. u32                     access_bit_width;
  118. u32                     alignment;
  119. u32                     nearest_byte_address;
  120. FUNCTION_TRACE ("Ex_prep_common_field_object");
  121. /*
  122.  * Note: the structure being initialized is the
  123.  * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common area
  124.  * are initialized by this procedure.
  125.  */
  126. /* Demultiplex the Field_flags byte */
  127. obj_desc->common_field.lock_rule = (u8) ((field_flags & LOCK_RULE_MASK)
  128.  >> LOCK_RULE_SHIFT);
  129. obj_desc->common_field.update_rule = (u8) ((field_flags & UPDATE_RULE_MASK)
  130.  >> UPDATE_RULE_SHIFT);
  131. /* Other misc fields */
  132. obj_desc->common_field.bit_length = (u16) field_bit_length;
  133. /*
  134.  * Decode the access type so we can compute offsets.  The access type gives
  135.  * two pieces of information - the width of each field access and the
  136.  * necessary alignment of the access.  For Any_acc, the width used is the
  137.  * largest necessary/possible in an attempt to access the whole field in one
  138.  * I/O operation.  However, for Any_acc, the alignment is 8. For all other
  139.  * access types (Byte, Word, Dword, Qword), the width is the same as the
  140.  * alignment.
  141.  */
  142. access_bit_width = acpi_ex_decode_field_access_type (
  143.    ((field_flags & ACCESS_TYPE_MASK) >> ACCESS_TYPE_SHIFT),
  144.    obj_desc->field.bit_length, &alignment);
  145. if (!access_bit_width) {
  146. return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
  147. }
  148. /* Setup width (access granularity) fields */
  149. obj_desc->common_field.access_bit_width = (u8) access_bit_width;         /* 8, 16, 32, 64 */
  150. obj_desc->common_field.access_byte_width = (u8) DIV_8 (access_bit_width); /* 1, 2,  4,  8 */
  151. if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
  152. /*
  153.  * Buffer_field access can be on any byte boundary, so the
  154.  * alignment is always 8 (regardless of any alignment implied by the
  155.  * field access type.)
  156.  */
  157. alignment = 8;
  158. }
  159. /*
  160.  * Base_byte_offset is the address of the start of the field within the region. It is
  161.  * the byte address of the first *datum* (field-width data unit) of the field.
  162.  * (i.e., the first datum that contains at least the first *bit* of the field.)
  163.  */
  164. nearest_byte_address                      = ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
  165. obj_desc->common_field.base_byte_offset   = ROUND_DOWN (nearest_byte_address,
  166.    DIV_8 (alignment));
  167. /*
  168.  * Start_field_bit_offset is the offset of the first bit of the field within a field datum.
  169.  * This is calculated as the number of bits from the Base_byte_offset. In other words,
  170.  * the start of the field is relative to a byte address, regardless of the access type
  171.  * of the field.
  172.  */
  173. obj_desc->common_field.start_field_bit_offset = (u8) (MOD_8 (field_bit_position));
  174. /*
  175.  * Datum_valid_bits is the number of valid field bits in the first field datum.
  176.  */
  177. obj_desc->common_field.datum_valid_bits   = (u8) (access_bit_width -
  178.    obj_desc->common_field.start_field_bit_offset);
  179. /*
  180.  * Valid bits -- the number of bits that compose a partial datum,
  181.  * 1) At the end of the field within the region (arbitrary starting bit offset)
  182.  * 2) At the end of a buffer used to contain the field (starting offset always zero)
  183.  */
  184. obj_desc->common_field.end_field_valid_bits = (u8) ((obj_desc->common_field.start_field_bit_offset +
  185.    field_bit_length) % access_bit_width);
  186. obj_desc->common_field.end_buffer_valid_bits = (u8) (field_bit_length % access_bit_width); /* Start_buffer_bit_offset always = 0 */
  187. /*
  188.  * Does the entire field fit within a single field access element
  189.  * (datum)?  (without crossing a datum boundary)
  190.  */
  191. if ((obj_desc->common_field.start_field_bit_offset + obj_desc->common_field.bit_length) <=
  192. (u16) obj_desc->common_field.access_bit_width) {
  193. obj_desc->common_field.access_flags |= AFIELD_SINGLE_DATUM;
  194. }
  195. return_ACPI_STATUS (AE_OK);
  196. }
  197. /*******************************************************************************
  198.  *
  199.  * FUNCTION:    Acpi_ex_prep_field_value
  200.  *
  201.  * PARAMETERS:  Node                - Owning Node
  202.  *              Region_node         - Region in which field is being defined
  203.  *              Field_flags         - Access, Lock_rule, and Update_rule.
  204.  *              Field_bit_position  - Field start position
  205.  *              Field_bit_length    - Field length in number of bits
  206.  *
  207.  * RETURN:      Status
  208.  *
  209.  * DESCRIPTION: Construct an acpi_operand_object of type Def_field and
  210.  *              connect it to the parent Node.
  211.  *
  212.  ******************************************************************************/
  213. acpi_status
  214. acpi_ex_prep_field_value (
  215. ACPI_CREATE_FIELD_INFO  *info)
  216. {
  217. acpi_operand_object     *obj_desc;
  218. u32                     type;
  219. acpi_status             status;
  220. FUNCTION_TRACE ("Ex_prep_field_value");
  221. /* Parameter validation */
  222. if (info->field_type != INTERNAL_TYPE_INDEX_FIELD) {
  223. if (!info->region_node) {
  224. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Region_noden"));
  225. return_ACPI_STATUS (AE_AML_NO_OPERAND);
  226. }
  227. type = acpi_ns_get_type (info->region_node);
  228. if (type != ACPI_TYPE_REGION) {
  229. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %sn",
  230. type, acpi_ut_get_type_name (type)));
  231. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  232. }
  233. }
  234. /* Allocate a new region object */
  235. obj_desc = acpi_ut_create_internal_object (info->field_type);
  236. if (!obj_desc) {
  237. return_ACPI_STATUS (AE_NO_MEMORY);
  238. }
  239. /* Initialize areas of the object that are common to all fields */
  240. status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags,
  241.   info->field_bit_position, info->field_bit_length);
  242. if (ACPI_FAILURE (status)) {
  243. acpi_ut_delete_object_desc (obj_desc);
  244. return_ACPI_STATUS (status);
  245. }
  246. /* Initialize areas of the object that are specific to the field type */
  247. switch (info->field_type) {
  248. case INTERNAL_TYPE_REGION_FIELD:
  249. obj_desc->field.region_obj  = acpi_ns_get_attached_object (info->region_node);
  250. /* An additional reference for the container */
  251. acpi_ut_add_reference (obj_desc->field.region_obj);
  252. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Region_field: Bitoff=%X Off=%X Gran=%X Region %pn",
  253. obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset,
  254. obj_desc->field.access_bit_width, obj_desc->field.region_obj));
  255. break;
  256. case INTERNAL_TYPE_BANK_FIELD:
  257. obj_desc->bank_field.value         = info->bank_value;
  258. obj_desc->bank_field.region_obj    = acpi_ns_get_attached_object (info->region_node);
  259. obj_desc->bank_field.bank_register_obj = acpi_ns_get_attached_object (info->register_node);
  260. /* An additional reference for the attached objects */
  261. acpi_ut_add_reference (obj_desc->bank_field.region_obj);
  262. acpi_ut_add_reference (obj_desc->bank_field.bank_register_obj);
  263. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bank Field: Bit_off=%X Off=%X Gran=%X Region %p Bank_reg %pn",
  264. obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset,
  265. obj_desc->field.access_bit_width, obj_desc->bank_field.region_obj,
  266. obj_desc->bank_field.bank_register_obj));
  267. break;
  268. case INTERNAL_TYPE_INDEX_FIELD:
  269. obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node);
  270. obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node);
  271. obj_desc->index_field.value  = (u32) (info->field_bit_position /
  272.   obj_desc->field.access_bit_width);
  273. if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
  274. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Index Objectn"));
  275. return_ACPI_STATUS (AE_AML_INTERNAL);
  276. }
  277. /* An additional reference for the attached objects */
  278. acpi_ut_add_reference (obj_desc->index_field.data_obj);
  279. acpi_ut_add_reference (obj_desc->index_field.index_obj);
  280. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Index_field: bitoff=%X off=%X gran=%X Index %p Data %pn",
  281. obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset,
  282. obj_desc->field.access_bit_width, obj_desc->index_field.index_obj,
  283. obj_desc->index_field.data_obj));
  284. break;
  285. }
  286. /*
  287.  * Store the constructed descriptor (Obj_desc) into the parent Node,
  288.  * preserving the current type of that Named_obj.
  289.  */
  290. status = acpi_ns_attach_object (info->field_node, obj_desc,
  291.   (u8) acpi_ns_get_type (info->field_node));
  292. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "set Named_obj %p (%4.4s) val = %pn",
  293. info->field_node, (char*)&(info->field_node->name), obj_desc));
  294. /* Remove local reference to the object */
  295. acpi_ut_remove_reference (obj_desc);
  296. return_ACPI_STATUS (status);
  297. }