Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 : : /******************************************************************************
3 : : *
4 : : * Module Name: dsfield - Dispatcher field routines
5 : : *
6 : : * Copyright (C) 2000 - 2020, Intel Corp.
7 : : *
8 : : *****************************************************************************/
9 : :
10 : : #include <acpi/acpi.h>
11 : : #include "accommon.h"
12 : : #include "amlcode.h"
13 : : #include "acdispat.h"
14 : : #include "acinterp.h"
15 : : #include "acnamesp.h"
16 : : #include "acparser.h"
17 : :
18 : : #ifdef ACPI_EXEC_APP
19 : : #include "aecommon.h"
20 : : #endif
21 : :
22 : : #define _COMPONENT ACPI_DISPATCHER
23 : : ACPI_MODULE_NAME("dsfield")
24 : :
25 : : /* Local prototypes */
26 : : #ifdef ACPI_ASL_COMPILER
27 : : #include "acdisasm.h"
28 : : static acpi_status
29 : : acpi_ds_create_external_region(acpi_status lookup_status,
30 : : union acpi_parse_object *op,
31 : : char *path,
32 : : struct acpi_walk_state *walk_state,
33 : : struct acpi_namespace_node **node);
34 : : #endif
35 : :
36 : : static acpi_status
37 : : acpi_ds_get_field_names(struct acpi_create_field_info *info,
38 : : struct acpi_walk_state *walk_state,
39 : : union acpi_parse_object *arg);
40 : :
41 : : #ifdef ACPI_ASL_COMPILER
42 : : /*******************************************************************************
43 : : *
44 : : * FUNCTION: acpi_ds_create_external_region (iASL Disassembler only)
45 : : *
46 : : * PARAMETERS: lookup_status - Status from ns_lookup operation
47 : : * op - Op containing the Field definition and args
48 : : * path - Pathname of the region
49 : : * ` walk_state - Current method state
50 : : * node - Where the new region node is returned
51 : : *
52 : : * RETURN: Status
53 : : *
54 : : * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
55 : : * region node/object.
56 : : *
57 : : ******************************************************************************/
58 : :
59 : : static acpi_status
60 : : acpi_ds_create_external_region(acpi_status lookup_status,
61 : : union acpi_parse_object *op,
62 : : char *path,
63 : : struct acpi_walk_state *walk_state,
64 : : struct acpi_namespace_node **node)
65 : : {
66 : : acpi_status status;
67 : : union acpi_operand_object *obj_desc;
68 : :
69 : : if (lookup_status != AE_NOT_FOUND) {
70 : : return (lookup_status);
71 : : }
72 : :
73 : : /*
74 : : * Table disassembly:
75 : : * operation_region not found. Generate an External for it, and
76 : : * insert the name into the namespace.
77 : : */
78 : : acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
79 : :
80 : : status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
81 : : ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
82 : : walk_state, node);
83 : : if (ACPI_FAILURE(status)) {
84 : : return (status);
85 : : }
86 : :
87 : : /* Must create and install a region object for the new node */
88 : :
89 : : obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
90 : : if (!obj_desc) {
91 : : return (AE_NO_MEMORY);
92 : : }
93 : :
94 : : obj_desc->region.node = *node;
95 : : status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
96 : : return (status);
97 : : }
98 : : #endif
99 : :
100 : : /*******************************************************************************
101 : : *
102 : : * FUNCTION: acpi_ds_create_buffer_field
103 : : *
104 : : * PARAMETERS: op - Current parse op (create_XXField)
105 : : * walk_state - Current state
106 : : *
107 : : * RETURN: Status
108 : : *
109 : : * DESCRIPTION: Execute the create_field operators:
110 : : * create_bit_field_op,
111 : : * create_byte_field_op,
112 : : * create_word_field_op,
113 : : * create_dword_field_op,
114 : : * create_qword_field_op,
115 : : * create_field_op (all of which define a field in a buffer)
116 : : *
117 : : ******************************************************************************/
118 : :
119 : : acpi_status
120 : 300 : acpi_ds_create_buffer_field(union acpi_parse_object *op,
121 : : struct acpi_walk_state *walk_state)
122 : : {
123 : 300 : union acpi_parse_object *arg;
124 : 300 : struct acpi_namespace_node *node;
125 : 300 : acpi_status status;
126 : 300 : union acpi_operand_object *obj_desc;
127 : 300 : union acpi_operand_object *second_desc = NULL;
128 : 300 : u32 flags;
129 : :
130 : 300 : ACPI_FUNCTION_TRACE(ds_create_buffer_field);
131 : :
132 : : /*
133 : : * Get the name_string argument (name of the new buffer_field)
134 : : */
135 [ - + ]: 300 : if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
136 : :
137 : : /* For create_field, name is the 4th argument */
138 : :
139 : 0 : arg = acpi_ps_get_arg(op, 3);
140 : : } else {
141 : : /* For all other create_XXXField operators, name is the 3rd argument */
142 : :
143 : 300 : arg = acpi_ps_get_arg(op, 2);
144 : : }
145 : :
146 [ + - ]: 300 : if (!arg) {
147 : : return_ACPI_STATUS(AE_AML_NO_OPERAND);
148 : : }
149 : :
150 [ - + ]: 300 : if (walk_state->deferred_node) {
151 : 0 : node = walk_state->deferred_node;
152 : : } else {
153 : : /* Execute flag should always be set when this function is entered */
154 : :
155 [ - + ]: 300 : if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
156 : 0 : ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
157 : 0 : return_ACPI_STATUS(AE_AML_INTERNAL);
158 : : }
159 : :
160 : : /* Creating new namespace node, should not already exist */
161 : :
162 : 300 : flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
163 : : ACPI_NS_ERROR_IF_FOUND;
164 : :
165 : : /*
166 : : * Mark node temporary if we are executing a normal control
167 : : * method. (Don't mark if this is a module-level code method)
168 : : */
169 [ + - ]: 300 : if (walk_state->method_node &&
170 [ + - ]: 300 : !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
171 : 300 : flags |= ACPI_NS_TEMPORARY;
172 : : }
173 : :
174 : : /* Enter the name_string into the namespace */
175 : :
176 : 300 : status = acpi_ns_lookup(walk_state->scope_info,
177 : : arg->common.value.string, ACPI_TYPE_ANY,
178 : : ACPI_IMODE_LOAD_PASS1, flags,
179 : : walk_state, &node);
180 [ - + ]: 300 : if (ACPI_FAILURE(status)) {
181 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
182 : 0 : arg->common.value.string, status);
183 : 0 : return_ACPI_STATUS(status);
184 : : }
185 : : }
186 : :
187 : : /*
188 : : * We could put the returned object (Node) on the object stack for later,
189 : : * but for now, we will put it in the "op" object that the parser uses,
190 : : * so we can get it again at the end of this scope.
191 : : */
192 : 300 : op->common.node = node;
193 : :
194 : : /*
195 : : * If there is no object attached to the node, this node was just created
196 : : * and we need to create the field object. Otherwise, this was a lookup
197 : : * of an existing node and we don't want to create the field object again.
198 : : */
199 : 300 : obj_desc = acpi_ns_get_attached_object(node);
200 [ + - ]: 300 : if (obj_desc) {
201 : : return_ACPI_STATUS(AE_OK);
202 : : }
203 : :
204 : : /*
205 : : * The Field definition is not fully parsed at this time.
206 : : * (We must save the address of the AML for the buffer and index operands)
207 : : */
208 : :
209 : : /* Create the buffer field object */
210 : :
211 : 300 : obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
212 [ - + ]: 300 : if (!obj_desc) {
213 : 0 : status = AE_NO_MEMORY;
214 : 0 : goto cleanup;
215 : : }
216 : :
217 : : /*
218 : : * Remember location in AML stream of the field unit opcode and operands
219 : : * -- since the buffer and index operands must be evaluated.
220 : : */
221 : 300 : second_desc = obj_desc->common.next_object;
222 : 300 : second_desc->extra.aml_start = op->named.data;
223 : 300 : second_desc->extra.aml_length = op->named.length;
224 : 300 : obj_desc->buffer_field.node = node;
225 : :
226 : : /* Attach constructed field descriptors to parent node */
227 : :
228 : 300 : status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
229 [ + - ]: 300 : if (ACPI_FAILURE(status)) {
230 : 0 : goto cleanup;
231 : : }
232 : :
233 : 300 : cleanup:
234 : :
235 : : /* Remove local reference to the object */
236 : :
237 : 300 : acpi_ut_remove_reference(obj_desc);
238 : 300 : return_ACPI_STATUS(status);
239 : : }
240 : :
241 : : /*******************************************************************************
242 : : *
243 : : * FUNCTION: acpi_ds_get_field_names
244 : : *
245 : : * PARAMETERS: info - create_field info structure
246 : : * walk_state - Current method state
247 : : * arg - First parser arg for the field name list
248 : : *
249 : : * RETURN: Status
250 : : *
251 : : * DESCRIPTION: Process all named fields in a field declaration. Names are
252 : : * entered into the namespace.
253 : : *
254 : : ******************************************************************************/
255 : :
256 : : static acpi_status
257 : 270 : acpi_ds_get_field_names(struct acpi_create_field_info *info,
258 : : struct acpi_walk_state *walk_state,
259 : : union acpi_parse_object *arg)
260 : : {
261 : 270 : acpi_status status;
262 : 270 : u64 position;
263 : 270 : union acpi_parse_object *child;
264 : :
265 : : #ifdef ACPI_EXEC_APP
266 : : union acpi_operand_object *result_desc;
267 : : union acpi_operand_object *obj_desc;
268 : : char *name_path;
269 : : #endif
270 : :
271 : 270 : ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
272 : :
273 : : /* First field starts at bit zero */
274 : :
275 : 270 : info->field_bit_position = 0;
276 : :
277 : : /* Process all elements in the field list (of parse nodes) */
278 : :
279 [ + + ]: 1140 : while (arg) {
280 : : /*
281 : : * Four types of field elements are handled:
282 : : * 1) name - Enters a new named field into the namespace
283 : : * 2) offset - specifies a bit offset
284 : : * 3) access_as - changes the access mode/attributes
285 : : * 4) connection - Associate a resource template with the field
286 : : */
287 [ + - - + : 870 : switch (arg->common.aml_opcode) {
- ]
288 : 240 : case AML_INT_RESERVEDFIELD_OP:
289 : :
290 : 240 : position = (u64)info->field_bit_position +
291 : 240 : (u64)arg->common.value.size;
292 : :
293 [ - + ]: 240 : if (position > ACPI_UINT32_MAX) {
294 : 0 : ACPI_ERROR((AE_INFO,
295 : : "Bit offset within field too large (> 0xFFFFFFFF)"));
296 : 0 : return_ACPI_STATUS(AE_SUPPORT);
297 : : }
298 : :
299 : 240 : info->field_bit_position = (u32) position;
300 : 240 : break;
301 : :
302 : 0 : case AML_INT_ACCESSFIELD_OP:
303 : : case AML_INT_EXTACCESSFIELD_OP:
304 : : /*
305 : : * Get new access_type, access_attribute, and access_length fields
306 : : * -- to be used for all field units that follow, until the
307 : : * end-of-field or another access_as keyword is encountered.
308 : : * NOTE. These three bytes are encoded in the integer value
309 : : * of the parseop for convenience.
310 : : *
311 : : * In field_flags, preserve the flag bits other than the
312 : : * ACCESS_TYPE bits.
313 : : */
314 : :
315 : : /* access_type (byte_acc, word_acc, etc.) */
316 : :
317 : 0 : info->field_flags = (u8)
318 : 0 : ((info->
319 : 0 : field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
320 : 0 : ((u8)((u32)(arg->common.value.integer & 0x07))));
321 : :
322 : : /* access_attribute (attrib_quick, attrib_byte, etc.) */
323 : :
324 : 0 : info->attribute = (u8)
325 : 0 : ((arg->common.value.integer >> 8) & 0xFF);
326 : :
327 : : /* access_length (for serial/buffer protocols) */
328 : :
329 : 0 : info->access_length = (u8)
330 : 0 : ((arg->common.value.integer >> 16) & 0xFF);
331 : 0 : break;
332 : :
333 : 0 : case AML_INT_CONNECTION_OP:
334 : : /*
335 : : * Clear any previous connection. New connection is used for all
336 : : * fields that follow, similar to access_as
337 : : */
338 : 0 : info->resource_buffer = NULL;
339 : 0 : info->connection_node = NULL;
340 : 0 : info->pin_number_index = 0;
341 : :
342 : : /*
343 : : * A Connection() is either an actual resource descriptor (buffer)
344 : : * or a named reference to a resource template
345 : : */
346 : 0 : child = arg->common.value.arg;
347 [ # # ]: 0 : if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
348 : 0 : info->resource_buffer = child->named.data;
349 : 0 : info->resource_length =
350 : 0 : (u16)child->named.value.integer;
351 : : } else {
352 : : /* Lookup the Connection() namepath, it should already exist */
353 : :
354 : 0 : status = acpi_ns_lookup(walk_state->scope_info,
355 : : child->common.value.
356 : : name, ACPI_TYPE_ANY,
357 : : ACPI_IMODE_EXECUTE,
358 : : ACPI_NS_DONT_OPEN_SCOPE,
359 : : walk_state,
360 : : &info->connection_node);
361 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
362 : 0 : ACPI_ERROR_NAMESPACE(walk_state->
363 : : scope_info,
364 : : child->common.
365 : : value.name,
366 : 0 : status);
367 : 0 : return_ACPI_STATUS(status);
368 : : }
369 : : }
370 : : break;
371 : :
372 : 630 : case AML_INT_NAMEDFIELD_OP:
373 : :
374 : : /* Lookup the name, it should already exist */
375 : :
376 : 630 : status = acpi_ns_lookup(walk_state->scope_info,
377 : 630 : (char *)&arg->named.name,
378 : 630 : info->field_type,
379 : : ACPI_IMODE_EXECUTE,
380 : : ACPI_NS_DONT_OPEN_SCOPE,
381 : : walk_state, &info->field_node);
382 [ - + ]: 630 : if (ACPI_FAILURE(status)) {
383 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
384 : : (char *)&arg->named.name,
385 : 0 : status);
386 : 0 : return_ACPI_STATUS(status);
387 : : } else {
388 : 630 : arg->common.node = info->field_node;
389 : 630 : info->field_bit_length = arg->common.value.size;
390 : :
391 : : /*
392 : : * If there is no object attached to the node, this node was
393 : : * just created and we need to create the field object.
394 : : * Otherwise, this was a lookup of an existing node and we
395 : : * don't want to create the field object again.
396 : : */
397 [ + - ]: 630 : if (!acpi_ns_get_attached_object
398 : : (info->field_node)) {
399 : 630 : status = acpi_ex_prep_field_value(info);
400 [ - + ]: 630 : if (ACPI_FAILURE(status)) {
401 : 0 : return_ACPI_STATUS(status);
402 : : }
403 : : #ifdef ACPI_EXEC_APP
404 : : name_path =
405 : : acpi_ns_get_external_pathname(info->
406 : : field_node);
407 : : if (ACPI_SUCCESS
408 : : (ae_lookup_init_file_entry
409 : : (name_path, &obj_desc))) {
410 : : acpi_ex_write_data_to_field
411 : : (obj_desc,
412 : : acpi_ns_get_attached_object
413 : : (info->field_node),
414 : : &result_desc);
415 : : acpi_ut_remove_reference
416 : : (obj_desc);
417 : : }
418 : : ACPI_FREE(name_path);
419 : : #endif
420 : : }
421 : : }
422 : :
423 : : /* Keep track of bit position for the next field */
424 : :
425 : 630 : position = (u64)info->field_bit_position +
426 : 630 : (u64)arg->common.value.size;
427 : :
428 [ - + ]: 630 : if (position > ACPI_UINT32_MAX) {
429 : 0 : ACPI_ERROR((AE_INFO,
430 : : "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
431 : : ACPI_CAST_PTR(char,
432 : : &info->field_node->
433 : : name)));
434 : 0 : return_ACPI_STATUS(AE_SUPPORT);
435 : : }
436 : :
437 : 630 : info->field_bit_position += info->field_bit_length;
438 : 630 : info->pin_number_index++; /* Index relative to previous Connection() */
439 : 630 : break;
440 : :
441 : 0 : default:
442 : :
443 : 0 : ACPI_ERROR((AE_INFO,
444 : : "Invalid opcode in field list: 0x%X",
445 : : arg->common.aml_opcode));
446 : 0 : return_ACPI_STATUS(AE_AML_BAD_OPCODE);
447 : : }
448 : :
449 : 870 : arg = arg->common.next;
450 : : }
451 : :
452 : : return_ACPI_STATUS(AE_OK);
453 : : }
454 : :
455 : : /*******************************************************************************
456 : : *
457 : : * FUNCTION: acpi_ds_create_field
458 : : *
459 : : * PARAMETERS: op - Op containing the Field definition and args
460 : : * region_node - Object for the containing Operation Region
461 : : * ` walk_state - Current method state
462 : : *
463 : : * RETURN: Status
464 : : *
465 : : * DESCRIPTION: Create a new field in the specified operation region
466 : : *
467 : : ******************************************************************************/
468 : :
469 : : acpi_status
470 : 270 : acpi_ds_create_field(union acpi_parse_object *op,
471 : : struct acpi_namespace_node *region_node,
472 : : struct acpi_walk_state *walk_state)
473 : : {
474 : 270 : acpi_status status;
475 : 270 : union acpi_parse_object *arg;
476 : 270 : struct acpi_create_field_info info;
477 : :
478 : 270 : ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
479 : :
480 : : /* First arg is the name of the parent op_region (must already exist) */
481 : :
482 : 270 : arg = op->common.value.arg;
483 : :
484 [ + - ]: 270 : if (!region_node) {
485 : 270 : status =
486 : 270 : acpi_ns_lookup(walk_state->scope_info,
487 : : arg->common.value.name, ACPI_TYPE_REGION,
488 : : ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
489 : : walk_state, ®ion_node);
490 : : #ifdef ACPI_ASL_COMPILER
491 : : status = acpi_ds_create_external_region(status, arg,
492 : : arg->common.value.name,
493 : : walk_state,
494 : : ®ion_node);
495 : : #endif
496 [ - + ]: 270 : if (ACPI_FAILURE(status)) {
497 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
498 : 0 : arg->common.value.name, status);
499 : 0 : return_ACPI_STATUS(status);
500 : : }
501 : : }
502 : :
503 : 270 : memset(&info, 0, sizeof(struct acpi_create_field_info));
504 : :
505 : : /* Second arg is the field flags */
506 : :
507 : 270 : arg = arg->common.next;
508 : 270 : info.field_flags = (u8) arg->common.value.integer;
509 : 270 : info.attribute = 0;
510 : :
511 : : /* Each remaining arg is a Named Field */
512 : :
513 : 270 : info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
514 : 270 : info.region_node = region_node;
515 : :
516 : 270 : status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
517 [ - + ]: 270 : if (info.region_node->object->region.space_id ==
518 : : ACPI_ADR_SPACE_PLATFORM_COMM
519 [ # # ]: 0 : && !(region_node->object->field.internal_pcc_buffer =
520 : 0 : ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
521 : : length))) {
522 : 0 : return_ACPI_STATUS(AE_NO_MEMORY);
523 : : }
524 : : return_ACPI_STATUS(status);
525 : : }
526 : :
527 : : /*******************************************************************************
528 : : *
529 : : * FUNCTION: acpi_ds_init_field_objects
530 : : *
531 : : * PARAMETERS: op - Op containing the Field definition and args
532 : : * ` walk_state - Current method state
533 : : *
534 : : * RETURN: Status
535 : : *
536 : : * DESCRIPTION: For each "Field Unit" name in the argument list that is
537 : : * part of the field declaration, enter the name into the
538 : : * namespace.
539 : : *
540 : : ******************************************************************************/
541 : :
542 : : acpi_status
543 : 270 : acpi_ds_init_field_objects(union acpi_parse_object *op,
544 : : struct acpi_walk_state *walk_state)
545 : : {
546 : 270 : acpi_status status;
547 : 270 : union acpi_parse_object *arg = NULL;
548 : 270 : struct acpi_namespace_node *node;
549 : 270 : u8 type = 0;
550 : 270 : u32 flags;
551 : :
552 : 270 : ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
553 : :
554 : : /* Execute flag should always be set when this function is entered */
555 : :
556 [ - + ]: 270 : if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
557 [ # # ]: 0 : if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
558 : :
559 : : /* bank_field Op is deferred, just return OK */
560 : :
561 : : return_ACPI_STATUS(AE_OK);
562 : : }
563 : :
564 : 0 : ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
565 : 0 : return_ACPI_STATUS(AE_AML_INTERNAL);
566 : : }
567 : :
568 : : /*
569 : : * Get the field_list argument for this opcode. This is the start of the
570 : : * list of field elements.
571 : : */
572 [ + - - - ]: 270 : switch (walk_state->opcode) {
573 : 270 : case AML_FIELD_OP:
574 : :
575 : 270 : arg = acpi_ps_get_arg(op, 2);
576 : 270 : type = ACPI_TYPE_LOCAL_REGION_FIELD;
577 : 270 : break;
578 : :
579 : 0 : case AML_BANK_FIELD_OP:
580 : :
581 : 0 : arg = acpi_ps_get_arg(op, 4);
582 : 0 : type = ACPI_TYPE_LOCAL_BANK_FIELD;
583 : 0 : break;
584 : :
585 : 0 : case AML_INDEX_FIELD_OP:
586 : :
587 : 0 : arg = acpi_ps_get_arg(op, 3);
588 : 0 : type = ACPI_TYPE_LOCAL_INDEX_FIELD;
589 : 0 : break;
590 : :
591 : : default:
592 : :
593 : : return_ACPI_STATUS(AE_BAD_PARAMETER);
594 : : }
595 : :
596 : : /* Creating new namespace node(s), should not already exist */
597 : :
598 : 270 : flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
599 : : ACPI_NS_ERROR_IF_FOUND;
600 : :
601 : : /*
602 : : * Mark node(s) temporary if we are executing a normal control
603 : : * method. (Don't mark if this is a module-level code method)
604 : : */
605 [ + - ]: 270 : if (walk_state->method_node &&
606 [ - + ]: 270 : !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
607 : 0 : flags |= ACPI_NS_TEMPORARY;
608 : : }
609 : : #ifdef ACPI_EXEC_APP
610 : : flags |= ACPI_NS_OVERRIDE_IF_FOUND;
611 : : #endif
612 : : /*
613 : : * Walk the list of entries in the field_list
614 : : * Note: field_list can be of zero length. In this case, Arg will be NULL.
615 : : */
616 [ + + ]: 1140 : while (arg) {
617 : : /*
618 : : * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
619 : : * in the field names in order to enter them into the namespace.
620 : : */
621 [ + + ]: 870 : if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
622 : 630 : status = acpi_ns_lookup(walk_state->scope_info,
623 : 630 : (char *)&arg->named.name, type,
624 : : ACPI_IMODE_LOAD_PASS1, flags,
625 : : walk_state, &node);
626 [ - + ]: 630 : if (ACPI_FAILURE(status)) {
627 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
628 : : (char *)&arg->named.name,
629 : 0 : status);
630 [ # # ]: 0 : if (status != AE_ALREADY_EXISTS) {
631 : 0 : return_ACPI_STATUS(status);
632 : : }
633 : :
634 : : /* Name already exists, just ignore this error */
635 : : }
636 : :
637 : 630 : arg->common.node = node;
638 : : }
639 : :
640 : : /* Get the next field element in the list */
641 : :
642 : 870 : arg = arg->common.next;
643 : : }
644 : :
645 : : return_ACPI_STATUS(AE_OK);
646 : : }
647 : :
648 : : /*******************************************************************************
649 : : *
650 : : * FUNCTION: acpi_ds_create_bank_field
651 : : *
652 : : * PARAMETERS: op - Op containing the Field definition and args
653 : : * region_node - Object for the containing Operation Region
654 : : * walk_state - Current method state
655 : : *
656 : : * RETURN: Status
657 : : *
658 : : * DESCRIPTION: Create a new bank field in the specified operation region
659 : : *
660 : : ******************************************************************************/
661 : :
662 : : acpi_status
663 : 0 : acpi_ds_create_bank_field(union acpi_parse_object *op,
664 : : struct acpi_namespace_node *region_node,
665 : : struct acpi_walk_state *walk_state)
666 : : {
667 : 0 : acpi_status status;
668 : 0 : union acpi_parse_object *arg;
669 : 0 : struct acpi_create_field_info info;
670 : :
671 : 0 : ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
672 : :
673 : : /* First arg is the name of the parent op_region (must already exist) */
674 : :
675 : 0 : arg = op->common.value.arg;
676 [ # # ]: 0 : if (!region_node) {
677 : 0 : status =
678 : 0 : acpi_ns_lookup(walk_state->scope_info,
679 : : arg->common.value.name, ACPI_TYPE_REGION,
680 : : ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
681 : : walk_state, ®ion_node);
682 : : #ifdef ACPI_ASL_COMPILER
683 : : status = acpi_ds_create_external_region(status, arg,
684 : : arg->common.value.name,
685 : : walk_state,
686 : : ®ion_node);
687 : : #endif
688 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
689 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
690 : 0 : arg->common.value.name, status);
691 : 0 : return_ACPI_STATUS(status);
692 : : }
693 : : }
694 : :
695 : : /* Second arg is the Bank Register (Field) (must already exist) */
696 : :
697 : 0 : arg = arg->common.next;
698 : 0 : status =
699 : 0 : acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
700 : : ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
701 : : ACPI_NS_SEARCH_PARENT, walk_state,
702 : : &info.register_node);
703 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
704 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
705 : 0 : arg->common.value.string, status);
706 : 0 : return_ACPI_STATUS(status);
707 : : }
708 : :
709 : : /*
710 : : * Third arg is the bank_value
711 : : * This arg is a term_arg, not a constant
712 : : * It will be evaluated later, by acpi_ds_eval_bank_field_operands
713 : : */
714 : 0 : arg = arg->common.next;
715 : :
716 : : /* Fourth arg is the field flags */
717 : :
718 : 0 : arg = arg->common.next;
719 : 0 : info.field_flags = (u8) arg->common.value.integer;
720 : :
721 : : /* Each remaining arg is a Named Field */
722 : :
723 : 0 : info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
724 : 0 : info.region_node = region_node;
725 : :
726 : : /*
727 : : * Use Info.data_register_node to store bank_field Op
728 : : * It's safe because data_register_node will never be used when create
729 : : * bank field \we store aml_start and aml_length in the bank_field Op for
730 : : * late evaluation. Used in acpi_ex_prep_field_value(Info)
731 : : *
732 : : * TBD: Or, should we add a field in struct acpi_create_field_info, like
733 : : * "void *ParentOp"?
734 : : */
735 : 0 : info.data_register_node = (struct acpi_namespace_node *)op;
736 : :
737 : 0 : status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
738 : 0 : return_ACPI_STATUS(status);
739 : : }
740 : :
741 : : /*******************************************************************************
742 : : *
743 : : * FUNCTION: acpi_ds_create_index_field
744 : : *
745 : : * PARAMETERS: op - Op containing the Field definition and args
746 : : * region_node - Object for the containing Operation Region
747 : : * ` walk_state - Current method state
748 : : *
749 : : * RETURN: Status
750 : : *
751 : : * DESCRIPTION: Create a new index field in the specified operation region
752 : : *
753 : : ******************************************************************************/
754 : :
755 : : acpi_status
756 : 0 : acpi_ds_create_index_field(union acpi_parse_object *op,
757 : : struct acpi_namespace_node *region_node,
758 : : struct acpi_walk_state *walk_state)
759 : : {
760 : 0 : acpi_status status;
761 : 0 : union acpi_parse_object *arg;
762 : 0 : struct acpi_create_field_info info;
763 : :
764 : 0 : ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
765 : :
766 : : /* First arg is the name of the Index register (must already exist) */
767 : :
768 : 0 : arg = op->common.value.arg;
769 : 0 : status =
770 : 0 : acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
771 : : ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
772 : : ACPI_NS_SEARCH_PARENT, walk_state,
773 : : &info.register_node);
774 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
775 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
776 : 0 : arg->common.value.string, status);
777 : 0 : return_ACPI_STATUS(status);
778 : : }
779 : :
780 : : /* Second arg is the data register (must already exist) */
781 : :
782 : 0 : arg = arg->common.next;
783 : 0 : status =
784 : 0 : acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
785 : : ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
786 : : ACPI_NS_SEARCH_PARENT, walk_state,
787 : : &info.data_register_node);
788 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
789 : 0 : ACPI_ERROR_NAMESPACE(walk_state->scope_info,
790 : 0 : arg->common.value.string, status);
791 : 0 : return_ACPI_STATUS(status);
792 : : }
793 : :
794 : : /* Next arg is the field flags */
795 : :
796 : 0 : arg = arg->common.next;
797 : 0 : info.field_flags = (u8) arg->common.value.integer;
798 : :
799 : : /* Each remaining arg is a Named Field */
800 : :
801 : 0 : info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
802 : 0 : info.region_node = region_node;
803 : :
804 : 0 : status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
805 : 0 : return_ACPI_STATUS(status);
806 : : }
|