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

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dsfield - Dispatcher field routines
  4.  *              $Revision: 46 $
  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 "amlcode.h"
  26. #include "acdispat.h"
  27. #include "acinterp.h"
  28. #include "acnamesp.h"
  29. #include "acparser.h"
  30. #define _COMPONENT          ACPI_DISPATCHER
  31.  MODULE_NAME         ("dsfield")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_ds_create_buffer_field
  35.  *
  36.  * PARAMETERS:  Opcode              - The opcode to be executed
  37.  *              Operands            - List of operands for the opcode
  38.  *              Walk_state          - Current state
  39.  *
  40.  * RETURN:      Status
  41.  *
  42.  * DESCRIPTION: Execute the Create_field operators:
  43.  *              Create_bit_field_op,
  44.  *              Create_byte_field_op,
  45.  *              Create_word_field_op,
  46.  *              Create_dWord_field_op,
  47.  *              Create_qWord_field_op,
  48.  *              Create_field_op     (all of which define fields in buffers)
  49.  *
  50.  ******************************************************************************/
  51. acpi_status
  52. acpi_ds_create_buffer_field (
  53. acpi_parse_object       *op,
  54. acpi_walk_state         *walk_state)
  55. {
  56. acpi_parse_object       *arg;
  57. acpi_namespace_node     *node;
  58. acpi_status             status;
  59. acpi_operand_object     *obj_desc;
  60. FUNCTION_TRACE ("Ds_create_buffer_field");
  61. /* Get the Name_string argument */
  62. if (op->opcode == AML_CREATE_FIELD_OP) {
  63. arg = acpi_ps_get_arg (op, 3);
  64. }
  65. else {
  66. /* Create Bit/Byte/Word/Dword field */
  67. arg = acpi_ps_get_arg (op, 2);
  68. }
  69. if (!arg) {
  70. return_ACPI_STATUS (AE_AML_NO_OPERAND);
  71. }
  72. /*
  73.  * Enter the Name_string into the namespace
  74.  */
  75. status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
  76.  INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1,
  77.  NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
  78.  walk_state, &(node));
  79. if (ACPI_FAILURE (status)) {
  80. return_ACPI_STATUS (status);
  81. }
  82. /* We could put the returned object (Node) on the object stack for later, but
  83.  * for now, we will put it in the "op" object that the parser uses, so we
  84.  * can get it again at the end of this scope
  85.  */
  86. op->node = node;
  87. /*
  88.  * If there is no object attached to the node, this node was just created and
  89.  * we need to create the field object.  Otherwise, this was a lookup of an
  90.  * existing node and we don't want to create the field object again.
  91.  */
  92. if (node->object) {
  93. return_ACPI_STATUS (AE_OK);
  94. }
  95. /*
  96.  * The Field definition is not fully parsed at this time.
  97.  * (We must save the address of the AML for the buffer and index operands)
  98.  */
  99. /* Create the buffer field object */
  100. obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD);
  101. if (!obj_desc) {
  102. status = AE_NO_MEMORY;
  103. goto cleanup;
  104. }
  105. /*
  106.  * Allocate a method object for this field unit
  107.  */
  108. obj_desc->buffer_field.extra = acpi_ut_create_internal_object (
  109.    INTERNAL_TYPE_EXTRA);
  110. if (!obj_desc->buffer_field.extra) {
  111. status = AE_NO_MEMORY;
  112. goto cleanup;
  113. }
  114. /*
  115.  * Remember location in AML stream of the field unit
  116.  * opcode and operands -- since the buffer and index
  117.  * operands must be evaluated.
  118.  */
  119. obj_desc->buffer_field.extra->extra.aml_start = ((acpi_parse2_object *) op)->data;
  120. obj_desc->buffer_field.extra->extra.aml_length = ((acpi_parse2_object *) op)->length;
  121. obj_desc->buffer_field.node = node;
  122. /* Attach constructed field descriptor to parent node */
  123. status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
  124. cleanup:
  125. /* Remove local reference to the object */
  126. acpi_ut_remove_reference (obj_desc);
  127. return_ACPI_STATUS (status);
  128. }
  129. /*******************************************************************************
  130.  *
  131.  * FUNCTION:    Acpi_ds_get_field_names
  132.  *
  133.  * PARAMETERS:  Info            - Create_field info structure
  134.  *  `           Walk_state      - Current method state
  135.  *              Arg             - First parser arg for the field name list
  136.  *
  137.  * RETURN:      Status
  138.  *
  139.  * DESCRIPTION: Process all named fields in a field declaration.  Names are
  140.  *              entered into the namespace.
  141.  *
  142.  ******************************************************************************/
  143. acpi_status
  144. acpi_ds_get_field_names (
  145. ACPI_CREATE_FIELD_INFO  *info,
  146. acpi_walk_state         *walk_state,
  147. acpi_parse_object       *arg)
  148. {
  149. acpi_status             status;
  150. FUNCTION_TRACE_U32 ("Ds_get_field_names", info);
  151. /* First field starts at bit zero */
  152. info->field_bit_position = 0;
  153. /* Process all elements in the field list (of parse nodes) */
  154. while (arg) {
  155. /*
  156.  * Three types of field elements are handled:
  157.  * 1) Offset - specifies a bit offset
  158.  * 2) Access_as - changes the access mode
  159.  * 3) Name - Enters a new named field into the namespace
  160.  */
  161. switch (arg->opcode) {
  162. case AML_INT_RESERVEDFIELD_OP:
  163. info->field_bit_position += arg->value.size;
  164. break;
  165. case AML_INT_ACCESSFIELD_OP:
  166. /*
  167.  * Get a new Access_type and Access_attribute for all
  168.  * entries (until end or another Access_as keyword)
  169.  */
  170. info->field_flags = (u8) ((info->field_flags & FIELD_ACCESS_TYPE_MASK) ||
  171.   ((u8) (arg->value.integer >> 8)));
  172. break;
  173. case AML_INT_NAMEDFIELD_OP:
  174. /* Enter a new field name into the namespace */
  175. status = acpi_ns_lookup (walk_state->scope_info,
  176.   (NATIVE_CHAR *) &((acpi_parse2_object *)arg)->name,
  177.   info->field_type, IMODE_LOAD_PASS1,
  178.   NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
  179.   NULL, &info->field_node);
  180. if (ACPI_FAILURE (status)) {
  181. return_ACPI_STATUS (status);
  182. }
  183. /* Create and initialize an object for the new Field Node */
  184. info->field_bit_length = arg->value.size;
  185. status = acpi_ex_prep_field_value (info);
  186. if (ACPI_FAILURE (status)) {
  187. return_ACPI_STATUS (status);
  188. }
  189. /* Keep track of bit position for the next field */
  190. info->field_bit_position += info->field_bit_length;
  191. break;
  192. default:
  193. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %Xn",
  194. arg->opcode));
  195. return_ACPI_STATUS (AE_AML_ERROR);
  196. break;
  197. }
  198. arg = arg->next;
  199. }
  200. return_ACPI_STATUS (AE_OK);
  201. }
  202. /*******************************************************************************
  203.  *
  204.  * FUNCTION:    Acpi_ds_create_field
  205.  *
  206.  * PARAMETERS:  Op              - Op containing the Field definition and args
  207.  *              Region_node     - Object for the containing Operation Region
  208.  *  `           Walk_state      - Current method state
  209.  *
  210.  * RETURN:      Status
  211.  *
  212.  * DESCRIPTION: Create a new field in the specified operation region
  213.  *
  214.  ******************************************************************************/
  215. acpi_status
  216. acpi_ds_create_field (
  217. acpi_parse_object       *op,
  218. acpi_namespace_node     *region_node,
  219. acpi_walk_state         *walk_state)
  220. {
  221. acpi_status             status = AE_AML_ERROR;
  222. acpi_parse_object       *arg;
  223. ACPI_CREATE_FIELD_INFO  info;
  224. FUNCTION_TRACE_PTR ("Ds_create_field", op);
  225. /* First arg is the name of the parent Op_region (must already exist) */
  226. arg = op->value.arg;
  227. if (!region_node) {
  228. status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
  229.   ACPI_TYPE_REGION, IMODE_EXECUTE,
  230.   NS_SEARCH_PARENT, walk_state, &region_node);
  231. if (ACPI_FAILURE (status)) {
  232. return_ACPI_STATUS (status);
  233. }
  234. }
  235. /* Second arg is the field flags */
  236. arg = arg->next;
  237. info.field_flags = arg->value.integer8;
  238. /* Each remaining arg is a Named Field */
  239. info.field_type = INTERNAL_TYPE_REGION_FIELD;
  240. info.region_node = region_node;
  241. status = acpi_ds_get_field_names (&info, walk_state, arg->next);
  242. return_ACPI_STATUS (status);
  243. }
  244. /*******************************************************************************
  245.  *
  246.  * FUNCTION:    Acpi_ds_create_bank_field
  247.  *
  248.  * PARAMETERS:  Op              - Op containing the Field definition and args
  249.  *              Region_node     - Object for the containing Operation Region
  250.  *  `           Walk_state      - Current method state
  251.  *
  252.  * RETURN:      Status
  253.  *
  254.  * DESCRIPTION: Create a new bank field in the specified operation region
  255.  *
  256.  ******************************************************************************/
  257. acpi_status
  258. acpi_ds_create_bank_field (
  259. acpi_parse_object       *op,
  260. acpi_namespace_node     *region_node,
  261. acpi_walk_state         *walk_state)
  262. {
  263. acpi_status             status = AE_AML_ERROR;
  264. acpi_parse_object       *arg;
  265. ACPI_CREATE_FIELD_INFO  info;
  266. FUNCTION_TRACE_PTR ("Ds_create_bank_field", op);
  267. /* First arg is the name of the parent Op_region (must already exist) */
  268. arg = op->value.arg;
  269. if (!region_node) {
  270. status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
  271.   ACPI_TYPE_REGION, IMODE_EXECUTE,
  272.   NS_SEARCH_PARENT, walk_state, &region_node);
  273. if (ACPI_FAILURE (status)) {
  274. return_ACPI_STATUS (status);
  275. }
  276. }
  277. /* Second arg is the Bank Register (must already exist) */
  278. arg = arg->next;
  279. status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
  280.   INTERNAL_TYPE_BANK_FIELD_DEFN, IMODE_EXECUTE,
  281.   NS_SEARCH_PARENT, walk_state, &info.register_node);
  282. if (ACPI_FAILURE (status)) {
  283. return_ACPI_STATUS (status);
  284. }
  285. /* Third arg is the Bank_value */
  286. arg = arg->next;
  287. info.bank_value = arg->value.integer32;
  288. /* Fourth arg is the field flags */
  289. arg = arg->next;
  290. info.field_flags = arg->value.integer8;
  291. /* Each remaining arg is a Named Field */
  292. info.field_type = INTERNAL_TYPE_BANK_FIELD;
  293. info.region_node = region_node;
  294. status = acpi_ds_get_field_names (&info, walk_state, arg->next);
  295. return_ACPI_STATUS (status);
  296. }
  297. /*******************************************************************************
  298.  *
  299.  * FUNCTION:    Acpi_ds_create_index_field
  300.  *
  301.  * PARAMETERS:  Op              - Op containing the Field definition and args
  302.  *              Region_node     - Object for the containing Operation Region
  303.  *  `           Walk_state      - Current method state
  304.  *
  305.  * RETURN:      Status
  306.  *
  307.  * DESCRIPTION: Create a new index field in the specified operation region
  308.  *
  309.  ******************************************************************************/
  310. acpi_status
  311. acpi_ds_create_index_field (
  312. acpi_parse_object       *op,
  313. acpi_namespace_node     *region_node,
  314. acpi_walk_state         *walk_state)
  315. {
  316. acpi_status             status;
  317. acpi_parse_object       *arg;
  318. ACPI_CREATE_FIELD_INFO  info;
  319. FUNCTION_TRACE_PTR ("Ds_create_index_field", op);
  320. /* First arg is the name of the Index register (must already exist) */
  321. arg = op->value.arg;
  322. status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
  323.   ACPI_TYPE_ANY, IMODE_EXECUTE,
  324.   NS_SEARCH_PARENT, walk_state, &info.register_node);
  325. if (ACPI_FAILURE (status)) {
  326. return_ACPI_STATUS (status);
  327. }
  328. /* Second arg is the data register (must already exist) */
  329. arg = arg->next;
  330. status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
  331.   INTERNAL_TYPE_INDEX_FIELD_DEFN, IMODE_EXECUTE,
  332.   NS_SEARCH_PARENT, walk_state, &info.data_register_node);
  333. if (ACPI_FAILURE (status)) {
  334. return_ACPI_STATUS (status);
  335. }
  336. /* Next arg is the field flags */
  337. arg = arg->next;
  338. info.field_flags = arg->value.integer8;
  339. /* Each remaining arg is a Named Field */
  340. info.field_type = INTERNAL_TYPE_INDEX_FIELD;
  341. info.region_node = region_node;
  342. status = acpi_ds_get_field_names (&info, walk_state, arg->next);
  343. return_ACPI_STATUS (status);
  344. }