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 <acpi/acnamesp.h>
46#include <acpi/amlcode.h>
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utobject")
50
51
52static acpi_status
53acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
54 acpi_size * obj_length);
55
56static acpi_status
57acpi_ut_get_package_object_size(union acpi_operand_object *obj,
58 acpi_size * obj_length);
59
60static acpi_status
61acpi_ut_get_element_length(u8 object_type,
62 union acpi_operand_object *source_object,
63 union acpi_generic_state *state, void *context);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
87 u32 line_number,
88 u32 component_id,
89 acpi_object_type
90 type)
91{
92 union acpi_operand_object *object;
93 union acpi_operand_object *second_object;
94
95 ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
96 acpi_ut_get_type_name(type));
97
98
99
100 object =
101 acpi_ut_allocate_object_desc_dbg(module_name, line_number,
102 component_id);
103 if (!object) {
104 return_PTR(NULL);
105 }
106
107 switch (type) {
108 case ACPI_TYPE_REGION:
109 case ACPI_TYPE_BUFFER_FIELD:
110
111
112
113 second_object = acpi_ut_allocate_object_desc_dbg(module_name,
114 line_number,
115 component_id);
116 if (!second_object) {
117 acpi_ut_delete_object_desc(object);
118 return_PTR(NULL);
119 }
120
121 second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
122 second_object->common.reference_count = 1;
123
124
125
126 object->common.next_object = second_object;
127 break;
128
129 default:
130
131 break;
132 }
133
134
135
136 object->common.type = (u8) type;
137
138
139
140 object->common.reference_count = 1;
141
142
143
144 return_PTR(object);
145}
146
147
148
149
150
151
152
153
154
155
156
157
158
159union acpi_operand_object *acpi_ut_create_package_object(u32 count)
160{
161 union acpi_operand_object *package_desc;
162 union acpi_operand_object **package_elements;
163
164 ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
165
166
167
168 package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
169 if (!package_desc) {
170 return_PTR(NULL);
171 }
172
173
174
175
176
177 package_elements = ACPI_ALLOCATE_ZEROED((acpi_size)
178 (count + 1) * sizeof(void *));
179 if (!package_elements) {
180 acpi_ut_remove_reference(package_desc);
181 return_PTR(NULL);
182 }
183
184 package_desc->package.count = count;
185 package_desc->package.elements = package_elements;
186 return_PTR(package_desc);
187}
188
189
190
191
192
193
194
195
196
197
198
199
200
201union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
202{
203 union acpi_operand_object *buffer_desc;
204 u8 *buffer = NULL;
205
206 ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
207
208
209
210 buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
211 if (!buffer_desc) {
212 return_PTR(NULL);
213 }
214
215
216
217 if (buffer_size > 0) {
218
219
220
221 buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
222 if (!buffer) {
223 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
224 (u32) buffer_size));
225 acpi_ut_remove_reference(buffer_desc);
226 return_PTR(NULL);
227 }
228 }
229
230
231
232 buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
233 buffer_desc->buffer.pointer = buffer;
234 buffer_desc->buffer.length = (u32) buffer_size;
235
236
237
238 return_PTR(buffer_desc);
239}
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
256{
257 union acpi_operand_object *string_desc;
258 char *string;
259
260 ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
261
262
263
264 string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
265 if (!string_desc) {
266 return_PTR(NULL);
267 }
268
269
270
271
272
273 string = ACPI_ALLOCATE_ZEROED(string_size + 1);
274 if (!string) {
275 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
276 (u32) string_size));
277 acpi_ut_remove_reference(string_desc);
278 return_PTR(NULL);
279 }
280
281
282
283 string_desc->string.pointer = string;
284 string_desc->string.length = (u32) string_size;
285
286
287
288 return_PTR(string_desc);
289}
290
291
292
293
294
295
296
297
298
299
300
301
302
303u8 acpi_ut_valid_internal_object(void *object)
304{
305
306 ACPI_FUNCTION_NAME(ut_valid_internal_object);
307
308
309
310 if (!object) {
311 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
312 return (FALSE);
313 }
314
315
316
317 switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
318 case ACPI_DESC_TYPE_OPERAND:
319
320
321
322 return (TRUE);
323
324 default:
325 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
326 "%p is not not an ACPI operand obj [%s]\n",
327 object, acpi_ut_get_descriptor_name(object)));
328 break;
329 }
330
331 return (FALSE);
332}
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349void *acpi_ut_allocate_object_desc_dbg(char *module_name,
350 u32 line_number, u32 component_id)
351{
352 union acpi_operand_object *object;
353
354 ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
355
356 object = acpi_os_acquire_object(acpi_gbl_operand_cache);
357 if (!object) {
358 ACPI_ERROR((module_name, line_number,
359 "Could not allocate an object descriptor"));
360
361 return_PTR(NULL);
362 }
363
364
365
366 memset(object, 0, sizeof(union acpi_operand_object));
367 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
368
369 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
370 object, (u32) sizeof(union acpi_operand_object)));
371
372 return_PTR(object);
373}
374
375
376
377
378
379
380
381
382
383
384
385
386
387void acpi_ut_delete_object_desc(union acpi_operand_object *object)
388{
389 ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
390
391
392
393 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
394 ACPI_ERROR((AE_INFO,
395 "%p is not an ACPI Operand object [%s]", object,
396 acpi_ut_get_descriptor_name(object)));
397 return_VOID;
398 }
399
400 (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
401 return_VOID;
402}
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421static acpi_status
422acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
423 acpi_size * obj_length)
424{
425 acpi_size length;
426 acpi_status status = AE_OK;
427
428 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
429
430
431
432
433
434 if (!internal_object) {
435 *obj_length = sizeof(union acpi_object);
436 return_ACPI_STATUS(AE_OK);
437 }
438
439
440
441 length = sizeof(union acpi_object);
442
443 if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
444
445
446
447 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
448 return_ACPI_STATUS(status);
449 }
450
451
452
453
454
455
456
457 switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
458 case ACPI_TYPE_STRING:
459
460 length += (acpi_size) internal_object->string.length + 1;
461 break;
462
463 case ACPI_TYPE_BUFFER:
464
465 length += (acpi_size) internal_object->buffer.length;
466 break;
467
468 case ACPI_TYPE_INTEGER:
469 case ACPI_TYPE_PROCESSOR:
470 case ACPI_TYPE_POWER:
471
472
473
474
475 break;
476
477 case ACPI_TYPE_LOCAL_REFERENCE:
478
479 switch (internal_object->reference.opcode) {
480 case AML_INT_NAMEPATH_OP:
481
482
483
484
485
486 length +=
487 ACPI_ROUND_UP_TO_NATIVE_WORD
488 (acpi_ns_get_pathname_length
489 (internal_object->reference.node));
490 break;
491
492 default:
493
494
495
496
497
498
499 ACPI_ERROR((AE_INFO,
500 "Unsupported Reference opcode=%X in object %p",
501 internal_object->reference.opcode,
502 internal_object));
503 status = AE_TYPE;
504 break;
505 }
506 break;
507
508 default:
509
510 ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p",
511 ACPI_GET_OBJECT_TYPE(internal_object),
512 internal_object));
513 status = AE_TYPE;
514 break;
515 }
516
517
518
519
520
521
522
523 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
524 return_ACPI_STATUS(status);
525}
526
527
528
529
530
531
532
533
534
535
536
537
538
539static acpi_status
540acpi_ut_get_element_length(u8 object_type,
541 union acpi_operand_object *source_object,
542 union acpi_generic_state *state, void *context)
543{
544 acpi_status status = AE_OK;
545 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
546 acpi_size object_space;
547
548 switch (object_type) {
549 case ACPI_COPY_TYPE_SIMPLE:
550
551
552
553
554
555 status =
556 acpi_ut_get_simple_object_size(source_object,
557 &object_space);
558 if (ACPI_FAILURE(status)) {
559 return (status);
560 }
561
562 info->length += object_space;
563 break;
564
565 case ACPI_COPY_TYPE_PACKAGE:
566
567
568
569 info->num_packages++;
570 state->pkg.this_target_obj = NULL;
571 break;
572
573 default:
574
575
576
577 return (AE_BAD_PARAMETER);
578 }
579
580 return (status);
581}
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600static acpi_status
601acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
602 acpi_size * obj_length)
603{
604 acpi_status status;
605 struct acpi_pkg_info info;
606
607 ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
608
609 info.length = 0;
610 info.object_space = 0;
611 info.num_packages = 1;
612
613 status = acpi_ut_walk_package_tree(internal_object, NULL,
614 acpi_ut_get_element_length, &info);
615 if (ACPI_FAILURE(status)) {
616 return_ACPI_STATUS(status);
617 }
618
619
620
621
622
623
624 info.length += ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
625 (acpi_size) info.num_packages;
626
627
628
629 *obj_length = info.length;
630 return_ACPI_STATUS(status);
631}
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647acpi_status
648acpi_ut_get_object_size(union acpi_operand_object *internal_object,
649 acpi_size * obj_length)
650{
651 acpi_status status;
652
653 ACPI_FUNCTION_ENTRY();
654
655 if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
656 ACPI_DESC_TYPE_OPERAND)
657 && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
658 status =
659 acpi_ut_get_package_object_size(internal_object,
660 obj_length);
661 } else {
662 status =
663 acpi_ut_get_simple_object_size(internal_object, obj_length);
664 }
665
666 return (status);
667}
668