1/******************************************************************************* 2 * 3 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 4 * $Revision: 1.1.1.1 $ 5 * 6 ******************************************************************************/ 7 8/* 9 * Copyright (C) 2000, 2001 R. Byron Moore 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 27#include "acpi.h" 28#include "amlcode.h" 29#include "acinterp.h" 30#include "acnamesp.h" 31#include "acdispat.h" 32 33 34#define _COMPONENT ACPI_NAMESPACE 35 MODULE_NAME ("nsaccess") 36 37 38/******************************************************************************* 39 * 40 * FUNCTION: Acpi_ns_root_initialize 41 * 42 * PARAMETERS: None 43 * 44 * RETURN: Status 45 * 46 * DESCRIPTION: Allocate and initialize the default root named objects 47 * 48 * MUTEX: Locks namespace for entire execution 49 * 50 ******************************************************************************/ 51 52acpi_status 53acpi_ns_root_initialize (void) 54{ 55 acpi_status status = AE_OK; 56 const predefined_names *init_val = NULL; 57 acpi_namespace_node *new_node; 58 acpi_operand_object *obj_desc; 59 60 61 FUNCTION_TRACE ("Ns_root_initialize"); 62 63 64 acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); 65 66 /* 67 * The global root ptr is initially NULL, so a non-NULL value indicates 68 * that Acpi_ns_root_initialize() has already been called; just return. 69 */ 70 if (acpi_gbl_root_node) { 71 status = AE_OK; 72 goto unlock_and_exit; 73 } 74 75 76 /* 77 * Tell the rest of the subsystem that the root is initialized 78 * (This is OK because the namespace is locked) 79 */ 80 acpi_gbl_root_node = &acpi_gbl_root_node_struct; 81 82 83 /* Enter the pre-defined names in the name table */ 84 85 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); 86 87 for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { 88 status = acpi_ns_lookup (NULL, init_val->name, init_val->type, 89 IMODE_LOAD_PASS2, NS_NO_UPSEARCH, 90 NULL, &new_node); 91 92 if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ { 93 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 94 "Could not create predefined name %s, %s\n", 95 init_val->name, acpi_format_exception (status))); 96 } 97 98 /* 99 * Name entered successfully. 100 * If entry in Pre_defined_names[] specifies an 101 * initial value, create the initial value. 102 */ 103 if (init_val->val) { 104 /* 105 * Entry requests an initial value, allocate a 106 * descriptor for it. 107 */ 108 obj_desc = acpi_ut_create_internal_object (init_val->type); 109 if (!obj_desc) { 110 status = AE_NO_MEMORY; 111 goto unlock_and_exit; 112 } 113 114 /* 115 * Convert value string from table entry to 116 * internal representation. Only types actually 117 * used for initial values are implemented here. 118 */ 119 120 switch (init_val->type) { 121 122 case ACPI_TYPE_INTEGER: 123 124 obj_desc->integer.value = 125 (acpi_integer) STRTOUL (init_val->val, NULL, 10); 126 break; 127 128 129 case ACPI_TYPE_STRING: 130 131 /* 132 * Build an object around the static string 133 */ 134 obj_desc->string.length = STRLEN (init_val->val); 135 obj_desc->string.pointer = init_val->val; 136 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; 137 break; 138 139 140 case ACPI_TYPE_MUTEX: 141 142 obj_desc->mutex.sync_level = 143 (u16) STRTOUL (init_val->val, NULL, 10); 144 145 if (STRCMP (init_val->name, "_GL_") == 0) { 146 /* 147 * Create a counting semaphore for the 148 * global lock 149 */ 150 status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 151 1, &obj_desc->mutex.semaphore); 152 153 if (ACPI_FAILURE (status)) { 154 goto unlock_and_exit; 155 } 156 157 /* 158 * We just created the mutex for the 159 * global lock, save it 160 */ 161 acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore; 162 } 163 164 else { 165 /* Create a mutex */ 166 167 status = acpi_os_create_semaphore (1, 1, 168 &obj_desc->mutex.semaphore); 169 170 if (ACPI_FAILURE (status)) { 171 goto unlock_and_exit; 172 } 173 } 174 break; 175 176 177 default: 178 REPORT_ERROR (("Unsupported initial type value %X\n", 179 init_val->type)); 180 acpi_ut_remove_reference (obj_desc); 181 obj_desc = NULL; 182 continue; 183 } 184 185 /* Store pointer to value descriptor in the Node */ 186 187 acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type); 188 189 /* Remove local reference to the object */ 190 191 acpi_ut_remove_reference (obj_desc); 192 } 193 } 194 195 196unlock_and_exit: 197 acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); 198 return_ACPI_STATUS (status); 199} 200 201 202/******************************************************************************* 203 * 204 * FUNCTION: Acpi_ns_lookup 205 * 206 * PARAMETERS: Prefix_node - Search scope if name is not fully qualified 207 * Pathname - Search pathname, in internal format 208 * (as represented in the AML stream) 209 * Type - Type associated with name 210 * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found 211 * Flags - Flags describing the search restrictions 212 * Walk_state - Current state of the walk 213 * Return_node - Where the Node is placed (if found 214 * or created successfully) 215 * 216 * RETURN: Status 217 * 218 * DESCRIPTION: Find or enter the passed name in the name space. 219 * Log an error if name not found in Exec mode. 220 * 221 * MUTEX: Assumes namespace is locked. 222 * 223 ******************************************************************************/ 224 225acpi_status 226acpi_ns_lookup ( 227 acpi_generic_state *scope_info, 228 NATIVE_CHAR *pathname, 229 acpi_object_type8 type, 230 operating_mode interpreter_mode, 231 u32 flags, 232 acpi_walk_state *walk_state, 233 acpi_namespace_node **return_node) 234{ 235 acpi_status status; 236 acpi_namespace_node *prefix_node; 237 acpi_namespace_node *current_node = NULL; 238 acpi_namespace_node *scope_to_push = NULL; 239 acpi_namespace_node *this_node = NULL; 240 u32 num_segments; 241 acpi_name simple_name; 242 u8 null_name_path = FALSE; 243 acpi_object_type8 type_to_check_for; 244 acpi_object_type8 this_search_type; 245 u32 local_flags = flags & ~NS_ERROR_IF_FOUND; 246 247 DEBUG_EXEC (u32 i;) 248 249 250 FUNCTION_TRACE ("Ns_lookup"); 251 252 253 if (!return_node) { 254 return_ACPI_STATUS (AE_BAD_PARAMETER); 255 } 256 257 258 acpi_gbl_ns_lookup_count++; 259 260 *return_node = ENTRY_NOT_FOUND; 261 262 263 if (!acpi_gbl_root_node) { 264 return (AE_NO_NAMESPACE); 265 } 266 267 /* 268 * Get the prefix scope. 269 * A null scope means use the root scope 270 */ 271 if ((!scope_info) || 272 (!scope_info->scope.node)) { 273 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Null scope prefix, using root node (%p)\n", 274 acpi_gbl_root_node)); 275 276 prefix_node = acpi_gbl_root_node; 277 } 278 else { 279 prefix_node = scope_info->scope.node; 280 } 281 282 283 /* 284 * This check is explicitly split to relax the Type_to_check_for 285 * conditions for Bank_field_defn. Originally, both Bank_field_defn and 286 * Def_field_defn caused Type_to_check_for to be set to ACPI_TYPE_REGION, 287 * but the Bank_field_defn may also check for a Field definition as well 288 * as an Operation_region. 289 */ 290 if (INTERNAL_TYPE_FIELD_DEFN == type) { 291 /* Def_field_defn defines fields in a Region */ 292 293 type_to_check_for = ACPI_TYPE_REGION; 294 } 295 296 else if (INTERNAL_TYPE_BANK_FIELD_DEFN == type) { 297 /* Bank_field_defn defines data fields in a Field Object */ 298 299 type_to_check_for = ACPI_TYPE_ANY; 300 } 301 302 else { 303 type_to_check_for = type; 304 } 305 306 307 /* TBD: [Restructure] - Move the pathname stuff into a new procedure */ 308 309 /* Examine the name pointer */ 310 311 if (!pathname) { 312 /* 8-12-98 ASL Grammar Update supports null Name_path */ 313 314 null_name_path = TRUE; 315 num_segments = 0; 316 this_node = acpi_gbl_root_node; 317 318 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 319 "Null Pathname (Zero segments), Flags=%x\n", flags)); 320 } 321 322 else { 323 /* 324 * Valid name pointer (Internal name format) 325 * 326 * Check for prefixes. As represented in the AML stream, a 327 * Pathname consists of an optional scope prefix followed by 328 * a segment part. 329 * 330 * If present, the scope prefix is either a Root_prefix (in 331 * which case the name is fully qualified), or zero or more 332 * Parent_prefixes (in which case the name's scope is relative 333 * to the current scope). 334 * 335 * The segment part consists of either: 336 * - A single 4-byte name segment, or 337 * - A Dual_name_prefix followed by two 4-byte name segments, or 338 * - A Multi_name_prefix_op, followed by a byte indicating the 339 * number of segments and the segments themselves. 340 */ 341 if (*pathname == AML_ROOT_PREFIX) { 342 /* Pathname is fully qualified, look in root name table */ 343 344 current_node = acpi_gbl_root_node; 345 346 /* point to segment part */ 347 348 pathname++; 349 350 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching from root [%p]\n", 351 current_node)); 352 353 /* Direct reference to root, "\" */ 354 355 if (!(*pathname)) { 356 this_node = acpi_gbl_root_node; 357 goto check_for_new_scope_and_exit; 358 } 359 } 360 361 else { 362 /* Pathname is relative to current scope, start there */ 363 364 current_node = prefix_node; 365 366 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching relative to pfx scope [%p]\n", 367 prefix_node)); 368 369 /* 370 * Handle up-prefix (carat). More than one prefix 371 * is supported 372 */ 373 while (*pathname == AML_PARENT_PREFIX) { 374 /* Point to segment part or next Parent_prefix */ 375 376 pathname++; 377 378 /* Backup to the parent's scope */ 379 380 this_node = acpi_ns_get_parent_object (current_node); 381 if (!this_node) { 382 /* Current scope has no parent scope */ 383 384 REPORT_ERROR ( 385 ("Too many parent prefixes (^) - reached root\n")); 386 return_ACPI_STATUS (AE_NOT_FOUND); 387 } 388 389 current_node = this_node; 390 } 391 } 392 393 394 /* 395 * Examine the name prefix opcode, if any, 396 * to determine the number of segments 397 */ 398 if (*pathname == AML_DUAL_NAME_PREFIX) { 399 num_segments = 2; 400 401 /* point to first segment */ 402 403 pathname++; 404 405 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 406 "Dual Pathname (2 segments, Flags=%X)\n", flags)); 407 } 408 409 else if (*pathname == AML_MULTI_NAME_PREFIX_OP) { 410 num_segments = (u32)* (u8 *) ++pathname; 411 412 /* point to first segment */ 413 414 pathname++; 415 416 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 417 "Multi Pathname (%d Segments, Flags=%X) \n", 418 num_segments, flags)); 419 } 420 421 else { 422 /* 423 * No Dual or Multi prefix, hence there is only one 424 * segment and Pathname is already pointing to it. 425 */ 426 num_segments = 1; 427 428 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 429 "Simple Pathname (1 segment, Flags=%X)\n", flags)); 430 } 431 432#ifdef ACPI_DEBUG 433 434 /* TBD: [Restructure] Make this a procedure */ 435 436 /* Debug only: print the entire name that we are about to lookup */ 437 438 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); 439 440 for (i = 0; i < num_segments; i++) { 441 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%4.4s/", (char*)&pathname[i * 4])); 442 } 443 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "]\n")); 444#endif 445 } 446 447 448 /* 449 * Search namespace for each segment of the name. 450 * Loop through and verify/add each name segment. 451 */ 452 while (num_segments-- && current_node) { 453 /* 454 * Search for the current name segment under the current 455 * named object. The Type is significant only at the last (topmost) 456 * level. (We don't care about the types along the path, only 457 * the type of the final target object.) 458 */ 459 this_search_type = ACPI_TYPE_ANY; 460 if (!num_segments) { 461 this_search_type = type; 462 local_flags = flags; 463 } 464 465 /* Pluck one ACPI name from the front of the pathname */ 466 467 MOVE_UNALIGNED32_TO_32 (&simple_name, pathname); 468 469 /* Try to find the ACPI name */ 470 471 status = acpi_ns_search_and_enter (simple_name, walk_state, 472 current_node, interpreter_mode, 473 this_search_type, local_flags, 474 &this_node); 475 476 if (ACPI_FAILURE (status)) { 477 if (status == AE_NOT_FOUND) { 478 /* Name not found in ACPI namespace */ 479 480 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 481 "Name [%4.4s] not found in scope %p\n", 482 (char*)&simple_name, current_node)); 483 } 484 485 return_ACPI_STATUS (status); 486 } 487 488 489 /* 490 * If 1) This is the last segment (Num_segments == 0) 491 * 2) and looking for a specific type 492 * (Not checking for TYPE_ANY) 493 * 3) Which is not an alias 494 * 4) which is not a local type (TYPE_DEF_ANY) 495 * 5) which is not a local type (TYPE_SCOPE) 496 * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN) 497 * 7) and type of object is known (not TYPE_ANY) 498 * 8) and object does not match request 499 * 500 * Then we have a type mismatch. Just warn and ignore it. 501 */ 502 if ((num_segments == 0) && 503 (type_to_check_for != ACPI_TYPE_ANY) && 504 (type_to_check_for != INTERNAL_TYPE_ALIAS) && 505 (type_to_check_for != INTERNAL_TYPE_DEF_ANY) && 506 (type_to_check_for != INTERNAL_TYPE_SCOPE) && 507 (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) && 508 (this_node->type != ACPI_TYPE_ANY) && 509 (this_node->type != type_to_check_for)) { 510 /* Complain about a type mismatch */ 511 512 REPORT_WARNING ( 513 ("Ns_lookup: %4.4s, type %X, checking for type %X\n", 514 (char*)&simple_name, this_node->type, type_to_check_for)); 515 } 516 517 /* 518 * If this is the last name segment and we are not looking for a 519 * specific type, but the type of found object is known, use that type 520 * to see if it opens a scope. 521 */ 522 if ((0 == num_segments) && (ACPI_TYPE_ANY == type)) { 523 type = this_node->type; 524 } 525 526 if ((num_segments || acpi_ns_opens_scope (type)) && 527 (this_node->child == NULL)) { 528 /* 529 * More segments or the type implies enclosed scope, 530 * and the next scope has not been allocated. 531 */ 532 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Load mode=%X This_node=%p\n", 533 interpreter_mode, this_node)); 534 } 535 536 current_node = this_node; 537 538 /* point to next name segment */ 539 540 pathname += ACPI_NAME_SIZE; 541 } 542 543 544 /* 545 * Always check if we need to open a new scope 546 */ 547check_for_new_scope_and_exit: 548 549 if (!(flags & NS_DONT_OPEN_SCOPE) && (walk_state)) { 550 /* 551 * If entry is a type which opens a scope, 552 * push the new scope on the scope stack. 553 */ 554 if (acpi_ns_opens_scope (type_to_check_for)) { 555 /* 8-12-98 ASL Grammar Update supports null Name_path */ 556 557 if (null_name_path) { 558 /* TBD: [Investigate] - is this the correct thing to do? */ 559 560 scope_to_push = NULL; 561 } 562 else { 563 scope_to_push = this_node; 564 } 565 566 status = acpi_ds_scope_stack_push (scope_to_push, type, 567 walk_state); 568 if (ACPI_FAILURE (status)) { 569 return_ACPI_STATUS (status); 570 } 571 572 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Set global scope to %p\n", scope_to_push)); 573 } 574 } 575 576 *return_node = this_node; 577 return_ACPI_STATUS (AE_OK); 578} 579 580