1 /******************************************************************************
3 * Module Name: amcreate - Named object creation
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #define _COMPONENT ACPI_EXECUTER
31 MODULE_NAME ("amcreate")
34 /*******************************************************************************
36 * FUNCTION: Acpi_aml_exec_create_field
38 * PARAMETERS: Opcode - The opcode to be executed
39 * Operands - List of operands for the opcode
43 * DESCRIPTION: Execute Create_field operators: Create_bit_field_op,
44 * Create_byte_field_op, Create_word_field_op, Create_dWord_field_op,
45 * Create_field_op (which define fields in buffers)
47 * ALLOCATION: Deletes Create_field_op's count operand descriptor
50 * ACPI SPECIFICATION REFERENCES:
51 * Def_create_bit_field := Create_bit_field_op Src_buf Bit_idx Name_string
52 * Def_create_byte_field := Create_byte_field_op Src_buf Byte_idx Name_string
53 * Def_create_dWord_field := Create_dWord_field_op Src_buf Byte_idx Name_string
54 * Def_create_field := Create_field_op Src_buf Bit_idx Num_bits Name_string
55 * Def_create_word_field := Create_word_field_op Src_buf Byte_idx Name_string
56 * Bit_index := Term_arg=>Integer
57 * Byte_index := Term_arg=>Integer
58 * Num_bits := Term_arg=>Integer
59 * Source_buff := Term_arg=>Buffer
61 ******************************************************************************/
65 acpi_aml_exec_create_field (
68 ACPI_NAMESPACE_NODE
*node
,
69 ACPI_WALK_STATE
*walk_state
)
72 ACPI_OPERAND_OBJECT
*obj_desc
;
73 ACPI_OPERAND_OBJECT
*tmp_desc
;
76 /* Create the region descriptor */
78 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT
);
80 status
= AE_NO_MEMORY
;
84 /* Construct the field object */
86 obj_desc
->field_unit
.access
= (u8
) ACCESS_ANY_ACC
;
87 obj_desc
->field_unit
.lock_rule
= (u8
) GLOCK_NEVER_LOCK
;
88 obj_desc
->field_unit
.update_rule
= (u8
) UPDATE_PRESERVE
;
91 * Allocate a method object for this field unit
94 obj_desc
->field_unit
.extra
= acpi_cm_create_internal_object (
96 if (!obj_desc
->field_unit
.extra
) {
97 status
= AE_NO_MEMORY
;
102 * Remember location in AML stream of the field unit
103 * opcode and operands -- since the buffer and index
104 * operands must be evaluated.
107 obj_desc
->field_unit
.extra
->extra
.pcode
= aml_ptr
;
108 obj_desc
->field_unit
.extra
->extra
.pcode_length
= aml_length
;
109 obj_desc
->field_unit
.node
= node
;
113 * This operation is supposed to cause the destination Name to refer
114 * to the defined Field_unit -- it must not store the constructed
115 * Field_unit object (or its current value) in some location that the
116 * Name may already be pointing to. So, if the Name currently contains
117 * a reference which would cause Acpi_aml_exec_store() to perform an indirect
118 * store rather than setting the value of the Name itself, clobber that
119 * reference before calling Acpi_aml_exec_store().
122 /* Type of Name's existing value */
124 switch (acpi_ns_get_type (node
)) {
126 case ACPI_TYPE_FIELD_UNIT
:
128 case INTERNAL_TYPE_ALIAS
:
129 case INTERNAL_TYPE_BANK_FIELD
:
130 case INTERNAL_TYPE_DEF_FIELD
:
131 case INTERNAL_TYPE_INDEX_FIELD
:
133 tmp_desc
= acpi_ns_get_attached_object (node
);
136 * There is an existing object here; delete it and zero out the
137 * object field within the Node
140 acpi_cm_remove_reference (tmp_desc
);
141 acpi_ns_attach_object ((ACPI_NAMESPACE_NODE
*) node
, NULL
,
145 /* Set the type to ANY (or the store below will fail) */
147 ((ACPI_NAMESPACE_NODE
*) node
)->type
= ACPI_TYPE_ANY
;
158 /* Store constructed field descriptor in result location */
160 status
= acpi_aml_exec_store (obj_desc
, (ACPI_OPERAND_OBJECT
*) node
, walk_state
);
163 * If the field descriptor was not physically stored (or if a failure
164 * above), we must delete it
166 if (obj_desc
->common
.reference_count
<= 1) {
167 acpi_cm_remove_reference (obj_desc
);
176 /* Delete region object and method subobject */
179 /* Remove deletes both objects! */
181 acpi_cm_remove_reference (obj_desc
);
189 /*****************************************************************************
191 * FUNCTION: Acpi_aml_exec_create_alias
193 * PARAMETERS: Operands - List of operands for the opcode
197 * DESCRIPTION: Create a new named alias
199 ****************************************************************************/
202 acpi_aml_exec_create_alias (
203 ACPI_WALK_STATE
*walk_state
)
205 ACPI_NAMESPACE_NODE
*source_node
;
206 ACPI_NAMESPACE_NODE
*alias_node
;
210 /* Get the source/alias operands (both NTEs) */
212 status
= acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT
**) &source_node
,
214 if (ACPI_FAILURE (status
)) {
219 * Don't pop it, it gets removed in the calling routine
222 alias_node
= acpi_ds_obj_stack_get_value (0, walk_state
);
224 /* Add an additional reference to the object */
226 acpi_cm_add_reference (source_node
->object
);
229 * Attach the original source Node to the new Alias Node.
231 status
= acpi_ns_attach_object (alias_node
, source_node
->object
,
236 * The new alias assumes the type of the source, but it points
237 * to the same object. The reference count of the object has two
238 * additional references to prevent deletion out from under either the
239 * source or the alias Node
242 /* Since both operands are NTEs, we don't need to delete them */
248 /*****************************************************************************
250 * FUNCTION: Acpi_aml_exec_create_event
256 * DESCRIPTION: Create a new event object
258 ****************************************************************************/
261 acpi_aml_exec_create_event (
262 ACPI_WALK_STATE
*walk_state
)
265 ACPI_OPERAND_OBJECT
*obj_desc
;
270 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_EVENT
);
272 status
= AE_NO_MEMORY
;
276 /* Create the actual OS semaphore */
278 /* TBD: [Investigate] should be created with 0 or 1 units? */
280 status
= acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT
, 1,
281 &obj_desc
->event
.semaphore
);
282 if (ACPI_FAILURE (status
)) {
283 acpi_cm_remove_reference (obj_desc
);
287 /* Attach object to the Node */
289 status
= acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state
),
290 obj_desc
, (u8
) ACPI_TYPE_EVENT
);
291 if (ACPI_FAILURE (status
)) {
292 acpi_os_delete_semaphore (obj_desc
->event
.semaphore
);
293 acpi_cm_remove_reference (obj_desc
);
304 /*****************************************************************************
306 * FUNCTION: Acpi_aml_exec_create_mutex
308 * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec)
309 * Operands - List of operands for the opcode
313 * DESCRIPTION: Create a new mutex object
315 ****************************************************************************/
318 acpi_aml_exec_create_mutex (
319 ACPI_WALK_STATE
*walk_state
)
321 ACPI_STATUS status
= AE_OK
;
322 ACPI_OPERAND_OBJECT
*sync_desc
;
323 ACPI_OPERAND_OBJECT
*obj_desc
;
326 /* Get the operand */
328 status
= acpi_ds_obj_stack_pop_object (&sync_desc
, walk_state
);
329 if (ACPI_FAILURE (status
)) {
333 /* Attempt to allocate a new object */
335 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_MUTEX
);
337 status
= AE_NO_MEMORY
;
341 /* Create the actual OS semaphore */
343 status
= acpi_os_create_semaphore (1, 1, &obj_desc
->mutex
.semaphore
);
344 if (ACPI_FAILURE (status
)) {
345 acpi_cm_remove_reference (obj_desc
);
349 obj_desc
->mutex
.sync_level
= (u8
) sync_desc
->integer
.value
;
351 /* Obj_desc was on the stack top, and the name is below it */
353 status
= acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state
),
354 obj_desc
, (u8
) ACPI_TYPE_MUTEX
);
355 if (ACPI_FAILURE (status
)) {
356 acpi_os_delete_semaphore (obj_desc
->mutex
.semaphore
);
357 acpi_cm_remove_reference (obj_desc
);
364 /* Always delete the operand */
366 acpi_cm_remove_reference (sync_desc
);
372 /*****************************************************************************
374 * FUNCTION: Acpi_aml_exec_create_region
376 * PARAMETERS: Aml_ptr - Pointer to the region declaration AML
377 * Aml_length - Max length of the declaration AML
378 * Operands - List of operands for the opcode
379 * Interpreter_mode - Load1/Load2/Execute
383 * DESCRIPTION: Create a new operation region object
385 ****************************************************************************/
388 acpi_aml_exec_create_region (
392 ACPI_WALK_STATE
*walk_state
)
395 ACPI_OPERAND_OBJECT
*obj_desc
;
396 ACPI_NAMESPACE_NODE
*node
;
400 * Space ID must be one of the predefined IDs, or in the user-defined
403 if ((region_space
>= NUM_REGION_TYPES
) &&
404 (region_space
< USER_REGION_BEGIN
)) {
405 REPORT_ERROR (("Invalid Address_space type %X\n", region_space
));
406 return (AE_AML_INVALID_SPACE_ID
);
410 /* Get the Node from the object stack */
412 node
= (ACPI_NAMESPACE_NODE
*) acpi_ds_obj_stack_get_value (0, walk_state
);
414 /* Create the region descriptor */
416 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_REGION
);
418 status
= AE_NO_MEMORY
;
423 * Allocate a method object for this region.
426 obj_desc
->region
.extra
= acpi_cm_create_internal_object (
427 INTERNAL_TYPE_EXTRA
);
428 if (!obj_desc
->region
.extra
) {
429 status
= AE_NO_MEMORY
;
434 * Remember location in AML stream of address & length
435 * operands since they need to be evaluated at run time.
438 obj_desc
->region
.extra
->extra
.pcode
= aml_ptr
;
439 obj_desc
->region
.extra
->extra
.pcode_length
= aml_length
;
441 /* Init the region from the operands */
443 obj_desc
->region
.space_id
= region_space
;
444 obj_desc
->region
.address
= 0;
445 obj_desc
->region
.length
= 0;
448 /* Install the new region object in the parent Node */
450 obj_desc
->region
.node
= node
;
452 status
= acpi_ns_attach_object (node
, obj_desc
,
453 (u8
) ACPI_TYPE_REGION
);
455 if (ACPI_FAILURE (status
)) {
460 * If we have a valid region, initialize it
461 * Namespace is NOT locked at this point.
464 status
= acpi_ev_initialize_region (obj_desc
, FALSE
);
466 if (ACPI_FAILURE (status
)) {
468 * If AE_NOT_EXIST is returned, it is not fatal
469 * because many regions get created before a handler
470 * is installed for said region.
472 if (AE_NOT_EXIST
== status
) {
479 if (ACPI_FAILURE (status
)) {
480 /* Delete region object and method subobject */
483 /* Remove deletes both objects! */
485 acpi_cm_remove_reference (obj_desc
);
494 /*****************************************************************************
496 * FUNCTION: Acpi_aml_exec_create_processor
498 * PARAMETERS: Op - Op containing the Processor definition and
500 * Processor_nTE - Node for the containing Node
504 * DESCRIPTION: Create a new processor object and populate the fields
506 ****************************************************************************/
509 acpi_aml_exec_create_processor (
510 ACPI_PARSE_OBJECT
*op
,
511 ACPI_HANDLE processor_nTE
)
514 ACPI_PARSE_OBJECT
*arg
;
515 ACPI_OPERAND_OBJECT
*obj_desc
;
518 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_PROCESSOR
);
520 status
= AE_NO_MEMORY
;
524 /* Install the new processor object in the parent Node */
526 status
= acpi_ns_attach_object (processor_nTE
, obj_desc
,
527 (u8
) ACPI_TYPE_PROCESSOR
);
528 if (ACPI_FAILURE (status
)) {
534 /* check existence */
537 status
= AE_AML_NO_OPERAND
;
541 /* First arg is the Processor ID */
543 obj_desc
->processor
.proc_id
= (u8
) arg
->value
.integer
;
545 /* Move to next arg and check existence */
549 status
= AE_AML_NO_OPERAND
;
553 /* Second arg is the PBlock Address */
555 obj_desc
->processor
.address
= (ACPI_IO_ADDRESS
) arg
->value
.integer
;
557 /* Move to next arg and check existence */
561 status
= AE_AML_NO_OPERAND
;
565 /* Third arg is the PBlock Length */
567 obj_desc
->processor
.length
= (u8
) arg
->value
.integer
;
573 /*****************************************************************************
575 * FUNCTION: Acpi_aml_exec_create_power_resource
577 * PARAMETERS: Op - Op containing the Power_resource definition
579 * Power_res_nTE - Node for the containing Node
583 * DESCRIPTION: Create a new Power_resource object and populate the fields
585 ****************************************************************************/
588 acpi_aml_exec_create_power_resource (
589 ACPI_PARSE_OBJECT
*op
,
590 ACPI_HANDLE power_res_nTE
)
593 ACPI_PARSE_OBJECT
*arg
;
594 ACPI_OPERAND_OBJECT
*obj_desc
;
597 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_POWER
);
599 status
= AE_NO_MEMORY
;
603 /* Install the new power resource object in the parent Node */
605 status
= acpi_ns_attach_object (power_res_nTE
, obj_desc
,
606 (u8
) ACPI_TYPE_POWER
);
607 if (ACPI_FAILURE (status
)) {
613 /* check existence */
616 status
= AE_AML_NO_OPERAND
;
620 /* First arg is the System_level */
622 obj_desc
->power_resource
.system_level
= (u8
) arg
->value
.integer
;
624 /* Move to next arg and check existence */
628 status
= AE_AML_NO_OPERAND
;
632 /* Second arg is the PBlock Address */
634 obj_desc
->power_resource
.resource_order
= (u16
) arg
->value
.integer
;
640 /*****************************************************************************
642 * FUNCTION: Acpi_aml_exec_create_method
644 * PARAMETERS: Aml_ptr - First byte of the method's AML
645 * Aml_length - AML byte count for this method
646 * Method_flags - AML method flag byte
647 * Method - Method Node
651 * DESCRIPTION: Create a new method object
653 ****************************************************************************/
656 acpi_aml_exec_create_method (
662 ACPI_OPERAND_OBJECT
*obj_desc
;
666 /* Create a new method object */
668 obj_desc
= acpi_cm_create_internal_object (ACPI_TYPE_METHOD
);
670 return (AE_NO_MEMORY
);
673 /* Get the method's AML pointer/length from the Op */
675 obj_desc
->method
.pcode
= aml_ptr
;
676 obj_desc
->method
.pcode_length
= aml_length
;
679 * First argument is the Method Flags (contains parameter count for the
683 obj_desc
->method
.method_flags
= (u8
) method_flags
;
684 obj_desc
->method
.param_count
= (u8
) (method_flags
&
685 METHOD_FLAGS_ARG_COUNT
);
688 * Get the concurrency count. If required, a semaphore will be
689 * created for this method when it is parsed.
691 if (method_flags
& METHOD_FLAGS_SERIALIZED
) {
693 * ACPI 1.0: Concurrency = 1
694 * ACPI 2.0: Concurrency = (Sync_level (in method declaration) + 1)
696 obj_desc
->method
.concurrency
= (u8
)
697 (((method_flags
& METHOD_FLAGS_SYNCH_LEVEL
) >> 4) + 1);
701 obj_desc
->method
.concurrency
= INFINITE_CONCURRENCY
;
704 /* Attach the new object to the method Node */
706 status
= acpi_ns_attach_object (method
, obj_desc
, (u8
) ACPI_TYPE_METHOD
);
707 if (ACPI_FAILURE (status
)) {
708 acpi_cm_delete_object_desc (obj_desc
);