1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acdispat.h"
47#include "acinterp.h"
48#include "amlcode.h"
49#include "acnamesp.h"
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exstore")
53
54
55static acpi_status
56acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
57 union acpi_operand_object *dest_desc,
58 struct acpi_walk_state *walk_state);
59
60static acpi_status
61acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
62 struct acpi_namespace_node *node,
63 struct acpi_walk_state *walk_state);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85acpi_status
86acpi_ex_store(union acpi_operand_object *source_desc,
87 union acpi_operand_object *dest_desc,
88 struct acpi_walk_state *walk_state)
89{
90 acpi_status status = AE_OK;
91 union acpi_operand_object *ref_desc = dest_desc;
92
93 ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
94
95
96
97 if (!source_desc || !dest_desc) {
98 ACPI_ERROR((AE_INFO, "Null parameter"));
99 return_ACPI_STATUS(AE_AML_NO_OPERAND);
100 }
101
102
103
104 if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
105
106
107
108
109 status = acpi_ex_store_object_to_node(source_desc,
110 (struct
111 acpi_namespace_node *)
112 dest_desc, walk_state,
113 ACPI_IMPLICIT_CONVERSION);
114
115 return_ACPI_STATUS(status);
116 }
117
118
119
120 switch (dest_desc->common.type) {
121 case ACPI_TYPE_LOCAL_REFERENCE:
122
123 break;
124
125 case ACPI_TYPE_INTEGER:
126
127
128
129 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
130 return_ACPI_STATUS(AE_OK);
131 }
132
133
134
135 default:
136
137
138
139 ACPI_ERROR((AE_INFO,
140 "Target is not a Reference or Constant object - [%s] %p",
141 acpi_ut_get_object_type_name(dest_desc),
142 dest_desc));
143
144 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
145 }
146
147
148
149
150
151
152
153
154
155 switch (ref_desc->reference.class) {
156 case ACPI_REFCLASS_REFOF:
157
158
159
160 status = acpi_ex_store_object_to_node(source_desc,
161 ref_desc->reference.
162 object, walk_state,
163 ACPI_IMPLICIT_CONVERSION);
164 break;
165
166 case ACPI_REFCLASS_INDEX:
167
168
169
170 status =
171 acpi_ex_store_object_to_index(source_desc, ref_desc,
172 walk_state);
173 break;
174
175 case ACPI_REFCLASS_LOCAL:
176 case ACPI_REFCLASS_ARG:
177
178
179
180 status =
181 acpi_ds_store_object_to_local(ref_desc->reference.class,
182 ref_desc->reference.value,
183 source_desc, walk_state);
184 break;
185
186 case ACPI_REFCLASS_DEBUG:
187
188
189
190
191 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
192 "**** Write to Debug Object: Object %p [%s] ****:\n\n",
193 source_desc,
194 acpi_ut_get_object_type_name(source_desc)));
195
196 ACPI_DEBUG_OBJECT(source_desc, 0, 0);
197 break;
198
199 default:
200
201 ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
202 ref_desc->reference.class));
203 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
204
205 status = AE_AML_INTERNAL;
206 break;
207 }
208
209 return_ACPI_STATUS(status);
210}
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226static acpi_status
227acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
228 union acpi_operand_object *index_desc,
229 struct acpi_walk_state *walk_state)
230{
231 acpi_status status = AE_OK;
232 union acpi_operand_object *obj_desc;
233 union acpi_operand_object *new_desc;
234 u8 value = 0;
235 u32 i;
236
237 ACPI_FUNCTION_TRACE(ex_store_object_to_index);
238
239
240
241
242
243 switch (index_desc->reference.target_type) {
244 case ACPI_TYPE_PACKAGE:
245
246
247
248
249
250
251
252
253
254 obj_desc = *(index_desc->reference.where);
255
256 if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
257 source_desc->reference.class == ACPI_REFCLASS_TABLE) {
258
259
260
261 acpi_ut_add_reference(source_desc);
262 new_desc = source_desc;
263 } else {
264
265
266 status =
267 acpi_ut_copy_iobject_to_iobject(source_desc,
268 &new_desc,
269 walk_state);
270 if (ACPI_FAILURE(status)) {
271 return_ACPI_STATUS(status);
272 }
273 }
274
275 if (obj_desc) {
276
277
278
279 for (i = 0; i < ((union acpi_operand_object *)
280 index_desc->reference.object)->common.
281 reference_count; i++) {
282 acpi_ut_remove_reference(obj_desc);
283 }
284 }
285
286 *(index_desc->reference.where) = new_desc;
287
288
289
290 for (i = 1; i < ((union acpi_operand_object *)
291 index_desc->reference.object)->common.
292 reference_count; i++) {
293 acpi_ut_add_reference(new_desc);
294 }
295
296 break;
297
298 case ACPI_TYPE_BUFFER_FIELD:
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 obj_desc = index_desc->reference.object;
314 if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
315 (obj_desc->common.type != ACPI_TYPE_STRING)) {
316 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
317 }
318
319
320
321
322
323 switch (source_desc->common.type) {
324 case ACPI_TYPE_INTEGER:
325
326
327
328 value = (u8) (source_desc->integer.value);
329 break;
330
331 case ACPI_TYPE_BUFFER:
332 case ACPI_TYPE_STRING:
333
334
335
336 value = source_desc->buffer.pointer[0];
337 break;
338
339 default:
340
341
342
343 ACPI_ERROR((AE_INFO,
344 "Source must be type [Integer/Buffer/String], found [%s]",
345 acpi_ut_get_object_type_name(source_desc)));
346 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
347 }
348
349
350
351 obj_desc->buffer.pointer[index_desc->reference.value] = value;
352 break;
353
354 default:
355 ACPI_ERROR((AE_INFO,
356 "Target is not of type [Package/BufferField]"));
357 status = AE_AML_TARGET_TYPE;
358 break;
359 }
360
361 return_ACPI_STATUS(status);
362}
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394acpi_status
395acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
396 struct acpi_namespace_node *node,
397 struct acpi_walk_state *walk_state,
398 u8 implicit_conversion)
399{
400 acpi_status status = AE_OK;
401 union acpi_operand_object *target_desc;
402 union acpi_operand_object *new_desc;
403 acpi_object_type target_type;
404
405 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
406
407
408
409 target_type = acpi_ns_get_type(node);
410 target_desc = acpi_ns_get_attached_object(node);
411
412 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
413 source_desc,
414 acpi_ut_get_object_type_name(source_desc), node,
415 acpi_ut_get_type_name(target_type)));
416
417
418
419 if (walk_state->opcode != AML_COPY_OBJECT_OP) {
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438 switch (target_type) {
439 case ACPI_TYPE_PACKAGE:
440
441
442
443
444
445 if (walk_state->opcode == AML_STORE_OP) {
446 if (source_desc->common.type !=
447 ACPI_TYPE_PACKAGE) {
448 ACPI_ERROR((AE_INFO,
449 "Cannot assign type [%s] to [Package] "
450 "(source must be type Pkg)",
451 acpi_ut_get_object_type_name
452 (source_desc)));
453
454 return_ACPI_STATUS(AE_AML_TARGET_TYPE);
455 }
456 break;
457 }
458
459
460
461 case ACPI_TYPE_DEVICE:
462 case ACPI_TYPE_EVENT:
463 case ACPI_TYPE_MUTEX:
464 case ACPI_TYPE_REGION:
465 case ACPI_TYPE_POWER:
466 case ACPI_TYPE_PROCESSOR:
467 case ACPI_TYPE_THERMAL:
468
469 ACPI_ERROR((AE_INFO,
470 "Target must be [Buffer/Integer/String/Reference]"
471 ", found [%s] (%4.4s)",
472 acpi_ut_get_type_name(node->type),
473 node->name.ascii));
474
475 return_ACPI_STATUS(AE_AML_TARGET_TYPE);
476
477 default:
478 break;
479 }
480 }
481
482
483
484
485
486 status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
487 if (ACPI_FAILURE(status)) {
488 return_ACPI_STATUS(status);
489 }
490
491
492
493 switch (target_type) {
494
495
496
497
498 case ACPI_TYPE_INTEGER:
499 case ACPI_TYPE_STRING:
500 case ACPI_TYPE_BUFFER:
501
502 if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
503 !implicit_conversion) {
504
505
506
507
508
509 status =
510 acpi_ex_store_direct_to_node(source_desc, node,
511 walk_state);
512 break;
513 }
514
515
516
517 status =
518 acpi_ex_store_object_to_object(source_desc, target_desc,
519 &new_desc, walk_state);
520 if (ACPI_FAILURE(status)) {
521 return_ACPI_STATUS(status);
522 }
523
524 if (new_desc != target_desc) {
525
526
527
528
529
530
531
532
533
534 status =
535 acpi_ns_attach_object(node, new_desc,
536 new_desc->common.type);
537
538 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
539 "Store type [%s] into [%s] via Convert/Attach\n",
540 acpi_ut_get_object_type_name
541 (source_desc),
542 acpi_ut_get_object_type_name
543 (new_desc)));
544 }
545 break;
546
547 case ACPI_TYPE_BUFFER_FIELD:
548 case ACPI_TYPE_LOCAL_REGION_FIELD:
549 case ACPI_TYPE_LOCAL_BANK_FIELD:
550 case ACPI_TYPE_LOCAL_INDEX_FIELD:
551
552
553
554
555
556
557 status = acpi_ex_write_data_to_field(source_desc, target_desc,
558 &walk_state->result_obj);
559 break;
560
561 default:
562
563
564
565
566
567
568
569
570 status =
571 acpi_ex_store_direct_to_node(source_desc, node, walk_state);
572 break;
573 }
574
575 return_ACPI_STATUS(status);
576}
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593static acpi_status
594acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
595 struct acpi_namespace_node *node,
596 struct acpi_walk_state *walk_state)
597{
598 acpi_status status;
599 union acpi_operand_object *new_desc;
600
601 ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
602
603 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
604 "Storing [%s] (%p) directly into node [%s] (%p)"
605 " with no implicit conversion\n",
606 acpi_ut_get_object_type_name(source_desc),
607 source_desc, acpi_ut_get_type_name(node->type),
608 node));
609
610
611
612 status =
613 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
614 if (ACPI_FAILURE(status)) {
615 return_ACPI_STATUS(status);
616 }
617
618
619
620 status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
621 acpi_ut_remove_reference(new_desc);
622 return_ACPI_STATUS(status);
623}
624