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