0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "amlcode.h"
0011 #include "acnamesp.h"
0012 #include "acdispat.h"
0013
0014 #ifdef ACPI_ASL_COMPILER
0015 #include "acdisasm.h"
0016 #endif
0017
0018 #define _COMPONENT ACPI_NAMESPACE
0019 ACPI_MODULE_NAME("nsaccess")
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 acpi_status acpi_ns_root_initialize(void)
0035 {
0036 acpi_status status;
0037 const struct acpi_predefined_names *init_val = NULL;
0038 struct acpi_namespace_node *new_node;
0039 struct acpi_namespace_node *prev_node = NULL;
0040 union acpi_operand_object *obj_desc;
0041 acpi_string val = NULL;
0042
0043 ACPI_FUNCTION_TRACE(ns_root_initialize);
0044
0045 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0046 if (ACPI_FAILURE(status)) {
0047 return_ACPI_STATUS(status);
0048 }
0049
0050
0051
0052
0053
0054 if (acpi_gbl_root_node) {
0055 status = AE_OK;
0056 goto unlock_and_exit;
0057 }
0058
0059
0060
0061
0062
0063 acpi_gbl_root_node = &acpi_gbl_root_node_struct;
0064
0065
0066
0067 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0068 "Entering predefined entries into namespace\n"));
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
0086 status = AE_OK;
0087
0088
0089
0090 if (!strcmp(init_val->name, "_OSI")
0091 && !acpi_gbl_create_osi_method) {
0092 continue;
0093 }
0094
0095
0096
0097
0098
0099
0100
0101 new_node =
0102 acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name));
0103 if (!new_node) {
0104 status = AE_NO_MEMORY;
0105 goto unlock_and_exit;
0106 }
0107
0108 new_node->descriptor_type = ACPI_DESC_TYPE_NAMED;
0109 new_node->type = init_val->type;
0110
0111 if (!prev_node) {
0112 acpi_gbl_root_node_struct.child = new_node;
0113 } else {
0114 prev_node->peer = new_node;
0115 }
0116
0117 new_node->parent = &acpi_gbl_root_node_struct;
0118 prev_node = new_node;
0119
0120
0121
0122
0123
0124 if (init_val->val) {
0125 status = acpi_os_predefined_override(init_val, &val);
0126 if (ACPI_FAILURE(status)) {
0127 ACPI_ERROR((AE_INFO,
0128 "Could not override predefined %s",
0129 init_val->name));
0130 }
0131
0132 if (!val) {
0133 val = init_val->val;
0134 }
0135
0136
0137
0138
0139
0140 obj_desc =
0141 acpi_ut_create_internal_object(init_val->type);
0142 if (!obj_desc) {
0143 status = AE_NO_MEMORY;
0144 goto unlock_and_exit;
0145 }
0146
0147
0148
0149
0150
0151
0152 switch (init_val->type) {
0153 case ACPI_TYPE_METHOD:
0154
0155 obj_desc->method.param_count =
0156 (u8) ACPI_TO_INTEGER(val);
0157 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
0158
0159 #if defined (ACPI_ASL_COMPILER)
0160
0161
0162
0163 new_node->value = obj_desc->method.param_count;
0164 #else
0165
0166
0167 obj_desc->method.info_flags =
0168 ACPI_METHOD_INTERNAL_ONLY;
0169 obj_desc->method.dispatch.implementation =
0170 acpi_ut_osi_implementation;
0171 #endif
0172 break;
0173
0174 case ACPI_TYPE_INTEGER:
0175
0176 obj_desc->integer.value = ACPI_TO_INTEGER(val);
0177 break;
0178
0179 case ACPI_TYPE_STRING:
0180
0181
0182
0183 obj_desc->string.length = (u32)strlen(val);
0184 obj_desc->string.pointer = val;
0185 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
0186 break;
0187
0188 case ACPI_TYPE_MUTEX:
0189
0190 obj_desc->mutex.node = new_node;
0191 obj_desc->mutex.sync_level =
0192 (u8) (ACPI_TO_INTEGER(val) - 1);
0193
0194
0195
0196 status =
0197 acpi_os_create_mutex(&obj_desc->mutex.
0198 os_mutex);
0199 if (ACPI_FAILURE(status)) {
0200 acpi_ut_remove_reference(obj_desc);
0201 goto unlock_and_exit;
0202 }
0203
0204
0205
0206 if (strcmp(init_val->name, "_GL_") == 0) {
0207 acpi_gbl_global_lock_mutex = obj_desc;
0208
0209
0210
0211 status =
0212 acpi_os_create_semaphore(1, 0,
0213 &acpi_gbl_global_lock_semaphore);
0214 if (ACPI_FAILURE(status)) {
0215 acpi_ut_remove_reference
0216 (obj_desc);
0217 goto unlock_and_exit;
0218 }
0219 }
0220 break;
0221
0222 default:
0223
0224 ACPI_ERROR((AE_INFO,
0225 "Unsupported initial type value 0x%X",
0226 init_val->type));
0227 acpi_ut_remove_reference(obj_desc);
0228 obj_desc = NULL;
0229 continue;
0230 }
0231
0232
0233
0234 status = acpi_ns_attach_object(new_node, obj_desc,
0235 obj_desc->common.type);
0236
0237
0238
0239 acpi_ut_remove_reference(obj_desc);
0240 }
0241 }
0242
0243 unlock_and_exit:
0244 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0245
0246
0247
0248 if (ACPI_SUCCESS(status)) {
0249 status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
0250 &acpi_gbl_fadt_gpe_device);
0251 }
0252
0253 return_ACPI_STATUS(status);
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 acpi_status
0280 acpi_ns_lookup(union acpi_generic_state *scope_info,
0281 char *pathname,
0282 acpi_object_type type,
0283 acpi_interpreter_mode interpreter_mode,
0284 u32 flags,
0285 struct acpi_walk_state *walk_state,
0286 struct acpi_namespace_node **return_node)
0287 {
0288 acpi_status status;
0289 char *path = pathname;
0290 char *external_path;
0291 struct acpi_namespace_node *prefix_node;
0292 struct acpi_namespace_node *current_node = NULL;
0293 struct acpi_namespace_node *this_node = NULL;
0294 u32 num_segments;
0295 u32 num_carats;
0296 acpi_name simple_name;
0297 acpi_object_type type_to_check_for;
0298 acpi_object_type this_search_type;
0299 u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
0300 u32 local_flags;
0301 acpi_interpreter_mode local_interpreter_mode;
0302
0303 ACPI_FUNCTION_TRACE(ns_lookup);
0304
0305 if (!return_node) {
0306 return_ACPI_STATUS(AE_BAD_PARAMETER);
0307 }
0308
0309 local_flags = flags &
0310 ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
0311 ACPI_NS_SEARCH_PARENT);
0312 *return_node = ACPI_ENTRY_NOT_FOUND;
0313 acpi_gbl_ns_lookup_count++;
0314
0315 if (!acpi_gbl_root_node) {
0316 return_ACPI_STATUS(AE_NO_NAMESPACE);
0317 }
0318
0319
0320
0321 if ((!scope_info) || (!scope_info->scope.node)) {
0322 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0323 "Null scope prefix, using root node (%p)\n",
0324 acpi_gbl_root_node));
0325
0326 prefix_node = acpi_gbl_root_node;
0327 } else {
0328 prefix_node = scope_info->scope.node;
0329 if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
0330 ACPI_DESC_TYPE_NAMED) {
0331 ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
0332 prefix_node,
0333 acpi_ut_get_descriptor_name(prefix_node)));
0334 return_ACPI_STATUS(AE_AML_INTERNAL);
0335 }
0336
0337 if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
0338
0339
0340
0341
0342
0343 while (!acpi_ns_opens_scope(prefix_node->type) &&
0344 prefix_node->type != ACPI_TYPE_ANY) {
0345 prefix_node = prefix_node->parent;
0346 }
0347 }
0348 }
0349
0350
0351
0352 type_to_check_for = type;
0353
0354
0355
0356
0357 if (!pathname) {
0358
0359
0360
0361 num_segments = 0;
0362 this_node = acpi_gbl_root_node;
0363 path = "";
0364
0365 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0366 "Null Pathname (Zero segments), Flags=%X\n",
0367 flags));
0368 } else {
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 if (*path == (u8) AML_ROOT_PREFIX) {
0383
0384
0385
0386 this_node = acpi_gbl_root_node;
0387 search_parent_flag = ACPI_NS_NO_UPSEARCH;
0388
0389
0390
0391 path++;
0392
0393 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0394 "Path is absolute from root [%p]\n",
0395 this_node));
0396 } else {
0397
0398
0399 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0400 "Searching relative to prefix scope [%4.4s] (%p)\n",
0401 acpi_ut_get_node_name(prefix_node),
0402 prefix_node));
0403
0404
0405
0406
0407
0408 this_node = prefix_node;
0409 num_carats = 0;
0410 while (*path == (u8) AML_PARENT_PREFIX) {
0411
0412
0413
0414 search_parent_flag = ACPI_NS_NO_UPSEARCH;
0415
0416
0417
0418
0419
0420 path++;
0421
0422
0423
0424 num_carats++;
0425 this_node = this_node->parent;
0426 if (!this_node) {
0427
0428
0429
0430
0431 status =
0432 acpi_ns_externalize_name
0433 (ACPI_UINT32_MAX, pathname, NULL,
0434 &external_path);
0435 if (ACPI_SUCCESS(status)) {
0436 ACPI_ERROR((AE_INFO,
0437 "%s: Path has too many parent prefixes (^)",
0438 external_path));
0439
0440 ACPI_FREE(external_path);
0441 }
0442
0443 return_ACPI_STATUS(AE_NOT_FOUND);
0444 }
0445 }
0446
0447 if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
0448 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0449 "Search scope is [%4.4s], path has %u carat(s)\n",
0450 acpi_ut_get_node_name
0451 (this_node), num_carats));
0452 }
0453 }
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 switch (*path) {
0469 case 0:
0470
0471
0472
0473
0474 num_segments = 0;
0475 type = this_node->type;
0476
0477 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0478 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
0479 flags));
0480 break;
0481
0482 case AML_DUAL_NAME_PREFIX:
0483
0484
0485
0486 search_parent_flag = ACPI_NS_NO_UPSEARCH;
0487
0488
0489
0490 num_segments = 2;
0491 path++;
0492
0493 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0494 "Dual Pathname (2 segments, Flags=%X)\n",
0495 flags));
0496 break;
0497
0498 case AML_MULTI_NAME_PREFIX:
0499
0500
0501
0502 search_parent_flag = ACPI_NS_NO_UPSEARCH;
0503
0504
0505
0506 path++;
0507 num_segments = (u32) (u8) * path;
0508 path++;
0509
0510 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0511 "Multi Pathname (%u Segments, Flags=%X)\n",
0512 num_segments, flags));
0513 break;
0514
0515 default:
0516
0517
0518
0519
0520 num_segments = 1;
0521
0522 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0523 "Simple Pathname (1 segment, Flags=%X)\n",
0524 flags));
0525 break;
0526 }
0527
0528 ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
0529 }
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539 this_search_type = ACPI_TYPE_ANY;
0540 current_node = this_node;
0541
0542 while (num_segments && current_node) {
0543 num_segments--;
0544 if (!num_segments) {
0545
0546
0547
0548 this_search_type = type;
0549
0550
0551
0552
0553
0554 if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
0555 (flags & ACPI_NS_SEARCH_PARENT)) {
0556 local_flags |= ACPI_NS_SEARCH_PARENT;
0557 }
0558
0559
0560
0561 if (flags & ACPI_NS_ERROR_IF_FOUND) {
0562 local_flags |= ACPI_NS_ERROR_IF_FOUND;
0563 }
0564
0565
0566
0567 if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
0568 local_flags |= ACPI_NS_OVERRIDE_IF_FOUND;
0569 }
0570 }
0571
0572
0573
0574 local_interpreter_mode = interpreter_mode;
0575 if ((flags & ACPI_NS_PREFIX_MUST_EXIST) && (num_segments > 0)) {
0576
0577
0578
0579 local_interpreter_mode = ACPI_IMODE_EXECUTE;
0580 }
0581
0582
0583
0584 ACPI_MOVE_32_TO_32(&simple_name, path);
0585
0586
0587
0588 status =
0589 acpi_ns_search_and_enter(simple_name, walk_state,
0590 current_node,
0591 local_interpreter_mode,
0592 this_search_type, local_flags,
0593 &this_node);
0594 if (ACPI_FAILURE(status)) {
0595 if (status == AE_NOT_FOUND) {
0596 #if !defined ACPI_ASL_COMPILER
0597 if (flags & ACPI_NS_PREFIX_MUST_EXIST) {
0598 acpi_os_printf(ACPI_MSG_BIOS_ERROR
0599 "Object does not exist: %4.4s\n",
0600 (char *)&simple_name);
0601 }
0602 #endif
0603
0604
0605 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0606 "Name [%4.4s] not found in scope [%4.4s] %p\n",
0607 (char *)&simple_name,
0608 (char *)¤t_node->name,
0609 current_node));
0610 }
0611 #ifdef ACPI_EXEC_APP
0612 if ((status == AE_ALREADY_EXISTS) &&
0613 (this_node->flags & ANOBJ_NODE_EARLY_INIT)) {
0614 this_node->flags &= ~ANOBJ_NODE_EARLY_INIT;
0615 status = AE_OK;
0616 }
0617 #endif
0618
0619 #ifdef ACPI_ASL_COMPILER
0620
0621
0622
0623
0624
0625
0626
0627
0628 if (acpi_gbl_disasm_flag &&
0629 (status == AE_ALREADY_EXISTS) &&
0630 ((this_node->flags & ANOBJ_IS_EXTERNAL) ||
0631 (walk_state
0632 && walk_state->opcode == AML_EXTERNAL_OP))) {
0633 this_node->flags &= ~ANOBJ_IS_EXTERNAL;
0634 this_node->type = (u8)this_search_type;
0635 if (walk_state->opcode != AML_EXTERNAL_OP) {
0636 acpi_dm_mark_external_conflict
0637 (this_node);
0638 }
0639 break;
0640 }
0641 #endif
0642
0643 *return_node = this_node;
0644 return_ACPI_STATUS(status);
0645 }
0646
0647
0648
0649 if (num_segments > 0) {
0650
0651
0652
0653
0654
0655
0656 if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
0657 if (!this_node->object) {
0658 return_ACPI_STATUS(AE_NOT_EXIST);
0659 }
0660
0661 if (acpi_ns_opens_scope
0662 (((struct acpi_namespace_node *)
0663 this_node->object)->type)) {
0664 this_node =
0665 (struct acpi_namespace_node *)
0666 this_node->object;
0667 }
0668 }
0669 }
0670
0671
0672
0673 else {
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687 if ((type_to_check_for != ACPI_TYPE_ANY) &&
0688 (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
0689 (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
0690 && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
0691 && (this_node->type != ACPI_TYPE_ANY)
0692 && (this_node->type != type_to_check_for)) {
0693
0694
0695
0696 ACPI_WARNING((AE_INFO,
0697 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
0698 ACPI_CAST_PTR(char, &simple_name),
0699 acpi_ut_get_type_name(this_node->
0700 type),
0701 acpi_ut_get_type_name
0702 (type_to_check_for)));
0703 }
0704
0705
0706
0707
0708
0709
0710 if (type == ACPI_TYPE_ANY) {
0711 type = this_node->type;
0712 }
0713 }
0714
0715
0716
0717 path += ACPI_NAMESEG_SIZE;
0718 current_node = this_node;
0719 }
0720
0721
0722
0723 if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
0724
0725
0726
0727
0728 if (acpi_ns_opens_scope(type)) {
0729 status =
0730 acpi_ds_scope_stack_push(this_node, type,
0731 walk_state);
0732 if (ACPI_FAILURE(status)) {
0733 return_ACPI_STATUS(status);
0734 }
0735 }
0736 }
0737 #ifdef ACPI_EXEC_APP
0738 if (flags & ACPI_NS_EARLY_INIT) {
0739 this_node->flags |= ANOBJ_NODE_EARLY_INIT;
0740 }
0741 #endif
0742
0743 *return_node = this_node;
0744 return_ACPI_STATUS(AE_OK);
0745 }