1 /******************************************************************************
3 * Module Name: dsfield - Dispatcher field routines
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
29 #define _COMPONENT ACPI_DISPATCHER
30 MODULE_NAME ("dsfield")
34 * Field flags: Bits 00 - 03 : Access_type (Any_acc, Byte_acc, etc.)
35 * 04 : Lock_rule (1 == Lock)
36 * 05 - 06 : Update_rule
39 #define FIELD_ACCESS_TYPE_MASK 0x0F
40 #define FIELD_LOCK_RULE_MASK 0x10
41 #define FIELD_UPDATE_RULE_MASK 0x60
44 /*******************************************************************************
46 * FUNCTION: Acpi_ds_create_field
48 * PARAMETERS: Op - Op containing the Field definition and args
49 * Region_node - Object for the containing Operation Region
53 * DESCRIPTION: Create a new field in the specified operation region
55 ******************************************************************************/
58 acpi_ds_create_field (
59 ACPI_PARSE_OBJECT
*op
,
60 ACPI_NAMESPACE_NODE
*region_node
,
61 ACPI_WALK_STATE
*walk_state
)
63 ACPI_STATUS status
= AE_AML_ERROR
;
64 ACPI_PARSE_OBJECT
*arg
;
65 ACPI_NAMESPACE_NODE
*node
;
67 u8 access_attribute
= 0;
68 u32 field_bit_position
= 0;
71 /* First arg is the name of the parent Op_region */
75 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.name
,
76 ACPI_TYPE_REGION
, IMODE_EXECUTE
,
77 NS_SEARCH_PARENT
, walk_state
,
80 if (ACPI_FAILURE (status
)) {
85 /* Second arg is the field flags */
88 field_flags
= (u8
) arg
->value
.integer
;
90 /* Each remaining arg is a Named Field */
94 switch (arg
->opcode
) {
95 case AML_RESERVEDFIELD_OP
:
97 field_bit_position
+= arg
->value
.size
;
101 case AML_ACCESSFIELD_OP
:
104 * Get a new Access_type and Access_attribute for all
105 * entries (until end or another Access_as keyword)
108 access_attribute
= (u8
) arg
->value
.integer
;
110 ((field_flags
& FIELD_ACCESS_TYPE_MASK
) ||
111 ((u8
) (arg
->value
.integer
>> 8)));
115 case AML_NAMEDFIELD_OP
:
117 status
= acpi_ns_lookup (walk_state
->scope_info
,
118 (NATIVE_CHAR
*) &((ACPI_PARSE2_OBJECT
*)arg
)->name
,
119 INTERNAL_TYPE_DEF_FIELD
,
121 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
124 if (ACPI_FAILURE (status
)) {
129 * Initialize an object for the new Node that is on
133 status
= acpi_aml_prep_def_field_value (node
, region_node
, field_flags
,
134 access_attribute
, field_bit_position
, arg
->value
.size
);
136 if (ACPI_FAILURE (status
)) {
140 /* Keep track of bit position for *next* field */
142 field_bit_position
+= arg
->value
.size
;
153 /*******************************************************************************
155 * FUNCTION: Acpi_ds_create_bank_field
157 * PARAMETERS: Op - Op containing the Field definition and args
158 * Region_node - Object for the containing Operation Region
162 * DESCRIPTION: Create a new bank field in the specified operation region
164 ******************************************************************************/
167 acpi_ds_create_bank_field (
168 ACPI_PARSE_OBJECT
*op
,
169 ACPI_NAMESPACE_NODE
*region_node
,
170 ACPI_WALK_STATE
*walk_state
)
172 ACPI_STATUS status
= AE_AML_ERROR
;
173 ACPI_PARSE_OBJECT
*arg
;
174 ACPI_NAMESPACE_NODE
*register_node
;
175 ACPI_NAMESPACE_NODE
*node
;
178 u8 access_attribute
= 0;
179 u32 field_bit_position
= 0;
182 /* First arg is the name of the parent Op_region */
186 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.name
,
187 ACPI_TYPE_REGION
, IMODE_EXECUTE
,
188 NS_SEARCH_PARENT
, walk_state
,
191 if (ACPI_FAILURE (status
)) {
196 /* Second arg is the Bank Register */
200 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.string
,
201 INTERNAL_TYPE_BANK_FIELD_DEFN
,
203 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
204 NULL
, ®ister_node
);
206 if (ACPI_FAILURE (status
)) {
210 /* Third arg is the Bank_value */
213 bank_value
= arg
->value
.integer
;
216 /* Next arg is the field flags */
219 field_flags
= (u8
) arg
->value
.integer
;
221 /* Each remaining arg is a Named Field */
225 switch (arg
->opcode
) {
226 case AML_RESERVEDFIELD_OP
:
228 field_bit_position
+= arg
->value
.size
;
232 case AML_ACCESSFIELD_OP
:
235 * Get a new Access_type and Access_attribute for
236 * all entries (until end or another Access_as keyword)
239 access_attribute
= (u8
) arg
->value
.integer
;
241 ((field_flags
& FIELD_ACCESS_TYPE_MASK
) ||
242 ((u8
) (arg
->value
.integer
>> 8)));
246 case AML_NAMEDFIELD_OP
:
248 status
= acpi_ns_lookup (walk_state
->scope_info
,
249 (NATIVE_CHAR
*) &((ACPI_PARSE2_OBJECT
*)arg
)->name
,
250 INTERNAL_TYPE_DEF_FIELD
,
252 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
255 if (ACPI_FAILURE (status
)) {
260 * Initialize an object for the new Node that is on
264 status
= acpi_aml_prep_bank_field_value (node
, region_node
, register_node
,
265 bank_value
, field_flags
, access_attribute
,
266 field_bit_position
, arg
->value
.size
);
268 if (ACPI_FAILURE (status
)) {
272 /* Keep track of bit position for the *next* field */
274 field_bit_position
+= arg
->value
.size
;
286 /*******************************************************************************
288 * FUNCTION: Acpi_ds_create_index_field
290 * PARAMETERS: Op - Op containing the Field definition and args
291 * Region_node - Object for the containing Operation Region
295 * DESCRIPTION: Create a new index field in the specified operation region
297 ******************************************************************************/
300 acpi_ds_create_index_field (
301 ACPI_PARSE_OBJECT
*op
,
302 ACPI_HANDLE region_node
,
303 ACPI_WALK_STATE
*walk_state
)
306 ACPI_PARSE_OBJECT
*arg
;
307 ACPI_NAMESPACE_NODE
*node
;
308 ACPI_NAMESPACE_NODE
*index_register_node
;
309 ACPI_NAMESPACE_NODE
*data_register_node
;
311 u8 access_attribute
= 0;
312 u32 field_bit_position
= 0;
317 /* First arg is the name of the Index register */
319 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.string
,
320 ACPI_TYPE_ANY
, IMODE_LOAD_PASS1
,
321 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
322 NULL
, &index_register_node
);
324 if (ACPI_FAILURE (status
)) {
328 /* Second arg is the data register */
332 status
= acpi_ns_lookup (walk_state
->scope_info
, arg
->value
.string
,
333 INTERNAL_TYPE_INDEX_FIELD_DEFN
,
335 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
336 NULL
, &data_register_node
);
338 if (ACPI_FAILURE (status
)) {
343 /* Next arg is the field flags */
346 field_flags
= (u8
) arg
->value
.integer
;
349 /* Each remaining arg is a Named Field */
353 switch (arg
->opcode
) {
354 case AML_RESERVEDFIELD_OP
:
356 field_bit_position
+= arg
->value
.size
;
360 case AML_ACCESSFIELD_OP
:
363 * Get a new Access_type and Access_attribute for all
364 * entries (until end or another Access_as keyword)
367 access_attribute
= (u8
) arg
->value
.integer
;
369 ((field_flags
& FIELD_ACCESS_TYPE_MASK
) ||
370 ((u8
) (arg
->value
.integer
>> 8)));
374 case AML_NAMEDFIELD_OP
:
376 status
= acpi_ns_lookup (walk_state
->scope_info
,
377 (NATIVE_CHAR
*) &((ACPI_PARSE2_OBJECT
*)arg
)->name
,
378 INTERNAL_TYPE_INDEX_FIELD
,
380 NS_NO_UPSEARCH
| NS_DONT_OPEN_SCOPE
,
383 if (ACPI_FAILURE (status
)) {
388 * Initialize an object for the new Node that is on
392 status
= acpi_aml_prep_index_field_value (node
, index_register_node
, data_register_node
,
393 field_flags
, access_attribute
,
394 field_bit_position
, arg
->value
.size
);
396 if (ACPI_FAILURE (status
)) {
400 /* Keep track of bit position for the *next* field */
402 field_bit_position
+= arg
->value
.size
;
408 status
= AE_AML_ERROR
;