0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "amlcode.h"
0014 #include "acdispat.h"
0015 #include "acinterp.h"
0016 #include "acparser.h"
0017
0018 #define _COMPONENT ACPI_NAMESPACE
0019 ACPI_MODULE_NAME("dspkginit")
0020
0021
0022 static void
0023 acpi_ds_resolve_package_element(union acpi_operand_object **element);
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 acpi_status
0055 acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
0056 union acpi_parse_object *op,
0057 u32 element_count,
0058 union acpi_operand_object **obj_desc_ptr)
0059 {
0060 union acpi_parse_object *arg;
0061 union acpi_parse_object *parent;
0062 union acpi_operand_object *obj_desc = NULL;
0063 acpi_status status = AE_OK;
0064 u8 module_level_code = FALSE;
0065 u16 reference_count;
0066 u32 index;
0067 u32 i;
0068
0069 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
0070
0071
0072
0073 if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
0074 module_level_code = TRUE;
0075 }
0076
0077
0078
0079 parent = op->common.parent;
0080 while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
0081 (parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP)) {
0082 parent = parent->common.parent;
0083 }
0084
0085
0086
0087
0088
0089
0090 obj_desc = *obj_desc_ptr;
0091 if (!obj_desc) {
0092 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
0093 *obj_desc_ptr = obj_desc;
0094 if (!obj_desc) {
0095 return_ACPI_STATUS(AE_NO_MEMORY);
0096 }
0097
0098 obj_desc->package.node = parent->common.node;
0099 }
0100
0101 if (obj_desc->package.flags & AOPOBJ_DATA_VALID) {
0102 return_ACPI_STATUS(AE_OK);
0103 }
0104
0105
0106
0107
0108
0109
0110
0111 if (!obj_desc->package.elements) {
0112 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
0113 element_count
0114 +
0115 1) *
0116 sizeof(void
0117 *));
0118
0119 if (!obj_desc->package.elements) {
0120 acpi_ut_delete_object_desc(obj_desc);
0121 return_ACPI_STATUS(AE_NO_MEMORY);
0122 }
0123
0124 obj_desc->package.count = element_count;
0125 }
0126
0127
0128
0129 arg = op->common.value.arg;
0130 arg = arg->common.next;
0131
0132
0133
0134
0135
0136
0137
0138 if (module_level_code) {
0139 obj_desc->package.aml_start = walk_state->aml;
0140 obj_desc->package.aml_length = 0;
0141
0142 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
0143 "%s: Deferring resolution of Package elements\n",
0144 ACPI_GET_FUNCTION_NAME));
0145 }
0146
0147
0148
0149
0150
0151
0152
0153 for (i = 0; arg && (i < element_count); i++) {
0154 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
0155 if (!arg->common.node) {
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 ACPI_EXCEPTION((AE_INFO, AE_SUPPORT,
0172 "Expressions within package elements are not supported"));
0173
0174
0175
0176 acpi_ut_remove_reference(walk_state->results->
0177 results.obj_desc[0]);
0178 return_ACPI_STATUS(AE_SUPPORT);
0179 }
0180
0181 if (arg->common.node->type == ACPI_TYPE_METHOD) {
0182
0183
0184
0185
0186 arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
0187 status =
0188 acpi_ds_build_internal_object(walk_state,
0189 arg,
0190 &obj_desc->
0191 package.
0192 elements[i]);
0193 } else {
0194
0195
0196 obj_desc->package.elements[i] =
0197 ACPI_CAST_PTR(union acpi_operand_object,
0198 arg->common.node);
0199 }
0200 } else {
0201 status =
0202 acpi_ds_build_internal_object(walk_state, arg,
0203 &obj_desc->package.
0204 elements[i]);
0205 if (status == AE_NOT_FOUND) {
0206 ACPI_ERROR((AE_INFO, "%-48s",
0207 "****DS namepath not found"));
0208 }
0209
0210 if (!module_level_code) {
0211
0212
0213
0214
0215
0216
0217 acpi_ds_init_package_element(0,
0218 obj_desc->package.
0219 elements[i], NULL,
0220 &obj_desc->package.
0221 elements[i]);
0222 }
0223 }
0224
0225 if (*obj_desc_ptr) {
0226
0227
0228
0229 reference_count =
0230 (*obj_desc_ptr)->common.reference_count;
0231 if (reference_count > 1) {
0232
0233
0234
0235
0236 for (index = 0;
0237 index < ((u32)reference_count - 1);
0238 index++) {
0239 acpi_ut_add_reference((obj_desc->
0240 package.
0241 elements[i]));
0242 }
0243 }
0244 }
0245
0246 arg = arg->common.next;
0247 }
0248
0249
0250
0251 if (arg) {
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 while (arg) {
0265
0266
0267
0268
0269 if (arg->common.node) {
0270 acpi_ut_remove_reference(ACPI_CAST_PTR
0271 (union
0272 acpi_operand_object,
0273 arg->common.node));
0274 arg->common.node = NULL;
0275 }
0276
0277
0278
0279 i++;
0280 arg = arg->common.next;
0281 }
0282
0283 ACPI_INFO(("Actual Package length (%u) is larger than "
0284 "NumElements field (%u), truncated",
0285 i, element_count));
0286 } else if (i < element_count) {
0287
0288
0289
0290
0291
0292
0293
0294 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
0295 "%s: Package List length (%u) smaller than NumElements "
0296 "count (%u), padded with null elements\n",
0297 ACPI_GET_FUNCTION_NAME, i,
0298 element_count));
0299 }
0300
0301
0302
0303 if (!module_level_code) {
0304 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
0305 }
0306
0307 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
0308 return_ACPI_STATUS(status);
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 acpi_status
0324 acpi_ds_init_package_element(u8 object_type,
0325 union acpi_operand_object *source_object,
0326 union acpi_generic_state *state, void *context)
0327 {
0328 union acpi_operand_object **element_ptr;
0329
0330 ACPI_FUNCTION_TRACE(ds_init_package_element);
0331
0332 if (!source_object) {
0333 return_ACPI_STATUS(AE_OK);
0334 }
0335
0336
0337
0338
0339
0340
0341
0342 if (context) {
0343
0344
0345
0346 element_ptr = (union acpi_operand_object **)context;
0347 } else {
0348
0349
0350 element_ptr = state->pkg.this_target_obj;
0351 }
0352
0353
0354
0355 if (source_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
0356
0357
0358
0359 acpi_ds_resolve_package_element(element_ptr);
0360 } else if (source_object->common.type == ACPI_TYPE_PACKAGE) {
0361 source_object->package.flags |= AOPOBJ_DATA_VALID;
0362 }
0363
0364 return_ACPI_STATUS(AE_OK);
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static void
0381 acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
0382 {
0383 acpi_status status;
0384 acpi_status status2;
0385 union acpi_generic_state scope_info;
0386 union acpi_operand_object *element = *element_ptr;
0387 struct acpi_namespace_node *resolved_node;
0388 struct acpi_namespace_node *original_node;
0389 char *external_path = "";
0390 acpi_object_type type;
0391
0392 ACPI_FUNCTION_TRACE(ds_resolve_package_element);
0393
0394
0395
0396 if (element->reference.resolved) {
0397 ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
0398 "%s: Package element is already resolved\n",
0399 ACPI_GET_FUNCTION_NAME));
0400
0401 return_VOID;
0402 }
0403
0404
0405
0406 scope_info.scope.node = element->reference.node;
0407
0408 status = acpi_ns_lookup(&scope_info, (char *)element->reference.aml,
0409 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
0410 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
0411 NULL, &resolved_node);
0412 if (ACPI_FAILURE(status)) {
0413 if ((status == AE_NOT_FOUND)
0414 && acpi_gbl_ignore_package_resolution_errors) {
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 acpi_ut_remove_reference(*element_ptr);
0430 *element_ptr = NULL;
0431 return_VOID;
0432 }
0433
0434 status2 = acpi_ns_externalize_name(ACPI_UINT32_MAX,
0435 (char *)element->reference.
0436 aml, NULL, &external_path);
0437
0438 ACPI_EXCEPTION((AE_INFO, status,
0439 "While resolving a named reference package element - %s",
0440 external_path));
0441 if (ACPI_SUCCESS(status2)) {
0442 ACPI_FREE(external_path);
0443 }
0444
0445
0446
0447 acpi_ut_remove_reference(*element_ptr);
0448 *element_ptr = NULL;
0449 return_VOID;
0450 } else if (resolved_node->type == ACPI_TYPE_ANY) {
0451
0452
0453
0454 ACPI_ERROR((AE_INFO,
0455 "Could not resolve named package element [%4.4s] in [%4.4s]",
0456 resolved_node->name.ascii,
0457 scope_info.scope.node->name.ascii));
0458 *element_ptr = NULL;
0459 return_VOID;
0460 }
0461
0462
0463
0464
0465
0466 if (resolved_node->type == ACPI_TYPE_LOCAL_ALIAS) {
0467 resolved_node = ACPI_CAST_PTR(struct acpi_namespace_node,
0468 resolved_node->object);
0469 }
0470
0471
0472
0473 element->reference.resolved = TRUE;
0474 element->reference.node = resolved_node;
0475 type = element->reference.node->type;
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 original_node = resolved_node;
0492 status = acpi_ex_resolve_node_to_value(&resolved_node, NULL);
0493 if (ACPI_FAILURE(status)) {
0494 return_VOID;
0495 }
0496
0497 switch (type) {
0498
0499
0500
0501
0502
0503 case ACPI_TYPE_DEVICE:
0504 case ACPI_TYPE_THERMAL:
0505 case ACPI_TYPE_METHOD:
0506 break;
0507
0508 case ACPI_TYPE_MUTEX:
0509 case ACPI_TYPE_POWER:
0510 case ACPI_TYPE_PROCESSOR:
0511 case ACPI_TYPE_EVENT:
0512 case ACPI_TYPE_REGION:
0513
0514
0515
0516 acpi_ut_remove_reference(original_node->object);
0517 break;
0518
0519 default:
0520
0521
0522
0523
0524
0525 acpi_ut_remove_reference(element);
0526 *element_ptr = (union acpi_operand_object *)resolved_node;
0527 break;
0528 }
0529
0530 return_VOID;
0531 }